1 Star 1 Fork 4

低代码开发/youran源码

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
youran.sql 939.68 KB
一键复制 编辑 原始数据 按行查看 历史
情天可视化 提交于 2021-01-14 17:06 . youran源码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
/*
SQLyog Ultimate v11.24 (32 bit)
MySQL - 5.7.26 : Database - youran
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`youran` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `youran`;
/*Table structure for table `code_template` */
DROP TABLE IF EXISTS `code_template`;
CREATE TABLE `code_template` (
`template_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`code` varchar(32) NOT NULL COMMENT '模板编号',
`name` varchar(32) NOT NULL COMMENT '模板名称',
`template_version` varchar(10) NOT NULL COMMENT '模板版本号',
`sys_low_version` varchar(10) NOT NULL COMMENT '兼容最低系统版本号',
`sys_default` tinyint(4) NOT NULL COMMENT '是否系统默认模板',
`remark` text COMMENT 'markdown备注',
`inner_version` int(11) NOT NULL COMMENT '内部版本号,每次模板有变动都自动加一',
`created_time` datetime NOT NULL COMMENT '创建时间【yyyy-MM-dd HH:mm:ss】',
`created_by` varchar(20) NOT NULL COMMENT '创建人【最大长度20】',
`operated_time` datetime NOT NULL COMMENT '修改时间【yyyy-MM-dd HH:mm:ss】',
`operated_by` varchar(20) NOT NULL COMMENT '修改人【最大长度20】',
`version` int(11) NOT NULL COMMENT '乐观锁版本号【整型】',
`deleted` tinyint(1) NOT NULL COMMENT '逻辑删除标识【0-未删除,1-已删除】',
PRIMARY KEY (`template_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='代码模板';
/*Data for the table `code_template` */
insert into `code_template`(`template_id`,`code`,`name`,`template_version`,`sys_low_version`,`sys_default`,`remark`,`inner_version`,`created_time`,`created_by`,`operated_time`,`operated_by`,`version`,`deleted`) values (1,'youran-template-01','java后端模板','1.3.2','3.4.0',1,'# java后端代码模板\n\n## 1.3.x新特性\n- 支持生成自定义表格和echarts图表的后端服务代码\n- 升级maven依赖\n\n## 介绍\n\n包含如下技术栈:\n- <a href=\"https://spring.io/projects/spring-boot\" target=\"_blank\">spring-boot</a> + <a href=\"http://www.mybatis.org/mybatis-3\" target=\"_blank\">mybatis</a>架构\n- <a href=\"http://hibernate.org/validator/releases\" target=\"_blank\">hibernate-validator</a>\n- <a href=\"https://swagger.io\" target=\"_blank\">swagger</a>(API文档自动生成)\n- <a href=\"http://mapstruct.org\" target=\"_blank\">mapstruct</a>(属性映射)\n- 基于<a href=\"http://www.h2database.com\" target=\"_blank\">H2</a>内存数据库的单元测试\n- <a href=\"https://github.com/alibaba/easyexcel\" target=\"_blank\">easyexcel</a>(excel导入导出)\n\n## 软件架构\n标准的maven模块化结构,包含以下三个模块:\n\n1. common模块\n2. core模块\n3. web模块\n\n#### common模块\n\n和业务无关的通用代码,包括:\n- LoginContext接口\n- dao接口\n- BusinessException异常类\n- 乐观锁相关抽象代码\n- pojo的超类及接口\n- 通用util工具包\n- 防xss相关通用代码\n\n\n#### core模块\n\n和具体业务相关的核心代码,包括:\n- 业务相关dao接口及mybatis的dao.xml\n- 业务相关pojo类\n- 业务相关service类\n\n#### web模块\n\n和具体业务相关的web层代码,包括:\n- 项目启动入口类\n- 包含swagger注解的api文档接口\n- controller类\n- 单元测试代码\n- 单元测试目录下还有数据库建表脚本\n\n\n',0,'2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(2,'youran-template-02','vue前端模板','1.3.0','3.4.0',1,'# vue前端模板\n\n\n## 软件架构\n\n将开源vue管理后台脚手架:\n<a href=\"https://github.com/PanJiaChen/vue-admin-template\" target=\"_blank\">vue-admin-template</a>\n包装成代码模板,所有前端技术细节请参考 <a href=\"https://panjiachen.github.io/vue-element-admin-site/zh/guide/\" target=\"_blank\">vue-element-admin手册</a>\n## 生成的前端工程支持两种开发模式\n\n```\n\n# 前端独立启动,自动mock后端服务\nnpm run dev\n\n# 配合生成的后端服务,前后联调(需要先启动后端服务)\nnpm run dev:joint\n\n```\n',0,'2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0);
/*Table structure for table `gen_history` */
DROP TABLE IF EXISTS `gen_history`;
CREATE TABLE `gen_history` (
`history_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`project_id` int(11) NOT NULL COMMENT '所属项目id',
`remote_url` varchar(256) NOT NULL COMMENT 'Git仓库地址',
`commit` varchar(64) NOT NULL COMMENT 'commit号',
`branch` varchar(32) NOT NULL COMMENT '分支名称',
`sys_version` varchar(20) NOT NULL COMMENT '系统版本号',
`project_version` int(11) NOT NULL COMMENT '项目版本号',
`template_id` int(11) DEFAULT NULL COMMENT '模板id',
`template_inner_version` int(11) DEFAULT NULL COMMENT '模板内部版本号',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`operated_time` datetime DEFAULT NULL COMMENT '操作时间',
`operated_by` varchar(32) DEFAULT NULL COMMENT '操作人',
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
`version` int(11) NOT NULL DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`history_id`),
KEY `i_gen_history_0` (`project_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COMMENT='gen_history';
/*Data for the table `gen_history` */
insert into `gen_history`(`history_id`,`project_id`,`remote_url`,`commit`,`branch`,`sys_version`,`project_version`,`template_id`,`template_inner_version`,`created_time`,`created_by`,`operated_time`,`operated_by`,`deleted`,`version`) values (7,1,'https://gitee.com/huangjun520/blog-test-vue.git','3b98536e50298714b63d62f1e075f9f53bd729ce','auto','3.5.0',70,2,0,'2021-01-12 16:50:50','admin','2021-01-12 16:50:50','admin',0,1),(8,1,'https://gitee.com/huangjun520/blog-test-java.git','3fb2562fe196bb5b71d607152be49b2da94f7e65','auto','3.5.0',70,1,0,'2021-01-12 16:50:59','admin','2021-01-12 16:50:59','admin',0,1),(9,2,'https://gitee.com/low-code-development/shouhou-vue.git','e8f8c511bd436b75ffa7c964ee26b0c0b4eafe57','auto','3.5.0',110,2,0,'2021-01-14 15:27:03','admin','2021-01-14 15:27:03','admin',0,1),(10,2,'https://gitee.com/low-code-development/shouhou-java.git','90cba9c7321c6274e934b92bb0c91a0d04108e40','auto','3.5.0',110,1,0,'2021-01-14 15:27:14','admin','2021-01-14 15:27:14','admin',0,1),(11,2,'https://gitee.com/low-code-development/shouhou-vue.git','b36df38f6821c7ed68ef34dd3820b624638ae8a5','auto','3.5.0',116,2,0,'2021-01-14 16:39:20','admin','2021-01-14 16:39:20','admin',0,1),(12,2,'https://gitee.com/low-code-development/shouhou-java.git','a5e847d3ad44a5c99ad6c92fa0db4787a15c4b4c','auto','3.5.0',116,1,0,'2021-01-14 16:39:29','admin','2021-01-14 16:39:29','admin',0,1);
/*Table structure for table `meta_cascade_ext` */
DROP TABLE IF EXISTS `meta_cascade_ext`;
CREATE TABLE `meta_cascade_ext` (
`cascade_ext_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`project_id` int(11) NOT NULL COMMENT '所属项目id',
`field_id` int(11) NOT NULL COMMENT '所属字段id',
`entity_id` int(11) NOT NULL COMMENT '所属实体id',
`alias` varchar(255) NOT NULL COMMENT '展示字段别名',
`list` tinyint(1) NOT NULL COMMENT '是否在列表中展示',
`show` tinyint(1) NOT NULL COMMENT '是否在详情中展示',
`query` tinyint(1) NOT NULL COMMENT '是否为查询条件',
`cascade_entity_id` int(11) NOT NULL COMMENT '级联实体的id',
`cascade_field_id` int(11) NOT NULL COMMENT '级联展示字段的id',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`operated_time` datetime DEFAULT NULL COMMENT '操作时间',
`operated_by` varchar(32) DEFAULT NULL COMMENT '操作人',
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
`version` int(11) NOT NULL DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`cascade_ext_id`),
KEY `i_meta_cascade_ext_0` (`field_id`) USING BTREE,
KEY `i_meta_cascade_ext_1` (`entity_id`) USING BTREE,
KEY `i_meta_cascade_ext_2` (`cascade_field_id`) USING BTREE,
KEY `i_meta_cascade_ext_3` (`cascade_entity_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COMMENT='级联扩展';
/*Data for the table `meta_cascade_ext` */
insert into `meta_cascade_ext`(`cascade_ext_id`,`project_id`,`field_id`,`entity_id`,`alias`,`list`,`show`,`query`,`cascade_entity_id`,`cascade_field_id`,`created_time`,`created_by`,`operated_time`,`operated_by`,`deleted`,`version`) values (1,1,12,2,'name',1,1,1,1,2,'2021-01-12 10:42:02','admin','2021-01-12 10:42:02','admin',0,1),(2,1,3,1,'pname',1,1,1,1,2,'2021-01-12 11:29:31','admin','2021-01-12 11:29:31','admin',0,1),(3,2,57,8,'customerName',1,1,1,5,29,'2021-01-14 14:05:33','admin','2021-01-14 16:38:17','admin',0,1),(4,2,61,8,'productName',1,1,1,6,39,'2021-01-14 14:06:39','admin','2021-01-14 16:38:26','admin',0,1),(5,2,66,8,'userName',1,1,1,7,46,'2021-01-14 14:07:02','admin','2021-01-14 16:38:34','admin',0,1),(6,2,75,9,'customerName',1,1,1,5,29,'2021-01-14 15:23:18','admin','2021-01-14 16:38:47','admin',0,1),(7,2,76,9,'productName',1,1,1,6,39,'2021-01-14 15:23:34','admin','2021-01-14 16:38:55','admin',0,1),(8,2,81,9,'userName',1,1,1,7,46,'2021-01-14 15:23:49','admin','2021-01-14 16:39:02','admin',0,1);
/*Table structure for table `meta_chart` */
DROP TABLE IF EXISTS `meta_chart`;
CREATE TABLE `meta_chart` (
`chart_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`project_id` int(11) NOT NULL COMMENT '项目id',
`source_id` int(11) NOT NULL COMMENT '数据源id',
`chart_type` tinyint(4) NOT NULL COMMENT '图表类型',
`chart_name` varchar(64) NOT NULL COMMENT '图表名称',
`module` varchar(50) DEFAULT NULL COMMENT '模块名',
`title` varchar(64) NOT NULL COMMENT '图表标题',
`feature` text COMMENT '特性json',
`created_time` datetime NOT NULL COMMENT '创建时间【yyyy-MM-dd HH:mm:ss】',
`created_by` varchar(20) NOT NULL COMMENT '创建人【最大长度20】',
`operated_time` datetime NOT NULL COMMENT '修改时间【yyyy-MM-dd HH:mm:ss】',
`operated_by` varchar(20) NOT NULL COMMENT '修改人【最大长度20】',
`version` int(11) NOT NULL COMMENT '乐观锁版本号【整型】',
`deleted` tinyint(1) NOT NULL COMMENT '逻辑删除标识【0-未删除,1-已删除】',
PRIMARY KEY (`chart_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='图表';
/*Data for the table `meta_chart` */
insert into `meta_chart`(`chart_id`,`project_id`,`source_id`,`chart_type`,`chart_name`,`module`,`title`,`feature`,`created_time`,`created_by`,`operated_time`,`operated_by`,`version`,`deleted`) values (1,1,1,1,'Test','blog','测试1','{\"columnList\":[{\"sourceItemId\":1,\"alias\":\"id\",\"titleAlias\":\"主键\",\"valuePrefix\":\"\",\"valueSuffix\":\"\",\"percent\":false,\"format\":\"\"},{\"sourceItemId\":2,\"alias\":\"title\",\"titleAlias\":\"标题\",\"valuePrefix\":\"\",\"valueSuffix\":\"\",\"percent\":false,\"format\":\"\"},{\"sourceItemId\":3,\"alias\":\"menuId\",\"titleAlias\":\"菜单主键\",\"valuePrefix\":\"\",\"valueSuffix\":\"\",\"percent\":false,\"format\":\"\"},{\"sourceItemId\":4,\"alias\":\"orderNo\",\"titleAlias\":\"排序号\",\"valuePrefix\":\"\",\"valueSuffix\":\"\",\"percent\":false,\"format\":\"\"},{\"sourceItemId\":5,\"alias\":\"operatedBy\",\"titleAlias\":\"修改人\",\"valuePrefix\":\"\",\"valueSuffix\":\"\",\"percent\":false,\"format\":\"\"}],\"hiddenColumnList\":[],\"defaultPageSize\":10,\"excelExport\":true}','2021-01-12 11:08:36','admin','2021-01-12 11:08:36','admin',1,0);
/*Table structure for table `meta_chart_source` */
DROP TABLE IF EXISTS `meta_chart_source`;
CREATE TABLE `meta_chart_source` (
`source_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`project_id` int(11) NOT NULL COMMENT '项目id',
`feature` text COMMENT '特性json',
`aggregation` tinyint(4) NOT NULL COMMENT '是否聚合',
`created_time` datetime NOT NULL COMMENT '创建时间【yyyy-MM-dd HH:mm:ss】',
`created_by` varchar(20) NOT NULL COMMENT '创建人【最大长度20】',
`operated_time` datetime NOT NULL COMMENT '修改时间【yyyy-MM-dd HH:mm:ss】',
`operated_by` varchar(20) NOT NULL COMMENT '修改人【最大长度20】',
`version` int(11) NOT NULL COMMENT '乐观锁版本号【整型】',
`deleted` tinyint(1) NOT NULL COMMENT '逻辑删除标识【0-未删除,1-已删除】',
PRIMARY KEY (`source_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='图表数据源';
/*Data for the table `meta_chart_source` */
insert into `meta_chart_source`(`source_id`,`project_id`,`feature`,`aggregation`,`created_time`,`created_by`,`operated_time`,`operated_by`,`version`,`deleted`) values (1,1,'{\"entityId\":2,\"joins\":[],\"limit\":0}',0,'2021-01-12 11:08:02','admin','2021-01-12 11:08:02','admin',1,0);
/*Table structure for table `meta_chart_source_item` */
DROP TABLE IF EXISTS `meta_chart_source_item`;
CREATE TABLE `meta_chart_source_item` (
`source_item_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`key` varchar(32) NOT NULL COMMENT '唯一键',
`project_id` int(11) NOT NULL COMMENT '项目id',
`source_id` int(11) NOT NULL COMMENT '所属数据源id',
`join_index` tinyint(4) NOT NULL COMMENT '关联实体序号',
`type` tinyint(4) NOT NULL COMMENT '数据项类型',
`parent_id` int(11) DEFAULT NULL COMMENT '父数据项id',
`parent_key` varchar(32) DEFAULT NULL COMMENT '父数据项key',
`feature` text COMMENT '特性json',
`created_time` datetime NOT NULL COMMENT '创建时间【yyyy-MM-dd HH:mm:ss】',
`created_by` varchar(20) NOT NULL COMMENT '创建人【最大长度20】',
`operated_time` datetime NOT NULL COMMENT '修改时间【yyyy-MM-dd HH:mm:ss】',
`operated_by` varchar(20) NOT NULL COMMENT '修改人【最大长度20】',
`version` int(11) NOT NULL COMMENT '乐观锁版本号【整型】',
`deleted` tinyint(1) NOT NULL COMMENT '逻辑删除标识【0-未删除,1-已删除】',
PRIMARY KEY (`source_item_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COMMENT='图表数据源项';
/*Data for the table `meta_chart_source_item` */
insert into `meta_chart_source_item`(`source_item_id`,`key`,`project_id`,`source_id`,`join_index`,`type`,`parent_id`,`parent_key`,`feature`,`created_time`,`created_by`,`operated_time`,`operated_by`,`version`,`deleted`) values (1,'detialColumn_0_6',1,1,0,1,NULL,NULL,'{\"fieldId\":6,\"custom\":false,\"customContent\":null,\"customFieldType\":null}','2021-01-12 11:08:02','admin','2021-01-12 11:08:02','admin',1,0),(2,'detialColumn_0_13',1,1,0,1,NULL,NULL,'{\"fieldId\":13,\"custom\":false,\"customContent\":null,\"customFieldType\":null}','2021-01-12 11:08:02','admin','2021-01-12 11:08:02','admin',1,0),(3,'detialColumn_0_12',1,1,0,1,NULL,NULL,'{\"fieldId\":12,\"custom\":false,\"customContent\":null,\"customFieldType\":null}','2021-01-12 11:08:02','admin','2021-01-12 11:08:02','admin',1,0),(4,'detialColumn_0_10',1,1,0,1,NULL,NULL,'{\"fieldId\":10,\"custom\":false,\"customContent\":null,\"customFieldType\":null}','2021-01-12 11:08:02','admin','2021-01-12 11:08:02','admin',1,0),(5,'detialColumn_0_11',1,1,0,1,NULL,NULL,'{\"fieldId\":11,\"custom\":false,\"customContent\":null,\"customFieldType\":null}','2021-01-12 11:08:02','admin','2021-01-12 11:08:02','admin',1,0);
/*Table structure for table `meta_const` */
DROP TABLE IF EXISTS `meta_const`;
CREATE TABLE `meta_const` (
`const_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '常量类id',
`project_id` int(11) NOT NULL COMMENT '所属项目id',
`const_name` varchar(20) NOT NULL COMMENT '常量类名',
`const_remark` varchar(100) DEFAULT NULL COMMENT '常量名称(中文描述)',
`const_type` int(11) NOT NULL COMMENT '常量字段类型【1-整数,2-字符串】',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`operated_time` datetime DEFAULT NULL COMMENT '操作时间',
`operated_by` varchar(32) DEFAULT NULL COMMENT '操作人',
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
`version` int(11) NOT NULL DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`const_id`),
KEY `i_meta_const_0` (`project_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COMMENT='meta_const';
/*Data for the table `meta_const` */
insert into `meta_const`(`const_id`,`project_id`,`const_name`,`const_remark`,`const_type`,`created_time`,`created_by`,`operated_time`,`operated_by`,`deleted`,`version`) values (1,1,'Sex','性别',1,'2021-01-12 11:04:56','admin','2021-01-12 11:06:10','admin',0,1),(2,2,'ProductType','产品分类',1,'2021-01-14 11:04:30','admin','2021-01-14 11:12:51','admin',0,1),(3,2,'OrderType','工单类型',1,'2021-01-14 11:16:27','admin','2021-01-14 11:16:27','admin',0,1),(4,2,'Role','员工角色',1,'2021-01-14 11:27:02','admin','2021-01-14 11:27:02','admin',0,1),(5,2,'ServerType','服务类型',1,'2021-01-14 11:51:38','admin','2021-01-14 11:51:38','admin',0,1),(6,2,'OrderStatus','工单状态',1,'2021-01-14 11:57:46','admin','2021-01-14 11:57:46','admin',0,1),(7,2,'RepairStatus','报修单状态',1,'2021-01-14 14:27:39','admin','2021-01-14 14:27:39','admin',0,1),(8,2,'RepairType','报修单类型',1,'2021-01-14 15:17:02','admin','2021-01-14 15:17:02','admin',0,1);
/*Table structure for table `meta_const_detail` */
DROP TABLE IF EXISTS `meta_const_detail`;
CREATE TABLE `meta_const_detail` (
`const_detail_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '常量值id',
`project_id` int(11) NOT NULL COMMENT '所属项目id',
`const_id` int(11) NOT NULL COMMENT '常量类id',
`detail_name` varchar(50) NOT NULL COMMENT '常量字段名称',
`detail_value` varchar(50) NOT NULL COMMENT '常量值',
`detail_remark` varchar(100) DEFAULT NULL COMMENT '常量值备注',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`operated_time` datetime DEFAULT NULL COMMENT '操作时间',
`operated_by` varchar(32) DEFAULT NULL COMMENT '操作人',
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
`version` int(11) NOT NULL DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`const_detail_id`),
KEY `i_meta_const_detail_0` (`const_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COMMENT='meta_const_detail';
/*Data for the table `meta_const_detail` */
insert into `meta_const_detail`(`const_detail_id`,`project_id`,`const_id`,`detail_name`,`detail_value`,`detail_remark`,`created_time`,`created_by`,`operated_time`,`operated_by`,`deleted`,`version`) values (1,1,1,'NAN','nana','男','2021-01-12 11:05:46','admin','2021-01-12 11:05:46','admin',1,1),(2,1,1,'NAN','1','男','2021-01-12 11:06:51','admin','2021-01-12 11:06:51','admin',0,1),(3,1,1,'NV','2','女','2021-01-12 11:07:03','admin','2021-01-12 11:07:03','admin',0,1),(4,2,2,'PEIJIAN','1','配件类','2021-01-14 11:05:05','admin','2021-01-14 11:05:05','admin',0,1),(5,2,2,'GONGJU','2','工具类','2021-01-14 11:05:28','admin','2021-01-14 11:05:28','admin',0,1),(6,2,2,'SHEIBEI','3','设备类','2021-01-14 11:05:46','admin','2021-01-14 11:05:46','admin',0,1),(7,2,3,'WEIXIU','1','维修单(默认)','2021-01-14 11:16:57','admin','2021-01-14 11:17:34','admin',0,1),(8,2,3,'FUWU','2','服务单','2021-01-14 11:17:09','admin','2021-01-14 11:17:09','admin',0,1),(9,2,4,'ADMIN','1','超级管理员','2021-01-14 11:27:17','admin','2021-01-14 11:27:17','admin',0,1),(10,2,4,'WEIXIU','2','维修工程师','2021-01-14 11:27:32','admin','2021-01-14 11:27:32','admin',0,1),(11,2,4,'KEFU','3','客服专员','2021-01-14 11:27:51','admin','2021-01-14 11:27:51','admin',0,1),(12,2,5,'BAONEI','1','保内免费','2021-01-14 11:51:52','admin','2021-01-14 11:51:52','admin',0,1),(13,2,5,'BAOWAI','2','保外免费','2021-01-14 11:52:05','admin','2021-01-14 11:52:05','admin',0,1),(14,2,6,'DAIJIESHOU','1','待接受','2021-01-14 11:58:06','admin','2021-01-14 11:58:06','admin',0,1),(15,2,6,'DAIWEIXIU','2','待维修','2021-01-14 11:58:18','admin','2021-01-14 11:58:18','admin',0,1),(16,2,6,'YIWANCHENG','3','已完成','2021-01-14 11:58:34','admin','2021-01-14 11:58:34','admin',0,1),(17,2,6,'YIGUANBI','4','已关闭','2021-01-14 14:19:06','admin','2021-01-14 14:19:06','admin',0,1),(18,2,7,'DAISHOULI','1','待受理','2021-01-14 14:28:21','admin','2021-01-14 14:28:21','admin',0,1),(19,2,7,'DAIWEIXIU','2','待维修','2021-01-14 14:29:02','admin','2021-01-14 14:29:02','admin',0,1),(20,2,7,'WEIXIUZHONG','3','维修中','2021-01-14 14:29:15','admin','2021-01-14 14:29:15','admin',0,1),(21,2,7,'DAIPINGJIA','4','待评价','2021-01-14 14:29:33','admin','2021-01-14 14:29:33','admin',0,1),(22,2,7,'YIJUEJUE','5','已拒绝','2021-01-14 14:29:48','admin','2021-01-14 14:29:48','admin',0,1),(23,2,7,'YIJUJUE','6','已关闭','2021-01-14 14:30:03','admin','2021-01-14 14:30:03','admin',0,1),(24,2,8,'WENTIFANKUI','1','客户问题反馈','2021-01-14 15:17:24','admin','2021-01-14 15:17:24','admin',0,1),(25,2,8,'FUWUQINGQIU','2','服务请求','2021-01-14 15:17:37','admin','2021-01-14 15:17:37','admin',0,1);
/*Table structure for table `meta_dashboard` */
DROP TABLE IF EXISTS `meta_dashboard`;
CREATE TABLE `meta_dashboard` (
`dashboard_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(64) NOT NULL COMMENT '名称',
`title` varchar(64) NOT NULL COMMENT '标题',
`module` varchar(50) DEFAULT NULL COMMENT '模块',
`feature` text COMMENT '特性',
`project_id` int(11) NOT NULL COMMENT '项目id',
`created_time` datetime NOT NULL COMMENT '创建时间【yyyy-MM-dd HH:mm:ss】',
`created_by` varchar(20) NOT NULL COMMENT '创建人【最大长度20】',
`operated_time` datetime NOT NULL COMMENT '修改时间【yyyy-MM-dd HH:mm:ss】',
`operated_by` varchar(20) NOT NULL COMMENT '修改人【最大长度20】',
`version` int(11) NOT NULL COMMENT '乐观锁版本号【整型】',
`deleted` tinyint(1) NOT NULL COMMENT '逻辑删除标识【0-未删除,1-已删除】',
PRIMARY KEY (`dashboard_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='看板';
/*Data for the table `meta_dashboard` */
/*Table structure for table `meta_entity` */
DROP TABLE IF EXISTS `meta_entity`;
CREATE TABLE `meta_entity` (
`entity_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '实体id',
`project_id` int(11) NOT NULL COMMENT '所属项目id',
`schema_name` varchar(20) DEFAULT NULL COMMENT '模式名',
`class_name` varchar(50) NOT NULL COMMENT '类名',
`table_name` varchar(50) NOT NULL COMMENT '表名',
`title` varchar(25) DEFAULT '' COMMENT '标题',
`module` varchar(50) DEFAULT NULL COMMENT '模块',
`desc` varchar(250) DEFAULT NULL COMMENT '实体描述',
`page_sign` tinyint(1) DEFAULT NULL COMMENT '是否支持分页查询',
`feature` text COMMENT '特性json',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`operated_time` datetime DEFAULT NULL COMMENT '操作时间',
`operated_by` varchar(32) DEFAULT NULL COMMENT '操作人',
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
`version` int(11) NOT NULL DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`entity_id`),
KEY `i_meta_entity_0` (`project_id`) USING BTREE,
KEY `i_meta_entity_1` (`project_id`,`class_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COMMENT='meta_entity';
/*Data for the table `meta_entity` */
insert into `meta_entity`(`entity_id`,`project_id`,`schema_name`,`class_name`,`table_name`,`title`,`module`,`desc`,`page_sign`,`feature`,`created_time`,`created_by`,`operated_time`,`operated_by`,`deleted`,`version`) values (1,1,NULL,'Menu','menu','博客菜单','menu','博客菜单',1,'{\"save\":true,\"update\":true,\"delete\":true,\"deleteBatch\":true,\"list\":true,\"show\":true,\"titleFieldId\":2,\"excelExport\":false,\"excelImport\":false}','2021-01-08 17:17:06','admin','2021-01-11 11:05:19','admin',0,1),(2,1,NULL,'Blog','blog','博客','blog','博客文章',1,'{\"save\":true,\"update\":true,\"delete\":true,\"deleteBatch\":true,\"list\":true,\"show\":true,\"titleFieldId\":null,\"excelExport\":true,\"excelImport\":true}','2021-01-08 17:46:07','admin','2021-01-08 17:46:07','admin',0,1),(3,1,'','NewsAccess','news_access','权限表','access','权限表',1,'{\"save\":true,\"update\":true,\"delete\":true,\"deleteBatch\":true,\"list\":true,\"show\":true,\"titleFieldId\":null,\"excelExport\":false,\"excelImport\":false}','2021-01-12 15:27:55','admin','2021-01-12 15:29:02','admin',0,1),(4,1,'','User','user','用户表','user','用户表',1,'{\"save\":true,\"update\":true,\"delete\":true,\"deleteBatch\":true,\"list\":true,\"show\":true,\"titleFieldId\":null,\"excelExport\":false,\"excelImport\":false}','2021-01-12 15:31:01','admin','2021-01-12 15:31:23','admin',0,1),(5,2,NULL,'Customer','customer','客户管理','customer','客户管理',1,'{\"save\":true,\"update\":true,\"delete\":true,\"deleteBatch\":true,\"list\":true,\"show\":true,\"titleFieldId\":29,\"excelExport\":false,\"excelImport\":false}','2021-01-14 10:46:46','admin','2021-01-14 15:26:09','admin',0,1),(6,2,NULL,'Product','product','产品管理','product','产品管理',1,'{\"save\":true,\"update\":true,\"delete\":true,\"deleteBatch\":true,\"list\":true,\"show\":true,\"titleFieldId\":39,\"excelExport\":true,\"excelImport\":true}','2021-01-14 11:00:00','admin','2021-01-14 15:26:26','admin',0,1),(7,2,NULL,'User','user','用户表(员工表)','user','用户表(员工表)',1,'{\"save\":true,\"update\":true,\"delete\":true,\"deleteBatch\":true,\"list\":true,\"show\":true,\"titleFieldId\":46,\"excelExport\":false,\"excelImport\":false}','2021-01-14 11:20:02','admin','2021-01-14 15:26:32','admin',0,1),(8,2,NULL,'Order','order','工单中心','order','工单中心',1,'{\"save\":true,\"update\":true,\"delete\":true,\"deleteBatch\":true,\"list\":true,\"show\":true,\"titleFieldId\":null,\"excelExport\":true,\"excelImport\":true}','2021-01-14 11:35:30','admin','2021-01-14 14:31:46','admin',0,1),(9,2,NULL,'Repair','repair','报修中心','repair','报修中心',1,'{\"save\":true,\"update\":true,\"delete\":true,\"deleteBatch\":true,\"list\":true,\"show\":true,\"titleFieldId\":null,\"excelExport\":true,\"excelImport\":true}','2021-01-14 15:12:20','admin','2021-01-14 15:12:20','admin',0,1);
/*Table structure for table `meta_field` */
DROP TABLE IF EXISTS `meta_field`;
CREATE TABLE `meta_field` (
`field_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`project_id` int(11) NOT NULL COMMENT '所属项目id',
`entity_id` int(11) NOT NULL COMMENT '所属实体id',
`jfield_name` varchar(50) NOT NULL COMMENT '实体字段名称',
`field_name` varchar(64) NOT NULL COMMENT '表字段名称',
`jfield_type` varchar(15) NOT NULL COMMENT '实体字段类型',
`field_type` varchar(15) NOT NULL COMMENT '表字段类型',
`field_desc` varchar(40) NOT NULL COMMENT '字段描述(中文名)',
`field_example` varchar(200) NOT NULL COMMENT '字段示例',
`field_comment` varchar(200) DEFAULT NULL COMMENT '字段备注',
`field_length` int(11) NOT NULL COMMENT '表字段长度',
`field_scale` int(11) DEFAULT NULL COMMENT '表字段精度',
`primary_key` tinyint(1) NOT NULL COMMENT '是否主键',
`auto_increment` tinyint(1) NOT NULL COMMENT '是否自动递增(已弃用,被pk_strategy字段替代)',
`pk_strategy` tinyint(4) DEFAULT NULL COMMENT '主键策略',
`not_null` tinyint(1) NOT NULL COMMENT '是否不能为空',
`default_value` varchar(40) NOT NULL COMMENT '默认值',
`foreign_key` tinyint(1) NOT NULL COMMENT '是否外键',
`foreign_entity_id` int(11) DEFAULT NULL COMMENT '外键实体id',
`foreign_field_id` int(11) DEFAULT NULL COMMENT '外键字段id',
`edit_type` int(11) DEFAULT NULL COMMENT '字段编辑方式:文本框、下拉框等',
`dic_type` varchar(100) DEFAULT NULL COMMENT '字典类型',
`insert` tinyint(1) NOT NULL COMMENT '是否手动插入字段',
`update` tinyint(1) NOT NULL COMMENT '是否手动更新字段',
`list` tinyint(1) NOT NULL COMMENT '是否列表展示字段',
`column_width` smallint(4) DEFAULT NULL COMMENT '列宽',
`list_sort` tinyint(1) NOT NULL COMMENT '是否支持排序',
`show` tinyint(1) NOT NULL COMMENT '是否详情展示字段',
`query` tinyint(1) NOT NULL COMMENT '是否查询字段',
`query_type` smallint(4) DEFAULT NULL COMMENT '查询方式',
`order_no` smallint(4) DEFAULT NULL COMMENT '排序号',
`special_field` varchar(20) DEFAULT NULL COMMENT '特殊字段类型',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`operated_time` datetime DEFAULT NULL COMMENT '操作时间',
`operated_by` varchar(32) DEFAULT NULL COMMENT '操作人',
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
`version` int(11) NOT NULL DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`field_id`),
KEY `i_meta_field_0` (`entity_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=85 DEFAULT CHARSET=utf8mb4 COMMENT='meta_field';
/*Data for the table `meta_field` */
insert into `meta_field`(`field_id`,`project_id`,`entity_id`,`jfield_name`,`field_name`,`jfield_type`,`field_type`,`field_desc`,`field_example`,`field_comment`,`field_length`,`field_scale`,`primary_key`,`auto_increment`,`pk_strategy`,`not_null`,`default_value`,`foreign_key`,`foreign_entity_id`,`foreign_field_id`,`edit_type`,`dic_type`,`insert`,`update`,`list`,`column_width`,`list_sort`,`show`,`query`,`query_type`,`order_no`,`special_field`,`created_time`,`created_by`,`operated_time`,`operated_by`,`deleted`,`version`) values (1,1,1,'id','id','Long','bigint','主键','1','主键ID',20,NULL,1,1,1,1,'NULL',0,0,0,1,NULL,0,0,1,100,0,1,0,NULL,1,NULL,'2021-01-08 17:17:55','admin','2021-01-12 15:36:15','admin',0,1),(2,1,1,'name','name','String','varchar','名称','php教程','菜单名称',50,NULL,0,0,0,1,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,1,2,1,NULL,'2021-01-08 17:19:29','admin','2021-01-08 17:26:20','admin',0,1),(3,1,1,'pid','pid','Long','bigint','父级id','1','父级id',20,NULL,0,0,0,0,'NULL',1,1,1,2,NULL,1,0,0,0,0,0,0,NULL,1,NULL,'2021-01-08 17:26:10','admin','2021-01-12 15:36:24','admin',0,1),(4,1,1,'addTime','add_time','LocalDateTime','datetime','添加时间','2020-01-08 17:24:54','添加时间',0,NULL,0,0,0,0,'NULL',0,0,0,7,NULL,1,1,1,0,0,1,1,7,1,NULL,'2021-01-08 17:28:12','admin','2021-01-08 17:30:21','admin',0,1),(5,1,1,'updateTime','update_time','LocalDateTime','datetime','更新时间','2020-01-01 17:24:41','更新时间',0,NULL,0,0,0,0,'NULL',0,0,0,7,NULL,1,1,1,0,0,1,1,7,1,NULL,'2021-01-08 17:30:12','admin','2021-01-08 17:30:12','admin',0,1),(6,1,2,'id','id','Long','bigint','主键','1','主键ID',20,NULL,1,1,1,1,'NULL',0,0,0,1,NULL,0,0,1,100,0,1,1,1,1,NULL,'2021-01-08 17:47:07','admin','2021-01-12 15:35:46','admin',0,1),(7,1,2,'createdBy','created_by','String','varchar','创建人','admin','创建人【最大长度20】',20,NULL,0,0,0,1,'NULL',0,0,0,1,NULL,0,0,0,0,0,0,1,2,101,'createdBy','2021-01-08 17:55:24','admin','2021-01-08 17:55:24','admin',0,1),(8,1,2,'operatedTime','operated_time','LocalDateTime','datetime','修改时间','2017-12-07 00:00:00','修改时间【yyyy-MM-dd HH:mm:ss】',0,NULL,0,0,0,1,'NULL',0,0,0,7,NULL,0,0,1,200,1,0,0,NULL,100,'operatedTime','2021-01-08 17:55:47','admin','2021-01-08 17:56:28','admin',0,1),(9,1,2,'createdTime','created_time','LocalDateTime','datetime','创建时间','2017-12-07 00:00:00','创建时间【yyyy-MM-dd HH:mm:ss】',0,NULL,0,0,0,1,'NULL',0,0,0,7,NULL,0,0,1,200,1,0,0,NULL,100,'createdTime','2021-01-08 17:55:59','admin','2021-01-08 17:55:59','admin',0,1),(10,1,2,'orderNo','order_no','Long','bigint','排序号','1','排序号【整型】',20,NULL,0,0,0,1,'NULL',0,0,0,4,NULL,1,1,1,100,1,1,0,NULL,90,NULL,'2021-01-08 17:56:18','admin','2021-01-12 15:36:04','admin',0,1),(11,1,2,'operatedBy','operated_by','String','varchar','修改人','admin','修改人【最大长度20】',20,NULL,0,0,0,1,'NULL',0,0,0,1,NULL,0,0,0,0,0,0,0,NULL,95,'operatedBy','2021-01-08 17:58:31','admin','2021-01-08 17:58:31','admin',0,1),(12,1,2,'menuId','menu_id','Long','bigint','菜单主键','1','菜单主键ID',20,NULL,0,0,0,1,'NULL',1,1,1,2,NULL,1,0,0,0,0,0,1,1,10,NULL,'2021-01-08 18:01:36','admin','2021-01-12 15:35:55','admin',0,1),(13,1,2,'title','title','String','varchar','标题','php语法','标题',32,NULL,0,0,0,1,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,1,2,1,NULL,'2021-01-12 10:38:51','admin','2021-01-12 10:38:51','admin',0,1),(14,1,3,'roleId','role_id','Integer','smallint','role_id','1','role_id',6,0,0,0,0,1,'NULL',0,NULL,NULL,4,NULL,1,1,1,NULL,0,1,1,1,10,NULL,'2021-01-12 15:27:55','admin','2021-01-12 15:27:55','admin',0,1),(15,1,3,'nodeId','node_id','Integer','smallint','node_id','1','node_id',6,0,0,0,0,1,'NULL',0,NULL,NULL,4,NULL,1,1,1,NULL,0,1,1,1,20,NULL,'2021-01-12 15:27:55','admin','2021-01-12 15:27:55','admin',0,1),(16,1,3,'level','level','Boolean','tinyint','level','true','level',1,0,0,0,0,1,'NULL',0,NULL,NULL,5,NULL,1,1,1,NULL,0,1,1,1,30,NULL,'2021-01-12 15:27:55','admin','2021-01-12 15:27:55','admin',0,1),(17,1,3,'module','module','String','varchar','module','','module',50,0,0,0,0,0,'NULL',0,NULL,NULL,1,NULL,1,1,1,NULL,0,1,1,2,40,NULL,'2021-01-12 15:27:55','admin','2021-01-12 15:27:55','admin',0,1),(18,1,4,'userId','user_id','Integer','int','用户表主键','1','用户表主键',10,0,1,1,1,1,'NULL',0,NULL,NULL,4,NULL,0,0,1,NULL,0,1,0,1,10,NULL,'2021-01-12 15:31:01','admin','2021-01-12 15:31:01','admin',0,1),(19,1,4,'user','user','String','varchar','账号','','账号',30,0,0,0,0,1,'\'\'',0,NULL,NULL,1,NULL,1,1,1,NULL,0,1,1,1,20,NULL,'2021-01-12 15:31:01','admin','2021-01-12 15:31:01','admin',0,1),(20,1,4,'name','name','String','varchar','用户姓名','name1','用户姓名',30,0,0,0,0,1,'\'\'',0,NULL,NULL,1,NULL,1,1,1,NULL,0,1,1,1,30,NULL,'2021-01-12 15:31:01','admin','2021-01-12 15:31:01','admin',0,1),(21,1,4,'password','password','String','varchar','登录密码','','登录密码',100,0,0,0,0,1,'\'\'',0,NULL,NULL,1,NULL,1,1,1,NULL,0,1,1,2,40,NULL,'2021-01-12 15:31:01','admin','2021-01-12 15:31:01','admin',0,1),(22,1,4,'sex','sex','Integer','tinyint','性别','1','性别:1男 2女',4,NULL,0,0,0,1,'\'1\'',0,NULL,NULL,2,'Sex',1,1,1,0,0,1,1,1,50,NULL,'2021-01-12 15:31:01','admin','2021-01-12 15:44:43','admin',0,1),(23,1,4,'phone','phone','String','char','手机号码','','手机号码',20,0,0,0,0,1,'\'\'',0,NULL,NULL,1,NULL,1,1,1,NULL,0,1,1,1,60,NULL,'2021-01-12 15:31:01','admin','2021-01-12 15:31:01','admin',0,1),(24,1,4,'addTime','add_time','Date','timestamp','添加时间','2021-01-12 15:31:00','添加时间',0,0,0,0,0,1,'CURRENT_TIMESTAMP',0,NULL,NULL,7,NULL,1,1,1,NULL,0,1,1,7,70,NULL,'2021-01-12 15:31:01','admin','2021-01-12 15:31:01','admin',0,1),(25,1,4,'updateTime','update_time','Date','timestamp','更新时间','2021-01-12 15:31:00','更新时间',0,0,0,0,0,1,'\'0000-00-00 00:00:00\'',0,NULL,NULL,7,NULL,1,1,1,NULL,0,1,1,7,80,'operatedTime','2021-01-12 15:31:01','admin','2021-01-12 15:31:01','admin',0,1),(26,1,4,'dataNodeId','data_node_id','Integer','int','数据节点主键id','1','数据节点主键id',11,0,0,0,0,1,'\'0\'',0,NULL,NULL,4,NULL,1,1,1,NULL,0,1,1,1,90,NULL,'2021-01-12 15:31:01','admin','2021-01-12 15:31:01','admin',0,1),(27,1,3,'id','id','Long','bigint','主键','1','主键ID',20,NULL,1,1,1,1,'NULL',0,0,0,4,NULL,0,0,1,100,0,1,0,NULL,1,NULL,'2021-01-12 15:35:24','admin','2021-01-12 15:35:24','admin',0,1),(28,2,5,'customerId','customer_id','Long','bigint','主键','1','主键ID',20,NULL,1,1,1,1,'NULL',0,0,0,4,NULL,0,0,1,100,0,1,0,NULL,1,NULL,'2021-01-14 10:47:54','admin','2021-01-14 10:47:54','admin',0,1),(29,2,5,'name','name','String','varchar','客户名称','客户名称','客户名称',50,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,1,2,1,NULL,'2021-01-14 10:49:41','admin','2021-01-14 10:49:41','admin',0,1),(30,2,5,'number','number','String','varchar','客户编号','CJK02190800001','客户编号',50,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,1,2,1,NULL,'2021-01-14 10:50:44','admin','2021-01-14 10:50:44','admin',0,1),(31,2,5,'phoneName','phone_name','String','varchar','联系人','张三','联系人',32,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,0,NULL,1,NULL,'2021-01-14 10:52:12','admin','2021-01-14 10:52:12','admin',0,1),(32,2,5,'phone','phone','String','varchar','联系电话','13734567890','联系电话',32,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,0,NULL,1,NULL,'2021-01-14 10:53:05','admin','2021-01-14 10:53:05','admin',0,1),(33,2,5,'address','address','String','varchar','地址','四川省成都市高新区','地址',100,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,0,NULL,1,NULL,'2021-01-14 10:53:43','admin','2021-01-14 10:53:43','admin',0,1),(34,2,5,'owner','owner','String','varchar','客户负责人','李师傅','客户负责人',32,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,1,2,1,NULL,'2021-01-14 10:55:17','admin','2021-01-14 10:55:17','admin',0,1),(35,2,5,'createdTime','created_time','LocalDateTime','datetime','创建时间','2017-12-07 00:00:00','创建时间【yyyy-MM-dd HH:mm:ss】',0,NULL,0,0,0,1,'NULL',0,0,0,7,NULL,0,0,1,200,1,1,0,NULL,100,'createdTime','2021-01-14 10:56:01','admin','2021-01-14 10:56:01','admin',0,1),(36,2,5,'operatedTime','operated_time','LocalDateTime','datetime','修改时间','2017-12-07 00:00:00','修改时间【yyyy-MM-dd HH:mm:ss】',0,NULL,0,0,0,1,'NULL',0,0,0,7,NULL,0,0,1,200,1,1,0,NULL,110,'operatedTime','2021-01-14 10:56:22','admin','2021-01-14 10:56:22','admin',0,1),(37,2,5,'createdBy','created_by','String','varchar','创建人','admin','创建人【最大长度20】',20,NULL,0,0,0,1,'NULL',0,0,0,1,NULL,0,0,0,0,0,1,0,NULL,101,'createdBy','2021-01-14 10:56:51','admin','2021-01-14 10:56:51','admin',0,1),(38,2,6,'productId','product_id','Long','bigint','主键','1','主键ID',20,NULL,1,1,1,1,'NULL',0,0,0,1,NULL,0,0,1,100,0,1,0,NULL,1,NULL,'2021-01-14 11:00:54','admin','2021-01-14 11:01:18','admin',0,1),(39,2,6,'name','name','String','varchar','产品名称','测试产品','产品名称',50,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,1,2,1,NULL,'2021-01-14 11:02:12','admin','2021-01-14 11:02:12','admin',0,1),(40,2,6,'number','number','String','varchar','产品编号','XTS201908290021','产品编号',50,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,1,2,1,NULL,'2021-01-14 11:02:53','admin','2021-01-14 11:02:53','admin',0,1),(41,2,6,'type','type','Integer','int','产品分类','1','产品分类:具体详细请见 枚举管理查看',11,NULL,0,0,0,0,'NULL',0,0,0,2,'ProductType',1,1,1,0,0,1,1,1,1,NULL,'2021-01-14 11:09:49','admin','2021-01-14 11:13:27','admin',0,1),(42,2,6,'createdBy','created_by','String','varchar','创建人','admin','创建人【最大长度20】',20,NULL,0,0,0,1,'NULL',0,0,0,1,NULL,0,0,0,0,0,0,0,NULL,101,'createdBy','2021-01-14 11:13:56','admin','2021-01-14 11:13:56','admin',0,1),(43,2,6,'createdTime','created_time','LocalDateTime','datetime','创建时间','2017-12-07 00:00:00','创建时间【yyyy-MM-dd HH:mm:ss】',0,NULL,0,0,0,1,'NULL',0,0,0,7,NULL,0,0,0,200,0,0,0,NULL,100,'createdTime','2021-01-14 11:14:07','admin','2021-01-14 11:14:32','admin',0,1),(44,2,6,'operatedTime','operated_time','LocalDateTime','datetime','修改时间','2017-12-07 00:00:00','修改时间【yyyy-MM-dd HH:mm:ss】',0,NULL,0,0,0,1,'NULL',0,0,0,7,NULL,0,0,1,200,1,0,0,NULL,110,'operatedTime','2021-01-14 11:14:19','admin','2021-01-14 11:14:19','admin',0,1),(45,2,7,'userId','user_id','Long','bigint','主键','1','主键ID',20,NULL,1,1,1,1,'NULL',0,0,0,4,NULL,0,0,1,100,0,1,0,NULL,1,NULL,'2021-01-14 11:26:05','admin','2021-01-14 11:26:05','admin',0,1),(46,2,7,'name','name','String','varchar','姓名','黄俊','姓名',32,NULL,0,0,0,1,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,1,2,1,NULL,'2021-01-14 11:29:19','admin','2021-01-14 11:29:19','admin',0,1),(47,2,7,'username','username','String','varchar','账号','admin','账号',50,NULL,0,0,0,1,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 11:30:39','admin','2021-01-14 11:30:39','admin',0,1),(48,2,7,'password','password','String','varchar','密码','123456','密码',100,NULL,0,0,0,1,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 11:31:14','admin','2021-01-14 11:31:14','admin',0,1),(49,2,7,'phone','phone','String','varchar','电话','电话','电话',32,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,0,NULL,1,NULL,'2021-01-14 11:32:41','admin','2021-01-14 11:32:41','admin',0,1),(50,2,7,'role','role','Integer','int','角色','角色','角色',11,NULL,0,0,0,0,'NULL',0,0,0,2,'Role',1,1,1,0,0,1,1,1,1,NULL,'2021-01-14 11:33:25','admin','2021-01-14 11:33:25','admin',0,1),(51,2,7,'createdBy','created_by','String','varchar','创建人','admin','创建人【最大长度20】',20,NULL,0,0,0,1,'NULL',0,0,0,1,NULL,0,0,0,0,0,0,0,NULL,101,'createdBy','2021-01-14 11:33:45','admin','2021-01-14 11:33:45','admin',0,1),(52,2,7,'createdTime','created_time','LocalDateTime','datetime','创建时间','2017-12-07 00:00:00','创建时间【yyyy-MM-dd HH:mm:ss】',0,NULL,0,0,0,1,'NULL',0,0,0,7,NULL,0,0,1,200,0,0,0,NULL,100,'createdTime','2021-01-14 11:34:05','admin','2021-01-14 11:34:05','admin',0,1),(53,2,7,'operatedTime','operated_time','LocalDateTime','datetime','修改时间','2017-12-07 00:00:00','修改时间【yyyy-MM-dd HH:mm:ss】',0,NULL,0,0,0,1,'NULL',0,0,0,7,NULL,0,0,0,200,0,0,0,NULL,110,'operatedTime','2021-01-14 11:34:15','admin','2021-01-14 11:34:15','admin',0,1),(54,2,8,'orderId','order_id','Long','bigint','主键','1','主键ID',20,NULL,1,1,1,1,'NULL',0,0,0,4,NULL,0,0,1,100,0,1,0,NULL,1,NULL,'2021-01-14 11:35:57','admin','2021-01-14 11:35:57','admin',0,1),(55,2,8,'repairNumber','repair_number','String','varchar','关联报修单号','XTC021198416001','关联报修单号',100,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 11:41:27','admin','2021-01-14 11:41:27','admin',0,1),(56,2,8,'orderNumber','order_number','String','varchar','工单编号','CJK02190800001','工单编号',50,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,1,2,1,NULL,'2021-01-14 11:42:28','admin','2021-01-14 11:42:49','admin',0,1),(57,2,8,'customerId','customer_id','Long','bigint','客户','1','客户',20,NULL,0,0,0,0,'NULL',1,5,28,2,NULL,1,1,1,0,0,1,0,NULL,10,NULL,'2021-01-14 11:44:21','admin','2021-01-14 11:44:21','admin',0,1),(58,2,8,'customerContacts','customer_contacts','String','varchar','客户联系人','李总','客户联系人',32,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 11:47:10','admin','2021-01-14 11:47:10','admin',0,1),(59,2,8,'phone','phone','String','varchar','电话','13734567890','电话',32,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 11:47:53','admin','2021-01-14 11:47:53','admin',0,1),(60,2,8,'address','address','String','varchar','地址','四川省成都市高新区天府大道125号','地址',100,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 11:48:57','admin','2021-01-14 11:48:57','admin',0,1),(61,2,8,'productId','product_id','Long','bigint','客户产品','1','客户产品',20,NULL,0,0,0,0,'NULL',1,6,38,2,NULL,1,1,1,0,0,1,1,1,10,NULL,'2021-01-14 11:50:03','admin','2021-01-14 11:50:03','admin',0,1),(62,2,8,'serverType','server_type','Integer','int','服务类型','1','服务类型',11,NULL,0,0,0,1,'NULL',0,0,0,2,'ServerType',1,1,1,0,0,1,0,NULL,1,NULL,'2021-01-14 11:53:14','admin','2021-01-14 11:53:14','admin',0,1),(63,2,8,'money','money','BigDecimal','decimal','本次服务费','150.00','本次服务费',20,2,0,0,0,0,'NULL',0,0,0,4,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 11:54:26','admin','2021-01-14 11:54:26','admin',0,1),(64,2,8,'remark','remark','String','varchar','备注','备注','备注',200,NULL,0,0,0,0,'NULL',0,0,0,9,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 11:55:01','admin','2021-01-14 11:55:01','admin',0,1),(65,2,8,'filePath','file_path','String','varchar','上传附件','上传附件','上传附件',100,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 11:55:55','admin','2021-01-14 11:55:55','admin',0,1),(66,2,8,'userId','user_id','Long','bigint','选择维修工','1','选择维修工',20,NULL,0,0,0,0,'NULL',1,7,45,2,NULL,1,1,0,0,0,1,0,NULL,10,NULL,'2021-01-14 11:56:59','admin','2021-01-14 11:56:59','admin',0,1),(67,2,8,'status','status','Integer','int','工单状态','1','工单状态',11,NULL,0,0,0,0,'NULL',0,0,0,2,'OrderStatus',1,1,1,0,0,1,1,1,1,NULL,'2021-01-14 14:03:23','admin','2021-01-14 14:03:23','admin',0,1),(68,2,8,'createdTime','created_time','LocalDateTime','datetime','创建时间','2017-12-07 00:00:00','创建时间【yyyy-MM-dd HH:mm:ss】',0,0,0,0,0,1,'NULL',0,NULL,NULL,7,NULL,0,0,1,200,1,0,0,NULL,100,'createdTime','2021-01-14 14:04:54','admin','2021-01-14 14:04:54','admin',0,1),(69,2,8,'operatedTime','operated_time','LocalDateTime','datetime','修改时间','2017-12-07 00:00:00','修改时间【yyyy-MM-dd HH:mm:ss】',0,0,0,0,0,1,'NULL',0,NULL,NULL,7,NULL,0,0,1,200,1,0,0,NULL,110,'operatedTime','2021-01-14 14:04:54','admin','2021-01-14 14:04:54','admin',0,1),(70,2,9,'repairId','repair_id','Long','bigint','主键','1','主键ID',20,NULL,1,1,1,1,'NULL',0,0,0,4,NULL,0,0,1,100,0,1,0,NULL,1,NULL,'2021-01-14 15:12:49','admin','2021-01-14 15:12:49','admin',0,1),(71,2,9,'repairNumber','repair_number','String','varchar','报修单编号','CJK02190800001','报修单编号',50,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,1,0,0,1,1,2,1,NULL,'2021-01-14 15:16:22','admin','2021-01-14 15:16:22','admin',0,1),(72,2,9,'customerContacts','customer_contacts','String','varchar','客户联系人','李总','客户联系人',32,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 15:18:16','admin','2021-01-14 15:18:16','admin',0,1),(73,2,9,'phone','phone','String','varchar','电话','13734567890','电话',32,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 15:18:24','admin','2021-01-14 15:18:24','admin',0,1),(74,2,9,'address','address','String','varchar','地址','四川省成都市高新区天府大道125号','地址',100,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 15:18:32','admin','2021-01-14 15:18:32','admin',0,1),(75,2,9,'customerId','customer_id','Long','bigint','客户','1','客户',20,NULL,0,0,0,0,'NULL',1,5,28,2,NULL,1,1,1,0,0,1,0,NULL,10,NULL,'2021-01-14 15:18:46','admin','2021-01-14 15:18:46','admin',0,1),(76,2,9,'productId','product_id','Long','bigint','客户产品','1','客户产品',20,NULL,0,0,0,0,'NULL',1,6,38,2,NULL,1,1,1,0,0,1,1,1,10,NULL,'2021-01-14 15:18:55','admin','2021-01-14 15:18:55','admin',0,1),(77,2,9,'filePath','file_path','String','varchar','上传附件','上传附件','上传附件',100,NULL,0,0,0,0,'NULL',0,0,0,1,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 15:19:05','admin','2021-01-14 15:19:05','admin',0,1),(78,2,9,'repairType','repair_type','Integer','int','报修类型','1','报修类型',11,NULL,0,0,0,1,'NULL',0,0,0,2,'RepairType',1,1,1,0,0,1,0,NULL,1,NULL,'2021-01-14 15:20:08','admin','2021-01-14 15:20:19','admin',0,1),(79,2,9,'remark','remark','String','varchar','备注','备注','备注',200,NULL,0,0,0,0,'NULL',0,0,0,9,NULL,1,1,0,0,0,1,0,NULL,1,NULL,'2021-01-14 15:21:48','admin','2021-01-14 15:21:48','admin',0,1),(80,2,9,'status','status','Integer','int','工单状态','1','工单状态',11,NULL,0,0,0,0,'NULL',0,0,0,2,'RepairStatus',1,1,1,0,0,1,1,1,1,NULL,'2021-01-14 15:22:10','admin','2021-01-14 15:22:10','admin',0,1),(81,2,9,'userId','user_id','Long','bigint','选择维修工','1','选择维修工',20,NULL,0,0,0,0,'NULL',1,7,45,2,NULL,1,1,0,0,0,1,0,NULL,10,NULL,'2021-01-14 15:22:56','admin','2021-01-14 15:22:56','admin',0,1),(82,2,9,'operatedTime','operated_time','LocalDateTime','datetime','修改时间','2017-12-07 00:00:00','修改时间【yyyy-MM-dd HH:mm:ss】',0,0,0,0,0,1,'NULL',0,NULL,NULL,7,NULL,0,0,1,200,1,0,0,NULL,110,'operatedTime','2021-01-14 15:25:06','admin','2021-01-14 15:25:06','admin',0,1),(83,2,9,'createdTime','created_time','LocalDateTime','datetime','创建时间','2017-12-07 00:00:00','创建时间【yyyy-MM-dd HH:mm:ss】',0,0,0,0,0,1,'NULL',0,NULL,NULL,7,NULL,0,0,1,200,1,0,0,NULL,100,'createdTime','2021-01-14 15:25:06','admin','2021-01-14 15:25:06','admin',0,1),(84,2,9,'createdBy','created_by','String','varchar','创建人','admin','创建人【最大长度20】',20,NULL,0,0,0,0,'NULL',0,NULL,NULL,1,NULL,0,0,0,0,0,0,0,NULL,101,'createdBy','2021-01-14 15:25:06','admin','2021-01-14 15:25:17','admin',0,1);
/*Table structure for table `meta_index` */
DROP TABLE IF EXISTS `meta_index`;
CREATE TABLE `meta_index` (
`index_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`project_id` int(11) NOT NULL COMMENT '所属项目id',
`index_name` varchar(40) NOT NULL COMMENT '索引名称',
`entity_id` int(11) NOT NULL COMMENT '所属实体id',
`unique` tinyint(1) NOT NULL COMMENT '是否唯一索引',
`unique_check` tinyint(1) NOT NULL COMMENT '唯一性校验',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`operated_time` datetime DEFAULT NULL COMMENT '操作时间',
`operated_by` varchar(32) DEFAULT NULL COMMENT '操作人',
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
`version` int(11) NOT NULL DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`index_id`),
KEY `i_meta_index_0` (`entity_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='meta_index';
/*Data for the table `meta_index` */
insert into `meta_index`(`index_id`,`project_id`,`index_name`,`entity_id`,`unique`,`unique_check`,`created_time`,`created_by`,`operated_time`,`operated_by`,`deleted`,`version`) values (1,1,'groupId',3,0,0,'2021-01-12 15:27:55','admin','2021-01-12 15:27:55','admin',0,1),(2,1,'nodeId',3,0,0,'2021-01-12 15:27:55','admin','2021-01-12 15:27:55','admin',0,1);
/*Table structure for table `meta_index_field` */
DROP TABLE IF EXISTS `meta_index_field`;
CREATE TABLE `meta_index_field` (
`index_id` int(11) NOT NULL COMMENT '索引id',
`field_id` int(11) NOT NULL COMMENT '字段id',
`project_id` int(11) NOT NULL COMMENT '项目id',
`order_no` int(11) NOT NULL COMMENT '排序号',
PRIMARY KEY (`index_id`,`field_id`),
KEY `i_meta_index_field_0` (`index_id`) USING BTREE,
KEY `i_meta_index_field_1` (`field_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='meta_index_field';
/*Data for the table `meta_index_field` */
insert into `meta_index_field`(`index_id`,`field_id`,`project_id`,`order_no`) values (1,14,1,0),(2,15,1,0);
/*Table structure for table `meta_mtm` */
DROP TABLE IF EXISTS `meta_mtm`;
CREATE TABLE `meta_mtm` (
`mtm_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`project_id` int(11) NOT NULL COMMENT '所属项目id',
`table_name` varchar(50) NOT NULL COMMENT '关联表名',
`schema_name` varchar(20) DEFAULT NULL COMMENT '模式名',
`desc` varchar(500) DEFAULT NULL COMMENT '关联描述',
`entity_id1` int(11) NOT NULL COMMENT '实体A的id',
`entity_id2` int(11) NOT NULL COMMENT '实体B的id',
`hold_refer1` tinyint(1) NOT NULL COMMENT '实体A是否持有B的引用',
`hold_refer2` tinyint(1) NOT NULL COMMENT '实体B是否持有A的引用',
`entity_id_field1` varchar(64) DEFAULT '' COMMENT '实体A对应多对多关联表的id字段名',
`entity_id_field2` varchar(64) NOT NULL DEFAULT '' COMMENT '实体B对应多对多关联表的id字段名',
`need_id` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否需要自增id字段',
`big_id` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'id字段是否bigint',
`feature` text COMMENT '特性json',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`operated_time` datetime DEFAULT NULL COMMENT '操作时间',
`operated_by` varchar(32) DEFAULT NULL COMMENT '操作人',
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
`version` int(11) NOT NULL DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`mtm_id`),
KEY `i_meta_mtm_0` (`project_id`) USING BTREE,
KEY `i_meta_mtm_1` (`entity_id1`) USING BTREE,
KEY `i_meta_mtm_2` (`entity_id2`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='meta_mtm';
/*Data for the table `meta_mtm` */
/*Table structure for table `meta_mtm_cascade_ext` */
DROP TABLE IF EXISTS `meta_mtm_cascade_ext`;
CREATE TABLE `meta_mtm_cascade_ext` (
`mtm_cascade_ext_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`project_id` int(11) NOT NULL COMMENT '所属项目id',
`mtm_id` int(11) NOT NULL COMMENT '多对多id',
`entity_id` int(11) NOT NULL COMMENT '实体id',
`cascade_entity_id` int(11) NOT NULL COMMENT '级联所属实体id',
`cascade_field_id` int(11) NOT NULL COMMENT '级联所属字段id',
`alias` varchar(255) NOT NULL COMMENT '级联查询字段别名',
`list` tinyint(1) NOT NULL COMMENT '是否在列表中展示',
`show` tinyint(1) NOT NULL COMMENT '是否在详情中展示',
`query` tinyint(1) NOT NULL COMMENT '是否为查询条件',
`created_time` datetime NOT NULL COMMENT '创建时间【yyyy-MM-dd HH:mm:ss】',
`created_by` varchar(20) NOT NULL COMMENT '创建人【最大长度20】',
`operated_time` datetime NOT NULL COMMENT '修改时间【yyyy-MM-dd HH:mm:ss】',
`operated_by` varchar(20) NOT NULL COMMENT '修改人【最大长度20】',
`version` int(11) NOT NULL COMMENT '乐观锁版本号【整型】',
`deleted` tinyint(1) NOT NULL COMMENT '逻辑删除标识【0-未删除,1-已删除】',
PRIMARY KEY (`mtm_cascade_ext_id`),
KEY `IDX_CAS_MTM_EXT_1` (`mtm_id`,`entity_id`,`cascade_entity_id`) USING BTREE,
KEY `IDX_CAS_MTM_EXT_2` (`cascade_field_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='多对多级联扩展';
/*Data for the table `meta_mtm_cascade_ext` */
/*Table structure for table `meta_project` */
DROP TABLE IF EXISTS `meta_project`;
CREATE TABLE `meta_project` (
`project_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '项目id',
`package_name` varchar(100) NOT NULL COMMENT '主包名',
`project_name` varchar(50) NOT NULL COMMENT '项目标识',
`project_desc` varchar(100) NOT NULL COMMENT '项目名称',
`group_id` varchar(50) NOT NULL COMMENT 'groupId',
`author` varchar(50) DEFAULT NULL COMMENT '开发者',
`template_id` int(11) DEFAULT NULL COMMENT '模板id',
`template_id_2` int(11) DEFAULT NULL COMMENT '模板id2',
`template_id_3` int(11) DEFAULT NULL COMMENT '模板id3',
`remote` tinyint(1) NOT NULL COMMENT '启用Git仓库',
`remote_url` varchar(256) DEFAULT NULL COMMENT 'Git仓库地址',
`remote_url_2` varchar(256) DEFAULT NULL COMMENT 'Git仓库地址2',
`remote_url_3` varchar(256) DEFAULT NULL COMMENT 'Git仓库地址3',
`username` varchar(32) DEFAULT NULL COMMENT 'Git用户名',
`password` varchar(256) DEFAULT NULL COMMENT 'Git密码',
`project_version` int(11) NOT NULL COMMENT '项目版本号',
`feature` text COMMENT '特性json',
`team_id` int(11) DEFAULT NULL COMMENT '项目组id',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`operated_time` datetime DEFAULT NULL COMMENT '操作时间',
`operated_by` varchar(32) DEFAULT NULL COMMENT '操作人',
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
`version` int(11) NOT NULL DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`project_id`),
KEY `i_meta_project_0` (`project_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='meta_project';
/*Data for the table `meta_project` */
insert into `meta_project`(`project_id`,`package_name`,`project_name`,`project_desc`,`group_id`,`author`,`template_id`,`template_id_2`,`template_id_3`,`remote`,`remote_url`,`remote_url_2`,`remote_url_3`,`username`,`password`,`project_version`,`feature`,`team_id`,`created_time`,`created_by`,`operated_time`,`operated_by`,`deleted`,`version`) values (1,'com.huangjun.blog','blog','博客','com.huangjun','黄俊',2,1,NULL,1,'https://gitee.com/huangjun520/blog-test-vue.git','https://gitee.com/huangjun520/blog-test-java.git',NULL,'498744110@qq.com','IMK0a8mHiARJFpRgpAT+ZQ==',70,'{\"bootVersion\":2,\"lombokEnabled\":true}',NULL,'2021-01-08 17:13:58','admin','2021-01-12 16:37:41','admin',0,1),(2,'com.huangjun.shouhou','shouhou','售后系统管理','com.huangjun','黄俊',2,1,NULL,1,'https://gitee.com/low-code-development/shouhou-vue.git','https://gitee.com/low-code-development/shouhou-java.git',NULL,'498744110@qq.com','IMK0a8mHiARJFpRgpAT+ZQ==',116,'{\"bootVersion\":2,\"lombokEnabled\":true}',NULL,'2021-01-14 10:42:33','admin','2021-01-14 16:39:02','admin',0,1);
/*Table structure for table `project_team` */
DROP TABLE IF EXISTS `project_team`;
CREATE TABLE `project_team` (
`team_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(32) NOT NULL COMMENT '名称',
`created_time` datetime NOT NULL COMMENT '创建时间【yyyy-MM-dd HH:mm:ss】',
`created_by` varchar(20) NOT NULL COMMENT '创建人【最大长度20】',
`operated_time` datetime NOT NULL COMMENT '修改时间【yyyy-MM-dd HH:mm:ss】',
`operated_by` varchar(20) NOT NULL COMMENT '修改人【最大长度20】',
`version` int(11) NOT NULL COMMENT '乐观锁版本号【整型】',
`deleted` tinyint(1) NOT NULL COMMENT '逻辑删除标识【0-未删除,1-已删除】',
PRIMARY KEY (`team_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目组';
/*Data for the table `project_team` */
/*Table structure for table `project_team_member` */
DROP TABLE IF EXISTS `project_team_member`;
CREATE TABLE `project_team_member` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`team_id` int(11) NOT NULL COMMENT '项目组id',
`username` varchar(32) NOT NULL COMMENT '用户名',
`created_time` datetime NOT NULL COMMENT '创建时间【yyyy-MM-dd HH:mm:ss】',
`created_by` varchar(20) NOT NULL COMMENT '创建人【最大长度20】',
PRIMARY KEY (`id`),
UNIQUE KEY `IDX_EJQOAQRUE` (`team_id`,`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目组成员';
/*Data for the table `project_team_member` */
/*Table structure for table `template_file` */
DROP TABLE IF EXISTS `template_file`;
CREATE TABLE `template_file` (
`file_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`file_name` varchar(100) NOT NULL COMMENT '文件名',
`file_dir` varchar(300) NOT NULL COMMENT '文件目录',
`template_id` int(11) NOT NULL COMMENT '模板id',
`context_type` tinyint(4) NOT NULL COMMENT '上下文类型【1全局、2实体、3常量】',
`file_type` tinyint(4) NOT NULL COMMENT '文件类型【1普通模板文件、2抽象模板文件、3二进制模板文件、4父路径渲染文件、5文件名渲染文件】',
`content` mediumtext COMMENT '内容',
`created_time` datetime NOT NULL COMMENT '创建时间【yyyy-MM-dd HH:mm:ss】',
`created_by` varchar(20) NOT NULL COMMENT '创建人【最大长度20】',
`operated_time` datetime NOT NULL COMMENT '修改时间【yyyy-MM-dd HH:mm:ss】',
`operated_by` varchar(20) NOT NULL COMMENT '修改人【最大长度20】',
`version` int(11) NOT NULL COMMENT '乐观锁版本号【整型】',
`deleted` tinyint(1) NOT NULL COMMENT '逻辑删除标识【0-未删除,1-已删除】',
PRIMARY KEY (`file_id`),
KEY `IDX_TEMPLATE_FILE_1` (`template_id`,`file_dir`,`file_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=320 DEFAULT CHARSET=utf8mb4 COMMENT='模板文件';
/*Data for the table `template_file` */
insert into `template_file`(`file_id`,`file_name`,`file_dir`,`template_id`,`context_type`,`file_type`,`content`,`created_time`,`created_by`,`operated_time`,`operated_by`,`version`,`deleted`) values (1,'.gitignore.ftl','/',1,1,1,'*.class\ntarget\ntarget/*\n\n\n# node\nnode_modules\nnode_modules/*\n\n# Package Files #\n*.jar\n*.war\n*.ear\n\n#idea files\n.idea\n*.iml\noverlays/\n*.log\nlogs\n*.epoch\n*.lck\n\n# OS generated files #\n######################\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nIcon?\nehthumbs.db\nThumbs.db\n</span>\n/bin/\n\n#eclipse file\n.classpath\n.gradle\n.project\n.settings\n/build/*\nsrc/main/webapp/WEB-INF/classes/\nbin\n.rules\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(2,'pom.xml.ftl','/',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/usingExcel.ftl\">\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n <parent>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-parent</artifactId>\n <version>2.3.6.RELEASE</version>\n </parent>\n <modelVersion>4.0.0</modelVersion>\n <groupId>${this.groupId}</groupId>\n <artifactId>${this.originProjectName}</artifactId>\n <version>1.0.0-SNAPSHOT</version>\n <packaging>pom</packaging>\n\n <modules>\n <module>${this.originProjectName}-common</module>\n <module>${this.originProjectName}-core</module>\n <module>${this.originProjectName}-web</module>\n </modules>\n\n <properties>\n <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n <java.version>1.8</java.version>\n <mybatis-spring-boot.version>2.1.3</mybatis-spring-boot.version>\n <commons-lang3.version>3.11</commons-lang3.version>\n <commons-io.version>2.7</commons-io.version>\n <commons-collections.version>4.4</commons-collections.version>\n <guava.version>29.0-jre</guava.version>\n <org.mapstruct.version>1.3.1.Final</org.mapstruct.version>\n <jsoup.version>1.13.1</jsoup.version>\n <h2.version>1.4.200</h2.version>\n <mysql2h2.version>0.2.1</mysql2h2.version>\n <springfox-boot-starter.version>3.0.0</springfox-boot-starter.version>\n <swagger-annotations.version>1.5.20</swagger-annotations.version>\n <#if this.projectFeature.lombokEnabled><lombok.version>1.18.12</lombok.version></#if>\n <#if usingExcel><easyexcel.version>2.2.6</easyexcel.version></#if>\n </properties>\n\n <dependencyManagement>\n <dependencies>\n\n <dependency>\n <groupId>${r\'$\'}{project.groupId}</groupId>\n <artifactId>${this.originProjectName}-common</artifactId>\n <version>${r\'$\'}{project.version}</version>\n </dependency>\n <dependency>\n <groupId>${r\'$\'}{project.groupId}</groupId>\n <artifactId>${this.originProjectName}-core</artifactId>\n <version>${r\'$\'}{project.version}</version>\n </dependency>\n <dependency>\n <groupId>${r\'$\'}{project.groupId}</groupId>\n <artifactId>${this.originProjectName}-web</artifactId>\n <version>${r\'$\'}{project.version}</version>\n </dependency>\n <!-- apache常用工具包 -->\n <dependency>\n <groupId>org.apache.commons</groupId>\n <artifactId>commons-lang3</artifactId>\n <version>${r\'$\'}{commons-lang3.version}</version>\n </dependency>\n <!-- apache io流工具包 -->\n <dependency>\n <groupId>commons-io</groupId>\n <artifactId>commons-io</artifactId>\n <version>${r\'$\'}{commons-io.version}</version>\n </dependency>\n <!-- apache集合工具包 -->\n <dependency>\n <groupId>org.apache.commons</groupId>\n <artifactId>commons-collections4</artifactId>\n <version>${r\'$\'}{commons-collections.version}</version>\n </dependency>\n <!-- guava工具包 -->\n <dependency>\n <groupId>com.google.guava</groupId>\n <artifactId>guava</artifactId>\n <version>${r\'$\'}{guava.version}</version>\n </dependency>\n <!-- 集成mybatis http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/index.html -->\n <dependency>\n <groupId>org.mybatis.spring.boot</groupId>\n <artifactId>mybatis-spring-boot-starter</artifactId>\n <version>${r\'$\'}{mybatis-spring-boot.version}</version>\n </dependency>\n <!-- 单元测试使用H2内存数据库 -->\n <dependency>\n <groupId>com.h2database</groupId>\n <artifactId>h2</artifactId>\n <version>${r\'$\'}{h2.version}</version>\n </dependency>\n <!-- 单元测试使用mysql脚本转H2 -->\n <dependency>\n <groupId>com.parmet</groupId>\n <artifactId>mysql2h2-parser</artifactId>\n <version>${r\'$\'}{mysql2h2.version}</version>\n </dependency>\n <!-- mapstruct提供属性映射功能 http://mapstruct.org/ -->\n <dependency>\n <groupId>org.mapstruct</groupId>\n <artifactId>mapstruct</artifactId>\n <version>${r\'$\'}{org.mapstruct.version}</version>\n </dependency>\n <!-- swagger依赖 -->\n <dependency>\n <groupId>io.swagger</groupId>\n <artifactId>swagger-annotations</artifactId>\n <version>${r\'$\'}{swagger-annotations.version}</version>\n </dependency>\n <dependency>\n <groupId>io.springfox</groupId>\n <artifactId>springfox-boot-starter</artifactId>\n <version>${r\'$\'}{springfox-boot-starter.version}</version>\n </dependency>\n <!-- jsoup HTML parser library(用于过滤XSS) https://jsoup.org/ -->\n <dependency>\n <groupId>org.jsoup</groupId>\n <artifactId>jsoup</artifactId>\n <version>${r\'$\'}{jsoup.version}</version>\n </dependency>\n <#if this.projectFeature.lombokEnabled>\n <!-- 用注解简化pojo类 https://projectlombok.org/ -->\n <dependency>\n <groupId>org.projectlombok</groupId>\n <artifactId>lombok</artifactId>\n <version>${r\'$\'}{lombok.version}</version>\n </dependency>\n </#if>\n <#if usingExcel>\n <!-- excel导入导出工具 https://github.com/alibaba/easyexcel -->\n <dependency>\n <groupId>com.alibaba</groupId>\n <artifactId>easyexcel</artifactId>\n <version>${r\'$\'}{easyexcel.version}</version>\n </dependency>\n </#if>\n </dependencies>\n </dependencyManagement>\n\n</project>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(3,'README.md.ftl','/',1,1,1,'<#include \"/abstracted/common.ftl\">\n# ${this.projectDesc}\n\n## 关于项目\n\n- web项目启动类:[${this.projectNameUpper}App.java](/${this.projectNameSplit}-web/src/main/java/${this.packageName?replace(\'.\',\'/\')}/${this.projectNameUpper}App.java)\n- 单元测试入口类:[Main.java](/${this.projectNameSplit}-web/src/test/java/${this.packageName?replace(\'.\',\'/\')}/Main.java)\n- mysql建表语句:[${this.projectName}.sql](/${this.projectNameSplit}-web/src/test/resources/DB/${this.projectName}.sql)\n\n## 表结构\n<#list this.metaEntities as metaEntity>\n\n### ${metaEntity.desc?replace(\'\\\'\',\'\"\')?replace(\'\\n\',\'\\\\n\')}【${metaEntity.tableName}】\n|字段名 | 类型 | 非空 | 键 | 注释 |\n|------ | ---- | --- | --- | ---- |\n <#list metaEntity.fields as fieldId,field>\n <#assign pk_display><#if field.primaryKey>主键</#if></#assign>\n <#assign notNull_display><#if field.notNull>是<#elseIf field.defaultValue == \'NULL\'> 否 </#if></#assign>\n| ${field.fieldName} | ${field.fieldType}${SqlTemplateFunction.getLengthDisplay(field)} | ${notNull_display} | ${pk_display} | ${CommonTemplateFunction.convertCommentDisplay(field.fetchComment())} |\n </#list>\n</#list>\n<#list this.mtms! as mtm>\n\n <#assign field1=mtm.refer1.pkField>\n <#assign field2=mtm.refer2.pkField>\n### ${mtm.desc?replace(\'\\\'\',\'\"\')?replace(\'\\n\',\'\\\\n\')}【${mtm.tableName}】\n|字段名 | 类型 | 非空 | 键 | 注释 |\n|------ | ---- | --- | --- | ---- |\n| ${mtm.fkAliasForSql1} | ${field1.fieldType}${SqlTemplateFunction.getLengthDisplay(field1)} | 是 | | ${CommonTemplateFunction.convertCommentDisplay(field1.fetchComment())} |\n| ${mtm.fkAliasForSql2} | ${field2.fieldType}${SqlTemplateFunction.getLengthDisplay(field2)} | 是 | | ${CommonTemplateFunction.convertCommentDisplay(field2.fetchComment())} |\n</#list>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(4,'chartItem.ftl','/abstracted',1,1,2,'<#include \"/abstracted/commonForChart.ftl\">\n<#-- 定义数据项id->图表项的映射 -->\n<#assign chartItemMapWrapper = CommonTemplateFunction.createHashMapWrapper()>\n<#--定义宏:组装chartItemMap-->\n<#macro buildChartItemMap items>\n <#list items as item>\n <@justCall chartItemMapWrapper.put(item.sourceItemId, item)/>\n </#list>\n</#macro>\n<#if isChartType(ChartType.DETAIL_LIST)>\n <@buildChartItemMap this.columnList/>\n<#elseif isChartType(ChartType.AGG_TABLE)>\n <@buildChartItemMap this.dimensionList/>\n <@buildChartItemMap this.metricsList/>\n<#elseif isChartType(ChartType.BAR_LINE)>\n <@buildChartItemMap [this.axisX]/>\n <#if this.axisX2??>\n <@buildChartItemMap [this.axisX2]/>\n </#if>\n <@buildChartItemMap this.axisYList/>\n<#elseif isChartType(ChartType.PIE)>\n <@buildChartItemMap [this.dimension, this.metrics]/>\n</#if>\n<#-- 判断数据项是否被图表项引用 -->\n<#function isSourceItemUsed sourceItem>\n <#return chartItemMapWrapper.containsKey(sourceItem.sourceItemId)>\n</#function>\n<#-- 过滤有效的dimension -->\n<#assign filteredDimension = []>\n<#list this.chartSource.dimensionMap as itemId,dimension>\n <#if isSourceItemUsed(dimension)>\n <#assign filteredDimension += [dimension]>\n </#if>\n</#list>\n<#-- 过滤有效的metrics -->\n<#assign filteredMetrics = []>\n<#list this.chartSource.metricsMap as itemId,metrics>\n <#if isSourceItemUsed(metrics)>\n <#assign filteredMetrics += [metrics]>\n </#if>\n</#list>\n<#-- 过滤有效的having -->\n<#assign filteredHaving = []>\n<#list this.chartSource.havingMap as itemId,having>\n <#if isSourceItemUsed(having.parent!)>\n <#assign filteredHaving += [having]>\n </#if>\n</#list>\n<#-- 过滤有效的aggOrder -->\n<#assign filteredAggOrder = []>\n<#list this.chartSource.aggOrderMap as itemId,aggOrder>\n <#if isSourceItemUsed(aggOrder.parent!)>\n <#assign filteredAggOrder += [aggOrder]>\n </#if>\n</#list>\n<#-- 需要传入参数的where条件 -->\n<#assign paramedWhere = []>\n<#-- 不需要传入参数的where条件 -->\n<#assign unparamedWhere = []>\n<#list this.chartSource.whereMap as itemId,where>\n <#if where.custom>\n <#assign unparamedWhere += [where]>\n <#else>\n <#if FilterOperator.IS_NULL.getValue() == where.filterOperator\n || FilterOperator.NOT_NULL.getValue() == where.filterOperator>\n <#assign unparamedWhere += [where]>\n <#else>\n <#assign paramedWhere += [where]>\n </#if>\n </#if>\n</#list>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(5,'checkFeatureForRest.ftl','/abstracted',1,1,2,'<#-- 功能简介:校验是否需要生成rest服务类 -->\n<#include \"/abstracted/common.ftl\">\n<#function getGenRest entity>\n <#local genRest = entity.entityFeature.save\n || entity.entityFeature.update\n || entity.entityFeature.delete\n || entity.entityFeature.deleteBatch\n || entity.entityFeature.list\n || entity.entityFeature.show\n || entity.entityFeature.excelExport\n || entity.entityFeature.excelImport >\n <#if !genRest>\n <#list entity.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(entity.entityId)>\n <#if entityFeature.addRemove\n || entityFeature.set\n || entityFeature.withinEntity >\n <#local genRest = true >\n </#if>\n </#list>\n </#if>\n <#return genRest>\n</#function>\n<#-- 提供rest服务的模块 -->\n<#assign modulesForRest = CommonTemplateFunction.createHashSet()>\n<#list this.metaEntities as metaEntity>\n <#if getGenRest(metaEntity)>\n <#if metaEntity.module?hasContent>\n <@justCall modulesForRest.add(metaEntity.module)/>\n </#if>\n </#if>\n</#list>\n<#list this.charts as chart>\n <#if chart.module?hasContent>\n <@justCall modulesForRest.add(chart.module)/>\n </#if>\n</#list>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(6,'common.ftl','/abstracted',1,1,2,'<#-- 调用函数,如果存在输出则打印 -->\n<#macro call func><#if func??>${func}</#if></#macro>\n<#-- 仅调用函数,不打印 -->\n<#macro justCall func></#macro>\n\n<#-- 将当前model赋值给this变量 -->\n<#assign this = .dataModel>\n\n<#-- 首个单词转小写 -->\n<#function lowerFirstWord value>\n <#return \"${CommonTemplateFunction.lowerFirstWord(value)}\" >\n</#function>\n\n<#-- common模块名 -->\n<#assign commonModule = this.projectNameSplit + \"-common\">\n<#-- core模块名 -->\n<#assign coreModule = this.projectNameSplit + \"-core\">\n<#-- web模块名 -->\n<#assign webModule = this.projectNameSplit + \"-web\">\n<#-- common包路径 -->\n<#assign commonPackagePath = this.commonPackage?replace(\".\", \"/\")>\n<#-- 包路径 -->\n<#assign packageNamePath = this.packageName?replace(\".\", \"/\")>\n\n<#-- 生成getter setter -->\n<#function genGetterSetter type name override=false indent=1>\n <#local code = \"\">\n <#local cap = name?capFirst>\n <#local uncap = name?uncapFirst>\n <#local indentPrefix = \"\">\n <#list 1..indent as t>\n <#local indentPrefix += \" \">\n </#list>\n <#if override>\n <#local code += indentPrefix + \"@Override\\n\">\n </#if>\n <#local code += indentPrefix + \"public \" + type + \" get\" + cap + \"() {\\n\">\n <#local code += indentPrefix + \" return this.\" + uncap + \";\\n\">\n <#local code += indentPrefix + \"}\\n\\n\">\n <#if override>\n <#local code += indentPrefix + \"@Override\\n\">\n </#if>\n <#local code += indentPrefix + \"public void set\" + cap + \"(\" + type + \" \" + uncap + \") {\\n\">\n <#local code += indentPrefix + \" this.\" + uncap + \" = \" + uncap + \";\\n\">\n <#local code += indentPrefix + \"}\\n\\n\">\n <#return code >\n</#function>\n\n<#-- 渲染API路径 -->\n<#function renderApiPath entity suffix>\n <@call this.addImport(\"${this.packageName}.web.constant.WebConst\")/>\n <#if entity.module?hasContent>\n <#return \"WebConst.ModulePath.${entity.module?upperCase} + \\\"/${lowerFirstWord(entity.className)}${suffix}\\\"\" >\n <#else>\n <#return \"WebConst.API_PATH + \\\"/${lowerFirstWord(entity.className)}${suffix}\\\"\" >\n </#if>\n</#function>\n<#-- 渲染API路径 -->\n<#function renderApiPathForChart chart suffix>\n <@call this.addImport(\"${this.packageName}.web.constant.WebConst\")/>\n <#if chart.module?hasContent>\n <#return \"WebConst.ModulePath.${chart.module?upperCase} + \\\"/${lowerFirstWord(chart.chartName)}${suffix}\\\"\" >\n <#else>\n <#return \"WebConst.API_PATH + \\\"/${lowerFirstWord(chart.chartName)}${suffix}\\\"\" >\n </#if>\n</#function>\n<#--是否存在图表-->\n<#assign hasChart = false>\n<#--是否存在明细表-->\n<#assign hasDetailList = false>\n<#--是否存在聚合表-->\n<#assign hasAggTable = false>\n<#--是否存在柱线图-->\n<#assign hasBarLine = false>\n<#--是否存在饼图-->\n<#assign hasPie = false>\n<#list this.charts as chart>\n <#assign hasChart = true>\n <#if chart.chartType == ChartType.DETAIL_LIST.getValue()>\n <#assign hasDetailList = true>\n <#elseIf chart.chartType == ChartType.AGG_TABLE.getValue()>\n <#assign hasAggTable = true>\n <#elseIf chart.chartType == ChartType.BAR_LINE.getValue()>\n <#assign hasBarLine = true>\n <#elseIf chart.chartType == ChartType.PIE.getValue()>\n <#assign hasPie = true>\n </#if>\n</#list>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(7,'commonForChart.ftl','/abstracted',1,1,2,'<#include \"/abstracted/common.ftl\">\n<#-- 定义变量——主实体 -->\n<#assign mainEntity=this.chartSource.entity>\n<#-- 定义变量——join关联 -->\n<#assign joins=this.chartSource.joins>\n<#-- 带模块名的包路径 -->\n<#if this.module?hasContent>\n <#assign daoPackageName = this.packageName+\".dao.\"+this.module>\n <#assign qoPackageName = this.packageName+\".pojo.qo.\"+this.module>\n <#assign voPackageName = this.packageName+\".pojo.vo.\"+this.module>\n <#assign mapperPackageName = this.packageName+\".pojo.mapper.\"+this.module>\n <#assign servicePackageName = this.packageName+\".service.\"+this.module>\n <#assign apiPackageName = this.packageName+\".web.api.\"+this.module>\n <#assign restPackageName = this.packageName+\".web.rest.\"+this.module>\n<#else>\n <#assign daoPackageName = this.packageName+\".dao\">\n <#assign qoPackageName = this.packageName+\".pojo.qo\">\n <#assign voPackageName = this.packageName+\".pojo.vo\">\n <#assign mapperPackageName = this.packageName+\".pojo.mapper\">\n <#assign servicePackageName = this.packageName+\".service\">\n <#assign apiPackageName = this.packageName+\".web.api\">\n <#assign restPackageName = this.packageName+\".web.rest\">\n</#if>\n<#-- 判断当前图表的类型 -->\n<#function isChartType chartTypeEnum>\n <#return this.chartType == chartTypeEnum.getValue()>\n</#function>\n<#-- 映射图表自定义字段类型 -->\n<#function convertCustomFieldType type>\n <#local jfieldType = CustomFieldType.valueToJfieldType(type)>\n <@call this.addFieldTypeImport(jfieldType)/>\n <#return jfieldType>\n</#function>\n<#-- 映射维度字段类型 -->\n<#function convertDimensionFieldType dimension>\n <#-- 时间聚合全部返回String类型 -->\n <#if Granularity.MINUTE.getValue() == dimension.granularity\n || Granularity.HOUR.getValue() == dimension.granularity\n || Granularity.DAY.getValue() == dimension.granularity\n || Granularity.WEEK.getValue() == dimension.granularity\n || Granularity.MONTH.getValue() == dimension.granularity\n || Granularity.QUARTER.getValue() == dimension.granularity\n || Granularity.YEAR.getValue() == dimension.granularity>\n <#return \"String\">\n <#else>\n <#local field = dimension.field>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#return field.jfieldType>\n </#if>\n</#function>\n<#-- 映射指标字段类型 -->\n<#function convertMetricsFieldType metrics>\n <#if metrics.custom>\n <#return convertCustomFieldType(metrics.customFieldType)>\n <#else>\n <#if AggFunction.COUNT.getValue() == metrics.aggFunction\n || AggFunction.COUNT_DISTINCT.getValue() == metrics.aggFunction>\n <#return \"Integer\">\n <#else>\n <#local field = metrics.field>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#return field.jfieldType>\n </#if>\n </#if>\n</#function>\n<#-- 柱线图的参数模式 -->\n<#assign barLineParamMode=0>\n<#if isChartType(ChartType.BAR_LINE)>\n <#if this.axisX2??>\n <#assign barLineParamMode=1>\n <#else>\n <#assign barLineParamMode=2>\n </#if>\n</#if>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(8,'commonForEntity.ftl','/abstracted',1,1,2,'<#include \"/abstracted/common.ftl\">\n<#-- 带模块名的包路径 -->\n<#if this.module?hasContent>\n <#assign daoPackageName = this.packageName+\".dao.\"+this.module>\n <#assign dtoPackageName = this.packageName+\".pojo.dto.\"+this.module>\n <#assign examplePackageName = this.packageName+\".pojo.example.\"+this.module>\n <#assign mapperPackageName = this.packageName+\".pojo.mapper.\"+this.module>\n <#assign poPackageName = this.packageName+\".pojo.po.\"+this.module>\n <#assign qoPackageName = this.packageName+\".pojo.qo.\"+this.module>\n <#assign voPackageName = this.packageName+\".pojo.vo.\"+this.module>\n <#assign servicePackageName = this.packageName+\".service.\"+this.module>\n <#assign apiPackageName = this.packageName+\".web.api.\"+this.module>\n <#assign restPackageName = this.packageName+\".web.rest.\"+this.module>\n <#assign helpPackageName = this.packageName+\".help.\"+this.module>\n<#else>\n <#assign daoPackageName = this.packageName+\".dao\">\n <#assign dtoPackageName = this.packageName+\".pojo.dto\">\n <#assign examplePackageName = this.packageName+\".pojo.example\">\n <#assign mapperPackageName = this.packageName+\".pojo.mapper\">\n <#assign poPackageName = this.packageName+\".pojo.po\">\n <#assign qoPackageName = this.packageName+\".pojo.qo\">\n <#assign voPackageName = this.packageName+\".pojo.vo\">\n <#assign servicePackageName = this.packageName+\".service\">\n <#assign apiPackageName = this.packageName+\".web.api\">\n <#assign restPackageName = this.packageName+\".web.rest\">\n <#assign helpPackageName = this.packageName+\".help\">\n</#if>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(9,'forEntityInsert.ftl','/abstracted',1,1,2,'<#-- 功能简介:实体添加专用 -->\n<#include \"/abstracted/common.ftl\">\n<#assign fkFieldsForInsert = []>\n<#list this.insertFields as id,field>\n <#if field.foreignKey>\n <#assign fkFieldsForInsert += [field]>\n </#if>\n</#list>\n<#assign withinEntityList = []>\n<#list this.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.withinEntity>\n <#assign withinEntityList += [otherEntity]>\n </#if>\n</#list>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(10,'guessDateFormat.ftl','/abstracted',1,1,2,'<#-- 功能简介:推断日期格式 -->\n<#include \"/abstracted/common.ftl\">\n<#-- 推断常规字段的日期格式 -->\n<#function guessDateFormat field>\n <#if field.editType == EditType.DATE.getValue()>\n <@call this.addImport(\"${this.commonPackage}.constant.JsonFieldConst\")/>\n <#return \"JsonFieldConst.DEFAULT_DATE_FORMAT\">\n <#elseIf field.editType == EditType.DATETIME.getValue()>\n <@call this.addImport(\"${this.commonPackage}.constant.JsonFieldConst\")/>\n <#return \"JsonFieldConst.DEFAULT_DATETIME_FORMAT\">\n <#elseIf field.fieldType == JFieldType.DATE.getJavaType()\n || field.fieldType == JFieldType.LOCALDATE.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.constant.JsonFieldConst\")/>\n <#return \"JsonFieldConst.DEFAULT_DATE_FORMAT\">\n <#elseIf field.fieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.constant.JsonFieldConst\")/>\n <#return \"JsonFieldConst.DEFAULT_DATETIME_FORMAT\">\n <#else>\n <#return \"\">\n </#if>\n</#function>\n<#-- 推断自定义字段类型的日期格式(图表专用) -->\n<#function guessDateFormatForCustom customFieldType>\n <#if customFieldType == CustomFieldType.DATE.getValue()>\n <@call this.addImport(\"${this.commonPackage}.constant.JsonFieldConst\")/>\n <#return \"JsonFieldConst.DEFAULT_DATE_FORMAT\">\n <#elseIf customFieldType == CustomFieldType.DATE_TIME.getValue()>\n <@call this.addImport(\"${this.commonPackage}.constant.JsonFieldConst\")/>\n <#return \"JsonFieldConst.DEFAULT_DATETIME_FORMAT\">\n <#else>\n <#return \"\">\n </#if>\n</#function>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(11,'guessDefaultJfieldValue.ftl','/abstracted',1,1,2,'<#-- 功能简介:根据java字段类型,猜测默认值 -->\n<#include \"/abstracted/common.ftl\">\n<#function guessDefaultJfieldValue jfieldType>\n <#if jfieldType == JFieldType.INTEGER.getJavaType()>\n <#return \"0\" >\n <#elseIf jfieldType == JFieldType.BOOLEAN.getJavaType()>\n <#return \"false\" >\n <#elseIf jfieldType == JFieldType.SHORT.getJavaType()>\n <#return \"0\" >\n <#elseIf jfieldType == JFieldType.LONG.getJavaType()>\n <#return \"0L\" >\n <#elseIf jfieldType == JFieldType.STRING.getJavaType()>\n <#return \"\\\"\\\"\" >\n <#elseIf jfieldType == JFieldType.DATE.getJavaType()>\n <@call this.addImport(\"java.util.Date\")/>\n <#return \"new Date()\" >\n <#elseIf jfieldType == JFieldType.DOUBLE.getJavaType()>\n <#return \"0.0d\" >\n <#elseIf jfieldType == JFieldType.FLOAT.getJavaType()>\n <@call this.addImport(\"java.util.Date\")/>\n <#return \"0.0f\" >\n <#elseIf jfieldType == JFieldType.BIGDECIMAL.getJavaType()>\n <@call this.addImport(\"java.math.BigDecimal\")/>\n <#return \"BigDecimal.ZERO\" >\n </#if>\n</#function>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(12,'mtmCascadeExtsForList.ftl','/abstracted',1,1,2,'<#-- 功能简介:多对多级联扩展字段列表专用 -->\n<#include \"/abstracted/common.ftl\">\n<#--将所有需要列表展示的级联实体放入数组中-->\n<#assign mtmCascadeEntitiesForList = []>\n<#--将所有需要列表展示的多对多放入数组中-->\n<#assign mtmForList = []>\n<#--将所有级联扩展列表字段按级联实体分组放入数组中-->\n<#assign groupMtmCascadeExtsForList = []>\n<#--组装多对多级联扩展相关的数据结构-->\n<#list this.holds as otherEntity,mtm>\n <#--初始化当前级联实体对应的级联扩展列表字段-->\n <#assign mtmCascadeExts=[]>\n <#list mtm.getCascadeExtList(this.entityId) as mtmCascadeExt>\n <#assign cascadeField=mtmCascadeExt.cascadeField>\n <#--判断是否开启级联列表展示开关-->\n <#if mtmCascadeExt.list>\n <#assign mtmCascadeExts +=[mtmCascadeExt]>\n </#if>\n </#list>\n <#if mtmCascadeExts?hasContent>\n <#assign groupMtmCascadeExtsForList += [mtmCascadeExts]>\n <#assign mtmCascadeEntitiesForList += [otherEntity]>\n <#assign mtmForList += [mtm]>\n </#if>\n</#list>\n<#--判断级联扩展列表字段中是否有标题字段-->\n<#function hasTitleField otherEntity mtmCascadeExts>\n <#list mtmCascadeExts as cascadeExt>\n <#if otherEntity.titleField?? && otherEntity.titleField == cascadeExt.cascadeField>\n <#return true>\n </#if>\n </#list>\n <#return false>\n</#function>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(13,'mtmCascadeExtsForOppList.ftl','/abstracted',1,1,2,'<#-- 功能简介:【对方】多对多级联扩展持有当前实体的【列表】信息 -->\n<#include \"/abstracted/common.ftl\">\n<#--将所有需要当前实体【列表】展示的【对方】实体放入数组中-->\n<#assign mtmCascadeEntitiesForOppList = []>\n<#--将所有需要当前实体【列表】展示的多对多放入数组中-->\n<#assign mtmForOppList = []>\n<#--将当前实体所有级联扩展【列表】字段按【对方】实体分组放入数组中-->\n<#assign groupMtmCascadeExtsForOppList = []>\n<#--定义宏:组装多对多级联扩展相关的数据结构-->\n<#macro buildMtmCascadeForOppList holds>\n <#list holds as otherEntity,mtm>\n <#--初始化当前级联实体对应的级联扩展【列表】字段-->\n <#assign mtmCascadeExts=[]>\n <#list mtm.getCascadeExtList(otherEntity.entityId) as mtmCascadeExt>\n <#assign cascadeField=mtmCascadeExt.cascadeField>\n <#--判断是否开启级联【列表】展示开关-->\n <#if mtmCascadeExt.list>\n <#assign mtmCascadeExts +=[mtmCascadeExt]>\n </#if>\n </#list>\n <#if mtmCascadeExts?hasContent>\n <#assign groupMtmCascadeExtsForOppList += [mtmCascadeExts]>\n <#assign mtmCascadeEntitiesForOppList += [otherEntity]>\n <#assign mtmForOppList += [mtm]>\n </#if>\n </#list>\n</#macro>\n<@buildMtmCascadeForOppList this.holds/>\n<@buildMtmCascadeForOppList this.unHolds/>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(14,'mtmCascadeExtsForOppShow.ftl','/abstracted',1,1,2,'<#-- 功能简介:【对方】多对多级联扩展持有当前实体的【详情】信息 -->\n<#include \"/abstracted/common.ftl\">\n<#--将所有需要当前实体【详情】展示的【对方】实体放入数组中-->\n<#assign mtmCascadeEntitiesForOppShow = []>\n<#--将所有需要当前实体【详情】展示的多对多放入数组中-->\n<#assign mtmForOppShow = []>\n<#--将当前实体所有级联扩展【详情】字段按【对方】实体分组放入数组中-->\n<#assign groupMtmCascadeExtsForOppShow = []>\n<#--定义宏:组装多对多级联扩展相关的数据结构-->\n<#macro buildMtmCascadeForOppShow holds>\n <#list holds as otherEntity,mtm>\n <#--初始化当前级联实体对应的级联扩展【详情】字段-->\n <#assign mtmCascadeExts=[]>\n <#list mtm.getCascadeExtList(otherEntity.entityId) as mtmCascadeExt>\n <#assign cascadeField=mtmCascadeExt.cascadeField>\n <#--判断是否开启级联【详情】展示开关-->\n <#if mtmCascadeExt.show>\n <#assign mtmCascadeExts +=[mtmCascadeExt]>\n </#if>\n </#list>\n <#if mtmCascadeExts?hasContent>\n <#assign groupMtmCascadeExtsForOppShow += [mtmCascadeExts]>\n <#assign mtmCascadeEntitiesForOppShow += [otherEntity]>\n <#assign mtmForOppShow += [mtm]>\n </#if>\n </#list>\n</#macro>\n<@buildMtmCascadeForOppShow this.holds/>\n<@buildMtmCascadeForOppShow this.unHolds/>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(15,'mtmCascadeExtsForQuery.ftl','/abstracted',1,1,2,'<#-- 功能简介:多对多级联扩展字段查询专用 -->\n<#include \"/abstracted/common.ftl\">\n<#--将所有级联扩展查询字段放入数组中-->\n<#assign mtmCascadeExtsForQuery = []>\n<#--将所有需要查询的级联实体放入数组中-->\n<#assign mtmCascadeEntitiesForQuery = []>\n<#--将所有需要查询的多对多放入数组中-->\n<#assign mtmForQuery = []>\n<#--将所有级联扩展查询字段按级联实体分组放入数组中-->\n<#assign groupMtmCascadeExtsForQuery = []>\n<#--定义宏:组装多对多级联扩展相关的数据结构-->\n<#macro buildMtmCascadeForQuery holds hostEntityId>\n <#list holds as otherEntity,mtm>\n <#--初始化当前级联实体对应的级联扩展查询字段-->\n <#assign mtmCascadeExts=[]>\n <#list mtm.getCascadeExtList(hostEntityId) as mtmCascadeExt>\n <#assign cascadeField=mtmCascadeExt.cascadeField>\n <#--开启级联查询开关 && (是主键 || 字段支持查询) -->\n <#if mtmCascadeExt.query && (cascadeField.primaryKey || cascadeField.query)>\n <#assign mtmCascadeExts +=[mtmCascadeExt]>\n <#assign mtmCascadeExtsForQuery += [mtmCascadeExt]>\n </#if>\n </#list>\n <#if mtmCascadeExts?hasContent>\n <#assign groupMtmCascadeExtsForQuery += [mtmCascadeExts]>\n <#assign mtmCascadeEntitiesForQuery += [otherEntity]>\n <#assign mtmForQuery += [mtm]>\n </#if>\n </#list>\n</#macro>\n<@buildMtmCascadeForQuery this.holds, this.entityId/>\n<@buildMtmCascadeForQuery this.unHolds, this.entityId/>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(16,'mtmCascadeExtsForShow.ftl','/abstracted',1,1,2,'<#-- 功能简介:多对多级联扩展字段详情专用 -->\n<#include \"/abstracted/common.ftl\">\n<#--将所有需要详情展示的级联实体放入数组中-->\n<#assign mtmCascadeEntitiesForShow = []>\n<#--将所有需要详情展示的多对多放入数组中-->\n<#assign mtmForShow = []>\n<#--将所有级联扩展详情字段按级联实体分组放入数组中-->\n<#assign groupMtmCascadeExtsForShow = []>\n<#--组装多对多级联扩展相关的数据结构-->\n<#list this.holds as otherEntity,mtm>\n <#--初始化当前级联实体对应的级联扩展详情字段-->\n <#assign mtmCascadeExts=[]>\n <#list mtm.getCascadeExtList(this.entityId) as mtmCascadeExt>\n <#assign cascadeField=mtmCascadeExt.cascadeField>\n <#--判断是否开启级联详情展示开关-->\n <#if mtmCascadeExt.show>\n <#assign mtmCascadeExts +=[mtmCascadeExt]>\n </#if>\n </#list>\n <#if mtmCascadeExts?hasContent>\n <#assign groupMtmCascadeExtsForShow += [mtmCascadeExts]>\n <#assign mtmCascadeEntitiesForShow += [otherEntity]>\n <#assign mtmForShow += [mtm]>\n </#if>\n</#list>\n<#--根据id查询详情展示的级联实体序号-->\n<#function getMtmCascadeEntityIndexForShow entityId>\n <#list mtmCascadeEntitiesForShow as entity>\n <#if entity.entityId == entityId>\n <#return entity?index>\n </#if>\n </#list>\n <#return -1>\n</#function>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(17,'mtmForOpp.ftl','/abstracted',1,1,2,'<#-- 功能简介:获取当前实体被对方所持有的多对多 -->\n<#include \"/abstracted/common.ftl\">\n<#--将所有持有当前实体的【对方】实体放入数组中-->\n<#assign mtmEntitiesForOpp = []>\n<#--将所有持有当前实体的【多对多】放入数组中-->\n<#assign mtmsForOpp = []>\n<#--定义宏:组装多对多级联扩展相关的数据结构-->\n<#macro buildMtmsForOpp holds>\n <#list holds as otherEntity,mtm>\n <#if mtm.isHold(otherEntity.entityId)>\n <#assign mtmsForOpp += [mtm]>\n <#assign mtmEntitiesForOpp += [otherEntity]>\n </#if>\n </#list>\n</#macro>\n<@buildMtmsForOpp this.holds/>\n<@buildMtmsForOpp this.unHolds/>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(18,'mybatis.ftl','/abstracted',1,1,2,'<#-- mybatis sql模板专用 -->\n<#include \"/abstracted/common.ftl\">\n<#-- 生成if不为空条件内容,支持字段别名-->\n<#function ifNotEmptyConditionWithAlias alias field>\n <#if QueryType.isIn(field.queryType)>\n <#return \"${alias} != null and ${alias}.size() > 0 \" >\n <#elseIf field.jfieldType == JFieldType.STRING.getJavaType()>\n <#return \"${alias} != null and ${alias} != \'\' \" >\n <#else>\n <#return \"${alias} != null \" >\n </#if>\n</#function>\n<#-- 生成if不为空条件内容 -->\n<#function ifNotEmptyCondition field>\n <#return \"${ifNotEmptyConditionWithAlias(field.jfieldName,field)}\" >\n</#function>\n<#-- 将mysql中的关键字加``包裹 -->\n<#function wrapMysqlKeyword fieldName>\n <#return \"${SqlTemplateFunction.wrapMysqlKeyword(fieldName)}\" >\n</#function>\n\n<#-- 获取select列名,支持别名 -->\n<#function getSelectFieldWithAlias field tableAlias fieldAlias=\"\">\n <#if fieldAlias?hasContent>\n <#return \"${tableAlias}.${wrapMysqlKeyword(field.fieldName)} as ${wrapMysqlKeyword(fieldAlias)}\">\n <#elseIf field.fieldName?capitalize != field.jfieldName?capitalize>\n <#return \"${tableAlias}.${wrapMysqlKeyword(field.fieldName)} as ${wrapMysqlKeyword(field.jfieldName)}\">\n <#else>\n <#return \"${tableAlias}.${wrapMysqlKeyword(field.fieldName)}\">\n </#if>\n</#function>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(19,'mybatisForChart.ftl','/abstracted',1,1,2,'<#-- mybatis sql模板专用 -->\n<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/mybatis.ftl\">\n<#-- 映射过滤运算符 -->\n<#function mapperOperatorSymbol operator>\n <#if FilterOperator.EQUAL.getValue() == operator>\n <#return \"=\">\n <#elseIf FilterOperator.NOT_EQUAL.getValue() == operator>\n <#return \"!=\">\n <#elseIf FilterOperator.GT.getValue() == operator>\n <#return \">\">\n <#elseIf FilterOperator.GE.getValue() == operator>\n <#return \">=\">\n <#elseIf FilterOperator.LT.getValue() == operator>\n <#return \"&lt;\">\n <#elseIf FilterOperator.LE.getValue() == operator>\n <#return \"&lt;=\">\n <#elseIf FilterOperator.BETWEEN.getValue() == operator>\n <#return \"between\">\n <#elseIf FilterOperator.CONTAIN.getValue() == operator>\n <#return \"in\">\n <#elseIf FilterOperator.NOT_CONTAIN.getValue() == operator>\n <#return \"not in\">\n <#elseIf FilterOperator.IS_NULL.getValue() == operator>\n <#return \"is null\">\n <#elseIf FilterOperator.NOT_NULL.getValue() == operator>\n <#return \"is not null\">\n <#elseIf FilterOperator.LIKE.getValue() == operator>\n <#return \"like\">\n <#elseIf FilterOperator.IS_NOW.getValue() == operator>\n <#return \"between\">\n <#elseIf FilterOperator.BEFORE_TIME.getValue() == operator>\n <#return \"between\">\n <#elseIf FilterOperator.AFTER_TIME.getValue() == operator>\n <#return \"between\">\n </#if>\n</#function>\n<#-- 映射排序运算符 -->\n<#function mapperOrderBySymbol sortType>\n <#if SortType.ASC.getValue() == sortType>\n <#return \"asc\">\n <#else>\n <#return \"desc\">\n </#if>\n</#function>\n<#-- 映射排序运算符 -->\n<#function mapperJoinSymbol joinType>\n <#if JoinType.RIGHT_JOIN.getValue() == joinType>\n <#return \"right join\">\n <#elseIf JoinType.LEFT_JOIN.getValue() == joinType>\n <#return \"left join\">\n <#else>\n <#return \"inner join\">\n </#if>\n</#function>\n<#-- join的表名 -->\n<#function joinTableName joinPart>\n <#if joinPart.joinPartType == \"entity\">\n <#return wrapMysqlKeyword(joinPart.entity.tableName)>\n <#else>\n <#return wrapMysqlKeyword(joinPart.mtm.tableName)>\n </#if>\n</#function>\n<#-- join的字段名 -->\n<#function joinFieldName joinPart>\n <#if joinPart.joinPartType == \"entity\">\n <#return wrapMysqlKeyword(joinPart.field.fieldName)>\n <#else>\n <#return wrapMysqlKeyword(joinPart.mtmField)>\n </#if>\n</#function>\n<#-- 渲染维度 -->\n<#function renderDimension dimension>\n <#local fieldName = \"t${dimension.joinIndex}.${wrapMysqlKeyword(dimension.field.fieldName)}\">\n <#if dimension.granularity == Granularity.INTERVAL_10.getValue()>\n <#return \"${fieldName} / 10\">\n <#elseIf dimension.granularity == Granularity.INTERVAL_100.getValue()>\n <#return \"${fieldName} / 100\">\n <#elseIf dimension.granularity == Granularity.INTERVAL_1000.getValue()>\n <#return \"${fieldName} / 1000\">\n <#elseIf dimension.granularity == Granularity.INTERVAL_10000.getValue()>\n <#return \"${fieldName} / 10000\">\n <#elseIf dimension.granularity == Granularity.MINUTE.getValue()>\n <#return \"DATE_FORMAT(${fieldName},\'%Y-%m-%d %H:%i:00\')\">\n <#elseIf dimension.granularity == Granularity.HOUR.getValue()>\n <#return \"DATE_FORMAT(${fieldName},\'%Y-%m-%d %H:00:00\')\">\n <#elseIf dimension.granularity == Granularity.DAY.getValue()>\n <#return \"DATE_FORMAT(${fieldName},\'%Y-%m-%d\')\">\n <#elseIf dimension.granularity == Granularity.WEEK.getValue()>\n <#return \"DATE_FORMAT(${fieldName},\'%x-%v\')\">\n <#elseIf dimension.granularity == Granularity.MONTH.getValue()>\n <#return \"DATE_FORMAT(${fieldName},\'%Y-%m\')\">\n <#elseIf dimension.granularity == Granularity.QUARTER.getValue()>\n <#return \"CONCAT(YEAR(${fieldName}),\'-\',QUARTER(${fieldName}))\">\n <#elseIf dimension.granularity == Granularity.YEAR.getValue()>\n <#return \"DATE_FORMAT(${fieldName},\'%Y\')\">\n <#else>\n <#return fieldName>\n </#if>\n</#function>\n<#-- 渲染指标 -->\n<#function renderMetrics metrics>\n <#if metrics.custom>\n <#return metrics.customContent>\n <#else>\n <#local fieldName = \"t${metrics.joinIndex}.${wrapMysqlKeyword(metrics.field.fieldName)}\">\n <#if metrics.aggFunction == AggFunction.SUM.getValue()>\n <#return \"SUM(${fieldName})\">\n <#elseIf metrics.aggFunction == AggFunction.MAX.getValue()>\n <#return \"MAX(${fieldName})\">\n <#elseIf metrics.aggFunction == AggFunction.MIN.getValue()>\n <#return \"MIN(${fieldName})\">\n <#elseIf metrics.aggFunction == AggFunction.AVG.getValue()>\n <#return \"AVG(${fieldName})\">\n <#elseIf metrics.aggFunction == AggFunction.COUNT.getValue()>\n <#return \"COUNT(${fieldName})\">\n <#elseIf metrics.aggFunction == AggFunction.COUNT_DISTINCT.getValue()>\n <#return \"COUNT(DISTINCT ${fieldName})\">\n </#if>\n </#if>\n</#function>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(20,'usingExcel.ftl','/abstracted',1,1,2,'<#-- 功能简介:判断是否需要引入excel功能 -->\n<#include \"/abstracted/common.ftl\">\n<#--是否引入excel-->\n<#assign usingExcel = false>\n<#list this.metaEntities as entity>\n <#if entity.entityFeature.excelExport || entity.entityFeature.excelImport>\n <#assign usingExcel = true>\n <#break>\n </#if>\n</#list>\n<#list this.charts as chart>\n <#if chart.excelExport!false>\n <#assign usingExcel = true>\n <#break>\n </#if>\n</#list>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(21,'__dir.ftl','/{commonModule}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${commonModule}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(22,'pom.xml.ftl','/{commonModule}',1,1,1,'<#include \"/abstracted/common.ftl\">\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n <parent>\n <artifactId>${this.originProjectName}</artifactId>\n <groupId>${this.groupId}</groupId>\n <version>1.0.0-SNAPSHOT</version>\n </parent>\n <modelVersion>4.0.0</modelVersion>\n\n <artifactId>${this.originProjectName}-common</artifactId>\n <packaging>jar</packaging>\n\n <dependencies>\n\n <dependency>\n <groupId>com.fasterxml.jackson.core</groupId>\n <artifactId>jackson-databind</artifactId>\n </dependency>\n <dependency>\n <groupId>com.fasterxml.jackson.datatype</groupId>\n <artifactId>jackson-datatype-jsr310</artifactId>\n </dependency>\n <dependency>\n <groupId>commons-io</groupId>\n <artifactId>commons-io</artifactId>\n </dependency>\n <dependency>\n <groupId>org.apache.commons</groupId>\n <artifactId>commons-lang3</artifactId>\n </dependency>\n <dependency>\n <groupId>org.apache.commons</groupId>\n <artifactId>commons-collections4</artifactId>\n </dependency>\n <dependency>\n <groupId>com.google.guava</groupId>\n <artifactId>guava</artifactId>\n </dependency>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-validation</artifactId>\n </dependency>\n <dependency>\n <groupId>io.swagger</groupId>\n <artifactId>swagger-annotations</artifactId>\n </dependency>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-aop</artifactId>\n </dependency>\n <dependency>\n <groupId>org.mybatis.spring.boot</groupId>\n <artifactId>mybatis-spring-boot-starter</artifactId>\n </dependency>\n <!-- jsoup HTML parser library @ https://jsoup.org/ -->\n <dependency>\n <groupId>org.jsoup</groupId>\n <artifactId>jsoup</artifactId>\n </dependency>\n <dependency>\n <groupId>org.springframework</groupId>\n <artifactId>spring-web</artifactId>\n <scope>provided</scope>\n </dependency>\n <!--servlet-->\n <dependency>\n <groupId>javax.servlet</groupId>\n <artifactId>javax.servlet-api</artifactId>\n <scope>provided</scope>\n </dependency>\n </dependencies>\n <build>\n <plugins>\n <plugin>\n <groupId>org.apache.maven.plugins</groupId>\n <artifactId>maven-compiler-plugin</artifactId>\n <configuration>\n <source>${r\'$\'}{java.version}</source>\n <target>${r\'$\'}{java.version}</target>\n </configuration>\n </plugin>\n </plugins>\n </build>\n\n</project>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(23,'__dir.ftl','/{commonModule}/src/main/java/{commonPackage}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${commonPackagePath}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(24,'ErrorCode.java.ftl','/{commonModule}/src/main/java/{commonPackage}/constant',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.util.HashMap\")/>\n<@call this.addImport(\"java.util.Map\")/>\n<@call this.printClassCom(\"错误代码枚举\")/>\npublic enum ErrorCode {\n\n /**\n * 参数校验失败\n */\n ERR_VALIDATION(\"400\", \"error.err_validation\"),\n /**\n * 并发访问失败\n */\n CONCURRENCY_FAILURE(\"409\", \"error.concurrency_failure\"),\n /**\n * http method不允许\n */\n METHOD_NOT_SUPPORTED(\"405\", \"error.method_not_supported\"),\n /**\n * 系统内部错误\n */\n INTERNAL_SERVER_ERROR(\"500\", \"error.internal_server_error\"),\n /**\n * 键值重复\n */\n DUPLICATE_KEY(\"521\", \"error.duplicate_key\"),\n /**\n * 记录未找到\n */\n RECORD_NOT_FIND(\"522\", \"error.record_not_find\"),\n /**\n * 参数为空\n */\n PARAM_IS_NULL(\"523\", \"error.param_is_null\"),\n /**\n * 级联删除异常\n */\n CASCADE_DELETE_ERROR(\"524\", \"error.cascade_delete_error\");\n\n\n private static final Map<String, ErrorCode> LOOKUP = new HashMap<>();\n\n static {\n for (ErrorCode e : ErrorCode.values()) {\n LOOKUP.put(e.value, e);\n }\n }\n\n private final String value;\n private final String desc;\n\n\n ErrorCode(String value, String desc) {\n this.value = value;\n this.desc = desc;\n }\n\n public static ErrorCode find(String value) {\n return LOOKUP.get(value);\n }\n\n public static ErrorCode findByDesc(String desc) {\n for (ErrorCode e : ErrorCode.values()) {\n if (e.getDesc().equals(desc)) {\n return e;\n }\n }\n return null;\n }\n\n public String getValue() {\n return value;\n }\n\n public String getDesc() {\n return desc;\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.constant;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(25,'JsonFieldConst.java.ftl','/{commonModule}/src/main/java/{commonPackage}/constant',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"json常量\")/>\npublic class JsonFieldConst {\n\n public static final String DEFAULT_DATE_FORMAT = \"yyyy-MM-dd\";\n\n public static final String DEFAULT_DATETIME_FORMAT = \"yyyy-MM-dd HH:mm:ss\";\n\n public static final String DEFAULT_DATETIME_FORMAT_2 = \"yyyy-MM-dd HH:mm:ss.SSS\";\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.constant;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(26,'LoginContext.java.ftl','/{commonModule}/src/main/java/{commonPackage}/context',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"登录上下文接口\")/>\npublic interface LoginContext {\n\n /**\n * 获取当前登录用户唯一标识\n *\n * @return 用户唯一标识\n */\n String getCurrentUser();\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.context;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(27,'MyCustomDateEditor.java.ftl','/{commonModule}/src/main/java/{commonPackage}/convert',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n<@call this.addImport(\"org.springframework.util.StringUtils\")/>\n<@call this.addImport(\"java.beans.PropertyEditorSupport\")/>\n<@call this.addImport(\"java.util.Date\")/>\n<@call this.printClassCom(\"自定义日期装换\")/>\npublic class MyCustomDateEditor extends PropertyEditorSupport {\n\n\n @Override\n public String getAsText() {\n Date value = (Date) getValue();\n return DateUtil.getDateStr(value);\n }\n\n @Override\n public void setAsText(String text) throws IllegalArgumentException {\n if (!StringUtils.hasText(text)) {\n // Treat empty String as null value.\n setValue(null);\n } else {\n setValue(DateUtil.parseDate(text));\n }\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.convert;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(28,'MyCustomLocalDateEditor.java.ftl','/{commonModule}/src/main/java/{commonPackage}/convert',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n<@call this.addImport(\"org.springframework.util.StringUtils\")/>\n<@call this.addImport(\"java.beans.PropertyEditorSupport\")/>\n<@call this.addImport(\"java.time.LocalDate\")/>\n<@call this.printClassCom(\"自定义日期装换\")/>\npublic class MyCustomLocalDateEditor extends PropertyEditorSupport {\n\n\n @Override\n public String getAsText() {\n LocalDate value = (LocalDate) getValue();\n return DateUtil.getLocalDateStr(value);\n }\n\n @Override\n public void setAsText(String text) throws IllegalArgumentException {\n if (!StringUtils.hasText(text)) {\n // Treat empty String as null value.\n setValue(null);\n } else {\n setValue(DateUtil.parseLocalDate(text));\n }\n }\n\n\n}\n\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.convert;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(29,'MyCustomLocalDateTimeEditor.java.ftl','/{commonModule}/src/main/java/{commonPackage}/convert',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n<@call this.addImport(\"org.springframework.util.StringUtils\")/>\n<@call this.addImport(\"java.beans.PropertyEditorSupport\")/>\n<@call this.addImport(\"java.time.LocalDateTime\")/>\n<@call this.printClassCom(\"自定义日期装换\")/>\npublic class MyCustomLocalDateTimeEditor extends PropertyEditorSupport {\n\n\n @Override\n public String getAsText() {\n LocalDateTime value = (LocalDateTime) getValue();\n return DateUtil.getLocalDateTimeStr(value);\n }\n\n @Override\n public void setAsText(String text) throws IllegalArgumentException {\n if (!StringUtils.hasText(text)) {\n // Treat empty String as null value.\n setValue(null);\n } else {\n setValue(DateUtil.parseLocalDateTime(text));\n }\n }\n\n\n}\n\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.convert;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(30,'DAO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/dao',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.context.LoginContext\")/>\n<@call this.addImport(\"${this.commonPackage}.pojo.po.AbstractPO\")/>\n<@call this.addImport(\"${this.commonPackage}.pojo.qo.AbstractQO\")/>\n<@call this.addImport(\"${this.commonPackage}.pojo.qo.PageQO\")/>\n<@call this.addImport(\"${this.commonPackage}.pojo.vo.AbstractVO\")/>\n<@call this.addImport(\"${this.commonPackage}.pojo.vo.PageVO\")/>\n<@call this.addImport(\"${this.commonPackage}.util.SpringUtil\")/>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.addImport(\"java.util.ArrayList\")/>\n<@call this.printClassCom(\"DAO父接口\")/>\npublic interface DAO<PO extends AbstractPO> {\n\n /**\n * 根据id查询记录\n *\n * @param id 主键\n * @return 实体PO对象\n */\n PO findById(Object id);\n\n /**\n * 查询分页结果\n *\n * @param qo 分页查询参数\n * @param <VO> 列表展示结果类型\n * @param <QO> 分页查询参数类型\n * @return 分页展示对象\n */\n default <VO extends AbstractVO, QO extends PageQO> PageVO<VO> findByPage(QO qo) {\n int count = this.findCountByQuery(qo);\n List<VO> list;\n if (count > 0) {\n list = this.findListByQuery(qo);\n } else {\n list = new ArrayList<>();\n }\n PageVO<VO> pageVO = new PageVO<>(list, qo.getPageNo(), qo.getPageSize(), count);\n return pageVO;\n }\n\n /**\n * 根据条件查询记录数\n *\n * @param qo 查询参数\n * @param <QO> 查询参数类型\n * @return\n */\n <QO extends PageQO> int findCountByQuery(QO qo);\n\n /**\n * 根据分页条件查询列表\n *\n * @param qo 查询参数\n * @param <VO> 列表展示结果类型\n * @param <QO> 查询参数类型\n * @return\n */\n <VO extends AbstractVO, QO extends AbstractQO> List<VO> findListByQuery(QO qo);\n\n /**\n * 执行插入记录\n *\n * @param po 实体PO对象\n * @return 保存成功数量\n * 如果保存成功返回1,失败则返回0\n */\n int _save(PO po);\n\n /**\n * 先填充附加字段,再插入记录\n *\n * @param po 实体PO对象\n * @return 保存成功数量\n * 如果保存成功返回1,失败则返回0\n */\n default int save(PO po) {\n LoginContext loginContext = SpringUtil.getBean(LoginContext.class);\n po.preInsert(loginContext.getCurrentUser());\n return this._save(po);\n }\n\n /**\n * 执行修改实体操作\n *\n * @param po 实体PO对象\n * @return 修改成功数量\n * 如果修改成功返回1,失败则返回0\n */\n int _update(PO po);\n\n /**\n * 修改实体操作\n * <p>先填充附加字段,再修改记录\n *\n * @param po 实体PO对象\n * @return 修改成功数量\n * 如果修改成功返回1,失败则返回0\n */\n default int update(PO po) {\n LoginContext loginContext = SpringUtil.getBean(LoginContext.class);\n po.preUpdate(loginContext.getCurrentUser());\n int count = this._update(po);\n if (count > 0) {\n po.postUpdate();\n }\n return count;\n }\n\n /**\n * 删除实体\n *\n * @param id 主键\n * @return 删除成功数量\n * 如果删除成功返回1,失败则返回0\n */\n int delete(Object id);\n\n /**\n * 根据id判断记录是否存在\n *\n * @param id 主键\n * @return 如果存在,则返回true,不存在则返回false\n */\n boolean exist(Object id);\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.dao;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(31,'BusinessException.java.ftl','/{commonModule}/src/main/java/{commonPackage}/exception',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.constant.ErrorCode\")/>\n<@call this.addImport(\"${this.commonPackage}.util.MessageSourceUtil\")/>\n<@call this.printClassCom(\"业务异常\")/>\npublic class BusinessException extends RuntimeException {\n\n private ErrorCode code;\n\n public BusinessException() {\n super(MessageSourceUtil.getMessage(ErrorCode.INTERNAL_SERVER_ERROR.getDesc()));\n this.code = ErrorCode.INTERNAL_SERVER_ERROR;\n }\n\n public BusinessException(String message) {\n super(message);\n this.code = ErrorCode.INTERNAL_SERVER_ERROR;\n }\n\n public BusinessException(Throwable cause) {\n super(cause.getMessage(), cause);\n this.code = ErrorCode.INTERNAL_SERVER_ERROR;\n }\n\n public BusinessException(String message, Throwable cause) {\n super(message, cause);\n this.code = ErrorCode.INTERNAL_SERVER_ERROR;\n }\n\n public BusinessException(ErrorCode code) {\n super(MessageSourceUtil.getMessage(code.getDesc()));\n this.code = code;\n }\n\n public BusinessException(ErrorCode code, String message) {\n super(message);\n this.code = code;\n }\n\n public ErrorCode getErrorCode() {\n return code;\n }\n\n public void setErrorCode(ErrorCode code) {\n this.code = code;\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.exception;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(32,'EnableOptimisticLock.java.ftl','/{commonModule}/src/main/java/{commonPackage}/optimistic',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.springframework.context.annotation.Import\")/>\n<@call this.addImport(\"java.lang.annotation.*\")/>\n<@call this.printClassCom(\"启用乐观锁\")/>\n@Target({ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Inherited\n@Import({OptimisticLockConfiguration.class})\npublic @interface EnableOptimisticLock {\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.optimistic;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(33,'OptimisticException.java.ftl','/{commonModule}/src/main/java/{commonPackage}/optimistic',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"乐观锁异常\")/>\npublic class OptimisticException extends RuntimeException {\n\n public OptimisticException() {\n\n }\n\n public OptimisticException(String message) {\n super(message);\n }\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.optimistic;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(34,'OptimisticLock.java.ftl','/{commonModule}/src/main/java/{commonPackage}/optimistic',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.lang.annotation.*\")/>\n<@call this.printClassCom(\"乐观锁注解\")/>\n@Inherited\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.METHOD})\npublic @interface OptimisticLock {\n\n /**\n * 捕获异常\n *\n * @return\n */\n Class<? extends Exception>[] catchType() default {OptimisticException.class};\n\n /**\n * 异常重试次数\n *\n * @return\n */\n int retry() default 3;\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.optimistic;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(35,'OptimisticLockAspect.java.ftl','/{commonModule}/src/main/java/{commonPackage}/optimistic',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.pojo.po.Version\")/>\n<@call this.addImport(\"${this.commonPackage}.util.MessageSourceUtil\")/>\n<@call this.addImport(\"org.aspectj.lang.ProceedingJoinPoint\")/>\n<@call this.addImport(\"org.aspectj.lang.Signature\")/>\n<@call this.addImport(\"org.aspectj.lang.annotation.Around\")/>\n<@call this.addImport(\"org.aspectj.lang.annotation.Aspect\")/>\n<@call this.addImport(\"org.aspectj.lang.annotation.Pointcut\")/>\n<@call this.addImport(\"org.aspectj.lang.reflect.MethodSignature\")/>\n<@call this.addImport(\"org.slf4j.Logger\")/>\n<@call this.addImport(\"org.slf4j.LoggerFactory\")/>\n<@call this.addImport(\"org.springframework.core.annotation.Order\")/>\n<@call this.addImport(\"java.lang.reflect.Method\")/>\n<@call this.printClassCom(\"乐观锁AOP\")/>\n@Aspect\n@Order(-1000)\npublic class OptimisticLockAspect {\n\n private final static Logger logger = LoggerFactory.getLogger(OptimisticLockAspect.class);\n\n /**\n * 拦截AbstractDAO的update方法\n * 用于抛出乐观锁冲突时的异常\n */\n @Pointcut(\"execution(int ${this.commonPackage}.dao.DAO.update(${this.commonPackage}.pojo.po.AbstractPO))\")\n public void daoPointcut() {\n }\n\n @Around(\"daoPointcut()\")\n public Object doDAOAround(final ProceedingJoinPoint thisJoinPoint) throws Throwable {\n Object[] args = thisJoinPoint.getArgs();\n int count = (int) thisJoinPoint.proceed();\n if ((args[0] instanceof Version) && count <= 0) {\n throw new OptimisticException(MessageSourceUtil.getMessage(\"error.optimistic_lock\"));\n }\n return count;\n }\n\n /**\n * 拦截任何添加了@Tx注解的Service方法\n * 捕获乐观锁冲突异常,并重试\n */\n @Pointcut(\"execution(@${this.commonPackage}.optimistic.OptimisticLock * *(..))\")\n public void servicePointcut() {\n }\n\n @Around(\"servicePointcut()\")\n public Object doServiceAround(final ProceedingJoinPoint thisJoinPoint) throws Throwable {\n Signature signature = thisJoinPoint.getSignature();\n MethodSignature methodSignature = (MethodSignature) signature;\n final Method targetMethod = methodSignature.getMethod();\n OptimisticLock optimisticLock = targetMethod.getAnnotation(OptimisticLock.class);\n if (optimisticLock == null) {\n throw new RuntimeException(\"optimistic lock aop error\");\n }\n\n Class<? extends Exception>[] catchTypes = optimisticLock.catchType();\n if (catchTypes == null || catchTypes.length == 0) {\n throw new RuntimeException(\"optimistic lock aop error\");\n }\n int retry = optimisticLock.retry();\n Object object = tryServiceProceed(thisJoinPoint, catchTypes, retry);\n return object;\n }\n\n private Object tryServiceProceed(ProceedingJoinPoint thisJoinPoint, Class<? extends Exception>[] catchTypes, int retry) throws Throwable {\n Object object = null;\n try {\n object = thisJoinPoint.proceed();\n } catch (Throwable throwable) {\n if (retry > 0) {\n for (Class<? extends Exception> catchType : catchTypes) {\n if (catchType.isInstance(throwable)) {\n try {\n // 睡100毫秒再试\n Thread.sleep(100);\n } catch (InterruptedException e) {\n }\n logger.warn(\"乐观锁重试,retry=\" + retry + \",method=\" + thisJoinPoint.getSignature().getName());\n return tryServiceProceed(thisJoinPoint, catchTypes, --retry);\n }\n }\n }\n throw throwable;\n }\n return object;\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.optimistic;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(36,'OptimisticLockConfiguration.java.ftl','/{commonModule}/src/main/java/{commonPackage}/optimistic',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.slf4j.Logger\")/>\n<@call this.addImport(\"org.slf4j.LoggerFactory\")/>\n<@call this.addImport(\"org.springframework.context.annotation.Bean\")/>\n<@call this.printClassCom(\"乐观锁配置\")/>\npublic class OptimisticLockConfiguration {\n\n private static final Logger logger = LoggerFactory.getLogger(OptimisticLockConfiguration.class);\n\n @Bean\n public OptimisticLockAspect optimisticLockAspect() {\n logger.info(\"创建OptimisticLockAspect\");\n return new OptimisticLockAspect();\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.optimistic;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(37,'AbstractDTO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/dto',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.util.JsonUtil\")/>\n<@call this.addImport(\"java.io.Serializable\")/>\n<@call this.printClassCom(\"数据传输对象超类\")/>\npublic abstract class AbstractDTO implements Serializable {\n\n private static final long serialVersionUID = 1915714417292764241L;\n\n @Override\n public String toString() {\n return JsonUtil.toJSONString(this);\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.dto;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(38,'AbstractPO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.util.Date\")/>\n<@call this.addImport(\"java.time.LocalDateTime\")/>\n<@call this.addImport(\"java.io.Serializable\")/>\n<@call this.printClassCom(\"抽象PO\")/>\npublic abstract class AbstractPO implements Serializable {\n\n private static final long serialVersionUID = 640619331196056814L;\n\n public void preInsert(String createdBy) {\n if (this instanceof CreatedTime || this instanceof OperatedTime) {\n Date now = new Date();\n if (this instanceof CreatedTime) {\n ((CreatedTime) this).setCreatedTime(now);\n }\n if (this instanceof OperatedTime) {\n ((OperatedTime) this).setOperatedTime(now);\n }\n }\n if (this instanceof Jsr310CreatedTime || this instanceof Jsr310OperatedTime) {\n LocalDateTime now = LocalDateTime.now();\n if (this instanceof Jsr310CreatedTime) {\n ((Jsr310CreatedTime) this).setCreatedTime(now);\n }\n if (this instanceof Jsr310OperatedTime) {\n ((Jsr310OperatedTime) this).setOperatedTime(now);\n }\n }\n if (this instanceof Deleted) {\n ((Deleted) this).setDeleted(false);\n }\n if (this instanceof CreatedBy) {\n ((CreatedBy) this).setCreatedBy(createdBy);\n }\n if (this instanceof OperatedBy) {\n ((OperatedBy) this).setOperatedBy(createdBy);\n }\n if (this instanceof Version) {\n ((Version) this).setVersion(1);\n }\n }\n\n public void preUpdate(String operatedBy) {\n if (this instanceof OperatedTime) {\n ((OperatedTime) this).setOperatedTime(new Date());\n }\n if (this instanceof Jsr310OperatedTime) {\n ((Jsr310OperatedTime) this).setOperatedTime(LocalDateTime.now());\n }\n if (this instanceof OperatedBy) {\n ((OperatedBy) this).setOperatedBy(operatedBy);\n }\n }\n\n public void postUpdate() {\n if (this instanceof Version) {\n Version version = (Version) this;\n version.setVersion(version.getVersion() + 1);\n }\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(39,'Created.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"创建人&创建时间\")/>\npublic interface Created extends CreatedBy, CreatedTime {\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(40,'CreatedBy.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"创建人接口\")/>\npublic interface CreatedBy {\n\n String getCreatedBy();\n\n void setCreatedBy(String createdBy);\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(41,'CreatedTime.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.util.Date\")/>\n<@call this.printClassCom(\"创建时间接口\")/>\npublic interface CreatedTime {\n\n Date getCreatedTime();\n\n void setCreatedTime(Date createdTime);\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(42,'CreatedOperatedDeleted.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"逻辑删除+创建人&创建时间+操作人&操作时间\")/>\npublic interface CreatedOperatedDeleted extends Created, Operated, Deleted {\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(43,'CreatedOperatedDeletedVersion.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"逻辑删除+创建人&创建时间+操作人&操作时间+版本号\")/>\npublic interface CreatedOperatedDeletedVersion extends Created, Operated, Deleted, Version {\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(44,'Deleted.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"是否逻辑删除接口\")/>\npublic interface Deleted {\n\n Boolean getDeleted();\n\n void setDeleted(Boolean deleted);\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(45,'Jsr310Created.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"创建人&创建时间-jsr310时间API\")/>\npublic interface Jsr310Created extends CreatedBy, Jsr310CreatedTime {\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(46,'Jsr310CreatedOperatedDeleted.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"逻辑删除+创建人&创建时间+操作人&操作时间-jsr310时间API\")/>\npublic interface Jsr310CreatedOperatedDeleted extends Jsr310Created, Jsr310Operated, Deleted {\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(47,'Jsr310CreatedOperatedDeletedVersion.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"逻辑删除+创建人&创建时间+操作人&操作时间+版本号-jsr310时间API\")/>\npublic interface Jsr310CreatedOperatedDeletedVersion extends Jsr310Created, Jsr310Operated, Deleted, Version {\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(48,'Jsr310CreatedTime.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.time.LocalDateTime\")/>\n<@call this.printClassCom(\"创建时间接口-jsr310时间API\")/>\npublic interface Jsr310CreatedTime {\n\n LocalDateTime getCreatedTime();\n\n void setCreatedTime(LocalDateTime createdTime);\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(49,'Jsr310Operated.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"操作人&操作时间-jsr310时间API\")/>\npublic interface Jsr310Operated extends OperatedBy, Jsr310OperatedTime {\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(50,'Jsr310OperatedTime.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.time.LocalDateTime\")/>\n<@call this.printClassCom(\"操作时间接口-jsr310时间API\")/>\npublic interface Jsr310OperatedTime {\n\n LocalDateTime getOperatedTime();\n\n void setOperatedTime(LocalDateTime operatedTime);\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(51,'Operated.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"操作人&操作时间\")/>\npublic interface Operated extends OperatedBy, OperatedTime {\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(52,'OperatedBy.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"操作人接口\")/>\npublic interface OperatedBy {\n\n String getOperatedBy();\n\n void setOperatedBy(String operatedBy);\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(53,'OperatedTime.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.util.Date\")/>\n<@call this.printClassCom(\"操作时间接口\")/>\npublic interface OperatedTime {\n\n Date getOperatedTime();\n\n void setOperatedTime(Date operatedTime);\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(54,'Version.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/po',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"是否乐观锁版本接口\")/>\npublic interface Version {\n\n Integer getVersion();\n\n void setVersion(Integer version);\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.po;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(55,'AbstractQO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/qo',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.util.JsonUtil\")/>\n<@call this.addImport(\"java.io.Serializable\")/>\n<@call this.printClassCom(\"数据查询参数对象超类\")/>\npublic abstract class AbstractQO implements Serializable {\n\n private static final long serialVersionUID = -2460649808778841614L;\n\n @Override\n public String toString() {\n return JsonUtil.toJSONString(this);\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.qo;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(56,'OptionQO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/qo',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"io.swagger.annotations.ApiParam\")/>\n<@call this.addImport(\"javax.validation.constraints.Max\")/>\n<@call this.printClassCom(\"查询选项入参\")/>\npublic class OptionQO<K, V> extends AbstractQO {\n\n public static final int DEFAULT_LIMIT = 10000;\n /**\n * 一次请求加载条数\n */\n @ApiParam(value = \"一次请求加载条数\", example = \"20\")\n @Max(value = 1000, message = \"limit不能大于1000\")\n protected Integer limit;\n\n /**\n * 上次查询最后一条记录的key\n */\n @ApiParam(value = \"上次查询最后一条记录的key\", example = \"1\")\n protected K lastKey;\n\n /**\n * 匹配值\n */\n @ApiParam(value = \"匹配值\")\n protected V matchValue;\n\n public OptionQO() {\n // 默认查询1万条\n this.limit = DEFAULT_LIMIT;\n }\n\n public Integer getLimit() {\n return limit;\n }\n\n public void setLimit(Integer limit) {\n this.limit = limit;\n }\n\n public K getLastKey() {\n return lastKey;\n }\n\n public void setLastKey(K lastKey) {\n this.lastKey = lastKey;\n }\n\n public V getMatchValue() {\n return matchValue;\n }\n\n public void setMatchValue(V matchValue) {\n this.matchValue = matchValue;\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.qo;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(57,'PageQO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/qo',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"io.swagger.annotations.ApiParam\")/>\n<@call this.addImport(\"javax.validation.constraints.Max\")/>\n<@call this.addImport(\"javax.validation.constraints.Min\")/>\n<@call this.printClassCom(\"分页查询入参\")/>\npublic class PageQO extends AbstractQO {\n\n public static final int DEFAULT_PAGE_NO = 1;\n public static final int DEFAULT_PAGE_SIZE = 20;\n\n /**\n * 每页的条数\n */\n @ApiParam(value = \"分页参数,每页的条数\", example = \"20\")\n @Max(value = 1000, message = \"pageSize不能大于1000\")\n protected Integer pageSize;\n\n /**\n * 当前第几页\n */\n @ApiParam(value = \"分页参数,第几页\", example = \"1\")\n @Min(value = 1, message = \"pageNo不能小于1\")\n protected Integer pageNo;\n\n public PageQO() {\n // 默认第一页,每页20条\n this(1, 20);\n }\n\n public PageQO(Integer pageNo, Integer pageSize) {\n if (pageNo == null) {\n pageNo = DEFAULT_PAGE_NO;\n }\n if (pageSize == null) {\n pageSize = DEFAULT_PAGE_SIZE;\n }\n this.pageNo = pageNo;\n this.pageSize = pageSize;\n }\n\n public Integer getPageSize() {\n return pageSize;\n }\n\n public void setPageSize(Integer pageSize) {\n this.pageSize = pageSize;\n }\n\n public Integer getPageNo() {\n return pageNo;\n }\n\n public void setPageNo(Integer pageNo) {\n this.pageNo = pageNo;\n }\n\n public int getStartIndex() {\n return (pageNo - 1) * pageSize;\n }\n\n public int getEndIndex() {\n return pageNo * pageSize;\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.qo;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(58,'AbstractVO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/vo',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.util.JsonUtil\")/>\n<@call this.addImport(\"java.io.Serializable\")/>\n<@call this.printClassCom(\"抽象VO\")/>\npublic abstract class AbstractVO implements Serializable {\n\n private static final long serialVersionUID = -1417748095004687576L;\n\n @Override\n public String toString() {\n return JsonUtil.toJSONString(this);\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.vo;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(59,'Chart2DimensionVO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/vo',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#if !hasChart>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"有两个维度的图表数据\")/>\npublic interface Chart2DimensionVO {\n\n /**\n * 获取第一维度值\n *\n * @return\n */\n Object fetchDimension1();\n\n /**\n * 获取第二维度值\n *\n * @return\n */\n Object fetchDimension2();\n\n /**\n * 获取指标值\n *\n * @return\n */\n Object fetchMetrics();\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.vo;\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(60,'OptionVO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/vo',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"下拉框选项VO\")/>\npublic class OptionVO<K, V> extends AbstractVO {\n\n private K key;\n\n private V value;\n\n public OptionVO(K key, V value) {\n this.key = key;\n this.value = value;\n }\n\n public K getKey() {\n return key;\n }\n\n public void setKey(K key) {\n this.key = key;\n }\n\n public V getValue() {\n return value;\n }\n\n public void setValue(V value) {\n this.value = value;\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.vo;\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(61,'PageVO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/vo',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"io.swagger.annotations.ApiModel\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiModelProperty\")/>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.addImport(\"org.apache.commons.lang3.builder.ToStringBuilder\")/>\n<@call this.addImport(\"org.apache.commons.lang3.builder.ToStringStyle\")/>\n<@call this.printClassCom(\"分页结果对象\")/>\n@ApiModel\npublic class PageVO<T> extends AbstractVO {\n\n @ApiModelProperty(notes = \"每页条数\", example = \"10\", required = true)\n private Integer pageSize;\n @ApiModelProperty(notes = \"页码\", example = \"1\", required = true)\n private Integer currentPage;\n @ApiModelProperty(notes = \"开始序号\", example = \"0\", required = true)\n private Integer firstIndex;\n @ApiModelProperty(notes = \"结束序号\", example = \"10\", required = true)\n private Integer lastIndex;\n\n @ApiModelProperty(notes = \"数据列表\", required = true)\n private List<T> list;\n @ApiModelProperty(notes = \"总条数\", example = \"100\", required = true)\n private Integer total;\n @ApiModelProperty(notes = \"总页数\", example = \"10\", required = true)\n private Integer pageCount;\n\n public PageVO() {\n }\n\n public PageVO(List<T> list, int currentPage, int pageSize, int total) {\n if (pageSize <= 0) {\n throw new IllegalArgumentException(\n \"Illegal paging arguments. [pageSize=\" + pageSize + \"]\");\n }\n this.list = list;\n this.currentPage = currentPage;\n this.pageSize = pageSize;\n this.total = total;\n this.firstIndex = (currentPage - 1) * pageSize;\n this.lastIndex = currentPage * pageSize;\n if (total % pageSize > 0) {\n this.pageCount = total / pageSize + 1;\n } else {\n this.pageCount = total / pageSize;\n }\n }\n\n\n @Override\n public String toString() {\n return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)\n .append(\"pageSize\", pageSize)\n .append(\"currentPage\", currentPage)\n .append(\"firstIndex\", firstIndex)\n .append(\"lastIndex\", lastIndex)\n .append(\"list\", list)\n .append(\"total\", total)\n .append(\"pageCount\", pageCount)\n .toString();\n }\n\n public Integer getPageSize() {\n return pageSize;\n }\n\n public void setPageSize(Integer pageSize) {\n this.pageSize = pageSize;\n }\n\n public Integer getCurrentPage() {\n return currentPage;\n }\n\n public void setCurrentPage(Integer currentPage) {\n this.currentPage = currentPage;\n }\n\n public Integer getFirstIndex() {\n return firstIndex;\n }\n\n public void setFirstIndex(Integer firstIndex) {\n this.firstIndex = firstIndex;\n }\n\n public Integer getLastIndex() {\n return lastIndex;\n }\n\n public void setLastIndex(Integer lastIndex) {\n this.lastIndex = lastIndex;\n }\n\n public List<T> getList() {\n return list;\n }\n\n public void setList(List<T> list) {\n this.list = list;\n }\n\n public Integer getTotal() {\n return total;\n }\n\n public void setTotal(Integer total) {\n this.total = total;\n }\n\n public Integer getPageCount() {\n return pageCount;\n }\n\n public void setPageCount(Integer pageCount) {\n this.pageCount = pageCount;\n }\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.vo;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(62,'ReplyVO.java.ftl','/{commonModule}/src/main/java/{commonPackage}/pojo/vo',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.constant.ErrorCode\")/>\n<@call this.addImport(\"${this.commonPackage}.util.MessageSourceUtil\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiModel\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiModelProperty\")/>\n<@call this.printClassCom(\"通用响应对象\")/>\n@ApiModel\npublic class ReplyVO<T> extends AbstractVO {\n\n public static final String SUCCESS_CODE = \"0\";\n public static final String DEFAULT_SUCCESS_MSG_KEY = \"success\";\n public static final String DEFAULT_ERROR_CODE = \"-1\";\n\n @ApiModelProperty(notes = \"响应代码【0正确,非0错误】\", example = SUCCESS_CODE, required = true)\n private String code;\n\n @ApiModelProperty(notes = \"结果描述\", example = \"success\", required = true)\n private String message;\n\n @ApiModelProperty(notes = \"返回数据\")\n private T data;\n\n public ReplyVO() {\n }\n\n public ReplyVO(T data) {\n this.data = data;\n }\n\n public ReplyVO(String code, String message) {\n this.code = code;\n this.message = message;\n }\n\n public static <T> ReplyVO<T> fail(String message) {\n return new ReplyVO<>(DEFAULT_ERROR_CODE, message);\n }\n\n public static <T> ReplyVO<T> fail(ErrorCode errorCode) {\n return new ReplyVO<>(errorCode.getValue(), MessageSourceUtil.getMessage(errorCode.getDesc()));\n }\n\n public static <T> ReplyVO<T> success() {\n return new ReplyVO<>(SUCCESS_CODE, MessageSourceUtil.getMessage(\"reply.success\", DEFAULT_SUCCESS_MSG_KEY));\n }\n\n public static <T> ReplyVO<T> success(T data) {\n ReplyVO<T> replyVO = new ReplyVO<>(SUCCESS_CODE, MessageSourceUtil.getMessage(\"reply.success\", DEFAULT_SUCCESS_MSG_KEY));\n return replyVO.data(data);\n }\n\n /**\n * 设置数据\n *\n * @param data\n * @return\n */\n public ReplyVO<T> data(T data) {\n setData(data);\n return this;\n }\n\n\n public String getCode() {\n return code;\n }\n\n public void setCode(String code) {\n this.code = code;\n }\n\n public String getMessage() {\n return message;\n }\n\n public void setMessage(String message) {\n this.message = message;\n }\n\n public T getData() {\n return data;\n }\n\n public void setData(T data) {\n this.data = data;\n }\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.pojo.vo;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(63,'ChartDataUtil.java.ftl','/{commonModule}/src/main/java/{commonPackage}/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#if !hasChart>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.pojo.vo.Chart2DimensionVO\")/>\n<@call this.addImport(\"org.apache.commons.collections4.CollectionUtils\")/>\n<@call this.addImport(\"java.util.*\")/>\n<@call this.addImport(\"java.util.function.BiConsumer\")/>\n<@call this.addImport(\"java.util.function.BinaryOperator\")/>\n<@call this.addImport(\"java.util.function.Function\")/>\n<@call this.addImport(\"java.util.function.Supplier\")/>\n<@call this.addImport(\"java.util.stream.Collector\")/>\n<@call this.addImport(\"java.util.stream.Collectors\")/>\n<@call this.printClassCom(\"图表数据工具类\")/>\npublic class ChartDataUtil {\n\n /**\n * 获取列表数据中某个字段的所有可能值\n *\n * @param chartVOList\n * @param getter\n * @param <T>\n * @param <R>\n * @return\n */\n public static <T, R> List<R> getDistinctValues(List<T> chartVOList,\n Function<T, R> getter) {\n if (CollectionUtils.isEmpty(chartVOList)) {\n return Collections.emptyList();\n }\n return chartVOList.stream()\n .map(getter)\n .filter(v -> v != null)\n .distinct()\n .collect(Collectors.toList());\n }\n\n\n /**\n * 将具有两个维度值的数据列表转换成二维矩阵\n *\n * @param chartVOList 列表数据\n * @param dimension2Values 第二维度的所有可能值\n * @return\n */\n public static <T extends Chart2DimensionVO> List<Object[]> convert2DimensionMetrix(List<T> chartVOList,\n List<Object> dimension2Values) {\n if (CollectionUtils.isEmpty(chartVOList)) {\n return Collections.emptyList();\n }\n // 转换\n return chartVOList.stream()\n .filter(v -> v != null)\n .collect(new Collector<T, Map<Object, Object[]>, List<Object[]>>() {\n @Override\n public Supplier<Map<Object, Object[]>> supplier() {\n return HashMap::new;\n }\n\n @Override\n public BiConsumer<Map<Object, Object[]>, T> accumulator() {\n return (map, vo) -> map.compute(vo.fetchDimension1(), (key, array) -> {\n if (array == null) {\n array = new Object[dimension2Values.size() + 1];\n array[0] = key;\n }\n int index = dimension2Values.indexOf(vo.fetchDimension2());\n array[index + 1] = vo.fetchMetrics();\n return array;\n });\n }\n\n @Override\n public BinaryOperator<Map<Object, Object[]>> combiner() {\n return (map1, map2) -> {\n HashMap<Object, Object[]> map = new HashMap<>(map1);\n map2.forEach((key, value) -> map.merge(key, value, (arr1, arr2) -> {\n Object[] merger = new Object[dimension2Values.size() + 1];\n merger[0] = arr1[0];\n for (int i = 1; i < merger.length; i++) {\n merger[i] = arr1[i] == null ? arr2[i] : arr1[i];\n }\n return merger;\n }));\n return map;\n };\n }\n\n @Override\n public Function<Map<Object, Object[]>, List<Object[]>> finisher() {\n return map -> map.values().stream().collect(Collectors.toList());\n }\n\n @Override\n public Set<Characteristics> characteristics() {\n return Collections.emptySet();\n }\n });\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.util;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(64,'ConvertUtil.java.ftl','/{commonModule}/src/main/java/{commonPackage}/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"com.google.common.base.Function\")/>\n<@call this.addImport(\"com.google.common.base.Joiner\")/>\n<@call this.addImport(\"com.google.common.base.Splitter\")/>\n<@call this.addImport(\"com.google.common.collect.Iterables\")/>\n<@call this.addImport(\"com.google.common.collect.Lists\")/>\n<@call this.addImport(\"org.apache.commons.lang3.StringUtils\")/>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.addImport(\"java.util.Map\")/>\n<@call this.printClassCom(\"各种形式的转换工具类\")/>\npublic class ConvertUtil {\n\n /**\n * 整型数组转字符串\n *\n * @param array\n * @return\n */\n public static String convertIntegerArrayToString(Iterable<?> array) {\n if (array == null) {\n return null;\n }\n String join = Joiner.on(\',\').join(array);\n return join;\n }\n\n /**\n * 逗号分割字符串转换成字符串数组\n *\n * @param str\n * @return\n */\n public static String[] convertStringArray(String str) {\n if (StringUtils.isBlank(str)) {\n return null;\n }\n Iterable<String> split = Splitter.on(\',\').omitEmptyStrings().split(str);\n return Iterables.toArray(split, String.class);\n }\n\n /**\n * 逗号分割字符串转换成字符串列表\n *\n * @param str\n * @return\n */\n public static List<String> convertStringList(String str) {\n if (StringUtils.isBlank(str)) {\n return null;\n }\n List<String> list = Splitter.on(\',\').omitEmptyStrings().splitToList(str);\n return list;\n }\n\n /**\n * 逗号分割字符串转换成整数数组\n *\n * @param str\n * @return\n */\n public static Integer[] convertIntegerArray(String str) {\n if (StringUtils.isBlank(str)) {\n return null;\n }\n Iterable<String> split = Splitter.on(\',\').omitEmptyStrings().split(str);\n Iterable<Integer> transform = Iterables.transform(split, SafeUtil::getInteger);\n return Iterables.toArray(transform, Integer.class);\n }\n\n /**\n * 逗号分割字符串转换成Double数组\n *\n * @param str\n * @return\n */\n public static Double[] convertDoubleArray(String str) {\n if (StringUtils.isBlank(str)) {\n return null;\n }\n Iterable<String> split = Splitter.on(\',\').omitEmptyStrings().split(str);\n Iterable<Double> transform = Iterables.transform(split, SafeUtil::getDouble);\n return Iterables.toArray(transform, Double.class);\n }\n\n\n /**\n * 将map列表转换成单一数组\n *\n * @param list\n * @param key\n * @param clazz\n * @return\n */\n public static <T> T[] convertMapListToArray(List<Map<String, Object>> list, final String key, Class<T> clazz) {\n if (list == null) {\n return null;\n }\n return convertListToArray(list, input -> (T) input.get(key), clazz);\n }\n\n /**\n * 自定义转换器进行数组转换\n *\n * @param list\n * @param function\n * @param clazz\n * @return\n */\n public static <F, T> T[] convertListToArray(List<F> list, Function<F, T> function, Class<T> clazz) {\n if (list == null) {\n return null;\n }\n Iterable<T> transform = Iterables.transform(list, function);\n return Iterables.toArray(transform, clazz);\n }\n\n /**\n * 自定义转换器进行列表转换\n *\n * @param list\n * @param function\n * @return\n */\n public static <F, T> List<T> convertList(List<F> list, Function<F, T> function) {\n if (list == null) {\n return null;\n }\n List<T> transform = Lists.transform(list, function);\n return transform;\n }\n\n /**\n * 逗号分割字符串转换成整数列表\n *\n * @param str\n * @return\n */\n public static List<Integer> convertIntegerList(String str) {\n if (StringUtils.isBlank(str)) {\n return null;\n }\n List<String> list = Splitter.on(\',\').omitEmptyStrings().splitToList(str);\n return Lists.transform(list, SafeUtil::getInteger);\n }\n\n /**\n * 逗号分割字符串转换成长整数列表\n *\n * @param str\n * @return\n */\n public static List<Long> convertLongList(String str) {\n if (StringUtils.isBlank(str)) {\n return null;\n }\n List<String> list = Splitter.on(\',\').omitEmptyStrings().splitToList(str);\n return Lists.transform(list, SafeUtil::getLong);\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.util;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(65,'DateUtil.java.ftl','/{commonModule}/src/main/java/{commonPackage}/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.apache.commons.lang3.StringUtils\")/>\n<@call this.addImport(\"org.apache.commons.lang3.time.DateFormatUtils\")/>\n<@call this.addImport(\"org.apache.commons.lang3.time.DateUtils\")/>\n<@call this.addImport(\"java.text.ParseException\")/>\n<@call this.addImport(\"java.time.LocalDate\")/>\n<@call this.addImport(\"java.time.LocalDateTime\")/>\n<@call this.addImport(\"java.time.format.DateTimeFormatter\")/>\n<@call this.addImport(\"java.time.format.DateTimeFormatterBuilder\")/>\n<@call this.addImport(\"java.time.temporal.ChronoField\")/>\n<@call this.addImport(\"java.util.Date\")/>\n<@call this.printClassCom(\"日期工具\")/>\npublic class DateUtil {\n\n public static final String DATE_FORMAT_1 = \"yyyy-MM-dd\";\n public static final String DATE_FORMAT_2 = \"yyyy-MM-dd HH:mm:ss\";\n\n /**\n * 获取日期字符串yyyy-MM-dd\n *\n * @param date\n * @return\n */\n public static String getDateStr(Date date) {\n return getDateStr(date, DATE_FORMAT_1);\n }\n\n /**\n * 获取指定格式的日期字符串\n *\n * @param date\n * @param dateFormat\n * @return\n */\n public static String getDateStr(Date date, String dateFormat) {\n if (date == null || StringUtils.isBlank(dateFormat)) {\n return \"\";\n }\n return DateFormatUtils.format(date, dateFormat);\n }\n\n /**\n * 获取日期字符串yyyy-MM-dd\n *\n * @param date\n * @return\n */\n public static String getLocalDateStr(LocalDate date) {\n return getLocalDateStr(date, DATE_FORMAT_1);\n }\n\n /**\n * 获取指定格式的日期字符串\n *\n * @param date\n * @param dateFormat\n * @return\n */\n public static String getLocalDateStr(LocalDate date, String dateFormat) {\n if (date == null || StringUtils.isBlank(dateFormat)) {\n return \"\";\n }\n return date.format(DateTimeFormatter.ofPattern(dateFormat));\n }\n\n /**\n * 获取日期字符串yyyy-MM-dd HH:mm:ss\n *\n * @param dateTime\n * @return\n */\n public static String getLocalDateTimeStr(LocalDateTime dateTime) {\n return getLocalDateTimeStr(dateTime, DATE_FORMAT_2);\n }\n\n /**\n * 获取指定格式的日期字符串\n *\n * @param dateTime\n * @param dateFormat\n * @return\n */\n public static String getLocalDateTimeStr(LocalDateTime dateTime, String dateFormat) {\n if (dateTime == null || StringUtils.isBlank(dateFormat)) {\n return \"\";\n }\n return dateTime.format(DateTimeFormatter.ofPattern(dateFormat));\n }\n\n /**\n * 解析日期字符串\n *\n * @param datetime\n * @param dateFormat\n * @return\n */\n public static Date parseDate(String datetime, String dateFormat) {\n if (StringUtils.isBlank(datetime)) {\n return null;\n }\n try {\n return DateUtils.parseDate(datetime, dateFormat);\n } catch (ParseException e) {\n throw new IllegalArgumentException(e);\n }\n }\n\n /**\n * 解析日期字符串yyyy-MM-dd\n *\n * @param datetime\n * @return\n */\n public static Date parseDate(String datetime) {\n if (StringUtils.isBlank(datetime)) {\n return null;\n }\n String dateFormat;\n if (datetime.length() == DATE_FORMAT_1.length()) {\n dateFormat = DATE_FORMAT_1;\n } else if (datetime.length() == DATE_FORMAT_2.length()) {\n dateFormat = DATE_FORMAT_2;\n } else {\n throw new IllegalArgumentException(MessageSourceUtil.getMessage(\"error.data_format_error\") + \",datetime=\" + datetime);\n }\n return parseDate(datetime, dateFormat);\n }\n\n\n /**\n * 解析日期字符串\n *\n * @param datetime\n * @return\n */\n public static LocalDate parseLocalDate(String datetime) {\n if (StringUtils.isBlank(datetime)) {\n return null;\n }\n String dateFormat;\n if (datetime.length() == DATE_FORMAT_1.length()) {\n dateFormat = DATE_FORMAT_1;\n } else if (datetime.length() == DATE_FORMAT_2.length()) {\n dateFormat = DATE_FORMAT_2;\n } else {\n throw new IllegalArgumentException(MessageSourceUtil.getMessage(\"error.data_format_error\") + \",datetime=\" + datetime);\n }\n return parseLocalDate(datetime, dateFormat);\n }\n\n /**\n * 解析日期字符串\n *\n * @param datetime\n * @param dateFormat\n * @return\n */\n public static LocalDate parseLocalDate(String datetime, String dateFormat) {\n if (StringUtils.isBlank(datetime)) {\n return null;\n }\n return LocalDate.parse(datetime, DateTimeFormatter.ofPattern(dateFormat));\n }\n\n /**\n * 解析日期字符串\n *\n * @param datetime\n * @return\n */\n public static LocalDateTime parseLocalDateTime(String datetime) {\n if (StringUtils.isBlank(datetime)) {\n return null;\n }\n String dateFormat;\n if (datetime.length() == DATE_FORMAT_1.length()) {\n dateFormat = DATE_FORMAT_1;\n } else if (datetime.length() == DATE_FORMAT_2.length()) {\n dateFormat = DATE_FORMAT_2;\n } else {\n throw new IllegalArgumentException(MessageSourceUtil.getMessage(\"error.data_format_error\") + \",datetime=\" + datetime);\n }\n return parseLocalDateTime(datetime, dateFormat);\n }\n\n /**\n * 解析日期字符串\n *\n * @param datetime\n * @param dateFormat\n * @return\n */\n public static LocalDateTime parseLocalDateTime(String datetime, String dateFormat) {\n if (StringUtils.isBlank(datetime)) {\n return null;\n }\n DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern(dateFormat)\n .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)\n .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)\n .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)\n .toFormatter();\n return LocalDateTime.parse(datetime, formatter);\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.util;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(66,'TempDirUtil.java.ftl','/{commonModule}/src/main/java/{commonPackage}/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.apache.commons.lang3.StringUtils\")/>\n<@call this.addImport(\"org.apache.commons.lang3.time.DateFormatUtils\")/>\n<@call this.addImport(\"java.io.File\")/>\n<@call this.addImport(\"java.util.Date\")/>\n<@call this.printClassCom(\"临时目录工具类\")/>\npublic class TempDirUtil {\n\n\n /**\n * 获取临时目录\n *\n * @param appName\n * @param withDate\n * @return\n */\n public static String getTmpDir(String appName, boolean withDate, boolean withUUID) {\n String tempFolder = System.getProperty(\"java.io.tmpdir\");\n if (tempFolder.endsWith(File.separator)) {\n tempFolder = tempFolder.substring(0, tempFolder.length() - 1);\n }\n if (StringUtils.isNotBlank(appName)) {\n tempFolder += File.separator + appName;\n }\n if (withDate) {\n String todayStr = DateFormatUtils.format(new Date(), \"yyyyMMdd\");\n tempFolder += File.separator + todayStr;\n }\n if (withUUID) {\n tempFolder += File.separator + UUIDUtil.getUUID16();\n }\n return tempFolder;\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.util;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(67,'JsonUtil.java.ftl','/{commonModule}/src/main/java/{commonPackage}/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"com.fasterxml.jackson.core.JsonParseException\")/>\n<@call this.addImport(\"com.fasterxml.jackson.core.JsonProcessingException\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.DeserializationFeature\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.JavaType\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.JsonMappingException\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.ObjectMapper\")/>\n<@call this.addImport(\"com.fasterxml.jackson.datatype.jsr310.JavaTimeModule\")/>\n<@call this.addImport(\"org.apache.commons.lang3.StringUtils\")/>\n<@call this.addImport(\"org.slf4j.Logger\")/>\n<@call this.addImport(\"org.slf4j.LoggerFactory\")/>\n<@call this.addImport(\"java.io.IOException\")/>\n<@call this.addImport(\"java.text.SimpleDateFormat\")/>\n<@call this.addImport(\"java.util.ArrayList\")/>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.printClassCom(\"封装json操作\")/>\npublic class JsonUtil {\n\n private final static Logger LOGGER = LoggerFactory.getLogger(JsonUtil.class);\n\n private static final ObjectMapper mapper = new ObjectMapper();\n\n static {\n mapper.setDateFormat(new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\"));\n mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);\n mapper.registerModule(new JavaTimeModule());\n }\n\n\n public static <T> T parseObject(String json, Class<T> clazz) {\n T t;\n if (StringUtils.isBlank(json)) {\n return null;\n }\n try {\n t = mapper.readValue(json, clazz);\n } catch (JsonParseException e) {\n LOGGER.error(\"json反序列化异常\", e);\n throw new RuntimeException(MessageSourceUtil.getMessage(\"error.json_deserialize_error\"), e);\n } catch (JsonMappingException e) {\n LOGGER.error(\"json反序列化异常\", e);\n throw new RuntimeException(MessageSourceUtil.getMessage(\"error.json_deserialize_error\"), e);\n } catch (IOException e) {\n LOGGER.error(\"json反序列化异常\", e);\n throw new RuntimeException(MessageSourceUtil.getMessage(\"error.json_deserialize_error\"), e);\n }\n return t;\n }\n\n\n public static String toJSONString(Object obj) {\n String str;\n try {\n str = mapper.writeValueAsString(obj);\n } catch (JsonProcessingException e) {\n LOGGER.error(\"json序列化异常\", e);\n throw new RuntimeException(MessageSourceUtil.getMessage(\"error.json_serialize_error\"), e);\n }\n return str;\n }\n\n public static String toJSONString(Object object, boolean prettyFormat) {\n if (prettyFormat) {\n try {\n return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);\n } catch (JsonProcessingException e) {\n LOGGER.error(\"json序列化异常\", e);\n throw new RuntimeException(MessageSourceUtil.getMessage(\"error.json_serialize_error\"), e);\n }\n }\n return toJSONString(object);\n\n }\n\n public static <T> List<T> parseArray(String json, Class<T> clazz) {\n List<T> list;\n if (StringUtils.isBlank(json)) {\n return null;\n }\n try {\n JavaType javaType = getCollectionType(ArrayList.class, clazz);\n list = mapper.readValue(json, javaType);\n } catch (JsonParseException e) {\n LOGGER.error(\"json反序列化异常\", e);\n throw new RuntimeException(MessageSourceUtil.getMessage(\"error.json_deserialize_error\"), e);\n } catch (JsonMappingException e) {\n LOGGER.error(\"json反序列化异常\", e);\n throw new RuntimeException(MessageSourceUtil.getMessage(\"error.json_deserialize_error\"), e);\n } catch (IOException e) {\n LOGGER.error(\"json反序列化异常\", e);\n throw new RuntimeException(MessageSourceUtil.getMessage(\"error.json_deserialize_error\"), e);\n }\n return list;\n }\n\n public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {\n return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.util;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(68,'MessageSourceUtil.java.ftl','/{commonModule}/src/main/java/{commonPackage}/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.slf4j.Logger\")/>\n<@call this.addImport(\"org.slf4j.LoggerFactory\")/>\n<@call this.addImport(\"org.springframework.context.MessageSource\")/>\n<@call this.addImport(\"org.springframework.context.i18n.LocaleContextHolder\")/>\n<@call this.addImport(\"java.util.Locale\")/>\n<@call this.printClassCom(\"静态国际化MessageSource工具类\")/>\npublic class MessageSourceUtil {\n\n private final static Logger LOGGER = LoggerFactory.getLogger(MessageSourceUtil.class);\n\n private static MessageSource messageSource;\n\n public static MessageSource getMessageSource() {\n if (messageSource != null) {\n return messageSource;\n }\n MessageSource ms = SpringUtil.getBean(MessageSource.class);\n if (ms != null) {\n messageSource = ms;\n return ms;\n }\n return null;\n }\n\n /**\n * 获取国际化后的字符串\n *\n * @param code 对应messages配置的key.\n * @return\n */\n public static String getMessage(String code) {\n return getMessage(code, null, null);\n }\n\n /**\n * 获取国际化后的字符串\n *\n * @param code 对应messages配置的key.\n * @param args 数组参数.\n * @return\n */\n public static String getMessage(String code, Object[] args) {\n return getMessage(code, args, \"\");\n }\n\n /**\n * 获取国际化后的字符串\n *\n * @param code 对应messages配置的key.\n * @param defaultMessage 没有设置key的时候的默认值.\n * @return\n */\n public static String getMessage(String code, String defaultMessage) {\n return getMessage(code, null, defaultMessage);\n }\n\n\n /**\n * 获取国际化后的字符串\n *\n * @param code 对应messages配置的key.\n * @param args 数组参数.\n * @param defaultMessage 没有设置key的时候的默认值.\n * @return\n */\n public static String getMessage(String code, Object[] args, String defaultMessage) {\n Locale locale = LocaleContextHolder.getLocale();\n MessageSource messageSource = getMessageSource();\n if (messageSource != null) {\n return messageSource.getMessage(code, args, defaultMessage, locale);\n }\n if (defaultMessage != null) {\n return defaultMessage;\n }\n LOGGER.warn(\"未找到{}对应的消息体\", code);\n return code;\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.util;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(69,'SafeUtil.java.ftl','/{commonModule}/src/main/java/{commonPackage}/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.math.BigDecimal\")/>\n<@call this.printClassCom(\"空指针安全的类型转换工具\")/>\npublic class SafeUtil {\n\n /**\n * 对象转Integer\n *\n * @param obj\n * @return\n */\n public static Integer getInteger(Object obj) {\n if (obj == null) {\n return null;\n }\n try {\n return Integer.valueOf(obj.toString());\n } catch (Exception e) {\n }\n return null;\n }\n\n /**\n * 对象转Long\n *\n * @param obj\n * @return\n */\n public static Long getLong(Object obj) {\n if (obj == null) {\n return null;\n }\n try {\n return Long.valueOf(obj.toString());\n } catch (Exception e) {\n }\n return null;\n }\n\n /**\n * 对象转Short\n *\n * @param obj\n * @return\n */\n public static Short getShort(Object obj) {\n if (obj == null) {\n return null;\n }\n try {\n return Short.valueOf(obj.toString());\n } catch (Exception e) {\n }\n return null;\n }\n\n /**\n * 对象转Double\n *\n * @param obj\n * @return\n */\n public static Double getDouble(Object obj) {\n if (obj == null) {\n return null;\n }\n try {\n return Double.valueOf(obj.toString());\n } catch (Exception e) {\n }\n return null;\n }\n\n /**\n * 对象转BigDecimal\n *\n * @param obj\n * @return\n */\n public static BigDecimal getBigDecimal(Object obj) {\n if (obj == null) {\n return null;\n }\n try {\n return new BigDecimal(obj.toString());\n } catch (Exception e) {\n }\n return null;\n }\n\n /**\n * 对象转Float\n *\n * @param obj\n * @return\n */\n public static Float getFloat(Object obj) {\n if (obj == null) {\n return null;\n }\n try {\n return Float.valueOf(obj.toString());\n } catch (Exception e) {\n }\n return null;\n }\n\n /**\n * 对象转Boolean\n *\n * @param obj\n * @return\n */\n public static Boolean getBoolean(Object obj) {\n if (obj == null) {\n return null;\n }\n try {\n return Boolean.valueOf(obj.toString());\n } catch (Exception e) {\n }\n return null;\n }\n\n /**\n * 转字符串\n *\n * @param obj\n * @return\n */\n public static String getString(Object obj) {\n return obj == null ? null : obj.toString();\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.util;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(70,'SpringUtil.java.ftl','/{commonModule}/src/main/java/{commonPackage}/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.exception.BusinessException\")/>\n<@call this.addImport(\"org.springframework.beans.factory.support.BeanDefinitionBuilder\")/>\n<@call this.addImport(\"org.springframework.beans.factory.support.DefaultListableBeanFactory\")/>\n<@call this.addImport(\"org.springframework.context.ApplicationContext\")/>\n<@call this.addImport(\"org.springframework.context.ApplicationContextAware\")/>\n<@call this.addImport(\"java.lang.annotation.Annotation\")/>\n<@call this.addImport(\"java.util.Map\")/>\n<@call this.printClassCom(\"spring bean 工具类\")/>\npublic class SpringUtil implements ApplicationContextAware {\n\n private static ApplicationContext applicationContext;\n\n /**\n * 得到上下文\n *\n * @return\n */\n public static ApplicationContext getApplicationContext() {\n return applicationContext;\n }\n\n /**\n * 注入context\n *\n * @param context\n */\n @Override\n public void setApplicationContext(ApplicationContext context) {\n applicationContext = context;\n }\n\n /**\n * 根据名称获取\n *\n * @param beanName\n * @return\n */\n public static Object getBean(String beanName) {\n if (applicationContext == null) {\n return null;\n }\n return applicationContext.getBean(beanName);\n }\n\n /**\n * 根据名称和类型\n *\n * @param beanName\n * @param clz\n * @return\n */\n public static <T> T getBean(String beanName, Class<T> clz) {\n if (applicationContext == null) {\n return null;\n }\n return applicationContext.getBean(beanName, clz);\n }\n\n /**\n * 根据类型获取bean\n *\n * @param clz\n * @return\n */\n public static <T> T getBean(Class<T> clz) {\n if (applicationContext == null) {\n return null;\n }\n return applicationContext.getBean(clz);\n }\n\n\n /**\n * 根据类型获取beanName\n *\n * @param clz\n * @return\n */\n public static String[] getBeanNamesForType(Class<?> clz) {\n if (applicationContext == null) {\n return null;\n }\n return applicationContext.getBeanNamesForType(clz);\n }\n\n /**\n * 根据类型获取beanMap\n *\n * @param clz\n * @return\n */\n public static <T> Map<String, T> getBeansOfType(Class<T> clz) {\n if (applicationContext == null) {\n return null;\n }\n return applicationContext.getBeansOfType(clz);\n }\n\n /**\n * 根据bean上的注解获取bean\n *\n * @param clz\n * @return\n */\n public static Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> clz) {\n if (applicationContext == null) {\n return null;\n }\n return applicationContext.getBeansWithAnnotation(clz);\n }\n\n /**\n * 获取beanFactory\n *\n * @return\n */\n public static DefaultListableBeanFactory getBeanFactory() {\n if (applicationContext == null) {\n return null;\n }\n return (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();\n }\n\n /**\n * 销毁bean\n *\n * @param beanName\n * @return\n */\n public static boolean destroy(String beanName) {\n DefaultListableBeanFactory beanFactory = getBeanFactory();\n if (beanFactory == null) {\n throw new BusinessException(\"spring容器未启动\");\n }\n if (!beanFactory.containsBean(beanName)) {\n return false;\n }\n beanFactory.destroySingleton(beanName);\n beanFactory.destroyBean(beanName);\n beanFactory.removeBeanDefinition(beanName);\n return true;\n }\n\n /**\n * 动态注册bean\n *\n * @param beanName\n * @param clz\n * @param <T>\n * @return\n */\n public static <T> T regist(String beanName, Class<T> clz) {\n DefaultListableBeanFactory beanFactory = getBeanFactory();\n if (beanFactory == null) {\n throw new BusinessException(\"spring容器未启动\");\n }\n if (!beanFactory.containsBean(beanName)) {\n BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(clz);\n beanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());\n }\n return getBean(beanName, clz);\n }\n\n /**\n * 动态注册bean\n *\n * @param beanName\n * @param beanDefinitionBuilder\n * @return\n */\n public static Object regist(String beanName, BeanDefinitionBuilder beanDefinitionBuilder) {\n DefaultListableBeanFactory beanFactory = getBeanFactory();\n if (beanFactory == null) {\n throw new BusinessException(\"spring容器未启动\");\n }\n if (!beanFactory.containsBean(beanName)) {\n beanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());\n }\n return getBean(beanName);\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.util;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(71,'UUIDUtil.java.ftl','/{commonModule}/src/main/java/{commonPackage}/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.util.UUID\")/>\n<@call this.printClassCom(\"获取UUID\")/>\npublic class UUIDUtil {\n\n public static String getUUID() {\n String uuid = UUID.randomUUID().toString();\n return uuid.replaceAll(\"-\", \"\");\n }\n\n public static String getUUID16() {\n return getUUID().substring(8, 24);\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.util;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(72,'Check.java.ftl','/{commonModule}/src/main/java/{commonPackage}/validator',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.lang.annotation.Retention\")/>\n<@call this.addImport(\"java.lang.annotation.Target\")/>\n<@call this.addStaticImport(\"java.lang.annotation.ElementType.METHOD\")/>\n<@call this.addStaticImport(\"java.lang.annotation.RetentionPolicy.RUNTIME\")/>\n<@call this.printClassCom(\"常量类中静态校验方法标记\" \"标记了Check注解的方法会用在常量校验中\")/>\n@Target(METHOD)\n@Retention(RUNTIME)\npublic @interface Check {\n\n String message() default \"\";\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.validator;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(73,'Const.java.ftl','/{commonModule}/src/main/java/{commonPackage}/validator',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.apache.commons.collections4.CollectionUtils\")/>\n<@call this.addImport(\"org.apache.commons.lang3.StringUtils\")/>\n<@call this.addImport(\"org.apache.commons.lang3.reflect.MethodUtils\")/>\n<@call this.addImport(\"org.slf4j.Logger\")/>\n<@call this.addImport(\"org.slf4j.LoggerFactory\")/>\n<@call this.addImport(\"javax.validation.Constraint\")/>\n<@call this.addImport(\"javax.validation.ConstraintValidator\")/>\n<@call this.addImport(\"javax.validation.ConstraintValidatorContext\")/>\n<@call this.addImport(\"javax.validation.Payload\")/>\n<@call this.addImport(\"java.lang.annotation.Documented\")/>\n<@call this.addImport(\"java.lang.annotation.Retention\")/>\n<@call this.addImport(\"java.lang.annotation.Target\")/>\n<@call this.addImport(\"java.lang.reflect.InvocationTargetException\")/>\n<@call this.addImport(\"java.lang.reflect.Method\")/>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.addStaticImport(\"java.lang.annotation.ElementType.FIELD\")/>\n<@call this.addStaticImport(\"java.lang.annotation.ElementType.METHOD\")/>\n<@call this.addStaticImport(\"java.lang.annotation.RetentionPolicy.RUNTIME\")/>\n<@call this.printClassCom(\"自定义校验注解:常量校验\" \"校验常量值是否合法\")/>\n@Target({FIELD, METHOD})\n@Retention(RUNTIME)\n@Constraint(validatedBy = {Const.Checker.class})\n@Documented\npublic @interface Const {\n\n String DEFAULT_MESSAGE = \"{${this.commonPackage}.validator.Const}\";\n\n Class constClass();\n\n String message() default DEFAULT_MESSAGE;\n\n Class<?>[] groups() default {};\n\n Class<? extends Payload>[] payload() default {};\n\n class Checker implements ConstraintValidator<Const, Object> {\n\n private static final Logger logger = LoggerFactory.getLogger(Checker.class);\n\n private Class constClass;\n private Method checkMethod;\n private String defaultMsg;\n\n @Override\n public void initialize(Const constAnnotation) {\n this.constClass = constAnnotation.constClass();\n List<Method> checkMethods = MethodUtils.getMethodsListWithAnnotation(this.constClass, Check.class);\n if (CollectionUtils.isNotEmpty(checkMethods)) {\n this.checkMethod = checkMethods.get(0);\n }\n if (this.checkMethod != null && DEFAULT_MESSAGE.equals(constAnnotation.message())) {\n Check check = this.checkMethod.getAnnotation(Check.class);\n this.defaultMsg = check.message();\n }\n }\n\n @Override\n public boolean isValid(Object value, ConstraintValidatorContext context) {\n if (value == null) {\n return true;\n }\n if (checkMethod == null) {\n return false;\n }\n boolean success;\n try {\n Object result = checkMethod.invoke(null, value);\n if (result instanceof Boolean) {\n success = (Boolean) result;\n } else {\n throw new RuntimeException(\"校验方法返回值类型必须是boolean\");\n }\n } catch (IllegalAccessException e) {\n logger.error(\"自定义校验异常\", e);\n throw new RuntimeException(\"自定义校验异常\", e);\n } catch (InvocationTargetException e) {\n logger.error(\"自定义校验异常\", e);\n throw new RuntimeException(\"自定义校验异常\", e);\n }\n\n if (!success && StringUtils.isNotBlank(defaultMsg)) {\n context.disableDefaultConstraintViolation();\n context.buildConstraintViolationWithTemplate(defaultMsg)\n .addConstraintViolation();\n }\n return success;\n }\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.validator;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(74,'IgnoreXSS.java.ftl','/{commonModule}/src/main/java/{commonPackage}/xss',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.lang.annotation.*\")/>\n<@call this.printClassCom(\"无视XSS脚本\")/>\n@Inherited\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.FIELD})\npublic @interface IgnoreXSS {\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.xss;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(75,'JacksonXSSDeserializer.java.ftl','/{commonModule}/src/main/java/{commonPackage}/xss',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"com.fasterxml.jackson.core.JsonParser\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.BeanProperty\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.DeserializationContext\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.JsonDeserializer\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.JsonMappingException\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.deser.ContextualDeserializer\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.deser.std.StringDeserializer\")/>\n<@call this.addImport(\"com.fasterxml.jackson.databind.jsontype.TypeDeserializer\")/>\n<@call this.addImport(\"java.io.IOException\")/>\n<@call this.printClassCom(\"jackson防XSS反序列化器\")/>\npublic class JacksonXSSDeserializer extends StdScalarDeserializer<String> implements ContextualDeserializer {\n\n public JacksonXSSDeserializer() {\n super(String.class);\n }\n\n @Override\n public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {\n if (property != null) {\n IgnoreXSS annotation = property.getAnnotation(IgnoreXSS.class);\n if (annotation != null) {\n return StringDeserializer.instance;\n }\n }\n return this;\n }\n\n @Override\n public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {\n String value = StringDeserializer.instance.deserialize(p, ctxt);\n return XSSUtil.clean(value);\n }\n\n @Override\n public String deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {\n String value = StringDeserializer.instance.deserializeWithType(jp, ctxt, typeDeserializer);\n return XSSUtil.clean(value);\n }\n\n @Override\n public boolean isCachable() {\n return StringDeserializer.instance.isCachable();\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.xss;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(76,'WebXSSFilter.java.ftl','/{commonModule}/src/main/java/{commonPackage}/xss',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"javax.servlet.*\")/>\n<@call this.addImport(\"javax.servlet.http.HttpServletRequest\")/>\n<@call this.addImport(\"java.io.IOException\")/>\n<@call this.printClassCom(\"防止通过parameter传入XSS脚本\")/>\npublic class WebXSSFilter implements Filter {\n\n @Override\n public void init(FilterConfig filterConfig) throws ServletException {\n\n }\n\n @Override\n public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {\n // 自定义request包装类,并把它传入过滤器链\n XSSRequestWrapper requestWrapper = new XSSRequestWrapper((HttpServletRequest) request);\n filterChain.doFilter(requestWrapper, servletResponse);\n }\n\n @Override\n public void destroy() {\n\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.xss;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(77,'XSSRequestWrapper.java.ftl','/{commonModule}/src/main/java/{commonPackage}/xss',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"javax.servlet.http.HttpServletRequest\")/>\n<@call this.addImport(\"javax.servlet.http.HttpServletRequestWrapper\")/>\n<@call this.addImport(\"java.util.HashMap\")/>\n<@call this.addImport(\"java.util.Map\")/>\n<@call this.printClassCom(\"包装HttpServletRequest,嵌入过滤XSS逻辑\")/>\npublic class XSSRequestWrapper extends HttpServletRequestWrapper {\n\n private final Map<String, String[]> params = new HashMap<>();\n\n @SuppressWarnings(\"unchecked\")\n public XSSRequestWrapper(HttpServletRequest request) {\n // 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似\n super(request);\n // 将参数表,赋予给当前的Map以便于持有request中的参数\n this.params.putAll(request.getParameterMap());\n }\n\n /**\n * 重写getParameter,代表参数从当前类中的map获取\n *\n * @param name\n * @return\n */\n @Override\n public String getParameter(String name) {\n String[] values = params.get(name);\n if (values == null || values.length == 0) {\n return null;\n }\n String result = values[0];\n // 转码\n result = clean(result);\n return result;\n }\n\n @Override\n public String[] getParameterValues(String name) {\n if (params.get(name) instanceof String[]) {\n int size = (params.get(name)).length;\n String[] vals = new String[size];\n for (int i = 0; i < (params.get(name)).length; i++) {\n // 转码\n String str = clean((params.get(name))[i]);\n vals[i] = str;\n }\n return vals;\n }\n return null;\n }\n\n private String clean(String value) {\n return XSSUtil.clean(value);\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.xss;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(78,'XSSUtil.java.ftl','/{commonModule}/src/main/java/{commonPackage}/xss',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.jsoup.Jsoup\")/>\n<@call this.addImport(\"org.jsoup.nodes.Document\")/>\n<@call this.addImport(\"org.jsoup.safety.Whitelist\")/>\n<@call this.printClassCom(\"过滤XSS工具\")/>\npublic class XSSUtil {\n\n public static String clean(String value) {\n if (value == null) {\n return null;\n }\n // 允许base64格式的图片,字符串不进行美化\n return Jsoup.clean(value, \"\",\n Whitelist.basicWithImages().addProtocols(\"img\", \"src\", \"data\"),\n new Document.OutputSettings().prettyPrint(false));\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.commonPackage}.xss;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(79,'__dir.ftl','/{coreModule}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${coreModule}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(80,'pom.xml.ftl','/{coreModule}',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/usingExcel.ftl\">\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n <parent>\n <artifactId>${this.originProjectName}</artifactId>\n <groupId>${this.groupId}</groupId>\n <version>1.0.0-SNAPSHOT</version>\n </parent>\n <modelVersion>4.0.0</modelVersion>\n\n <artifactId>${this.originProjectName}-core</artifactId>\n <packaging>jar</packaging>\n\n <dependencies>\n <dependency>\n <groupId>${r\'$\'}{project.groupId}</groupId>\n <artifactId>${this.originProjectName}-common</artifactId>\n </dependency>\n <!-- mapstruct提供属性映射功能 -->\n <dependency>\n <groupId>org.mapstruct</groupId>\n <artifactId>mapstruct</artifactId>\n </dependency>\n <#if this.projectFeature.lombokEnabled>\n <!-- 用注解简化pojo类 https://projectlombok.org/ -->\n <dependency>\n <groupId>org.projectlombok</groupId>\n <artifactId>lombok</artifactId>\n <scope>provided</scope>\n </dependency>\n </#if>\n <#if usingExcel>\n <!-- excel导入导出工具 https://github.com/alibaba/easyexcel -->\n <dependency>\n <groupId>com.alibaba</groupId>\n <artifactId>easyexcel</artifactId>\n </dependency>\n </#if>\n </dependencies>\n <build>\n <plugins>\n <plugin>\n <groupId>org.apache.maven.plugins</groupId>\n <artifactId>maven-compiler-plugin</artifactId>\n <configuration>\n <source>${r\'$\'}{java.version}</source>\n <target>${r\'$\'}{java.version}</target>\n <annotationProcessorPaths>\n <!-- 提供编译期生成mapper实现类 -->\n <path>\n <groupId>org.mapstruct</groupId>\n <artifactId>mapstruct-processor</artifactId>\n <version>${r\'$\'}{org.mapstruct.version}</version>\n </path>\n <#if this.projectFeature.lombokEnabled>\n <!-- 编译期生成pojo的getter-setter -->\n <path>\n <groupId>org.projectlombok</groupId>\n <artifactId>lombok</artifactId>\n <version>${r\'$\'}{lombok.version}</version>\n </path>\n </#if>\n </annotationProcessorPaths>\n </configuration>\n </plugin>\n </plugins>\n </build>\n\n</project>\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(81,'__dir.ftl','/{coreModule}/src/main/java/{packageName}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${packageNamePath}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(82,'__{ProjectName}Configuration.java.ftl','/{coreModule}/src/main/java/{packageName}/config',1,1,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.projectNameUpper}Configuration.java\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(83,'{ProjectName}Configuration.java.ftl','/{coreModule}/src/main/java/{packageName}/config',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.util.SpringUtil\")/>\n<@call this.addImport(\"org.springframework.boot.autoconfigure.condition.ConditionalOnClass\")/>\n<@call this.addImport(\"org.springframework.context.MessageSource\")/>\n<@call this.addImport(\"org.springframework.context.annotation.Bean\")/>\n<@call this.addImport(\"org.springframework.context.annotation.Configuration\")/>\n<@call this.addImport(\"org.springframework.context.annotation.PropertySource\")/>\n<@call this.addImport(\"org.springframework.context.annotation.PropertySources\")/>\n<@call this.addImport(\"org.springframework.validation.beanvalidation.LocalValidatorFactoryBean\")/>\n<@call this.addImport(\"javax.validation.Validator\")/>\n<@call this.printClassCom(\"配置类\")/>\n@Configuration\n@PropertySources(value = @PropertySource(\"classpath:/config/${this.projectNameSplit}-default.properties\"))\npublic class ${this.projectNameUpper}Configuration {\n\n\n /**\n * 在这配置bean以后会把applicationContext注入到该类\n *\n * @return\n */\n @Bean\n public SpringUtil springUtil() {\n return new SpringUtil();\n }\n\n /**\n * 使用自己配置的参数校验器,支持国际化\n * 如果不自定义的话,会由ValidationAutoConfiguration自动注册,不支持国际化\n *\n * @param messageSource 由MessageSourceAutoConfiguration自动注册\n * @return\n */\n @Bean\n @ConditionalOnClass(name = \"javax.el.ELContext\")\n public Validator validator(MessageSource messageSource) {\n LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();\n factory.setValidationMessageSource(messageSource);\n return factory;\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.config;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(84,'__{EnumName}.java.ftl','/{coreModule}/src/main/java/{packageName}/constant',1,3,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.constNameUpper}.java\n','2021-01-08 17:12:49','admin','2021-01-08 17:12:49','admin',1,0),(85,'{EnumName}.java.ftl','/{coreModule}/src/main/java/{packageName}/constant',1,3,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.validator.Check\")/>\n<@call this.addImport(\"java.util.HashMap\")/>\n<@call this.addImport(\"java.util.Map\")/>\n<@call this.printClassCom(\"枚举【${this.remark}】\")/>\npublic enum ${this.constNameUpper} {\n\n<#assign allValuesStr=\"\">\n<#list this.detailList as detail>\n <#if this.constType == MetaConstType.INTEGER>\n <#assign valueStr>${detail.detailValue}</#assign>\n <#elseIf this.constType == MetaConstType.STRING>\n <#assign valueStr>\"${detail.detailValue}\"</#assign>\n </#if>\n <#if detail?hasNext>\n <#assign allValuesStr+=detail.detailValue+\",\">\n <#else>\n <#assign allValuesStr+=detail.detailValue>\n </#if>\n /**\n * ${detail.detailRemark}\n */\n ${detail.detailName}(${valueStr}, \"${detail.detailRemark}\"),\n</#list>\n ;\n\n\n /**\n * 枚举值罗列,给swagger接口文档展示用\n */\n public static final String VALUES_STR = \"${allValuesStr}\";\n\n private static final Map<${this.constTypeStr}, ${this.constNameUpper}> LOOKUP = new HashMap<>();\n\n static {\n for (${this.constNameUpper} e : ${this.constNameUpper}.values()) {\n LOOKUP.put(e.value, e);\n }\n }\n\n private final ${this.constTypeStr} value;\n private final String desc;\n\n\n ${this.constNameUpper}(${this.constTypeStr} value, String desc) {\n this.value = value;\n this.desc = desc;\n }\n\n public static ${this.constNameUpper} find(${this.constTypeStr} value) {\n return LOOKUP.get(value);\n }\n\n public static ${this.constNameUpper} findByDesc(String desc) {\n for (${this.constNameUpper} e : ${this.constNameUpper}.values()) {\n if (e.getDesc().equals(desc)) {\n return e;\n }\n }\n return null;\n }\n\n\n /**\n * desc映射value\n *\n * @param desc\n * @return\n */\n public static ${this.constTypeStr} descToValue(String desc) {\n ${this.constNameUpper} theEnum = findByDesc(desc);\n if (theEnum != null) {\n return theEnum.getValue();\n }\n return null;\n }\n\n /**\n * value映射desc\n *\n * @param value\n * @return\n */\n public static String valueToDesc(${this.constTypeStr} value) {\n ${this.constNameUpper} theEnum = find(value);\n if (theEnum != null) {\n return theEnum.getDesc();\n }\n return null;\n }\n\n /**\n * 校验有效性\n */\n @Check\n public static final boolean validate(${this.constTypeStr} value) {\n ${this.constNameUpper} theEnum = find(value);\n return theEnum != null;\n }\n\n public ${this.constTypeStr} getValue() {\n return value;\n }\n\n public String getDesc() {\n return desc;\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.constant;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(86,'__dir.ftl','/{coreModule}/src/main/java/{packageName}/dao/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(87,'__{ChartName}DAO.java.ftl','/{coreModule}/src/main/java/{packageName}/dao/{module}',1,4,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}DAO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(88,'__{ClassName}DAO.java.ftl','/{coreModule}/src/main/java/{packageName}/dao/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}DAO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(89,'{ChartName}DAO.java.ftl','/{coreModule}/src/main/java/{packageName}/dao/{module}',1,4,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForChart.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.apache.ibatis.annotations.Mapper\")/>\n<@call this.addImport(\"org.springframework.stereotype.Repository\")/>\n<@call this.addImport(\"${qoPackageName}.${this.chartName}QO\")/>\n<@call this.addImport(\"${voPackageName}.${this.chartName}VO\")/>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.printClassCom(\"【${this.title}】数据库操作\")/>\n@Repository\n@Mapper\npublic interface ${this.chartName}DAO {\n\n<#if isChartType(ChartType.DETAIL_LIST) || isChartType(ChartType.AGG_TABLE)>\n /**\n * 根据条件查询【${this.title}】记录数\n *\n * @param qo\n * @return\n */\n int selectCount(${this.chartName}QO qo);\n\n</#if>\n /**\n * 根据条件查询【${this.title}】列表数据\n *\n * @param qo\n * @return\n */\n List<${this.chartName}VO> selectList(${this.chartName}QO qo);\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${daoPackageName};\n\n<@call this.printImport()/>\n\n${code}\n\n\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(90,'{ClassName}DAO.java.ftl','/{coreModule}/src/main/java/{packageName}/dao/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/mtmForOpp.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForOppList.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForOppShow.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${poPackageName}.${this.className}PO\")/>\n<@call this.addImport(\"${this.commonPackage}.dao.DAO\")/>\n<@call this.addImport(\"org.apache.ibatis.annotations.Mapper\")/>\n<@call this.addImport(\"org.springframework.stereotype.Repository\")/>\n<@call this.printClassCom(\"【${this.title}】数据库操作\")/>\n@Repository\n@Mapper\npublic interface ${this.className}DAO extends DAO<${this.className}PO> {\n\n<#if !this.pageSign>\n <@call this.addImport(\"${qoPackageName}.${this.className}QO\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ListVO\")/>\n <@call this.addImport(\"java.util.List\")/>\n /**\n * 根据条件查询【${this.title}】列表\n * @param ${this.classNameLower}QO\n * @return\n */\n List<${this.className}ListVO> findListByQuery(${this.className}QO ${this.classNameLower}QO);\n\n</#if>\n<#if this.titleField??>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.OptionVO\")/>\n <@call this.addImport(\"${this.commonPackage}.pojo.qo.OptionQO\")/>\n List<OptionVO<${this.type}, ${this.titleField.jfieldType}>> findOptions(OptionQO<${this.type}, ${this.titleField.jfieldType}> qo);\n\n</#if>\n<#list this.fkFields as id,field>\n int getCountBy${field.jfieldName?capFirst}(${field.jfieldType} ${field.jfieldName});\n\n</#list>\n<#list this.holds! as otherEntity,mtm>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"org.apache.ibatis.annotations.Param\")/>\n <#assign otherCName=otherEntity.className>\n <#assign otherType=otherEntity.pkField.jfieldType>\n <#assign theFkId=mtm.getFkAlias(this.entityId,false)>\n <#assign otherFkId=mtm.getFkAlias(otherEntity.entityId,false)>\n int getCountBy${otherCName}(${otherType} ${otherFkId});\n\n int add${otherCName}(@Param(\"${theFkId}\")${this.type} ${theFkId},@Param(\"${otherFkId}\")${otherType} ${otherFkId});\n\n int remove${otherCName}(@Param(\"${theFkId}\")${this.type} ${theFkId},@Param(\"${otherFkId}\")${otherType}[] ${otherFkId});\n\n int removeAll${otherCName}(${this.type} ${theFkId});\n\n</#list>\n<#list mtmEntitiesForOpp as otherEntity>\n <@call this.addImport(\"java.util.List\")/>\n <#assign mtm=mtmsForOpp[otherEntity?index]/>\n <#assign otherCName=otherEntity.className/>\n <#assign otherType=otherEntity.pkField.jfieldType>\n <#assign otherFkId=mtm.getFkAlias(otherEntity.entityId,false)>\n List<${this.className}PO> findBy${otherCName}(${otherType} ${otherFkId});\n\n</#list>\n\n<#list this.metaEntity.checkUniqueIndexes as index>\n <@call this.addImport(\"org.apache.ibatis.annotations.Param\")/>\n <#assign suffix=(index?index == 0)?string(\'\', \'\' + index?index)>\n <#assign params=\'\'>\n <#list index.fields as field>\n <#assign params+=\'@Param(\"\'+field.jfieldName+\'\") \'+field.jfieldType+\' \'+field.jfieldName+\', \'>\n </#list>\n boolean notUnique${suffix}(${params}@Param(\"${this.id}\") ${this.type} ${this.id});\n\n</#list>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${daoPackageName};\n\n<@call this.printImport()/>\n\n${code}\n\n\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(91,'LocalDateConverter.java.ftl','/{coreModule}/src/main/java/{packageName}/excel/converter',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/usingExcel.ftl\">\n<#if !usingExcel>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"com.alibaba.excel.converters.Converter\")/>\n<@call this.addImport(\"com.alibaba.excel.enums.CellDataTypeEnum\")/>\n<@call this.addImport(\"com.alibaba.excel.metadata.CellData\")/>\n<@call this.addImport(\"com.alibaba.excel.metadata.GlobalConfiguration\")/>\n<@call this.addImport(\"com.alibaba.excel.metadata.property.ExcelContentProperty\")/>\n<@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n<@call this.addImport(\"java.time.LocalDate\")/>\n<@call this.printClassCom(\"LocalDate格式的日期转换器\")/>\npublic class LocalDateConverter implements Converter<LocalDate> {\n\n @Override\n public Class supportJavaTypeKey() {\n return LocalDate.class;\n }\n\n @Override\n public CellDataTypeEnum supportExcelTypeKey() {\n return CellDataTypeEnum.STRING;\n }\n\n @Override\n public LocalDate convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {\n return DateUtil.parseLocalDate(cellData.getStringValue());\n }\n\n @Override\n public CellData convertToExcelData(LocalDate value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {\n return new CellData(DateUtil.getLocalDateStr(value));\n }\n\n}\n\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.excel.converter;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(92,'LocalDateTimeConverter.java.ftl','/{coreModule}/src/main/java/{packageName}/excel/converter',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/usingExcel.ftl\">\n<#if !usingExcel>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"com.alibaba.excel.converters.Converter\")/>\n<@call this.addImport(\"com.alibaba.excel.enums.CellDataTypeEnum\")/>\n<@call this.addImport(\"com.alibaba.excel.metadata.CellData\")/>\n<@call this.addImport(\"com.alibaba.excel.metadata.GlobalConfiguration\")/>\n<@call this.addImport(\"com.alibaba.excel.metadata.property.ExcelContentProperty\")/>\n<@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n<@call this.addImport(\"java.time.LocalDateTime\")/>\n<@call this.printClassCom(\"LocalDateTime格式的日期转换器\")/>\npublic class LocalDateTimeConverter implements Converter<LocalDateTime> {\n\n @Override\n public Class supportJavaTypeKey() {\n return LocalDateTime.class;\n }\n\n @Override\n public CellDataTypeEnum supportExcelTypeKey() {\n return CellDataTypeEnum.STRING;\n }\n\n @Override\n public LocalDateTime convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {\n return DateUtil.parseLocalDateTime(cellData.getStringValue());\n }\n\n @Override\n public CellData convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {\n return new CellData(DateUtil.getLocalDateTimeStr(value));\n }\n\n}\n\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.excel.converter;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(93,'ConstConstraintHandler.java.ftl','/{coreModule}/src/main/java/{packageName}/excel/handler',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/usingExcel.ftl\">\n<#if !usingExcel>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"com.alibaba.excel.write.handler.SheetWriteHandler\")/>\n<@call this.addImport(\"com.alibaba.excel.write.metadata.holder.WriteSheetHolder\")/>\n<@call this.addImport(\"com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder\")/>\n<@call this.addImport(\"org.apache.poi.ss.usermodel.DataValidation\")/>\n<@call this.addImport(\"org.apache.poi.ss.usermodel.DataValidationConstraint\")/>\n<@call this.addImport(\"org.apache.poi.ss.usermodel.DataValidationHelper\")/>\n<@call this.addImport(\"org.apache.poi.ss.util.CellRangeAddressList\")/>\n<@call this.printClassCom(\"给excel单元格设置下拉框\")/>\npublic class ConstConstraintHandler implements SheetWriteHandler {\n\n private final String[] constraint;\n private final int firstRow;\n private final int lastRow;\n private final int firstCol;\n private final int lastCol;\n\n public ConstConstraintHandler(String[] constraint,\n int firstRow, int lastRow,\n int firstCol, int lastCol) {\n this.constraint = constraint;\n this.firstRow = firstRow;\n this.lastRow = lastRow;\n this.firstCol = firstCol;\n this.lastCol = lastCol;\n }\n\n @Override\n public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {\n\n }\n\n @Override\n public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {\n CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);\n DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper();\n DataValidationConstraint validationConstraint = helper.createExplicitListConstraint(constraint);\n DataValidation dataValidation = helper.createValidation(validationConstraint, cellRangeAddressList);\n writeSheetHolder.getSheet().addValidationData(dataValidation);\n }\n\n}\n\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.excel.handler;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(94,'TemplateCellStyleStrategy.java.ftl','/{coreModule}/src/main/java/{packageName}/excel/handler',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/usingExcel.ftl\">\n<#if !usingExcel>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"com.alibaba.excel.metadata.Head\")/>\n<@call this.addImport(\"com.alibaba.excel.util.StyleUtil\")/>\n<@call this.addImport(\"com.alibaba.excel.write.metadata.style.WriteCellStyle\")/>\n<@call this.addImport(\"com.alibaba.excel.write.metadata.style.WriteFont\")/>\n<@call this.addImport(\"com.alibaba.excel.write.style.AbstractCellStyleStrategy\")/>\n<@call this.addImport(\"org.apache.poi.ss.usermodel.*\")/>\n<@call this.printClassCom(\"excel模板单元格样式策略\")/>\npublic class TemplateCellStyleStrategy extends AbstractCellStyleStrategy {\n\n private final WriteCellStyle headWriteCellStyle;\n private final WriteCellStyle contentWriteCellStyle;\n\n private CellStyle headCellStyle;\n private CellStyle contentCellStyle;\n\n public TemplateCellStyleStrategy() {\n // 表头的样式\n headWriteCellStyle = new WriteCellStyle();\n // 表头背景色\n headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());\n WriteFont headWriteFont = new WriteFont();\n headWriteFont.setBold(true);\n headWriteCellStyle.setWriteFont(headWriteFont);\n // 内容的样式\n contentWriteCellStyle = new WriteCellStyle();\n contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);\n // 内容背景色\n contentWriteCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());\n }\n\n @Override\n protected void initCellStyle(Workbook workbook) {\n if (headWriteCellStyle != null) {\n headCellStyle = StyleUtil.buildHeadCellStyle(workbook, headWriteCellStyle);\n }\n if (contentWriteCellStyle != null) {\n contentCellStyle = StyleUtil.buildContentCellStyle(workbook, contentWriteCellStyle);\n }\n }\n\n @Override\n protected void setHeadCellStyle(Cell cell, Head head, Integer relativeRowIndex) {\n if (headCellStyle == null) {\n return;\n }\n cell.setCellStyle(headCellStyle);\n }\n\n @Override\n protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) {\n if (contentCellStyle == null) {\n return;\n }\n cell.setCellStyle(contentCellStyle);\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.excel.handler;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(95,'TitleDescriptionWriteHandler.java.ftl','/{coreModule}/src/main/java/{packageName}/excel/handler',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/usingExcel.ftl\">\n<#if !usingExcel>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"com.alibaba.excel.util.StyleUtil\")/>\n<@call this.addImport(\"com.alibaba.excel.write.handler.SheetWriteHandler\")/>\n<@call this.addImport(\"com.alibaba.excel.write.metadata.holder.WriteSheetHolder\")/>\n<@call this.addImport(\"com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder\")/>\n<@call this.addImport(\"org.apache.poi.ss.usermodel.*\")/>\n<@call this.addImport(\"org.apache.poi.ss.util.CellRangeAddress\")/>\n<@call this.printClassCom(\"给excel单元格设置下拉框\")/>\npublic class TitleDescriptionWriteHandler implements SheetWriteHandler {\n\n private final String title;\n private final String[] description;\n private final Class dtoClass;\n\n public TitleDescriptionWriteHandler(String title, String[] description, Class dtoClass) {\n this.title = title;\n this.description = description;\n this.dtoClass = dtoClass;\n }\n\n private String parseDescriptionCellValue() {\n StringBuilder sb = new StringBuilder(\"说明:\\n\");\n for (int i = 0; i < description.length; i++) {\n sb.append(i + 1).append(\"、\").append(description[i]);\n if (i < description.length - 1) {\n sb.append(\"\\n\");\n }\n }\n return sb.toString();\n }\n\n\n @Override\n public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {\n\n }\n\n @Override\n public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {\n int lastCol = dtoClass.getDeclaredFields().length - 1;\n Sheet sheet = writeSheetHolder.getSheet();\n Row row1 = sheet.createRow(0);\n Row row2 = sheet.createRow(1);\n row2.setHeightInPoints(80);\n Workbook workbook = writeWorkbookHolder.getWorkbook();\n CellStyle cellStyle1 = StyleUtil.buildDefaultCellStyle(workbook);\n Font font = workbook.createFont();\n font.setFontName(\"宋体\");\n font.setFontHeightInPoints((short) 14);\n font.setBold(true);\n cellStyle1.setFont(font);\n CellStyle cellStyle2 = StyleUtil.buildDefaultCellStyle(workbook);\n cellStyle2.setAlignment(HorizontalAlignment.LEFT);\n for (int i = 0; i <= lastCol; i++) {\n Cell cell1 = row1.createCell(i);\n Cell cell2 = row2.createCell(i);\n cell1.setCellStyle(cellStyle1);\n cell2.setCellStyle(cellStyle2);\n if (i == 0) {\n cell1.setCellValue(this.title);\n cell2.setCellValue(this.parseDescriptionCellValue());\n }\n }\n // 合并单元格\n if (lastCol > 0) {\n CellRangeAddress region = new CellRangeAddress(0, 0, 0, lastCol);\n sheet.addMergedRegion(region);\n CellRangeAddress region2 = new CellRangeAddress(1, 1, 0, lastCol);\n sheet.addMergedRegion(region2);\n }\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.excel.handler;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(96,'SyncReadExcelListener.java.ftl','/{coreModule}/src/main/java/{packageName}/excel/listener',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/usingExcel.ftl\">\n<#if !usingExcel>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"com.alibaba.excel.context.AnalysisContext\")/>\n<@call this.addImport(\"com.alibaba.excel.event.AnalysisEventListener\")/>\n<@call this.addImport(\"com.alibaba.excel.read.metadata.holder.ReadRowHolder\")/>\n<@call this.addImport(\"${this.packageName}.pojo.dto.AbstractExcelDTO\")/>\n<@call this.addImport(\"java.util.ArrayList\")/>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.printClassCom(\"同步读取excel的监听器\")/>\npublic class SyncReadExcelListener<T extends AbstractExcelDTO> extends AnalysisEventListener<T> {\n\n private final List<T> list = new ArrayList<>();\n\n @Override\n public void invoke(T data, AnalysisContext context) {\n ReadRowHolder rowHolder = context.readRowHolder();\n data.setRowIndex(rowHolder.getRowIndex());\n list.add(data);\n }\n\n @Override\n public void doAfterAllAnalysed(AnalysisContext context) {\n\n }\n\n public List<T> getList() {\n return list;\n }\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.excel.listener;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(97,'AbstractExcelDTO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/dto',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/usingExcel.ftl\">\n<#if !usingExcel>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.pojo.dto.AbstractDTO\")/>\n<@call this.printClassCom(\"抽象excel数据传输对象\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n@Data\n</#if>\npublic abstract class AbstractExcelDTO extends AbstractDTO {\n\n /**\n * 行号\n */\n <@call this.addImport(\"com.alibaba.excel.annotation.ExcelIgnore\")/>\n @ExcelIgnore\n private Integer rowIndex;\n\n<#if !this.projectFeature.lombokEnabled>\n public Integer getRowIndex() {\n return rowIndex;\n }\n\n public void setRowIndex(Integer rowIndex) {\n this.rowIndex = rowIndex;\n }\n</#if>\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.pojo.dto;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(98,'UserLoginDTO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/dto',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"用户登录请求体\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n@Data\n</#if>\npublic class UserLoginDTO {\n\n private String username;\n\n private String password;\n\n<#if !this.projectFeature.lombokEnabled>\n public String getUsername() {\n return username;\n }\n\n public void setUsername(String username) {\n this.username = username;\n }\n\n public String getPassword() {\n return password;\n }\n\n public void setPassword(String password) {\n this.password = password;\n }\n</#if>\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.pojo.dto;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(99,'__dir.ftl','/{coreModule}/src/main/java/{packageName}/pojo/dto/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(100,'__{ClassName}AddDTO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/dto/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}AddDTO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(101,'__{ClassName}ExcelDTO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/dto/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}ExcelDTO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(102,'__{ClassName}UpdateDTO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/dto/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}UpdateDTO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(103,'{ClassName}AddDTO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/dto/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/guessDateFormat.ftl\">\n<#include \"/abstracted/forEntityInsert.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.pojo.dto.AbstractDTO\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiModel\")/>\n<@call this.addStaticImport(\"${examplePackageName}.${this.className}Example.*\")/>\n<@call this.printClassCom(\"新增【${this.title}】的参数\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\n@ApiModel(description = \"新增【${this.title}】的参数\")\npublic class ${this.className}AddDTO extends AbstractDTO {\n\n<#list this.insertFields as id,field>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <@call this.addImport(\"io.swagger.annotations.ApiModelProperty\")/>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(field.jfieldName,true)>\n @ApiModelProperty(notes = N_${jfieldNameSnakeCase}, example = E_${jfieldNameSnakeCase}<#if field.notNull>, required = true</#if><#if field.dicType??>, allowableValues = ${field.dicType}.VALUES_STR</#if>)\n <#if field.notNull>\n <@call this.addImport(\"javax.validation.constraints.NotNull\")/>\n @NotNull\n </#if>\n <#if field.dicType??>\n <@call this.addImport(\"${this.commonPackage}.validator.Const\")/>\n <@call this.addConstImport(field.dicType)/>\n @Const(constClass = ${field.dicType}.class)\n <#elseIf field.jfieldType == JFieldType.STRING.getJavaType()>\n <#if field.fieldLength gt 0 >\n <@call this.addImport(\"org.hibernate.validator.constraints.Length\")/>\n @Length(max = ${field.fieldLength})\n </#if>\n <#elseIf field.jfieldType == JFieldType.DATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern=${guessDateFormat(field)},timezone=\"GMT+8\")\n </#if>\n private ${field.jfieldType} ${field.jfieldName};\n\n</#list>\n<#list withinEntityList as otherEntity>\n <#assign otherPk=otherEntity.pkField>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call this.addImport(\"java.util.List\")/>\n private List<${otherPk.jfieldType}> ${othercName}List;\n\n</#list>\n\n<#if !this.projectFeature.lombokEnabled>\n <#list this.insertFields as id,field>\n <@call JavaTemplateFunction.printGetterSetter(field)/>\n </#list>\n <#list withinEntityList as otherEntity>\n <#assign otherPk=otherEntity.pkField>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call JavaTemplateFunction.printGetterSetterList(othercName,otherPk.jfieldType)/>\n </#list>\n</#if>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${dtoPackageName};\n\n<@call this.printImport()/>\n\n${code}\n\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(104,'{ClassName}ExcelDTO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/dto/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/guessDateFormat.ftl\">\n<#include \"/abstracted/forEntityInsert.ftl\">\n<#if !this.entityFeature.excelImport>\n <@call this.skipCurrent()/>\n</#if>\n<#--解析字段类型-->\n<#function parseJfieldType field>\n<#--枚举字段使用String类型-->\n <#if field.dicType??>\n <#local jfieldType = \"String\">\n <#else>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#local jfieldType = field.jfieldType>\n </#if>\n <#return jfieldType>\n</#function>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.packageName}.pojo.dto.AbstractExcelDTO\")/>\n<@call this.addImport(\"com.alibaba.excel.annotation.ExcelProperty\")/>\n<@call this.addImport(\"com.alibaba.excel.annotation.write.style.ColumnWidth\")/>\n<@call this.addStaticImport(\"${examplePackageName}.${this.className}Example.*\")/>\n<@call this.printClassCom(\"excel导入【${this.title}】的数据传输对象\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\npublic class ${this.className}ExcelDTO extends AbstractExcelDTO {\n\n<#list this.insertFields as id,field>\n <#if field.jfieldType == JFieldType.LOCALDATE.getJavaType()>\n <@call this.addImport(\"${this.packageName}.excel.converter.LocalDateConverter\")/>\n @ExcelProperty(value = \"${field.fieldDesc}<#if field.notNull>*</#if>\", converter = LocalDateConverter.class)\n <#elseIf field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"${this.packageName}.excel.converter.LocalDateTimeConverter\")/>\n @ExcelProperty(value = \"${field.fieldDesc}<#if field.notNull>*</#if>\", converter = LocalDateTimeConverter.class)\n <#else>\n @ExcelProperty(\"${field.fieldDesc}<#if field.notNull>*</#if>\")\n </#if>\n <#if field.jfieldType == JFieldType.DATE.getJavaType()>\n <@call this.addImport(\"com.alibaba.excel.annotation.format.DateTimeFormat\")/>\n @DateTimeFormat(${guessDateFormat(field)})\n </#if>\n <#if field.columnWidth?? && field.columnWidth &gt; 0>\n @ColumnWidth(${field.columnWidth/8})\n <#else>\n @ColumnWidth(15)\n </#if>\n private ${parseJfieldType(field)} ${field.jfieldName};\n\n</#list>\n<#list withinEntityList as otherEntity>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n @ExcelProperty(\"${otherEntity.title}\")\n @ColumnWidth(15)\n private String ${othercName}List;\n\n</#list>\n\n /**\n * 创建模板示例\n *\n * @return\n */\n public static ${this.className}ExcelDTO example() {\n ${this.className}ExcelDTO example = new ${this.className}ExcelDTO();\n<#list this.insertFields as id,field>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(field.jfieldName,true)>\n <#assign arg=\"\">\n <#if field.dicType??>\n <@call this.addConstImport(field.dicType)/>\n <@call this.addImport(\"${this.commonPackage}.util.SafeUtil\")/>\n <#assign arg=\"${field.dicType}.valueToDesc(SafeUtil.get${field.jfieldType}(E_${jfieldNameSnakeCase}))\">\n <#elseIf field.jfieldType == JFieldType.STRING.getJavaType()>\n <#assign arg=\"E_${jfieldNameSnakeCase}\">\n <#elseIf field.jfieldType == JFieldType.DATE.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n <#assign arg=\"DateUtil.parseDate(E_${jfieldNameSnakeCase})\">\n <#elseIf field.jfieldType == JFieldType.LOCALDATE.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n <#assign arg=\"DateUtil.parseLocalDate(E_${jfieldNameSnakeCase})\">\n <#elseIf field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n <#assign arg=\"DateUtil.parseLocalDateTime(E_${jfieldNameSnakeCase})\">\n <#elseIf field.jfieldType == JFieldType.BIGDECIMAL.getJavaType()>\n <@call this.addImport(\"java.math.BigDecimal\")/>\n <@call this.addImport(\"${this.commonPackage}.util.SafeUtil\")/>\n <#assign arg=\"SafeUtil.get${field.jfieldType}(E_${jfieldNameSnakeCase})\">\n <#else>\n <@call this.addImport(\"${this.commonPackage}.util.SafeUtil\")/>\n <#assign arg=\"SafeUtil.get${field.jfieldType}(E_${jfieldNameSnakeCase})\">\n </#if>\n example.set${field.jfieldName?capFirst}(${arg});\n</#list>\n return example;\n }\n\n<#if !this.projectFeature.lombokEnabled>\n <#list this.insertFields as id,field>\n <@call JavaTemplateFunction.printGetterSetter(field.jfieldName,parseJfieldType(field))/>\n </#list>\n <#list withinEntityList as otherEntity>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call JavaTemplateFunction.printGetterSetter(othercName+\"List\",\"String\")/>\n </#list>\n</#if>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${dtoPackageName};\n\n<@call this.printImport()/>\n\n${code}\n\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(105,'{ClassName}UpdateDTO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/dto/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/guessDateFormat.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.pojo.dto.AbstractDTO\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiModel\")/>\n<@call this.addImport(\"javax.validation.constraints.NotNull\")/>\n<@call this.addStaticImport(\"${examplePackageName}.${this.className}Example.*\")/>\n<@call this.printClassCom(\"修改【${this.title}】的参数\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\n@ApiModel(description = \"修改【${this.title}】的参数\")\npublic class ${this.className}UpdateDTO extends AbstractDTO {\n\n <@call this.addImport(\"io.swagger.annotations.ApiModelProperty\")/>\n <#--字段名转下划线大写-->\n <#assign pkNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(this.pk.jfieldName,true)>\n @ApiModelProperty(notes = N_${pkNameSnakeCase}, example = E_${pkNameSnakeCase}, required = true)\n @NotNull\n <#if this.pk.jfieldType == JFieldType.STRING.getJavaType()>\n <#if this.pk.fieldLength gt 0 >\n <@call this.addImport(\"org.hibernate.validator.constraints.Length\")/>\n @Length(max = ${this.pk.fieldLength})\n </#if>\n </#if>\n private ${this.pk.jfieldType} ${this.pk.jfieldName};\n\n<#list this.updateFields as id,field>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <@call this.addImport(\"io.swagger.annotations.ApiModelProperty\")/>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(field.jfieldName,true)>\n @ApiModelProperty(notes = N_${jfieldNameSnakeCase}, example = E_${jfieldNameSnakeCase}<#if field.notNull>, required = true</#if><#if field.dicType??>, allowableValues = ${field.dicType}.VALUES_STR</#if>)\n <#if field.notNull>\n @NotNull\n </#if>\n <#if field.dicType??>\n <@call this.addImport(\"${this.commonPackage}.validator.Const\")/>\n <@call this.addConstImport(field.dicType)/>\n @Const(constClass = ${field.dicType}.class)\n <#elseIf field.jfieldType == JFieldType.STRING.getJavaType()>\n <#if field.fieldLength gt 0 >\n <@call this.addImport(\"org.hibernate.validator.constraints.Length\")/>\n @Length(max = ${field.fieldLength})\n </#if>\n <#elseIf field.jfieldType == JFieldType.DATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern=${guessDateFormat(field)},timezone=\"GMT+8\")\n </#if>\n private ${field.jfieldType} ${field.jfieldName};\n\n</#list>\n<#list this.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.withinEntity>\n <#assign otherPk=otherEntity.pkField>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call this.addImport(\"java.util.List\")/>\n private List<${otherPk.jfieldType}> ${othercName}List;\n\n </#if>\n</#list>\n\n<#if !this.projectFeature.lombokEnabled>\n <@call JavaTemplateFunction.printGetterSetter(this.pk)/>\n <#list this.updateFields as id,field>\n <@call JavaTemplateFunction.printGetterSetter(field)/>\n </#list>\n <#list this.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.withinEntity>\n <#assign otherPk=otherEntity.pkField>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call JavaTemplateFunction.printGetterSetterList(othercName,otherPk.jfieldType)/>\n </#if>\n </#list>\n</#if>\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${dtoPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(106,'__dir.ftl','/{coreModule}/src/main/java/{packageName}/pojo/example/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(107,'__{ClassName}Example.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/example/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}Example.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(108,'{ClassName}Example.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/example/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"【${this.title}】参数示例\")/>\npublic class ${this.className}Example {\n\n<#list this.fields as id,field>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(field.jfieldName,true)>\n public static final String N_${jfieldNameSnakeCase} = \"${field.fetchComment()?replace(\'\\\"\',\'\\\\\"\')?replace(\'\\n\',\'\\\\n\')}\";\n public static final String E_${jfieldNameSnakeCase} = \"${field.fieldExample?replace(\'\\\"\',\'\\\\\"\')?replace(\'\\n\',\'\\\\n\')}\";\n</#list>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${examplePackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(109,'__dir.ftl','/{coreModule}/src/main/java/{packageName}/pojo/mapper/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(110,'__{ChartName}Mapper.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/mapper/{module}',1,4,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}Mapper.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(111,'__{ClassName}Mapper.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/mapper/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}Mapper.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(112,'{ChartName}Mapper.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/mapper/{module}',1,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#include \"/abstracted/chartItem.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<#if !isChartType(ChartType.DETAIL_LIST) && !isChartType(ChartType.AGG_TABLE)>\n <@call this.skipCurrent()/>\n</#if>\n<#if !this.excelExport>\n <@call this.skipCurrent()/>\n</#if>\n<#-- 包裹Mapping注解 -->\n<#macro wrapMappings>\n <#local content><#nested></#local>\n <#if content?hasContent>\n <@call this.addImport(\"org.mapstruct.Mappings\")/>\n <@call this.addImport(\"org.mapstruct.Mapping\")/>\n @Mappings({\n${content}<#rt>\n })\n </#if>\n</#macro>\n<@call this.addImport(\"org.mapstruct.Mapper\")/>\n<@call this.addImport(\"org.mapstruct.factory.Mappers\")/>\n<@call this.printClassCom(\"【${this.title}】映射\")/>\n@Mapper\npublic interface ${this.chartName}Mapper {\n\n ${this.chartName}Mapper INSTANCE = Mappers.getMapper(${this.chartName}Mapper.class);\n\n<#if this.excelExport>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${voPackageName}.${this.chartName}ExcelVO\")/>\n <@call this.addImport(\"${voPackageName}.${this.chartName}VO\")/>\n /**\n * 转excelVO列表\n *\n * @param list\n * @return\n */\n List<${this.chartName}ExcelVO> toExcelVOList(List<${this.chartName}VO> list);\n\n /**\n * 转excelVO\n *\n * @param vo\n * @return\n */\n <@wrapMappings>\n <#if isChartType(ChartType.DETAIL_LIST)>\n <#-- 明细列字段 -->\n <#list this.columnList as column>\n <#assign sourceItem=column.sourceItem>\n <#if !sourceItem.custom && sourceItem.field.dicType??>\n <#assign field=sourceItem.field>\n <#if column.alias?hasContent>\n <#assign name=column.alias>\n <#else>\n <#assign name=field.jfieldName>\n </#if>\n @Mapping(target = \"${name}\", expression = \"java(${this.getConstFullClassPath(field.dicType)}.valueToDesc(vo.get${name?capFirst}()))\"),\n </#if>\n </#list>\n <#elseIf isChartType(ChartType.AGG_TABLE)>\n <#-- 维度字段 -->\n <#list filteredDimension as dimension>\n <#assign chartItem = chartItemMapWrapper.get(dimension.sourceItemId)>\n <#if dimension.field.dicType??>\n <#assign field=dimension.field>\n <#if chartItem.alias?hasContent>\n <#assign name=chartItem.alias>\n <#else>\n <#assign name=field.jfieldName>\n </#if>\n @Mapping(target = \"${name}\", expression = \"java(${this.getConstFullClassPath(field.dicType)}.valueToDesc(vo.get${name?capFirst}()))\"),\n </#if>\n </#list>\n </#if>\n </@wrapMappings>\n ${this.chartName}ExcelVO toExcelVO(${this.chartName}VO vo);\n</#if>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${mapperPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(113,'{ClassName}Mapper.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/mapper/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForList.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForOppList.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForOppShow.ftl\">\n<#include \"/abstracted/mtmForOpp.ftl\">\n<#-- 包裹Mapping注解 -->\n<#macro wrapMappings>\n <#local content><#nested></#local>\n <#if content?hasContent>\n <@call this.addImport(\"org.mapstruct.Mappings\")/>\n <@call this.addImport(\"org.mapstruct.Mapping\")/>\n @Mappings({\n${content}<#rt>\n })\n </#if>\n</#macro>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${dtoPackageName}.${this.className}AddDTO\")/>\n<@call this.addImport(\"${dtoPackageName}.${this.className}UpdateDTO\")/>\n<@call this.addImport(\"${poPackageName}.${this.className}PO\")/>\n<@call this.addImport(\"${voPackageName}.${this.className}ShowVO\")/>\n<@call this.addImport(\"org.mapstruct.Mapper\")/>\n<@call this.addImport(\"org.mapstruct.MappingTarget\")/>\n<@call this.addImport(\"org.mapstruct.factory.Mappers\")/>\n<@call this.printClassCom(\"【${this.title}】映射\")/>\n@Mapper\npublic interface ${this.className}Mapper {\n\n ${this.className}Mapper INSTANCE = Mappers.getMapper(${this.className}Mapper.class);\n\n /**\n * addDTO映射po\n *\n * @param ${this.classNameLower}AddDTO\n * @return\n */\n ${this.className}PO fromAddDTO(${this.className}AddDTO ${this.classNameLower}AddDTO);\n\n /**\n * 将updateDTO中的值设置到po\n *\n * @param ${this.classNameLower}PO\n * @param ${this.classNameLower}UpdateDTO\n */\n void setUpdateDTO(@MappingTarget ${this.className}PO ${this.classNameLower}PO, ${this.className}UpdateDTO ${this.classNameLower}UpdateDTO);\n\n /**\n * po映射showVO\n *\n * @param ${this.classNameLower}PO\n * @return\n */\n ${this.className}ShowVO toShowVO(${this.className}PO ${this.classNameLower}PO);\n\n\n<#--为被持有的实体提供级联【列表】查询方法-->\n<#list mtmCascadeEntitiesForOppList as otherEntity>\n <#assign otherCName=otherEntity.className>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${voPackageName}.${otherCName}ListVO\")/>\n List<${otherCName}ListVO.${this.className}VO> to${this.className}VOFor${otherCName}List(List<${this.className}PO> list);\n\n</#list>\n<#--为被持有的实体提供级联【详情】查询方法-->\n<#list mtmCascadeEntitiesForOppShow as otherEntity>\n <#assign otherCName=otherEntity.className>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${voPackageName}.${otherCName}ShowVO\")/>\n List<${otherCName}ShowVO.${this.className}VO> to${this.className}VOFor${otherCName}Show(List<${this.className}PO> list);\n\n</#list>\n<#--多对多被对方持有,提供PO列表转ListVO列表 -->\n<#list mtmEntitiesForOpp as otherEntity>\n <#assign mtm=mtmsForOpp[otherEntity?index]/>\n <#assign otherEntityFeature=mtm.getEntityFeature(otherEntity.entityId)>\n <#--对方支持添加删除的情况才需要该服务 -->\n <#if otherEntityFeature.addRemove>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ListVO\")/>\n List<${this.className}ListVO> toListVOList(List<${this.className}PO> list);\n\n </#if>\n</#list>\n<#if this.entityFeature.excelImport>\n <@call this.addImport(\"${dtoPackageName}.${this.className}ExcelDTO\")/>\n /**\n * excelDTO映射addDTO\n *\n * @param dto\n * @return\n */\n <@wrapMappings>\n <#list this.insertFields as id,field>\n <#if field.dicType??>\n @Mapping(target = \"${field.jfieldName}\", expression = \"java(${this.getConstFullClassPath(field.dicType)}.descToValue(dto.get${field.jfieldName?capFirst}()))\"),\n </#if>\n </#list>\n <#list this.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#assign pkFieldType=otherEntity.pkField.jfieldType>\n <#if entityFeature.withinEntity>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign otherCName=otherEntity.className>\n @Mapping(target = \"${othercName}List\", expression = \"java(${this.commonPackage}.util.ConvertUtil.convert${pkFieldType}List(dto.get${otherCName}List()))\"),\n </#if>\n </#list>\n </@wrapMappings>\n ${this.className}AddDTO fromExcelDTO(${this.className}ExcelDTO dto);\n\n</#if>\n<#if this.entityFeature.excelExport>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ExcelVO\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ListVO\")/>\n /**\n * listVO列表转excelVO列表\n *\n * @param list\n * @return\n */\n List<${this.className}ExcelVO> toExcelVOList(List<${this.className}ListVO> list);\n\n /**\n * listVO转excelVO\n *\n * @param vo\n * @return\n */\n <@wrapMappings>\n <#list this.listFields as id,field>\n <#if field.dicType??>\n @Mapping(target = \"${field.jfieldName}\", expression = \"java(${this.getConstFullClassPath(field.dicType)}.valueToDesc(vo.get${field.jfieldName?capFirst}()))\"),\n </#if>\n </#list>\n <#list this.fkFields as id,field>\n <#list field.cascadeListExts! as cascadeExt>\n <#assign cascadeField=cascadeExt.cascadeField>\n <#if cascadeField.dicType??>\n @Mapping(target = \"${cascadeField.jfieldName}\", expression = \"java(${this.getConstFullClassPath(cascadeField.dicType)}.valueToDesc(vo.get${cascadeField.jfieldName?capFirst}()))\"),\n </#if>\n </#list>\n </#list>\n </@wrapMappings>\n ${this.className}ExcelVO toExcelVO(${this.className}ListVO vo);\n\n <#list mtmCascadeEntitiesForList as otherEntity>\n <#assign mtmCascadeExts = groupMtmCascadeExtsForList[otherEntity?index]>\n <#assign otherCName=otherEntity.className>\n <#--级联扩展列表字段中,如果有标题字段,则使用标题字段展示,否则直接展示主键字段-->\n <#if hasTitleField(otherEntity,mtmCascadeExts)>\n <#assign displayField = otherEntity.titleField>\n <#else>\n <#assign displayField = otherEntity.pkField>\n </#if>\n /**\n * ${otherEntity.title}列表转字符串逗号分隔\n *\n * @param list\n * @return\n */\n default String convert${otherCName}List(List<${this.className}ListVO.${otherCName}VO> list) {\n String result = \"\";\n <@call this.addImport(\"org.apache.commons.collections4.CollectionUtils\")/>\n if (CollectionUtils.isNotEmpty(list)) {\n result = list.stream()\n .map(${this.className}ListVO.${otherCName}VO::get${displayField.jfieldName?capFirst})\n <@call this.addImport(\"java.util.stream.Collectors\")/>\n .collect(Collectors.joining(\",\"));\n }\n return result;\n }\n </#list>\n\n</#if>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${mapperPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(114,'__dir.ftl','/{coreModule}/src/main/java/{packageName}/pojo/po/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(115,'__{ClassName}PO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/po/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}PO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(116,'{ClassName}PO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/po/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.pojo.po.AbstractPO\")/>\n<#--判断是否继承特殊接口-->\n<#assign implementsVersion=false>\n<#assign implementsDeleteSign=false>\n<#assign implementsCreatedBy=false>\n<#assign implementsCreatedTime=false>\n<#assign implementsOperatedBy=false>\n<#assign implementsOperatedTime=false>\n<#assign implementsCreated=false>\n<#assign implementsOperated=false>\n<#assign implementsCreatedOperatedDeleted=false>\n<#assign implementsCreatedOperatedDeletedVersion=false>\n<#assign implementsJsr310CreatedTime=false>\n<#assign implementsJsr310OperatedTime=false>\n<#assign implementsJsr310Created=false>\n<#assign implementsJsr310Operated=false>\n<#assign implementsJsr310CreatedOperatedDeleted=false>\n<#assign implementsJsr310CreatedOperatedDeletedVersion=false>\n<#--判断是否继承单一接口-->\n<#if this.delField??>\n <#assign implementsDeleteSign=true>\n</#if>\n<#if this.createdByField??>\n <#assign implementsCreatedBy=true>\n</#if>\n<#if this.createdTimeField??>\n <#if this.createdTimeField.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <#assign implementsJsr310CreatedTime=true>\n <#else>\n <#assign implementsCreatedTime=true>\n </#if>\n</#if>\n<#if this.operatedByField??>\n <#assign implementsOperatedBy=true>\n</#if>\n<#if this.operatedTimeField??>\n <#if this.operatedTimeField.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <#assign implementsJsr310OperatedTime=true>\n <#else>\n <#assign implementsOperatedTime=true>\n </#if>\n</#if>\n<#if this.versionField??>\n <#assign implementsVersion=true>\n</#if>\n<#--判断是否继承合并接口-->\n<#if implementsCreatedBy && implementsCreatedTime>\n <#assign implementsCreated=true>\n</#if>\n<#if implementsOperatedBy && implementsOperatedTime>\n <#assign implementsOperated=true>\n</#if>\n<#if implementsCreated && implementsOperated && implementsDeleteSign>\n <#assign implementsCreatedOperatedDeleted=true>\n</#if>\n<#if implementsCreated && implementsOperated && implementsDeleteSign && implementsVersion>\n <#assign implementsCreatedOperatedDeletedVersion=true>\n</#if>\n<#--判断是否继承合并接口-jsr310-->\n<#if implementsCreatedBy && implementsJsr310CreatedTime>\n <#assign implementsJsr310Created=true>\n</#if>\n<#if implementsOperatedBy && implementsJsr310OperatedTime>\n <#assign implementsJsr310Operated=true>\n</#if>\n<#if implementsJsr310Created && implementsJsr310Operated && implementsDeleteSign>\n <#assign implementsJsr310CreatedOperatedDeleted=true>\n</#if>\n<#if implementsJsr310Created && implementsJsr310Operated && implementsDeleteSign && implementsVersion>\n <#assign implementsJsr310CreatedOperatedDeletedVersion=true>\n</#if>\n<#--构建继承串-->\n<#assign implementsStr=\"\">\n<#if implementsCreatedOperatedDeletedVersion>\n <#assign implementsStr+=\" CreatedOperatedDeletedVersion,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.CreatedOperatedDeletedVersion\")/>\n<#elseIf implementsJsr310CreatedOperatedDeletedVersion>\n <#assign implementsStr+=\" Jsr310CreatedOperatedDeletedVersion,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.Jsr310CreatedOperatedDeletedVersion\")/>\n<#elseIf implementsCreatedOperatedDeleted>\n <#assign implementsStr+=\" CreatedOperatedDeleted,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.CreatedOperatedDeleted\")/>\n<#elseIf implementsJsr310CreatedOperatedDeleted>\n <#assign implementsStr+=\" Jsr310CreatedOperatedDeleted,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.Jsr310CreatedOperatedDeleted\")/>\n<#else>\n <#if implementsCreated>\n <#assign implementsStr+=\" Created,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.Created\")/>\n <#elseIf implementsJsr310Created>\n <#assign implementsStr+=\" Jsr310Created,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.Jsr310Created\")/>\n <#elseIf implementsCreatedBy>\n <#assign implementsStr+=\" CreatedBy,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.CreatedBy\")/>\n <#elseIf implementsCreatedTime>\n <#assign implementsStr+=\" CreatedTime,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.CreatedTime\")/>\n <#elseIf implementsJsr310CreatedTime>\n <#assign implementsStr+=\" Jsr310CreatedTime,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.Jsr310CreatedTime\")/>\n </#if>\n <#if implementsOperated>\n <#assign implementsStr+=\" Operated,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.Operated\")/>\n <#elseIf implementsJsr310Operated>\n <#assign implementsStr+=\" Jsr310Operated,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.Jsr310Operated\")/>\n <#elseIf implementsOperatedBy>\n <#assign implementsStr+=\" OperatedBy,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.OperatedBy\")/>\n <#elseIf implementsOperatedTime>\n <#assign implementsStr+=\" OperatedTime,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.OperatedTime\")/>\n <#elseIf implementsJsr310OperatedTime>\n <#assign implementsStr+=\" Jsr310OperatedTime,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.Jsr310OperatedTime\")/>\n </#if>\n <#if implementsDeleteSign>\n <#assign implementsStr+=\" Deleted,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.Deleted\")/>\n </#if>\n <#if implementsVersion>\n <#assign implementsStr+=\" Version,\">\n <@call this.addImport(\"${this.commonPackage}.pojo.po.Version\")/>\n </#if>\n</#if>\n<#if implementsStr != \"\">\n <#assign implementsStr=\" implements\"+implementsStr?removeEnding(\",\")>\n</#if>\n<@call this.printClassCom(\"${this.title}\" \"${this.desc}\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\npublic class ${this.className}PO extends AbstractPO${implementsStr} {\n\n<#list this.fields as id,field>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n /**\n${JavaTemplateFunction.convertCommentDisplayWithIndentStar(field.fetchComment())}\n <#if field.dicType??>\n *\n * @see ${this.getConstFullClassPath(field.dicType)}\n </#if>\n */\n private ${field.jfieldType} ${field.jfieldName};\n\n</#list>\n <#list this.holds! as otherEntity,mtm>\n <@call this.addImport(\"java.util.List\")/>\n private List<${otherEntity.className}PO> ${lowerFirstWord(otherEntity.className)}POList;\n\n </#list>\n<#if !this.projectFeature.lombokEnabled>\n <#list this.fields as id,field>\n <@call JavaTemplateFunction.printGetterSetterForPO(field)/>\n </#list>\n <#list this.holds! as otherEntity,mtm>\n <@call JavaTemplateFunction.printGetterSetterList(\"${otherEntity.className}PO\",\"${otherEntity.className}PO\")/>\n </#list>\n</#if>\n<#if implementsDeleteSign && this.delField.jfieldName != \"deleted\">\n @Override\n public Boolean getDeleted() {\n return this.${this.delField.jfieldName};\n }\n\n @Override\n public void setDeleted(Boolean deleted) {\n this.${this.delField.jfieldName} = deleted;\n }\n\n</#if>\n<#if implementsCreatedBy && this.createdByField.jfieldName != \"createdBy\">\n @Override\n public String getCreatedBy() {\n return this.${this.createdByField.jfieldName};\n }\n\n @Override\n public void setCreatedBy(String createdBy) {\n this.${this.createdByField.jfieldName} = createdBy;\n }\n\n</#if>\n<#if implementsCreatedTime && this.createdTimeField.jfieldName != \"createdTime\">\n @Override\n public Date getCreatedTime() {\n return this.${this.createdTimeField.jfieldName};\n }\n\n @Override\n public void setCreatedTime(Date createdTime) {\n this.${this.createdTimeField.jfieldName} = createdTime;\n }\n\n</#if>\n<#if implementsJsr310CreatedTime && this.createdTimeField.jfieldName != \"createdTime\">\n @Override\n public LocalDateTime getCreatedTime() {\n return this.${this.createdTimeField.jfieldName};\n }\n\n @Override\n public void setCreatedTime(LocalDateTime createdTime) {\n this.${this.createdTimeField.jfieldName} = createdTime;\n }\n\n</#if>\n<#if implementsOperatedBy && this.operatedByField.jfieldName != \"operatedBy\">\n @Override\n public String getOperatedBy() {\n return this.${this.operatedByField.jfieldName};\n }\n\n @Override\n public void setOperatedBy(String operatedBy) {\n this.${this.operatedByField.jfieldName} = operatedBy;\n }\n\n</#if>\n<#if implementsOperatedTime && this.operatedTimeField.jfieldName != \"operatedTime\">\n @Override\n public Date getOperatedTime() {\n return this.${this.operatedTimeField.jfieldName};\n }\n\n @Override\n public void setOperatedTime(Date createdTime) {\n this.${this.operatedTimeField.jfieldName} = createdTime;\n }\n\n</#if>\n<#if implementsJsr310OperatedTime && this.operatedTimeField.jfieldName != \"operatedTime\">\n @Override\n public LocalDateTime getOperatedTime() {\n return this.${this.operatedTimeField.jfieldName};\n }\n\n @Override\n public void setOperatedTime(LocalDateTime createdTime) {\n this.${this.operatedTimeField.jfieldName} = createdTime;\n }\n\n</#if>\n<#if implementsVersion && this.versionField.jfieldName != \"version\">\n @Override\n public Integer getVersion() {\n return this.${this.versionField.jfieldName};\n }\n\n @Override\n public void setVersion(Integer version) {\n this.${this.versionField.jfieldName} = version;\n }\n\n</#if>\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${poPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(117,'__dir.ftl','/{coreModule}/src/main/java/{packageName}/pojo/qo/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(118,'__{ChartName}QO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/qo/{module}',1,4,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}QO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(119,'__{ClassName}QO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/qo/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}QO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(120,'{ChartName}QO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/qo/{module}',1,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#include \"/abstracted/chartItem.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"io.swagger.annotations.ApiParam\")/>\n<#if isChartType(ChartType.DETAIL_LIST) || isChartType(ChartType.AGG_TABLE)>\n <@call this.addImport(\"${this.commonPackage}.pojo.qo.PageQO\")/>\n<#else>\n <@call this.addImport(\"${this.commonPackage}.pojo.qo.AbstractQO\")/>\n</#if>\n<@call this.printClassCom(\"查询【${this.title}】的参数\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\npublic class ${this.chartName}QO extends <#if isChartType(ChartType.DETAIL_LIST) || isChartType(ChartType.AGG_TABLE)>PageQO<#else>AbstractQO</#if> {\n\n<#list paramedWhere as where>\n <#assign field=where.field>\n <#if FilterOperator.CONTAIN.getValue() == where.filterOperator\n || FilterOperator.NOT_CONTAIN.getValue() == where.filterOperator>\n <@call this.addImport(\"java.util.List\")/>\n @ApiParam(hidden = true)\n private List<${field.jfieldType}> whereParam${where?counter};\n\n <#elseIf FilterOperator.BETWEEN.getValue() == where.filterOperator\n || FilterOperator.IS_NOW.getValue() == where.filterOperator\n || FilterOperator.BEFORE_TIME.getValue() == where.filterOperator\n || FilterOperator.AFTER_TIME.getValue() == where.filterOperator>\n @ApiParam(hidden = true)\n private ${field.jfieldType} whereParam${where?counter}Start;\n\n @ApiParam(hidden = true)\n private ${field.jfieldType} whereParam${where?counter}End;\n\n <#else>\n @ApiParam(hidden = true)\n private ${field.jfieldType} whereParam${where?counter};\n\n </#if>\n</#list>\n<#list filteredHaving as having>\n <#if FilterOperator.IS_NULL.getValue() == having.filterOperator\n || FilterOperator.NOT_NULL.getValue() == having.filterOperator>\n <#continue>\n </#if>\n <#assign jfieldType=convertMetricsFieldType(having.parent)>\n <#if FilterOperator.CONTAIN.getValue() == having.filterOperator\n || FilterOperator.NOT_CONTAIN.getValue() == having.filterOperator>\n <@call this.addImport(\"java.util.List\")/>\n @ApiParam(hidden = true)\n private List<${field.jfieldType}> havingParam${having?counter};\n\n <#elseIf FilterOperator.BETWEEN.getValue() == having.filterOperator\n || FilterOperator.IS_NOW.getValue() == having.filterOperator\n || FilterOperator.BEFORE_TIME.getValue() == having.filterOperator\n || FilterOperator.AFTER_TIME.getValue() == having.filterOperator>\n @ApiParam(hidden = true)\n private ${jfieldType} havingParam${having?counter}Start;\n\n @ApiParam(hidden = true)\n private ${jfieldType} havingParam${having?counter}End;\n\n <#else>\n @ApiParam(hidden = true)\n private ${jfieldType} havingParam${having?counter};\n\n </#if>\n</#list>\n\n<#if !this.projectFeature.lombokEnabled>\n <#list paramedWhere as where>\n <#assign field=where.field>\n <#if FilterOperator.CONTAIN.getValue() == where.filterOperator\n || FilterOperator.NOT_CONTAIN.getValue() == where.filterOperator>\n <@call JavaTemplateFunction.printGetterSetterList(\"whereParam${where?counter}\",\"${field.jfieldType}\",false)/>\n <#elseIf FilterOperator.BETWEEN.getValue() == where.filterOperator\n || FilterOperator.IS_NOW.getValue() == where.filterOperator\n || FilterOperator.BEFORE_TIME.getValue() == where.filterOperator\n || FilterOperator.AFTER_TIME.getValue() == where.filterOperator>\n <@call JavaTemplateFunction.printGetterSetter(\"whereParam${where?counter}Start\",\"${field.jfieldType}\")/>\n <@call JavaTemplateFunction.printGetterSetter(\"whereParam${where?counter}End\",\"${field.jfieldType}\")/>\n <#else>\n <@call JavaTemplateFunction.printGetterSetter(\"whereParam${where?counter}\",\"${field.jfieldType}\")/>\n </#if>\n </#list>\n <#list filteredHaving as having>\n <#if FilterOperator.IS_NULL.getValue() == having.filterOperator\n || FilterOperator.NOT_NULL.getValue() == having.filterOperator>\n <#continue>\n </#if>\n <#assign jfieldType=convertMetricsFieldType(having.parent)>\n <#if FilterOperator.CONTAIN.getValue() == having.filterOperator\n || FilterOperator.NOT_CONTAIN.getValue() == having.filterOperator>\n <@call JavaTemplateFunction.printGetterSetterList(\"havingParam${having?counter}\",\"${jfieldType}\",false)/>\n <#elseIf FilterOperator.BETWEEN.getValue() == having.filterOperator\n || FilterOperator.IS_NOW.getValue() == having.filterOperator\n || FilterOperator.BEFORE_TIME.getValue() == having.filterOperator\n || FilterOperator.AFTER_TIME.getValue() == having.filterOperator>\n <@call JavaTemplateFunction.printGetterSetter(\"havingParam${having?counter}Start\",\"${jfieldType}\")/>\n <@call JavaTemplateFunction.printGetterSetter(\"havingParam${having?counter}End\",\"${jfieldType}\")/>\n <#else>\n <@call JavaTemplateFunction.printGetterSetter(\"havingParam${having?counter}\",\"${jfieldType}\")/>\n </#if>\n </#list>\n</#if>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${qoPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(121,'{ClassName}QO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/qo/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/guessDateFormat.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForQuery.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"io.swagger.annotations.ApiParam\")/>\n<#if this.pageSign>\n <@call this.addImport(\"${this.commonPackage}.pojo.qo.PageQO\")/>\n<#else>\n <@call this.addImport(\"${this.commonPackage}.pojo.qo.AbstractQO\")/>\n</#if>\n<@call this.addStaticImport(\"${examplePackageName}.${this.className}Example.*\")/>\n<@call this.printClassCom(\"查询【${this.title}】的参数\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\npublic class ${this.className}QO extends <#if this.pageSign>PageQO<#else>AbstractQO</#if> {\n\n<#--定义宏-查询字段申明模块\n field-字段对象\n alias-字段别名\n exampleClass-示例类名\n-->\n<#macro queryField field alias=\"\" exampleClass=\"\">\n <#if alias?hasContent>\n <#assign jfieldName=alias>\n <#else>\n <#assign jfieldName=field.jfieldName>\n </#if>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(field.jfieldName,true)>\n <#--查询方式:IN-->\n <#if QueryType.isIn(field.queryType)>\n <@call this.addImport(\"java.util.List\")/>\n @ApiParam(value = ${exampleClass}N_${jfieldNameSnakeCase})\n private List<${field.jfieldType}> ${jfieldName};\n <#else>\n <#--其他查询方式-->\n @ApiParam(value = ${exampleClass}N_${jfieldNameSnakeCase}, example = ${exampleClass}E_${jfieldNameSnakeCase})\n <#if field.jfieldType == JFieldType.STRING.getJavaType()>\n <@call this.addImport(\"org.hibernate.validator.constraints.Length\")/>\n @Length(max = ${field.fieldLength}, message = \"${jfieldName}最大长度不能超过{max}\")\n <#elseIf field.jfieldType == JFieldType.DATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern = ${guessDateFormat(field)}, timezone = \"GMT+8\")\n </#if>\n private ${field.jfieldType} ${jfieldName};\n </#if>\n\n</#macro>\n<#--开始渲染查询字段声明语句-->\n<#list this.queryFields as id,field>\n <#if !QueryType.isBetween(field.queryType)>\n <@queryField field></@queryField>\n <#else>\n <@queryField field field.jfieldName+\"Start\"></@queryField>\n <@queryField field field.jfieldName+\"End\"></@queryField>\n </#if>\n</#list>\n<#--开始渲染【外键级联扩展】字段声明语句-->\n<#list this.fkFields as id,field>\n <#if field.cascadeQueryExts?? && field.cascadeQueryExts?size &gt; 0>\n <#assign exampleClass=\"\">\n <#if field.foreignEntity != this.metaEntity>\n <@call this.addImport(\"${examplePackageName}.${field.foreignEntity.className}Example\")/>\n <#assign exampleClass=\"${field.foreignEntity.className}Example.\">\n </#if>\n <#list field.cascadeQueryExts as cascadeExt>\n <#assign cascadeField=cascadeExt.cascadeField>\n <#if !QueryType.isBetween(cascadeField.queryType)>\n <@queryField cascadeField cascadeExt.alias exampleClass></@queryField>\n <#else>\n <@queryField cascadeField cascadeExt.alias+\"Start\" exampleClass></@queryField>\n <@queryField cascadeField cascadeExt.alias+\"End\" exampleClass></@queryField>\n </#if>\n </#list>\n </#if>\n</#list>\n<#--开始渲染【多对多级联扩展】字段声明语句-->\n<#list mtmCascadeExtsForQuery as mtmCascadeExt>\n <#assign cascadeField=mtmCascadeExt.cascadeField>\n <#assign cascadeEntity=mtmCascadeExt.cascadeEntity>\n <@call this.addImport(\"${examplePackageName}.${cascadeEntity.className}Example\")/>\n <#assign exampleClass=\"${cascadeEntity.className}Example.\">\n <#if !QueryType.isBetween(cascadeField.queryType)>\n <@queryField cascadeField mtmCascadeExt.alias exampleClass></@queryField>\n <#else>\n <@queryField cascadeField mtmCascadeExt.alias+\"Start\" exampleClass></@queryField>\n <@queryField cascadeField mtmCascadeExt.alias+\"End\" exampleClass></@queryField>\n </#if>\n</#list>\n<#--开始渲染排序条件声明语句-->\n<#list this.listSortFields as id,field>\n @ApiParam(value = \"${field.fieldDesc}排序标识【1升序,-1降序,0不排序】\", example = \"1\")\n private Integer ${field.jfieldName}SortSign;\n\n</#list>\n\n<#if !this.projectFeature.lombokEnabled>\n <#--定义宏-查询字段getter-setter模块\n field-字段对象\n alias-字段别名\n -->\n <#macro queryMethod field alias=\"\">\n <#if alias?hasContent>\n <#assign jfieldName=alias>\n <#else>\n <#assign jfieldName=field.jfieldName>\n </#if>\n <#--查询方式:IN-->\n <#if QueryType.isIn(field.queryType)>\n <@call JavaTemplateFunction.printGetterSetterList(\"${jfieldName}\",\"${field.jfieldType}\",false)/>\n <#else>\n <#--其他查询方式-->\n <@call JavaTemplateFunction.printGetterSetter(\"${jfieldName}\",\"${field.jfieldType}\")/>\n </#if>\n </#macro>\n <#--开始渲染查询字段getter-setter方法-->\n <#list this.queryFields as id,field>\n <#if !QueryType.isBetween(field.queryType)>\n <@queryMethod field></@queryMethod>\n <#else>\n <@queryMethod field field.jfieldName+\"Start\"></@queryMethod>\n <@queryMethod field field.jfieldName+\"End\"></@queryMethod>\n </#if>\n </#list>\n <#--开始渲染【外键级联扩展】字段getter-setter方法-->\n <#list this.fkFields as id,field>\n <#list field.cascadeQueryExts! as cascadeExt>\n <#assign cascadeField=cascadeExt.cascadeField>\n <#if !QueryType.isBetween(cascadeField.queryType)>\n <@queryMethod cascadeField cascadeExt.alias></@queryMethod>\n <#else>\n <@queryMethod cascadeField cascadeExt.alias+\"Start\"></@queryMethod>\n <@queryMethod cascadeField cascadeExt.alias+\"End\"></@queryMethod>\n </#if>\n </#list>\n </#list>\n <#--开始渲染【多对多级联扩展】字段getter-setter方法-->\n <#list mtmCascadeExtsForQuery as mtmCascadeExt>\n <#assign cascadeField=mtmCascadeExt.cascadeField>\n <#if !QueryType.isBetween(cascadeField.queryType)>\n <@queryMethod cascadeField mtmCascadeExt.alias></@queryMethod>\n <#else>\n <@queryMethod cascadeField mtmCascadeExt.alias+\"Start\"></@queryMethod>\n <@queryMethod cascadeField mtmCascadeExt.alias+\"End\"></@queryMethod>\n </#if>\n </#list>\n <#--开始渲染排序字段getter-setter方法-->\n <#list this.listSortFields as id,field>\n <@call JavaTemplateFunction.printGetterSetter(\"${field.jfieldName}SortSign\",\"Integer\")/>\n </#list>\n</#if>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${qoPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(122,'UserLoginVO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.printClassCom(\"登录用户信息\")/>\npublic class UserLoginVO {\n\n private List<String> roles;\n private String introduction;\n private String avatar;\n private String name;\n\n public List<String> getRoles() {\n return roles;\n }\n\n public void setRoles(List<String> roles) {\n this.roles = roles;\n }\n\n public String getIntroduction() {\n return introduction;\n }\n\n public void setIntroduction(String introduction) {\n this.introduction = introduction;\n }\n\n public String getAvatar() {\n return avatar;\n }\n\n public void setAvatar(String avatar) {\n this.avatar = avatar;\n }\n\n public String getName() {\n return name;\n }\n\n public void setName(String name) {\n this.name = name;\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.pojo.vo;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(123,'__dir.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(124,'__{ChartName}ExcelVO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,4,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}ExcelVO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(125,'__{ChartName}VO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,4,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}VO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(126,'__{ClassName}ExcelVO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}ExcelVO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(127,'__{ClassName}ListVO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}ListVO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(128,'__{ClassName}ShowVO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}ShowVO.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(129,'{ChartName}ExcelVO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#include \"/abstracted/guessDateFormat.ftl\">\n<#include \"/abstracted/chartItem.ftl\">\n<#if !isChartType(ChartType.DETAIL_LIST) && !isChartType(ChartType.AGG_TABLE)>\n <@call this.skipCurrent()/>\n</#if>\n<#if !this.excelExport>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.pojo.vo.AbstractVO\")/>\n<@call this.addImport(\"com.alibaba.excel.annotation.ExcelProperty\")/>\n<@call this.addImport(\"com.alibaba.excel.annotation.write.style.ColumnWidth\")/>\n<@call this.printClassCom(\"【${this.title}】excel导出对象\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\npublic class ${this.chartName}ExcelVO extends AbstractVO <#if barLineParamMode == 1>implements Chart2DimensionVO </#if>{\n\n<#-- 定义getterSetter代码 -->\n<#assign getterSetterCode = \"\">\n<#if isChartType(ChartType.DETAIL_LIST)>\n <#-- 明细列字段 -->\n <#list this.columnList as column>\n <#assign sourceItem=column.sourceItem>\n <#if sourceItem.custom>\n <#--字段类型-->\n <#assign jfieldType=convertCustomFieldType(sourceItem.customFieldType)>\n <#--字段名-->\n <#assign name=column.alias>\n <#--字段标题-->\n <#assign label=column.titleAlias>\n <#--日期格式-->\n <#assign dateFormat=guessDateFormatForCustom(sourceItem.customFieldType)>\n <#--列宽-->\n <#assign columnWidth=15>\n <#else>\n <#assign field=sourceItem.field>\n <#if field.dicType??>\n <#assign jfieldType = \"String\">\n <#else>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#assign jfieldType=field.jfieldType>\n </#if>\n <#if column.alias?hasContent>\n <#assign name=column.alias>\n <#else>\n <#assign name=field.jfieldName>\n </#if>\n <#if column.titleAlias?hasContent>\n <#assign label=column.titleAlias>\n <#else>\n <#assign label=field.fetchComment()?replace(\'\\\"\',\'\\\\\"\')?replace(\'\\n\',\'\\\\n\')>\n </#if>\n <#--日期格式-->\n <#assign dateFormat=guessDateFormat(field)>\n <#--列宽-->\n <#if field.columnWidth?? && field.columnWidth &gt; 0>\n <#assign columnWidth=field.columnWidth/8>\n <#else>\n <#assign columnWidth=15>\n </#if>\n </#if>\n <#if jfieldType == JFieldType.DATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.alibaba.excel.annotation.format.DateTimeFormat\")/>\n @DateTimeFormat(${dateFormat})\n </#if>\n @ExcelProperty(\"${label}\")\n @ColumnWidth(${columnWidth})\n private ${jfieldType} ${name};\n <#assign getterSetterCode += genGetterSetter(jfieldType,name)>\n\n </#list>\n<#elseIf isChartType(ChartType.AGG_TABLE)>\n\n <#-- 维度字段 -->\n <#list filteredDimension as dimension>\n <#assign chartItem = chartItemMapWrapper.get(dimension.sourceItemId)>\n <#if dimension.field.dicType??>\n <#assign jfieldType = \"String\">\n <#else>\n <#assign jfieldType=convertDimensionFieldType(dimension)>\n </#if>\n <#if chartItem.alias?hasContent>\n <#assign name=chartItem.alias>\n <#else>\n <#assign name=dimension.field.jfieldName>\n </#if>\n <#if jfieldType == JFieldType.DATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.alibaba.excel.annotation.format.DateTimeFormat\")/>\n @DateTimeFormat(${guessDateFormat(dimension.field)})\n </#if>\n @ExcelProperty(\"${chartItem.titleAlias}\")\n <#if dimension.field.columnWidth?? && dimension.field.columnWidth &gt; 0>\n @ColumnWidth(${dimension.field.columnWidth/8})\n <#else>\n @ColumnWidth(15)\n </#if>\n private ${jfieldType} ${name};\n <#assign getterSetterCode += genGetterSetter(jfieldType,name)>\n\n </#list>\n <#-- 指标字段 -->\n <#list filteredMetrics as metrics>\n <#assign chartItem = chartItemMapWrapper.get(metrics.sourceItemId)>\n <#assign jfieldType=convertMetricsFieldType(metrics)>\n <#--字段名-->\n <#assign name=chartItem.alias>\n <#--字段标题-->\n <#assign label=chartItem.titleAlias>\n <#if metrics.custom>\n <#--日期格式-->\n <#assign dateFormat=guessDateFormatForCustom(metrics.customFieldType)>\n <#--列宽-->\n <#assign columnWidth=15>\n <#else>\n <#--日期格式-->\n <#assign dateFormat=guessDateFormat(metrics.field)>\n <#--列宽-->\n <#if metrics.field.columnWidth?? && metrics.field.columnWidth &gt; 0>\n <#assign columnWidth=metrics.field.columnWidth/8>\n <#else>\n <#assign columnWidth=15>\n </#if>\n </#if>\n <#if jfieldType == JFieldType.DATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.alibaba.excel.annotation.format.DateTimeFormat\")/>\n @DateTimeFormat(${dateFormat})\n </#if>\n @ExcelProperty(\"${label}\")\n @ColumnWidth(${columnWidth})\n private ${jfieldType} ${name};\n <#assign getterSetterCode += genGetterSetter(jfieldType,name)>\n\n </#list>\n</#if>\n\n<#if !this.projectFeature.lombokEnabled>${getterSetterCode}</#if>\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${voPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(130,'{ChartName}VO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#include \"/abstracted/guessDateFormat.ftl\">\n<#include \"/abstracted/chartItem.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"io.swagger.annotations.ApiModel\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiModelProperty\")/>\n<@call this.addImport(\"${this.commonPackage}.pojo.vo.AbstractVO\")/>\n<@call this.printClassCom(\"【${this.title}】图表展示对象\")/>\n<#if barLineParamMode == 1>\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.Chart2DimensionVO\")/>\n</#if>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\n@ApiModel(description = \"【${this.title}】图表展示对象\")\npublic class ${this.chartName}VO extends AbstractVO <#if barLineParamMode == 1>implements Chart2DimensionVO </#if>{\n\n<#-- 定义getterSetter代码 -->\n<#assign getterSetterCode = \"\">\n<#if isChartType(ChartType.DETAIL_LIST)>\n <#-- 明细列字段 -->\n <#list this.columnList as column>\n <#assign sourceItem=column.sourceItem>\n <#if sourceItem.custom>\n <#--字段类型-->\n <#assign jfieldType=convertCustomFieldType(sourceItem.customFieldType)>\n <#--字段名-->\n <#assign name=column.alias>\n <#--字段标题-->\n <#assign label=column.titleAlias>\n <#--日期格式-->\n <#assign dateFormat=guessDateFormatForCustom(sourceItem.customFieldType)>\n <#else>\n <#assign field=sourceItem.field>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#assign jfieldType=field.jfieldType>\n <#if column.alias?hasContent>\n <#assign name=column.alias>\n <#else>\n <#assign name=field.jfieldName>\n </#if>\n <#if column.titleAlias?hasContent>\n <#assign label=column.titleAlias>\n <#else>\n <#assign label=field.fetchComment()?replace(\'\\\"\',\'\\\\\"\')?replace(\'\\n\',\'\\\\n\')>\n </#if>\n <#--日期格式-->\n <#assign dateFormat=guessDateFormat(field)>\n </#if>\n <#if jfieldType == JFieldType.DATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern = ${dateFormat}, timezone = \"GMT+8\")\n </#if>\n @ApiModelProperty(notes = \"${label}\")\n private ${jfieldType} ${name};\n <#assign getterSetterCode += genGetterSetter(jfieldType,name)>\n\n </#list>\n<#else>\n\n <#-- 维度字段 -->\n <#list filteredDimension as dimension>\n <#assign chartItem = chartItemMapWrapper.get(dimension.sourceItemId)>\n <#assign jfieldType=convertDimensionFieldType(dimension)>\n <#if chartItem.alias?hasContent>\n <#assign name=chartItem.alias>\n <#else>\n <#assign name=dimension.field.jfieldName>\n </#if>\n <#if jfieldType == JFieldType.DATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern = ${guessDateFormat(dimension.field)}, timezone = \"GMT+8\")\n </#if>\n @ApiModelProperty(notes = \"${chartItem.titleAlias}\")\n private ${jfieldType} ${name};\n <#assign getterSetterCode += genGetterSetter(jfieldType,name)>\n\n </#list>\n <#-- 指标字段 -->\n <#list filteredMetrics as metrics>\n <#assign chartItem = chartItemMapWrapper.get(metrics.sourceItemId)>\n <#assign jfieldType=convertMetricsFieldType(metrics)>\n <#--字段名-->\n <#assign name=chartItem.alias>\n <#--字段标题-->\n <#assign label=chartItem.titleAlias>\n <#if metrics.custom>\n <#--日期格式-->\n <#assign dateFormat=guessDateFormatForCustom(metrics.customFieldType)>\n <#else>\n <#--日期格式-->\n <#assign dateFormat=guessDateFormat(metrics.field)>\n </#if>\n <#if jfieldType == JFieldType.DATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATE.getJavaType()\n || jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern = ${dateFormat}, timezone = \"GMT+8\")\n </#if>\n @ApiModelProperty(notes = \"${label}\")\n private ${jfieldType} ${name};\n <#assign getterSetterCode += genGetterSetter(jfieldType,name)>\n\n </#list>\n</#if>\n\n<#if isChartType(ChartType.BAR_LINE)>\n <#if barLineParamMode == 1>\n <#assign axisXField = this.axisX.sourceItem.field>\n <#assign axisX2Field = this.axisX2.sourceItem.field>\n public static String header0() {\n return \"${this.axisX.titleAlias}\";\n }\n\n @Override\n public Object fetchDimension1() {\n <#if axisXField.dicType??>\n <@call this.addConstImport(axisXField.dicType)/>\n return ${axisXField.dicType}.valueToDesc(${this.axisX.alias});\n <#else>\n return ${this.axisX.alias};\n </#if>\n }\n\n @Override\n public Object fetchDimension2() {\n <#if axisX2Field.dicType??>\n <@call this.addConstImport(axisX2Field.dicType)/>\n return ${axisX2Field.dicType}.valueToDesc(${this.axisX2.alias});\n <#else>\n return ${this.axisX2.alias};\n </#if>\n }\n\n @Override\n public Object fetchMetrics() {\n return ${this.axisYList[0].alias};\n }\n\n <#elseIf barLineParamMode == 2>\n <#assign axisXField = this.axisX.sourceItem.field>\n public static Object[] header() {\n return new Object[]{\n \"${this.axisX.titleAlias}\",\n <#list this.axisYList as axisY>\n \"${axisY.titleAlias}\"<#if axisY_has_next>,</#if>\n </#list>\n };\n }\n\n public Object[] dataArray() {\n return new Object[]{\n <#if axisXField.dicType??>\n <@call this.addConstImport(axisXField.dicType)/>\n ${axisXField.dicType}.valueToDesc(${this.axisX.alias}),\n <#else>\n ${this.axisX.alias},\n </#if>\n <#list this.axisYList as axisY>\n ${axisY.alias}<#if axisY_has_next>,</#if>\n </#list>\n };\n }\n\n </#if>\n<#elseIf isChartType(ChartType.PIE)>\n <#assign dimensionField = this.dimension.sourceItem.field>\n public static Object[] header() {\n return new Object[]{\n \"${this.dimension.titleAlias}\",\n \"${this.metrics.titleAlias}\"\n };\n }\n\n public Object[] dataArray() {\n return new Object[]{\n <#if dimensionField.dicType??>\n <@call this.addConstImport(dimensionField.dicType)/>\n ${dimensionField.dicType}.valueToDesc(${this.dimension.alias}),\n <#else>\n ${this.dimension.alias},\n </#if>\n ${this.metrics.alias}\n };\n }\n\n</#if>\n<#if !this.projectFeature.lombokEnabled>${getterSetterCode}</#if>\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${voPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(131,'{ClassName}ExcelVO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/guessDateFormat.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForList.ftl\">\n<#if !this.entityFeature.excelExport>\n <@call this.skipCurrent()/>\n</#if>\n<#--解析字段类型-->\n<#function parseJfieldType field>\n<#--枚举字段使用String类型-->\n <#if field.dicType??>\n <#local jfieldType = \"String\">\n <#else>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#local jfieldType = field.jfieldType>\n </#if>\n <#return jfieldType>\n</#function>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.pojo.vo.AbstractVO\")/>\n<@call this.addImport(\"com.alibaba.excel.annotation.ExcelProperty\")/>\n<@call this.addImport(\"com.alibaba.excel.annotation.write.style.ColumnWidth\")/>\n<@call this.printClassCom(\"【${this.title}】excel导出对象\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\npublic class ${this.className}ExcelVO extends AbstractVO {\n\n<#--当前实体列表展示字段-->\n<#list this.listFields as id,field>\n <#if field.jfieldType == JFieldType.LOCALDATE.getJavaType()>\n <@call this.addImport(\"${this.packageName}.excel.converter.LocalDateConverter\")/>\n @ExcelProperty(value = \"${field.fieldDesc}\", converter = LocalDateConverter.class)\n <#elseIf field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"${this.packageName}.excel.converter.LocalDateTimeConverter\")/>\n @ExcelProperty(value = \"${field.fieldDesc}\", converter = LocalDateTimeConverter.class)\n <#else>\n @ExcelProperty(\"${field.fieldDesc}\")\n </#if>\n <#if field.jfieldType == JFieldType.DATE.getJavaType()>\n <@call this.addImport(\"com.alibaba.excel.annotation.format.DateTimeFormat\")/>\n @DateTimeFormat(${guessDateFormat(field)})\n </#if>\n <#if field.columnWidth?? && field.columnWidth &gt; 0>\n @ColumnWidth(${field.columnWidth/8})\n <#else>\n @ColumnWidth(15)\n </#if>\n private ${parseJfieldType(field)} ${field.jfieldName};\n\n</#list>\n<#--外键级联扩展,列表展示字段-->\n<#list this.fkFields as id,field>\n <#list field.cascadeListExts! as cascadeExt>\n <#assign cascadeField=cascadeExt.cascadeField>\n <#if cascadeField.jfieldType == JFieldType.LOCALDATE.getJavaType()>\n <@call this.addImport(\"${this.packageName}.excel.converter.LocalDateConverter\")/>\n @ExcelProperty(value = \"${cascadeField.fieldDesc}\", converter = LocalDateConverter.class)\n <#elseIf cascadeField.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"${this.packageName}.excel.converter.LocalDateTimeConverter\")/>\n @ExcelProperty(value = \"${cascadeField.fieldDesc}\", converter = LocalDateTimeConverter.class)\n <#else>\n @ExcelProperty(\"${cascadeField.fieldDesc}\")\n </#if>\n <#if cascadeField.jfieldType == JFieldType.DATE.getJavaType()>\n <@call this.addImport(\"com.alibaba.excel.annotation.format.DateTimeFormat\")/>\n @DateTimeFormat(${guessDateFormat(cascadeField)})\n </#if>\n <#if cascadeField.columnWidth?? && cascadeField.columnWidth &gt; 0>\n @ColumnWidth(${cascadeField.columnWidth/8})\n <#else>\n @ColumnWidth(15)\n </#if>\n private ${parseJfieldType(cascadeField)} ${cascadeExt.alias};\n\n </#list>\n</#list>\n<#--多对多级联扩展列表展示-->\n<#list mtmCascadeEntitiesForList as otherEntity>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n @ExcelProperty(\"${otherEntity.title}\")\n @ColumnWidth(20)\n private String ${othercName}List;\n\n</#list>\n\n<#if !this.projectFeature.lombokEnabled>\n <#--当前实体列表展示字段:getter-setter方法-->\n <#list this.listFields as id,field>\n <@call JavaTemplateFunction.printGetterSetter(field.jfieldName,parseJfieldType(field))/>\n </#list>\n <#--外键级联扩展,列表展示字段:getter-setter方法-->\n <#list this.fkFields as id,field>\n <#list field.cascadeListExts! as cascadeExt>\n <@call JavaTemplateFunction.printGetterSetter(cascadeExt.alias,parseJfieldType(cascadeExt.cascadeField))/>\n </#list>\n </#list>\n <#--多对多列表展示:getter-setter方法-->\n <#list mtmCascadeEntitiesForList as otherEntity>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call JavaTemplateFunction.printGetterSetter(othercName+\"List\",\"String\")/>\n </#list>\n</#if>\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${voPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(132,'{ClassName}ListVO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/guessDateFormat.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForList.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"io.swagger.annotations.ApiModel\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiModelProperty\")/>\n<@call this.addImport(\"${this.commonPackage}.pojo.vo.AbstractVO\")/>\n<@call this.addStaticImport(\"${examplePackageName}.${this.className}Example.*\")/>\n<@call this.printClassCom(\"【${this.title}】列表展示对象\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\n@ApiModel(description = \"【${this.title}】列表展示对象\")\npublic class ${this.className}ListVO extends AbstractVO {\n\n<#--当前实体列表展示字段-->\n<#list this.listFields as id,field>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(field.jfieldName,true)>\n <#if field.dicType??>\n <@call this.addConstImport(field.dicType)/>\n </#if>\n @ApiModelProperty(notes = N_${jfieldNameSnakeCase}, example = E_${jfieldNameSnakeCase}<#if field.dicType??>, allowableValues = ${field.dicType}.VALUES_STR</#if>)\n <#if field.jfieldType == JFieldType.DATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern = ${guessDateFormat(field)}, timezone = \"GMT+8\")\n </#if>\n private ${field.jfieldType} ${field.jfieldName};\n\n</#list>\n<#--外键级联扩展,列表展示字段-->\n<#list this.fkFields as id,field>\n <#list field.cascadeListExts! as cascadeExt>\n <#assign cascadeField=cascadeExt.cascadeField>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(cascadeField)/>\n <#assign exampleClass=\"\">\n <#if cascadeField.dicType??>\n <@call this.addConstImport(cascadeField.dicType)/>\n </#if>\n <#if field.foreignEntity != this.metaEntity>\n <@call this.addImport(\"${examplePackageName}.${field.foreignEntity.className}Example\")/>\n <#assign exampleClass=\"${field.foreignEntity.className}Example.\">\n </#if>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(cascadeField.jfieldName,true)>\n @ApiModelProperty(notes = ${exampleClass}N_${jfieldNameSnakeCase}, example = ${exampleClass}E_${jfieldNameSnakeCase}<#if cascadeField.dicType??>, allowableValues = ${cascadeField.dicType}.VALUES_STR</#if>)\n <#if cascadeField.jfieldType == JFieldType.DATE.getJavaType()\n || cascadeField.jfieldType == JFieldType.LOCALDATE.getJavaType()\n || cascadeField.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern = ${guessDateFormat(cascadeField)}, timezone = \"GMT+8\")\n </#if>\n private ${cascadeField.jfieldType} ${cascadeExt.alias};\n\n </#list>\n</#list>\n<#--多对多级联扩展列表展示-->\n<#list mtmCascadeEntitiesForList as otherEntity>\n <@call this.addImport(\"java.util.List\")/>\n <#assign otherCName=otherEntity.className/>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n @ApiModelProperty(notes = \"【${otherEntity.title}】列表\")\n private List<${otherCName}VO> ${othercName}List;\n\n</#list>\n\n<#if !this.projectFeature.lombokEnabled>\n <#--当前实体列表展示字段:getter-setter方法-->\n <#list this.listFields as id,field>\n <@call JavaTemplateFunction.printGetterSetter(field)/>\n </#list>\n <#--外键级联扩展,列表展示字段:getter-setter方法-->\n <#list this.fkFields as id,field>\n <#list field.cascadeListExts! as cascadeExt>\n <@call JavaTemplateFunction.printGetterSetter(cascadeExt.alias,cascadeExt.cascadeField.jfieldType)/>\n </#list>\n </#list>\n <#--多对多列表展示:getter-setter方法-->\n <#list mtmCascadeEntitiesForList as otherEntity>\n <#assign otherCName=otherEntity.className/>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call JavaTemplateFunction.printGetterSetterList(othercName,\"${otherCName}VO\")/>\n </#list>\n</#if>\n<#--多对多列表展示【静态内部类】-->\n<#list mtmCascadeEntitiesForList as otherEntity>\n <#assign mtmCascadeExts = groupMtmCascadeExtsForList[otherEntity?index]>\n <#assign otherCName=otherEntity.className>\n <#assign exampleClass=\"${otherEntity.className}Example\">\n <@call this.addImport(\"${examplePackageName}.${exampleClass}\")/>\n <#if this.projectFeature.lombokEnabled>\n @Data\n @EqualsAndHashCode(callSuper=true)\n </#if>\n public static class ${otherCName}VO extends AbstractVO {\n\n <#--主键字段-->\n <#assign otherPkField=otherEntity.pkField>\n <#--字段名转下划线大写-->\n <#assign pkFieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(otherPkField.jfieldName,true)>\n @ApiModelProperty(notes = ${exampleClass}.N_${pkFieldNameSnakeCase},example = ${exampleClass}.E_${pkFieldNameSnakeCase})\n private ${otherPkField.jfieldType} ${otherPkField.jfieldName};\n\n <#--多对多级联扩展,列表展示字段-->\n <#list mtmCascadeExts as mtmCascadeExt>\n <#assign field=mtmCascadeExt.cascadeField>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(field.jfieldName,true)>\n <#if field.dicType??>\n <@call this.addConstImport(field.dicType)/>\n </#if>\n @ApiModelProperty(notes = ${exampleClass}.N_${jfieldNameSnakeCase},example = ${exampleClass}.E_${jfieldNameSnakeCase}<#if field.dicType??>, allowableValues = ${field.dicType}.VALUES_STR</#if>)\n <#if field.jfieldType == JFieldType.DATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern = ${guessDateFormat(field)}, timezone = \"GMT+8\")\n </#if>\n private ${field.jfieldType} ${field.jfieldName};\n\n </#list>\n\n <#if !this.projectFeature.lombokEnabled>\n <#--主键字段:getter-setter方法-->\n <@call JavaTemplateFunction.printGetterSetter(otherPkField,2)/>\n <#--多对多级联扩展,列表展示字段:getter-setter方法-->\n <#list mtmCascadeExts as mtmCascadeExt>\n <#assign field=mtmCascadeExt.cascadeField>\n <@call JavaTemplateFunction.printGetterSetter(field,2)/>\n </#list>\n </#if>\n }\n\n</#list>\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${voPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(133,'{ClassName}ShowVO.java.ftl','/{coreModule}/src/main/java/{packageName}/pojo/vo/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/guessDateFormat.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForShow.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"io.swagger.annotations.ApiModel\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiModelProperty\")/>\n<@call this.addImport(\"${this.commonPackage}.pojo.vo.AbstractVO\")/>\n<@call this.addStaticImport(\"${examplePackageName}.${this.className}Example.*\")/>\n<@call this.printClassCom(\"【${this.title}】详情展示对象\")/>\n<#if this.projectFeature.lombokEnabled>\n <@call this.addImport(\"lombok.Data\")/>\n <@call this.addImport(\"lombok.EqualsAndHashCode\")/>\n@Data\n@EqualsAndHashCode(callSuper=true)\n</#if>\n@ApiModel(description = \"【${this.title}】详情展示对象\")\npublic class ${this.className}ShowVO extends AbstractVO {\n\n<#--当前实体详情展示字段-->\n<#list this.showFields as id,field>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(field.jfieldName,true)>\n <#if field.dicType??>\n <@call this.addConstImport(field.dicType)/>\n </#if>\n @ApiModelProperty(notes = N_${jfieldNameSnakeCase}, example = E_${jfieldNameSnakeCase}<#if field.dicType??>, allowableValues = ${field.dicType}.VALUES_STR</#if>)\n <#if field.jfieldType == JFieldType.DATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern=${guessDateFormat(field)}, timezone=\"GMT+8\")\n </#if>\n private ${field.jfieldType} ${field.jfieldName};\n\n</#list>\n<#--外键级联扩展,详情展示字段-->\n<#list this.fkFields as id,field>\n <#list field.cascadeShowExts! as cascadeExt>\n <#assign cascadeField=cascadeExt.cascadeField>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(cascadeField)/>\n <#assign exampleClass=\"\">\n <#if cascadeField.dicType??>\n <@call this.addConstImport(cascadeField.dicType)/>\n </#if>\n <#if field.foreignEntity != this.metaEntity>\n <@call this.addImport(\"${examplePackageName}.${field.foreignEntity.className}Example\")/>\n <#assign exampleClass=\"${field.foreignEntity.className}Example.\">\n </#if>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(cascadeField.jfieldName,true)>\n @ApiModelProperty(notes = ${exampleClass}N_${jfieldNameSnakeCase}, example = ${exampleClass}E_${jfieldNameSnakeCase}<#if cascadeField.dicType??>, allowableValues = ${cascadeField.dicType}.VALUES_STR</#if>)\n <#if cascadeField.jfieldType == JFieldType.DATE.getJavaType()\n || cascadeField.jfieldType == JFieldType.LOCALDATE.getJavaType()\n || cascadeField.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern = ${guessDateFormat(cascadeField)}, timezone=\"GMT+8\")\n </#if>\n private ${cascadeField.jfieldType} ${cascadeExt.alias};\n\n </#list>\n</#list>\n<#--多对多随实体一起维护并且未设置级联扩展时,需要返回对方的id列表-->\n<#list this.holds! as otherEntity,mtm>\n <#if mtm.getEntityFeature(this.entityId).withinEntity\n && !mtmCascadeEntitiesForShow?seqContains(otherEntity)>\n <@call this.addImport(\"java.util.List\")/>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n @ApiModelProperty(notes = \"【${otherEntity.title}】主键列表\")\n private List<${otherEntity.pkField.jfieldType}> ${othercName}List;\n\n </#if>\n</#list>\n<#--多对多级联扩展详情展示-->\n<#list mtmCascadeEntitiesForShow as otherEntity>\n <@call this.addImport(\"java.util.List\")/>\n <#assign otherCName=otherEntity.className/>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n @ApiModelProperty(notes = \"【${otherEntity.title}】列表\")\n private List<${otherCName}VO> ${othercName}List;\n\n</#list>\n\n<#if !this.projectFeature.lombokEnabled>\n <#--当前实体详情展示字段:getter-setter方法-->\n <#list this.showFields as id,field>\n <@call JavaTemplateFunction.printGetterSetter(field)/>\n </#list>\n <#--外键级联扩展,详情展示字段:getter-setter方法-->\n <#list this.fkFields as id,field>\n <#list field.cascadeShowExts! as cascadeExt>\n <@call JavaTemplateFunction.printGetterSetter(cascadeExt.alias,cascadeExt.cascadeField.jfieldType)/>\n </#list>\n </#list>\n <#--多对多随实体一起维护并且未设置级联扩展时,需要返回对方的id列表-->\n <#list this.holds! as otherEntity,mtm>\n <#if mtm.getEntityFeature(this.entityId).withinEntity\n && !mtmCascadeEntitiesForShow?seqContains(otherEntity)>\n <@call JavaTemplateFunction.printGetterSetterList(\"${othercName}List\",otherEntity.pkField.jfieldType,false)/>\n </#if>\n </#list>\n <#--多对多级联扩展详情展示:getter-setter方法-->\n <#list mtmCascadeEntitiesForShow as otherEntity>\n <#assign otherCName=otherEntity.className/>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call JavaTemplateFunction.printGetterSetterList(othercName,\"${otherCName}VO\")/>\n </#list>\n</#if>\n<#--多对多级联扩展详情展示【静态内部类】-->\n<#list mtmCascadeEntitiesForShow as otherEntity>\n <#assign mtmCascadeExts = groupMtmCascadeExtsForShow[otherEntity?index]>\n <#assign otherCName=otherEntity.className>\n <#assign exampleClass=\"${otherEntity.className}Example\">\n <@call this.addImport(\"${examplePackageName}.${exampleClass}\")/>\n <#if this.projectFeature.lombokEnabled>\n @Data\n @EqualsAndHashCode(callSuper=true)\n </#if>\n public static class ${otherCName}VO extends AbstractVO {\n\n <#--主键字段-->\n <#assign pkField=otherEntity.pkField>\n <#--字段名转下划线大写-->\n <#assign pkFieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(pkField.jfieldName,true)>\n @ApiModelProperty(notes = ${exampleClass}.N_${pkFieldNameSnakeCase}, example = ${exampleClass}.E_${pkFieldNameSnakeCase})\n private ${pkField.jfieldType} ${pkField.jfieldName};\n\n <#--多对多级联扩展,列表展示字段-->\n <#list mtmCascadeExts as mtmCascadeExt>\n <#assign field=mtmCascadeExt.cascadeField>\n <#--import字段类型-->\n <@call this.addFieldTypeImport(field)/>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(field.jfieldName,true)>\n <#if field.dicType??>\n <@call this.addConstImport(field.dicType)/>\n </#if>\n @ApiModelProperty(notes = ${exampleClass}.N_${jfieldNameSnakeCase}, example = ${exampleClass}.E_${jfieldNameSnakeCase}<#if field.dicType??>, allowableValues = ${field.dicType}.VALUES_STR</#if>)\n <#if field.jfieldType == JFieldType.DATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATE.getJavaType()\n || field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"com.fasterxml.jackson.annotation.JsonFormat\")/>\n @JsonFormat(pattern = ${guessDateFormat(field)}, timezone=\"GMT+8\")\n </#if>\n private ${field.jfieldType} ${field.jfieldName};\n\n </#list>\n\n <#if !this.projectFeature.lombokEnabled>\n <#--主键字段:getter-setter方法-->\n <@call JavaTemplateFunction.printGetterSetter(pkField,2)/>\n <#--多对多级联扩展,列表展示字段:getter-setter方法-->\n <#list mtmCascadeExts as mtmCascadeExt>\n <#assign field=mtmCascadeExt.cascadeField>\n <@call JavaTemplateFunction.printGetterSetter(field,2)/>\n </#list>\n </#if>\n }\n\n</#list>\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${voPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(134,'__dir.ftl','/{coreModule}/src/main/java/{packageName}/service/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(135,'__{ChartName}Service.java.ftl','/{coreModule}/src/main/java/{packageName}/service/{module}',1,4,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}Service.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(136,'__{ClassName}Service.java.ftl','/{coreModule}/src/main/java/{packageName}/service/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}Service.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(137,'{ChartName}Service.java.ftl','/{coreModule}/src/main/java/{packageName}/service/{module}',1,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#include \"/abstracted/chartItem.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.addImport(\"${daoPackageName}.${this.chartName}DAO\")/>\n<@call this.addImport(\"${qoPackageName}.${this.chartName}QO\")/>\n<@call this.addImport(\"${voPackageName}.${this.chartName}VO\")/>\n<@call this.addImport(\"org.springframework.beans.factory.annotation.Autowired\")/>\n<@call this.addImport(\"org.springframework.stereotype.Service\")/>\n<@call this.printClassCom(\"【${this.title}】图表查询服务\")/>\n@Service\npublic class ${this.chartName}Service {\n\n @Autowired\n private ${this.chartName}DAO ${this.chartNameLower}DAO;\n\n<#if isChartType(ChartType.DETAIL_LIST) || isChartType(ChartType.AGG_TABLE)>\n /**\n * 查询明细表\n *\n * @param qo\n * @return\n */\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.PageVO\")/>\n public PageVO<${this.chartName}VO> findList(${this.chartName}QO qo) {\n <#if paramedWhere?hasContent || filteredHaving?hasContent>\n this.initQueryParam(qo);\n </#if>\n List<${this.chartName}VO> list;\n int count = ${this.chartNameLower}DAO.selectCount(qo);\n if (count > 0) {\n list = ${this.chartNameLower}DAO.selectList(qo);\n } else {\n <@call this.addImport(\"java.util.ArrayList\")/>\n list = new ArrayList<>();\n }\n PageVO<${this.chartName}VO> pageVO = new PageVO<>(list, qo.getPageNo(), qo.getPageSize(), count);\n return pageVO;\n }\n\n<#else>\n /**\n * 查询图表数据\n *\n * @param qo\n * @return\n */\n public List<Object[]> findChartData(${this.chartName}QO qo) {\n <#if paramedWhere?hasContent || filteredHaving?hasContent>\n this.initQueryParam(qo);\n </#if>\n List<${this.chartName}VO> list = ${this.chartNameLower}DAO.selectList(qo);\n return this.convertChartData(list);\n }\n\n /**\n * 图表数据转换\n *\n * @param list\n * @return\n */\n private static List<Object[]> convertChartData(List<${this.chartName}VO> list) {\n <@call this.addImport(\"java.util.LinkedList\")/>\n List<Object[]> result = new LinkedList<>();\n <#-- 柱线图的数据转换 -->\n <#if isChartType(ChartType.BAR_LINE)>\n <#-- 模式1 -->\n <#if barLineParamMode == 1>\n <@call this.addImport(\"${this.commonPackage}.util.ChartDataUtil\")/>\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.Chart2DimensionVO\")/>\n <@call this.addImport(\"java.util.ArrayList\")/>\n List<Object> dimension2Values = ChartDataUtil.getDistinctValues(list, Chart2DimensionVO::fetchDimension2);\n List<Object> header = new ArrayList<>();\n header.add(${this.chartName}VO.header0());\n header.addAll(dimension2Values);\n result.add(header.toArray());\n List<Object[]> datas = ChartDataUtil.convert2DimensionMetrix(list, dimension2Values);\n result.addAll(datas);\n <#-- 模式2 -->\n <#elseIf barLineParamMode == 2>\n result.add(${this.chartName}VO.header());\n for (${this.chartName}VO vo : list) {\n result.add(vo.dataArray());\n }\n </#if>\n <#elseIf isChartType(ChartType.PIE)>\n result.add(${this.chartName}VO.header());\n for (${this.chartName}VO vo : list) {\n result.add(vo.dataArray());\n }\n </#if>\n return result;\n }\n\n</#if>\n<#-- 打印字段过滤值 -->\n<#function printFilterValue jfieldType value>\n <#if jfieldType == JFieldType.STRING.getJavaType()>\n <#return \"\\\"${value}\\\"\">\n <#elseIf jfieldType == JFieldType.BOOLEAN.getJavaType()>\n <#return \"${value}\">\n <#elseIf jfieldType == JFieldType.INTEGER.getJavaType()>\n <#return \"${value}\">\n <#elseIf jfieldType == JFieldType.SHORT.getJavaType()>\n <#return \"${value}\">\n <#elseIf jfieldType == JFieldType.LONG.getJavaType()>\n <#return \"${value}L\">\n <#elseIf jfieldType == JFieldType.DOUBLE.getJavaType()>\n <#return \"${value}d\">\n <#elseIf jfieldType == JFieldType.FLOAT.getJavaType()>\n <#return \"${value}f\">\n <#elseIf jfieldType == JFieldType.BIGDECIMAL.getJavaType()>\n <@call this.addImport(\"java.math.BigDecimal\")/>\n <#return \"new BigDecimal(\\\"${value}\\\")\">\n <#elseIf jfieldType == JFieldType.DATE.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n <#return \"DateUtil.parseDate(\\\"${value}\\\")\">\n <#elseIf jfieldType == JFieldType.LOCALDATE.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n <#return \"DateUtil.parseLocalDate(\\\"${value}\\\")\">\n <#elseIf jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n <#return \"DateUtil.parseLocalDateTime(\\\"${value}\\\")\">\n </#if>\n</#function>\n<#if this.chartSource.whereMap?hasContent>\n /**\n * 初始化固定查询参数\n *\n * @param qo\n */\n private void initQueryParam(${this.chartName}QO qo) {\n <#list paramedWhere as where>\n <#assign jfieldType=where.field.jfieldType>\n <#if FilterOperator.CONTAIN.getValue() == where.filterOperator\n || FilterOperator.NOT_CONTAIN.getValue() == where.filterOperator>\n <@call this.addImport(\"com.google.common.collect.Lists\")/>\n qo.setWhereParam${where?counter}(Lists.newArrayList(\n <#list where.filterValue as filterValue>\n ${printFilterValue(jfieldType,filterValue)}<#if filterValue?hasNext>,</#if>\n </#list>\n ));\n <#elseIf FilterOperator.BETWEEN.getValue() == where.filterOperator\n || FilterOperator.IS_NOW.getValue() == where.filterOperator\n || FilterOperator.BEFORE_TIME.getValue() == where.filterOperator\n || FilterOperator.AFTER_TIME.getValue() == where.filterOperator>\n qo.setWhereParam${where?counter}Start(${printFilterValue(jfieldType,where.filterValue[0])});\n qo.setWhereParam${where?counter}End(${printFilterValue(jfieldType,where.filterValue[1])});\n <#else>\n qo.setWhereParam${where?counter}(${printFilterValue(jfieldType,where.filterValue[0])});\n </#if>\n </#list>\n <#list filteredHaving as having>\n <#assign jfieldType=convertMetricsFieldType(having.parent)>\n <#if FilterOperator.CONTAIN.getValue() == having.filterOperator\n || FilterOperator.NOT_CONTAIN.getValue() == having.filterOperator>\n <@call this.addImport(\"com.google.common.collect.Lists\")/>\n qo.setHavingParam${having?counter}(Lists.newArrayList(\n <#list having.filterValue as filterValue>\n ${printFilterValue(jfieldType,filterValue)}<#if filterValue?hasNext>,</#if>\n </#list>\n ));\n <#elseIf FilterOperator.BETWEEN.getValue() == having.filterOperator\n || FilterOperator.IS_NOW.getValue() == having.filterOperator\n || FilterOperator.BEFORE_TIME.getValue() == having.filterOperator\n || FilterOperator.AFTER_TIME.getValue() == having.filterOperator>\n qo.setHavingParam${having?counter}Start(${printFilterValue(jfieldType,having.filterValue[0])});\n qo.setHavingParam${having?counter}End(${printFilterValue(jfieldType,having.filterValue[1])});\n <#else>\n qo.setHavingParam${having?counter}(${printFilterValue(jfieldType,having.filterValue[0])});\n </#if>\n </#list>\n }\n</#if>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${servicePackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(138,'{ClassName}Service.java.ftl','/{coreModule}/src/main/java/{packageName}/service/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/mtmForOpp.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForList.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForShow.ftl\">\n<#include \"/abstracted/guessDefaultJfieldValue.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.constant.ErrorCode\")/>\n<@call this.addImport(\"${this.commonPackage}.exception.BusinessException\")/>\n<@call this.addImport(\"${dtoPackageName}.${this.className}AddDTO\")/>\n<@call this.addImport(\"${qoPackageName}.${this.className}QO\")/>\n<@call this.addImport(\"${voPackageName}.${this.className}ListVO\")/>\n<@call this.addImport(\"${dtoPackageName}.${this.className}UpdateDTO\")/>\n<@call this.addImport(\"${mapperPackageName}.${this.className}Mapper\")/>\n<@call this.addImport(\"${poPackageName}.${this.className}PO\")/>\n<@call this.addImport(\"${voPackageName}.${this.className}ShowVO\")/>\n<@call this.addImport(\"org.springframework.beans.factory.annotation.Autowired\")/>\n<@call this.addImport(\"org.springframework.stereotype.Service\")/>\n<@call this.addImport(\"org.springframework.transaction.annotation.Transactional\")/>\n<@call this.printClassCom(\"【${this.title}】增删改查服务\")/>\n@Service\npublic class ${this.className}Service {\n\n<#-- 引入当前实体的DAO -->\n<@call this.addAutowired(\"${daoPackageName}\" \"${this.className}DAO\")/>\n<#-- 引入多对多关联实体的DAO(当前持有) -->\n<#list this.holds! as otherEntity,mtm>\n <#assign otherCName=otherEntity.className>\n <@call this.addAutowired(\"${daoPackageName}\" \"${otherCName}DAO\")/>\n</#list>\n<#-- 引入多对多关联实体的DAO(被对方持有) -->\n<#list mtmEntitiesForOpp as otherEntity>\n <@call this.addAutowired(\"${daoPackageName}\" \"${otherEntity.className}DAO\")/>\n</#list>\n<#-- 引入外键对应的DAO (插入字段对应的外键)-->\n<#list this.insertFields as id,field>\n <#if field.foreignKey>\n <@call this.addAutowired(\"${daoPackageName}\" \"${field.foreignEntity.className}DAO\")/>\n </#if>\n</#list>\n<#-- 引入外键对应的DAO (更新字段对应的外键)-->\n<#list this.updateFields as id,field>\n <#if field.foreignKey>\n <@call this.addAutowired(\"${daoPackageName}\" \"${field.foreignEntity.className}DAO\")/>\n </#if>\n</#list>\n<#-- 被其他实体外键关联时,引入其他实体DAO -->\n<#list this.foreignEntities! as foreignEntity>\n <@call this.addAutowired(\"${daoPackageName}\" \"${foreignEntity.className}DAO\")/>\n</#list>\n<#-- 当前实体的外键字段存在级联扩展时,引入对应实体的DAO -->\n<#list this.fkFields as id,field>\n <#if field.cascadeListExts?? && field.cascadeListExts?size &gt; 0>\n <@call this.addAutowired(\"${daoPackageName}\" \"${field.foreignEntity.className}DAO\")/>\n </#if>\n</#list>\n<@call this.printAutowired()/>\n\n<#if this.metaEntity.checkUniqueIndexes?? && this.metaEntity.checkUniqueIndexes?size &gt; 0>\n /**\n * 校验数据唯一性\n *\n * @param ${this.classNameLower}\n * @param isUpdate 是否更新校验\n */\n private void checkUnique(${this.className}PO ${this.classNameLower}, boolean isUpdate) {\n <#list this.metaEntity.checkUniqueIndexes as index>\n <#assign suffix=(index?index == 0)?string(\'\',\'\'+index?index)>\n <#assign params=\'\'>\n <#list index.fields as field>\n <#assign params+=this.classNameLower+\'.get\'+field.jfieldName?capFirst+\'(), \'>\n </#list>\n if (${this.classNameLower}DAO.notUnique${suffix}(${params}isUpdate ? ${this.classNameLower}.get${this.idUpper}() : null)) {\n throw new BusinessException(ErrorCode.DUPLICATE_KEY);\n }\n </#list>\n }\n\n</#if>\n<#-- 抽象出公共方法【校验外键字段对应实体是否存在】 -->\n<#macro checkForeignKeys fields>\n <#list fields as id,field>\n <#if field.foreignKey>\n <@call this.addImport(\"org.springframework.util.Assert\")/>\n <#assign foreigncName=lowerFirstWord(field.foreignEntity.className)>\n if (${this.classNameLower}.get${field.jfieldName?capFirst}() != null) {\n Assert.isTrue(${foreigncName}DAO.exist(${this.classNameLower}.get${field.jfieldName?capFirst}()), \"${field.fieldDesc}有误\");\n }\n </#if>\n </#list>\n</#macro>\n\n /**\n * 新增【${this.title}】\n *\n * @param ${this.classNameLower}DTO\n * @return\n */\n @Transactional(rollbackFor = RuntimeException.class)\n public ${this.className}PO save(${this.className}AddDTO ${this.classNameLower}DTO) {\n ${this.className}PO ${this.classNameLower} = ${this.className}Mapper.INSTANCE.fromAddDTO(${this.classNameLower}DTO);\n <@checkForeignKeys this.insertFields/>\n<#if this.metaEntity.checkUniqueIndexes?? && this.metaEntity.checkUniqueIndexes?size &gt; 0>\n // 唯一性校验\n this.checkUnique(${this.classNameLower}, false);\n</#if>\n<#-- addDTO中不存在并且不能为空的字段,赋初始值 -->\n<#list this.fields as id,field>\n <#if !field.insert && field.notNull && field.specialField?default(\"\")?length == 0>\n <#if !field.primaryKey>\n ${this.classNameLower}.set${field.jfieldName?capFirst}(${guessDefaultJfieldValue(field.jfieldType)});\n <#elseIf field.pkStrategy == PrimaryKeyStrategy.UUID_16.getValue()>\n <@call this.addImport(\"${this.commonPackage}.util.UUIDUtil\")/>\n ${this.classNameLower}.set${field.jfieldName?capFirst}(UUIDUtil.getUUID16());\n <#elseIf field.pkStrategy == PrimaryKeyStrategy.UUID_32.getValue()>\n <@call this.addImport(\"${this.commonPackage}.util.UUIDUtil\")/>\n ${this.classNameLower}.set${field.jfieldName?capFirst}(UUIDUtil.getUUID());\n <#elseIf field.pkStrategy == PrimaryKeyStrategy.NONE.getValue()>\n // TODO 请手动给主键赋值\n // ${this.classNameLower}.set${field.jfieldName?capFirst}();\n </#if>\n </#if>\n</#list>\n ${this.classNameLower}DAO.save(${this.classNameLower});\n<#list this.holds! as otherEntity,mtm>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"org.apache.commons.collections4.CollectionUtils\")/>\n <#assign otherPk=otherEntity.pkField>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.withinEntity>\n List<${otherPk.jfieldType}> ${othercName}List = ${this.classNameLower}DTO.get${otherCName}List();\n if (CollectionUtils.isNotEmpty(${othercName}List)) {\n this.doAdd${otherCName}(${this.classNameLower}.get${this.idUpper}(), ${othercName}List.toArray(new ${otherPk.jfieldType}[0]));\n }\n </#if>\n</#list>\n return ${this.classNameLower};\n }\n\n<#if this.entityFeature.excelImport>\n /**\n * 批量新增【${this.title}】\n *\n * @param list\n * @return\n */\n @Transactional(rollbackFor = RuntimeException.class)\n <@call this.addImport(\"java.util.List\")/>\n public int batchSave(List<${this.className}AddDTO> list) {\n <@call this.addImport(\"org.apache.commons.collections4.CollectionUtils\")/>\n if (CollectionUtils.isEmpty(list)) {\n return 0;\n }\n for (${this.className}AddDTO addDTO : list) {\n this.save(addDTO);\n }\n return list.size();\n }\n\n</#if>\n /**\n * 修改【${this.title}】\n *\n * @param ${this.classNameLower}UpdateDTO\n * @return\n */\n @Transactional(rollbackFor = RuntimeException.class)\n <#if this.metaEntity.versionField??>\n <@call this.addImport(\"${this.commonPackage}.optimistic.OptimisticLock\")/>\n @OptimisticLock\n </#if>\n public ${this.className}PO update(${this.className}UpdateDTO ${this.classNameLower}UpdateDTO) {\n ${this.type} ${this.id} = ${this.classNameLower}UpdateDTO.get${this.idUpper}();\n ${this.className}PO ${this.classNameLower} = this.get${this.className}(${this.id}, true);\n ${this.className}Mapper.INSTANCE.setUpdateDTO(${this.classNameLower}, ${this.classNameLower}UpdateDTO);\n <@checkForeignKeys this.updateFields/>\n<#if this.metaEntity.checkUniqueIndexes?? && this.metaEntity.checkUniqueIndexes?size &gt; 0>\n // 唯一性校验\n this.checkUnique(${this.classNameLower}, true);\n</#if>\n ${this.classNameLower}DAO.update(${this.classNameLower});\n<#list this.holds! as otherEntity,mtm>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"org.apache.commons.collections4.CollectionUtils\")/>\n <#assign otherPk=otherEntity.pkField>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.withinEntity>\n List<${otherPk.jfieldType}> ${othercName}List = ${this.classNameLower}UpdateDTO.get${otherCName}List();\n if (${othercName}List != null) {\n this.set${otherCName}(${this.classNameLower}.get${this.idUpper}(), ${othercName}List.toArray(new ${otherPk.jfieldType}[]{}));\n }\n </#if>\n</#list>\n return ${this.classNameLower};\n }\n\n<#if this.pageSign>\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.PageVO\")/>\n /**\n * 查询分页列表\n *\n * @param ${this.classNameLower}QO\n * @return\n */\n public PageVO<${this.className}ListVO> list(${this.className}QO ${this.classNameLower}QO) {\n PageVO<${this.className}ListVO> page = ${this.classNameLower}DAO.findByPage(${this.classNameLower}QO);\n <#if mtmCascadeEntitiesForList?hasContent>\n for (${this.className}ListVO listVO : page.getList()) {\n <#list mtmCascadeEntitiesForList as otherEntity>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call this.addImport(\"${mapperPackageName}.${otherCName}Mapper\")/>\n listVO.set${otherCName}List(${otherCName}Mapper.INSTANCE.to${otherCName}VOFor${this.className}List(\n ${othercName}DAO.findBy${this.className}(listVO.get${this.idUpper}())));\n </#list>\n }\n </#if>\n return page;\n }\n<#else>\n<@call this.addImport(\"java.util.List\")/>\n /**\n * 查询列表\n *\n * @param ${this.classNameLower}QO\n * @return\n */\n public List<${this.className}ListVO> list(${this.className}QO ${this.classNameLower}QO) {\n List<${this.className}ListVO> list = ${this.classNameLower}DAO.findListByQuery(${this.classNameLower}QO);\n <#if mtmCascadeEntitiesForList?hasContent>\n for (${this.className}ListVO listVO : list) {\n <#list mtmCascadeEntitiesForList as otherEntity>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call this.addImport(\"${mapperPackageName}.${otherCName}Mapper\")/>\n listVO.set${otherCName}List(${otherCName}Mapper.INSTANCE.to${otherCName}VOFor${this.className}List(\n ${othercName}DAO.findBy${this.className}(listVO.get${this.idUpper}())));\n </#list>\n }\n </#if>\n return list;\n }\n</#if>\n\n<#if this.titleField??>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.OptionVO\")/>\n <@call this.addImport(\"${this.commonPackage}.pojo.qo.OptionQO\")/>\n /**\n * 查询【${this.title}】选项列表\n *\n * @return\n */\n public List<OptionVO<${this.type}, ${this.titleField.jfieldType}>> findOptions(OptionQO<${this.type}, ${this.titleField.jfieldType}> qo) {\n List<OptionVO<${this.type}, ${this.titleField.jfieldType}>> options = ${this.classNameLower}DAO.findOptions(qo);\n return options;\n }\n\n</#if>\n<#if this.holds!?hasContent>\n /**\n * 根据主键获取【${this.title}】\n * 不获取多对多级联对象\n * @param ${this.id} 主键\n * @param force 是否强制获取\n * @return\n */\n public ${this.className}PO get${this.className}(${this.type} ${this.id}, boolean force) {\n <#assign withFalseCode=\"\">\n <#list this.holds! as otherEntity,mtm>\n <#assign withFalseCode=withFalseCode+\"false, \">\n </#list>\n return this.get${this.className}(${this.id}, ${withFalseCode}force);\n }\n\n</#if>\n /**\n * 根据主键获取【${this.title}】\n *\n * @param ${this.id} 主键\n<#assign withHoldParam=\"\">\n<#list this.holds! as otherEntity,mtm>\n <#assign otherCName=otherEntity.className>\n <#assign withParamName=\"with\"+otherCName>\n <#assign withHoldParam=withHoldParam+\"boolean with\"+otherCName+\", \">\n * @param ${withParamName} 是否级联获取【${otherEntity.title}】\n</#list>\n * @param force 是否强制获取\n * @return\n */\n public ${this.className}PO get${this.className}(${this.type} ${this.id}, ${withHoldParam}boolean force) {\n ${this.className}PO ${this.classNameLower} = ${this.classNameLower}DAO.findById(${this.id});\n if (force && ${this.classNameLower} == null) {\n throw new BusinessException(ErrorCode.RECORD_NOT_FIND);\n }\n<#list this.holds! as otherEntity,mtm>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n if (with${otherCName}) {\n ${this.classNameLower}.set${otherCName}POList(${othercName}DAO.findBy${this.className}(${this.id}));\n }\n</#list>\n return ${this.classNameLower};\n }\n\n\n /**\n * 查询【${this.title}】详情\n *\n * @param ${this.id}\n * @return\n */\n public ${this.className}ShowVO show(${this.type} ${this.id}) {\n ${this.className}PO ${this.classNameLower} = this.get${this.className}(${this.id}, true);\n ${this.className}ShowVO showVO = ${this.className}Mapper.INSTANCE.toShowVO(${this.classNameLower});\n<#--外键级联扩展,详情展示-->\n<#list this.fkFields as id,field>\n <#if field.cascadeShowExts?? && field.cascadeShowExts?size &gt; 0>\n <#assign otherCName=field.foreignEntity.className>\n <#assign othercName=lowerFirstWord(field.foreignEntity.className)>\n <@call this.addImport(\"${poPackageName}.${otherCName}PO\")/>\n if (${this.classNameLower}.get${field.jfieldName?capFirst}() != null) {\n ${otherCName}PO _${othercName}PO = ${othercName}DAO.findById(${this.classNameLower}.get${field.jfieldName?capFirst}());\n <#list field.cascadeShowExts as cascadeExt>\n showVO.set${cascadeExt.alias?capFirst}(_${othercName}PO.get${cascadeExt.cascadeField.jfieldName?capFirst}());\n </#list>\n }\n </#if>\n</#list>\n<#--多对多随实体一起维护并且未设置级联扩展时,需要返回对方的id列表-->\n<#list this.holds! as otherEntity,mtm>\n <#if mtm.getEntityFeature(this.entityId).withinEntity\n && !mtmCascadeEntitiesForShow?seqContains(otherEntity)>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call this.addImport(\"java.util.stream.Collectors\")/>\n // 设置【${otherEntity.title}】主键列表\n showVO.set${otherCName}List(${othercName}DAO.findBy${this.className}(${this.id})\n .stream()\n .map(t -> t.get${otherEntity.pkField.jfieldName?capFirst}())\n .collect(Collectors.toList()));\n </#if>\n</#list>\n<#--多对多级联扩展详情展示-->\n<#list mtmCascadeEntitiesForShow as otherEntity>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@call this.addImport(\"${mapperPackageName}.${otherCName}Mapper\")/>\n // 设置【${otherEntity.title}】列表\n showVO.set${otherCName}List(${otherCName}Mapper.INSTANCE.to${otherCName}VOFor${this.className}Show(\n ${othercName}DAO.findBy${this.className}(${this.id})));\n</#list>\n return showVO;\n }\n\n /**\n * 删除【${this.title}】\n *\n * @param ${this.id}s\n * @return\n */\n @Transactional(rollbackFor = RuntimeException.class)\n public int delete(${this.type}... ${this.id}s) {\n int count = 0;\n for (${this.type} ${this.id} : ${this.id}s) {\n<#list this.foreignEntities! as foreignEntity>\n <#assign foreignCName=foreignEntity.className>\n this.checkDeleteBy${foreignCName}(${this.id});\n</#list>\n<#list mtmEntitiesForOpp as otherEntity>\n <#assign otherCName=otherEntity.className>\n // 校验是否存在【${otherEntity.title}】关联\n this.checkDeleteBy${otherCName}(${this.id});\n</#list>\n count += ${this.classNameLower}DAO.delete(${this.id});\n }\n return count;\n }\n\n<#list this.foreignEntities! as foreignEntity>\n <#assign foreignCName=foreignEntity.className>\n <#assign foreigncName=lowerFirstWord(foreignEntity.className)>\n <#assign alreadyFind=false>\n /**\n * 校验是否存在【${foreignEntity.title}】关联\n *\n * @param ${this.id}\n */\n private void checkDeleteBy${foreignCName}(${this.type} ${this.id}) {\n <#list this.foreignFields as foreignField>\n <#if foreignField.entityId == foreignEntity.entityId>\n <#if !alreadyFind>int </#if>count = ${foreigncName}DAO.getCountBy${foreignField.jfieldName?capFirst}(${this.id});\n if (count > 0) {\n throw new BusinessException(ErrorCode.CASCADE_DELETE_ERROR);\n }\n <#assign alreadyFind=true>\n </#if>\n </#list>\n }\n\n</#list>\n<#list mtmEntitiesForOpp as otherEntity>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n /**\n * 校验是否存在【${otherEntity.title}】关联\n *\n * @param ${this.id}\n */\n private void checkDeleteBy${otherCName}(${this.type} ${this.id}) {\n int count = ${othercName}DAO.getCountBy${this.className}(${this.id});\n if (count > 0) {\n throw new BusinessException(ErrorCode.CASCADE_DELETE_ERROR);\n }\n }\n\n</#list>\n<#list this.holds! as otherEntity,mtm>\n <@call this.addImport(\"org.apache.commons.lang3.ArrayUtils\")/>\n <#assign otherPk=otherEntity.pkField>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign otherFkId=mtm.getFkAlias(otherEntity.entityId,false)>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n /**\n * 执行【${otherEntity.title}】添加\n *\n * @param ${this.id}\n * @param ${otherFkId}\n * @return\n */\n private int doAdd${otherCName}(${this.type} ${this.id}, ${otherPk.jfieldType}... ${otherFkId}) {\n int count = 0;\n for (${otherPk.jfieldType} _id : ${otherFkId}) {\n if (${othercName}DAO.exist(_id)) {\n count += ${this.classNameLower}DAO.add${otherCName}(${this.id}, _id);\n }\n }\n return count;\n }\n\n <#if entityFeature.addRemove>\n /**\n * 添加【${otherEntity.title}】\n *\n * @param ${this.id}\n * @param ${otherFkId}\n * @return\n */\n @Transactional(rollbackFor = RuntimeException.class)\n public int add${otherCName}(${this.type} ${this.id}, ${otherPk.jfieldType}... ${otherFkId}) {\n ${this.className}PO ${this.classNameLower} = this.get${this.className}(${this.id}, true);\n if (ArrayUtils.isEmpty(${otherFkId})) {\n throw new BusinessException(ErrorCode.PARAM_IS_NULL);\n }\n return doAdd${otherCName}(${this.id}, ${otherFkId});\n }\n\n /**\n * 移除【${otherEntity.title}】\n *\n * @param ${this.id}\n * @param ${otherFkId}\n * @return\n */\n @Transactional(rollbackFor = RuntimeException.class)\n public int remove${otherCName}(${this.type} ${this.id}, ${otherPk.jfieldType}... ${otherFkId}) {\n ${this.className}PO ${this.classNameLower} = this.get${this.className}(${this.id}, true);\n if (ArrayUtils.isEmpty(${otherFkId})) {\n throw new BusinessException(ErrorCode.PARAM_IS_NULL);\n }\n return ${this.classNameLower}DAO.remove${otherCName}(${this.id}, ${otherFkId});\n }\n\n </#if>\n <#if entityFeature.set || entityFeature.withinEntity>\n /**\n * 设置【${otherEntity.title}】\n *\n * @param ${this.id}\n * @param ${otherFkId}\n * @return\n */\n @Transactional(rollbackFor = RuntimeException.class)\n public int set${otherCName}(${this.type} ${this.id}, ${otherPk.jfieldType}[] ${otherFkId}) {\n ${this.className}PO ${this.classNameLower} = this.get${this.className}(${this.id}, true);\n ${this.classNameLower}DAO.removeAll${otherCName}(${this.id});\n if (ArrayUtils.isEmpty(${otherFkId})) {\n return 0;\n }\n return doAdd${otherCName}(${this.id}, ${otherFkId});\n }\n\n </#if>\n</#list>\n\n}\n\n</#assign>\n<#--开始渲染代码-->\npackage ${servicePackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(139,'messages.properties.ftl','/{coreModule}/src/main/resources',1,1,1,'<#include \"/abstracted/common.ftl\">\n# \\u82F1\\u6587\\u8D44\\u6E90\\u6587\\u4EF6\nreply.success=success\nerror.data_format_error=data format error\nerror.json_serialize_error=json serialize error\nerror.json_deserialize_error=json deserialize error\nerror.optimistic_lock=update failure by optimistic lock\nerror.internal_server_error=internal server error\nerror.err_validation=validation error\nerror.concurrency_failure=concurrency failure\nerror.method_not_supported=method not supported\nerror.duplicate_key=duplicate key error\nerror.record_not_find=record not find\nerror.param_is_null=param is null\nerror.cascade_delete_error=cascade delete error\n\n${this.commonPackage}.validator.Const=Constant invalid\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(140,'messages_zh_CN.properties.ftl','/{coreModule}/src/main/resources',1,1,1,'<#include \"/abstracted/common.ftl\">\n# \\u9ED8\\u8BA4\\u56FD\\u9645\\u5316\\u8D44\\u6E90\\u6587\\u4EF6\\uFF0C\\u9ED8\\u8BA4\\u4E2D\\u6587\nreply.success=\\u6210\\u529F\nerror.data_format_error=\\u65E5\\u671F\\u683C\\u5F0F\\u6709\\u8BEF\nerror.json_serialize_error=json\\u5E8F\\u5217\\u5316\\u5F02\\u5E38\nerror.json_deserialize_error=json\\u53CD\\u5E8F\\u5217\\u5316\\u5F02\\u5E38\nerror.optimistic_lock=\\u66F4\\u65B0\\u64CD\\u4F5C\\u4E50\\u89C2\\u9501\\u5F02\\u5E38\nerror.internal_server_error=\\u7CFB\\u7EDF\\u5185\\u90E8\\u9519\\u8BEF\nerror.err_validation=\\u53C2\\u6570\\u6821\\u9A8C\\u5931\\u8D25\nerror.concurrency_failure=\\u5E76\\u53D1\\u8BBF\\u95EE\\u5931\\u8D25\nerror.method_not_supported=http method\\u4E0D\\u5141\\u8BB8\nerror.duplicate_key=\\u552F\\u4E00\\u952E\\u91CD\\u590D\nerror.record_not_find=\\u8BB0\\u5F55\\u672A\\u627E\\u5230\nerror.param_is_null=\\u53C2\\u6570\\u4E3A\\u7A7A\nerror.cascade_delete_error=\\u7EA7\\u8054\\u5220\\u9664\\u5F02\\u5E38\n\n${this.commonPackage}.validator.Const=\\u5E38\\u91CF\\u4E0D\\u5408\\u6CD5\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(141,'mybatis-config.xml.ftl','/{coreModule}/src/main/resources',1,1,1,'<#include \"/abstracted/common.ftl\">\n<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE configuration\n PUBLIC \"-//mybatis.org//DTD Config 3.0//EN\"\n \"http://mybatis.org/dtd/mybatis-3-config.dtd\">\n<configuration>\n <settings>\n <!--开启驼峰命名转换Table:create_time到 Entity(createTime)-->\n <setting name=\"mapUnderscoreToCamelCase\" value=\"true\"/>\n </settings>\n <typeAliases>\n <package name=\"${this.commonPackage}.pojo\"/>\n <package name=\"${this.packageName}.pojo\"/>\n </typeAliases>\n <mappers>\n <package name=\"${this.packageName}.dao\"/>\n </mappers>\n</configuration>\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(142,'__{project-name}-default.properties.ftl','/{coreModule}/src/main/resources/config',1,1,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.projectNameSplit}-default.properties\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(143,'{project-name}-default.properties.ftl','/{coreModule}/src/main/resources/config',1,1,1,'# \\u9ED8\\u8BA4mybatis\\u7684\\u914D\\u7F6E\\u6587\\u4EF6\\u8DEF\\u5F84\nmybatis.config-location=classpath:mybatis-config.xml\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(144,'__dir.ftl','/{coreModule}/src/main/resources/{packageName}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${packageNamePath}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(145,'__dir.ftl','/{coreModule}/src/main/resources/{packageName}/dao/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(146,'__{ChartName}DAO.xml.ftl','/{coreModule}/src/main/resources/{packageName}/dao/{module}',1,4,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}DAO.xml\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(147,'__{ClassName}DAO.xml.ftl','/{coreModule}/src/main/resources/{packageName}/dao/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}DAO.xml\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(148,'{ChartName}DAO.xml.ftl','/{coreModule}/src/main/resources/{packageName}/dao/{module}',1,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#include \"/abstracted/mybatisForChart.ftl\">\n<#include \"/abstracted/chartItem.ftl\">\n<#-- 渲染别名 -->\n<#function renderAlias sourceItem>\n <#local chartItem = chartItemMapWrapper.get(sourceItem.sourceItemId)>\n <#return wrapMysqlKeyword(chartItem.alias)>\n</#function>\n<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n<mapper namespace=\"${daoPackageName}.${this.chartName}DAO\">\n\n<#-- 明细列sql片段 -->\n<#if isChartType(ChartType.DETAIL_LIST)>\n <sql id=\"columns\">\n <#list this.columnList as column>\n <#assign sourceItem=column.sourceItem>\n <#if sourceItem.custom>\n ${sourceItem.customContent} as ${wrapMysqlKeyword(column.alias)}<#if column?hasNext>,</#if>\n <#else>\n <#assign field=sourceItem.field>\n ${getSelectFieldWithAlias(field,\"t${sourceItem.joinIndex}\",column.alias)}<#if column?hasNext>,</#if>\n </#if>\n </#list>\n </sql>\n</#if>\n\n<#-- 过滤条件where -->\n<#if this.chartSource.whereMap?hasContent>\n <sql id=\"queryCondition\">\n <#list paramedWhere as where>\n <#assign field=where.field>\n <#--in、not in查询-->\n <#if FilterOperator.CONTAIN.getValue() == where.filterOperator\n || FilterOperator.NOT_CONTAIN.getValue() == where.filterOperator>\n and t${where.joinIndex}.${wrapMysqlKeyword(field.fieldName)} ${mapperOperatorSymbol(where.filterOperator)}\n <foreach collection=\"whereParam${where?counter}\" item=\"_value\" open=\"(\" separator=\",\" close=\")\">\n ${r\'#\'}{_value}\n </foreach>\n <#--like查询-->\n <#elseIf FilterOperator.LIKE.getValue() == where.filterOperator>\n <bind name=\"whereParam${where?counter}_pattern\" value=\"\'%\' + whereParam${where?counter} + \'%\'\" />\n and t${where.joinIndex}.${wrapMysqlKeyword(field.fieldName)} ${mapperOperatorSymbol(where.filterOperator)} ${r\'#\'}{whereParam${where?counter}_pattern}\n <#--between查询-->\n <#elseIf FilterOperator.BETWEEN.getValue() == where.filterOperator\n || FilterOperator.IS_NOW.getValue() == where.filterOperator\n || FilterOperator.BEFORE_TIME.getValue() == where.filterOperator\n || FilterOperator.AFTER_TIME.getValue() == where.filterOperator>\n and t${where.joinIndex}.${wrapMysqlKeyword(field.fieldName)} ${mapperOperatorSymbol(where.filterOperator)} ${r\'#\'}{whereParam${where?counter}Start} and ${r\'#\'}{whereParam${where?counter}End}\n <#else>\n and t${where.joinIndex}.${wrapMysqlKeyword(field.fieldName)} ${mapperOperatorSymbol(where.filterOperator)} ${r\'#\'}{whereParam${where?counter}}\n </#if>\n </#list>\n <#list unparamedWhere as where>\n <#if where.custom>\n and ${where.customContent}\n <#else>\n <#--is null 、is not null查询-->\n <#assign field=where.field>\n and t${where.joinIndex}.${wrapMysqlKeyword(field.fieldName)} ${mapperOperatorSymbol(where.filterOperator)}\n </#if>\n </#list>\n </sql>\n\n</#if>\n<#-- 过滤条件having -->\n<#list filteredHaving>\n <sql id=\"havingCondition\">\n having\n <#items as having>\n <#assign metricsAlias = renderAlias(having.parent)>\n <#--is null 、is not null查询-->\n <#if FilterOperator.IS_NULL.getValue() == having.filterOperator\n || FilterOperator.NOT_NULL.getValue() == having.filterOperator>\n <#if !having?isFirst>and </#if>${metricsAlias} ${mapperOperatorSymbol(having.filterOperator)}\n <#--in、not in查询-->\n <#elseIf FilterOperator.CONTAIN.getValue() == having.filterOperator\n || FilterOperator.NOT_CONTAIN.getValue() == having.filterOperator>\n <#if !having?isFirst>and </#if>${metricsAlias} ${mapperOperatorSymbol(having.filterOperator)}\n <foreach collection=\"havingParam${having?counter}\" item=\"_value\" open=\"(\" separator=\",\" close=\")\">\n ${r\'#\'}{_value}\n </foreach>\n <#--like查询-->\n <#elseIf FilterOperator.LIKE.getValue() == having.filterOperator>\n <bind name=\"havingParam${having?counter}_pattern\" value=\"\'%\' + havingParam${having?counter} + \'%\'\" />\n <#if !having?isFirst>and </#if>${metricsAlias} ${mapperOperatorSymbol(having.filterOperator)} ${r\'#\'}{havingParam${having?counter}_pattern}\n <#--between查询-->\n <#elseIf FilterOperator.BETWEEN.getValue() == having.filterOperator\n || FilterOperator.IS_NOW.getValue() == having.filterOperator\n || FilterOperator.BEFORE_TIME.getValue() == having.filterOperator\n || FilterOperator.AFTER_TIME.getValue() == having.filterOperator>\n <#if !having?isFirst>and </#if>${metricsAlias} ${mapperOperatorSymbol(having.filterOperator)} ${r\'#\'}{havingParam${having?counter}Start} and ${r\'#\'}{havingParam${having?counter}End}\n <#else>\n <#if !having?isFirst>and </#if>${metricsAlias} ${mapperOperatorSymbol(having.filterOperator)} ${r\'#\'}{havingParam${having?counter}}\n </#if>\n </#items>\n </sql>\n\n</#list>\n<#-- 排序条件 -->\n<#if isChartType(ChartType.DETAIL_LIST)>\n <#list this.chartSource.detailOrderMap>\n <sql id=\"orderCondition\">\n order by\n <#items as itemId,detailOrderItem>\n <#assign detailListItem=detailOrderItem.parent>\n <#if detailListItem.custom>\n ${detailListItem.customContent} ${mapperOrderBySymbol(detailOrderItem.sortType)}<#if itemId?hasNext>,</#if>\n <#else>\n <#assign field=detailListItem.field>\n t${detailListItem.joinIndex}.${wrapMysqlKeyword(field.fieldName)} ${mapperOrderBySymbol(detailOrderItem.sortType)}<#if itemId?hasNext>,</#if>\n </#if>\n </#items>\n </sql>\n\n </#list>\n</#if>\n<#-- 查询记录数 -->\n<#if isChartType(ChartType.DETAIL_LIST)>\n <select id=\"selectCount\" parameterType=\"${this.chartName}QO\" resultType=\"int\">\n select count(1)\n from ${wrapMysqlKeyword(mainEntity.tableName)} t0\n <#list joins as join>\n ${mapperJoinSymbol(join.joinType)} ${joinTableName(join.right)} t${join.right.joinIndex}\n on t${join.left.joinIndex}.${joinFieldName(join.left)} = t${join.right.joinIndex}.${joinFieldName(join.right)}\n </#list>\n <#if this.chartSource.whereMap?hasContent>\n <where>\n <include refid=\"queryCondition\"/>\n </where>\n </#if>\n </select>\n<#elseIf isChartType(ChartType.AGG_TABLE)>\n <select id=\"selectCount\" parameterType=\"${this.chartName}QO\" resultType=\"int\">\n select count(1) from (\n select\n <#list filteredDimension as dimension>\n ${renderDimension(dimension)} as ${renderAlias(dimension)}<#if dimension?hasNext || filteredMetrics?hasContent>,</#if>\n </#list>\n <#list filteredMetrics as metrics>\n ${renderMetrics(metrics)} as ${renderAlias(metrics)}<#if metrics?hasNext>,</#if>\n </#list>\n from ${wrapMysqlKeyword(mainEntity.tableName)} t0\n <#list joins as join>\n ${mapperJoinSymbol(join.joinType)} ${joinTableName(join.right)} t${join.right.joinIndex}\n on t${join.left.joinIndex}.${joinFieldName(join.left)} = t${join.right.joinIndex}.${joinFieldName(join.right)}\n </#list>\n <#if this.chartSource.whereMap?hasContent>\n <where>\n <include refid=\"queryCondition\"/>\n </where>\n </#if>\n group by\n <#list filteredDimension as dimension>\n ${renderAlias(dimension)}<#if dimension?hasNext>,</#if>\n </#list>\n <#if filteredHaving?hasContent>\n <include refid=\"havingCondition\"/>\n </#if>\n ) tmp\n </select>\n</#if>\n\n<#-- 查询列表数据 -->\n<#if isChartType(ChartType.DETAIL_LIST)>\n <select id=\"selectList\" parameterType=\"${this.chartName}QO\" resultType=\"${this.chartName}VO\">\n select\n <include refid=\"columns\"></include>\n from ${wrapMysqlKeyword(mainEntity.tableName)} t0\n <#list joins as join>\n ${mapperJoinSymbol(join.joinType)} ${joinTableName(join.right)} t${join.right.joinIndex}\n on t${join.left.joinIndex}.${joinFieldName(join.left)} = t${join.right.joinIndex}.${joinFieldName(join.right)}\n </#list>\n <#if this.chartSource.whereMap?hasContent>\n <where>\n <include refid=\"queryCondition\"/>\n </where>\n </#if>\n <#if this.chartSource.detailOrderMap?hasContent>\n <include refid=\"orderCondition\"/>\n </#if>\n limit ${r\'#\'}{startIndex},${r\'#\'}{pageSize}\n </select>\n<#else>\n <select id=\"selectList\" parameterType=\"${this.chartName}QO\" resultType=\"${this.chartName}VO\">\n select\n <#list filteredDimension as dimension>\n ${renderDimension(dimension)} as ${renderAlias(dimension)}<#if dimension?hasNext || filteredMetrics?hasContent>,</#if>\n </#list>\n <#list filteredMetrics as metrics>\n ${renderMetrics(metrics)} as ${renderAlias(metrics)}<#if metrics?hasNext>,</#if>\n </#list>\n from ${wrapMysqlKeyword(mainEntity.tableName)} t0\n <#list joins as join>\n ${mapperJoinSymbol(join.joinType)} ${joinTableName(join.right)} t${join.right.joinIndex}\n on t${join.left.joinIndex}.${joinFieldName(join.left)} = t${join.right.joinIndex}.${joinFieldName(join.right)}\n </#list>\n <#if this.chartSource.whereMap?hasContent>\n <where>\n <include refid=\"queryCondition\"/>\n </where>\n </#if>\n group by\n <#list filteredDimension as dimension>\n ${renderAlias(dimension)}<#if dimension?hasNext>,</#if>\n </#list>\n <#if filteredHaving?hasContent>\n <include refid=\"havingCondition\"/>\n </#if>\n <#if filteredAggOrder?hasContent>\n order by\n <#list filteredAggOrder as aggOrder>\n ${renderAlias(aggOrder.parent)} ${mapperOrderBySymbol(aggOrder.sortType)}<#if aggOrder?hasNext>,</#if>\n </#list>\n </#if>\n <#if isChartType(ChartType.AGG_TABLE)>\n limit ${r\'#\'}{startIndex},${r\'#\'}{pageSize}\n </#if>\n </select>\n</#if>\n\n</mapper>\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(149,'{ClassName}DAO.xml.ftl','/{coreModule}/src/main/resources/{packageName}/dao/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/mybatis.ftl\">\n<#include \"/abstracted/mtmForOpp.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForQuery.ftl\">\n<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper\n PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n<mapper namespace=\"${daoPackageName}.${this.className}DAO\">\n\n <#assign wrapTableName=wrapMysqlKeyword(this.tableName)>\n <#assign wrapPkFieldName=wrapMysqlKeyword(this.pk.fieldName)>\n <#if this.delField??>\n <#assign wrapDelFieldName=wrapMysqlKeyword(this.delField.fieldName)>\n </#if>\n\n <sql id=\"${this.classNameLower}Columns\">\n <#list this.fields as id,field>\n ${getSelectFieldWithAlias(field,\"${r\'$\'}{alias}\",\"\")}<#if id?hasNext>,</#if>\n </#list>\n </sql>\n\n\n <select id=\"findById\" resultType=\"${this.className}PO\">\n select\n <include refid=\"${this.classNameLower}Columns\"><property name=\"alias\" value=\"t\"/></include>\n from ${wrapTableName} t\n <where>\n <#if delField??>\n and t.${wrapDelFieldName}=0\n </#if>\n and t.${wrapPkFieldName} = ${r\'#\'}{arg0}\n </where>\n limit 1\n </select>\n\n <select id=\"exist\" resultType=\"boolean\">\n select count(1) from ${wrapTableName}\n <where>\n <#if delField??>\n and ${wrapDelFieldName}=0\n </#if>\n and ${wrapPkFieldName} = ${r\'#\'}{arg0}\n </where>\n </select>\n\n <insert id=\"_save\" <#if this.pk.pkStrategy == PrimaryKeyStrategy.AUTO_INCREMENT.getValue()>useGeneratedKeys=\"true\" </#if>keyProperty=\"${this.id}\" parameterType=\"${this.className}PO\">\n insert into ${wrapTableName}(\n <#list this.fields as id,field>\n ${wrapMysqlKeyword(field.fieldName)}<#if id?hasNext>,</#if>\n </#list>\n ) VALUES (\n <#list this.fields as id,field>\n ${r\'#\'}{${field.jfieldName},jdbcType=${JFieldType.mapperJdbcType(field.jfieldType)}}<#if id?hasNext>,</#if>\n </#list>\n )\n </insert>\n\n\n <update id=\"_update\" parameterType=\"${this.className}PO\">\n update ${wrapTableName} set\n <#assign set_field_arr=[]>\n <#--过滤出需要设值的字段-->\n <#list this.fields as id,field>\n <#--去除主键、创建人、创建时间-->\n <#if !field.primaryKey && !MetaSpecialField.isCreatedBy(field.specialField) && !MetaSpecialField.isCreatedTime(field.specialField) >\n <#assign set_field_arr = set_field_arr + [ field ] >\n </#if>\n </#list>\n <#list set_field_arr as field>\n <#if field.specialField?? && field.specialField == MetaSpecialField.VERSION>\n ${wrapMysqlKeyword(field.fieldName)} = ${wrapMysqlKeyword(field.fieldName)}+1<#if field?hasNext>,</#if>\n <#elseIf !field.primaryKey && !MetaSpecialField.isCreatedBy(field.specialField) && !MetaSpecialField.isCreatedTime(field.specialField) >\n ${wrapMysqlKeyword(field.fieldName)}=${r\'#\'}{${field.jfieldName},jdbcType=${JFieldType.mapperJdbcType(field.jfieldType)}}<#if field?hasNext>,</#if>\n </#if>\n </#list>\n where ${wrapPkFieldName}=${r\'#\'}{${this.id},jdbcType=${JFieldType.mapperJdbcType(this.pk.jfieldType)}}\n <#if this.versionField??>\n and ${wrapMysqlKeyword(this.versionField.fieldName)}=${r\'#\'}{${this.versionField.jfieldName},jdbcType=${JFieldType.mapperJdbcType(this.versionField.jfieldType)}}\n </#if>\n <#if this.delField??>\n and ${wrapDelFieldName}=0\n </#if>\n </update>\n\n <delete id=\"delete\">\n <#if this.delField??>\n update ${wrapTableName} set ${wrapDelFieldName}=1\n where ${wrapPkFieldName}=${r\'#\'}{arg0,jdbcType=${JFieldType.mapperJdbcType(this.pk.jfieldType)}}\n and ${wrapDelFieldName}=0\n <#else>\n delete from ${wrapTableName}\n where ${wrapPkFieldName}=${r\'#\'}{arg0,jdbcType=${JFieldType.mapperJdbcType(this.pk.jfieldType)}}\n </#if>\n </delete>\n\n\n <sql id=\"queryCondition\">\n <#list this.queryFields as id,field>\n <#if QueryType.isBetween(field.queryType)>\n <#--between类型查询-->\n <if test=\"${ifNotEmptyConditionWithAlias(field.jfieldName+\'Start\',field)}\">\n and t.${wrapMysqlKeyword(field.fieldName)} >= ${r\'#\'}{${field.jfieldName}Start}\n </if>\n <if test=\"${ifNotEmptyConditionWithAlias(field.jfieldName+\'End\',field)}\">\n and t.${wrapMysqlKeyword(field.fieldName)} &lt;= ${r\'#\'}{${field.jfieldName}End}\n </if>\n <#elseIf QueryType.isIn(field.queryType)>\n <#--in类型查询-->\n <if test=\"${ifNotEmptyCondition(field)}\">\n and t.${wrapMysqlKeyword(field.fieldName)} in\n <foreach collection=\"${field.jfieldName}\" item=\"_value\" open=\"(\" separator=\",\" close=\")\">\n ${r\'#\'}{_value}\n </foreach>\n </if>\n <#elseIf QueryType.isLike(field.queryType)>\n <#--like类型查询-->\n <if test=\"${ifNotEmptyCondition(field)}\">\n <bind name=\"${field.jfieldName}_pattern\" value=\"\'%\' + ${field.jfieldName} + \'%\'\" />\n and t.${wrapMysqlKeyword(field.fieldName)} like ${r\'#\'}{${field.jfieldName}_pattern}\n </if>\n <#else>\n <#--其他类型查询-->\n <if test=\"${ifNotEmptyCondition(field)}\">\n and t.${wrapMysqlKeyword(field.fieldName)} ${QueryType.mapperSymbol(field.queryType)} ${r\'#\'}{${field.jfieldName}}\n </if>\n </#if>\n </#list>\n <#assign cascadeIndex=0>\n <#list this.fkFields as id,field>\n <#if field.cascadeQueryExts?? && field.cascadeQueryExts?size &gt; 0>\n <#assign cascadeIndex=cascadeIndex+1>\n <#assign con_ex_arr=[]>\n <#list field.cascadeQueryExts as cascadeExt>\n <#assign cascadeField=cascadeExt.cascadeField>\n <#--非between类型-->\n <#if !QueryType.isBetween(cascadeField.queryType)>\n <#assign con_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(cascadeExt.alias,false)}_con_ex\">\n <#assign con_ex_arr = con_ex_arr + [ con_ex ] >\n <bind name=\"${con_ex}\" value=\"${ifNotEmptyConditionWithAlias(cascadeExt.alias,cascadeField)}\" />\n <#else>\n <#--between类型-->\n <#assign con_start_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(cascadeExt.alias,false)}_start_con_ex\">\n <#assign con_end_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(cascadeExt.alias,false)}_end_con_ex\">\n <#assign con_ex_arr = con_ex_arr + [ con_start_ex,con_end_ex ] >\n <bind name=\"${con_start_ex}\" value=\"${ifNotEmptyConditionWithAlias(cascadeExt.alias+\'Start\',cascadeField)}\" />\n <bind name=\"${con_end_ex}\" value=\"${ifNotEmptyConditionWithAlias(cascadeExt.alias+\'End\',cascadeField)}\" />\n </#if>\n </#list>\n <if test=\"${con_ex_arr?join(\' or \')} \">\n and exists(\n select 1 from ${wrapMysqlKeyword(field.foreignEntity.tableName)} e${cascadeIndex}\n where e${cascadeIndex}.${wrapMysqlKeyword(field.foreignEntity.pkField.fieldName)} = t.${wrapMysqlKeyword(field.fieldName)}\n <#if field.foreignEntity.delField??>\n and e${cascadeIndex}.${wrapMysqlKeyword(field.foreignEntity.delField.fieldName)}=0\n </#if>\n <#list field.cascadeQueryExts as cascadeExt>\n <#assign cascadeField=cascadeExt.cascadeField>\n <#--非between类型-->\n <#if !QueryType.isBetween(cascadeField.queryType)>\n <#assign con_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(cascadeExt.alias,false)}_con_ex\">\n <if test=\"${con_ex}\">\n <#if QueryType.isLike(cascadeField.queryType)>\n <bind name=\"${cascadeExt.alias}_pattern\" value=\"\'%\' + ${cascadeExt.alias} + \'%\'\" />\n and e${cascadeIndex}.${wrapMysqlKeyword(cascadeField.fieldName)} ${QueryType.mapperSymbol(cascadeField.queryType)} ${r\'#\'}{${cascadeExt.alias}_pattern}\n <#else>\n and e${cascadeIndex}.${wrapMysqlKeyword(cascadeField.fieldName)} ${QueryType.mapperSymbol(cascadeField.queryType)} ${r\'#\'}{${cascadeExt.alias}}\n </#if>\n </if>\n <#else>\n <#--between类型-->\n <#assign con_start_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(cascadeExt.alias,false)}_start_con_ex\">\n <#assign con_end_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(cascadeExt.alias,false)}_end_con_ex\">\n <if test=\"${con_start_ex}\">\n and e${cascadeIndex}.${wrapMysqlKeyword(cascadeField.fieldName)} >= ${r\'#\'}{${cascadeExt.alias}Start}\n </if>\n <if test=\"${con_end_ex}\">\n and e${cascadeIndex}.${wrapMysqlKeyword(cascadeField.fieldName)} &lt;= ${r\'#\'}{${cascadeExt.alias}End}\n </if>\n </#if>\n </#list>\n )\n </if>\n </#if>\n </#list>\n <#list mtmCascadeEntitiesForQuery as otherEntity>\n <#assign mtmCascadeExts = groupMtmCascadeExtsForQuery[otherEntity?index]>\n <#assign mtm = mtmForQuery[otherEntity?index]>\n <#assign table_r = \'r${otherEntity?index+1}\'>\n <#assign table_m = \'m${otherEntity?index+1}\'>\n <#assign other_fk_id=mtm.getFkAlias(otherEntity.entityId,true)>\n <#assign the_fk_id=mtm.getFkAlias(this.entityId,true)>\n <#list mtmCascadeExts as mtmCascadeExt>\n <#assign con_ex_arr=[]>\n <#assign cascadeField=mtmCascadeExt.cascadeField>\n <#--非between类型-->\n <#if !QueryType.isBetween(cascadeField.queryType)>\n <#assign con_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(mtmCascadeExt.alias,false)}_con_ex\">\n <#assign con_ex_arr = con_ex_arr + [ con_ex ] >\n <bind name=\"${con_ex}\" value=\"${ifNotEmptyConditionWithAlias(mtmCascadeExt.alias,cascadeField)}\" />\n <#else>\n <#--between类型-->\n <#assign con_start_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(mtmCascadeExt.alias,false)}_start_con_ex\">\n <#assign con_end_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(mtmCascadeExt.alias,false)}_end_con_ex\">\n <#assign con_ex_arr = con_ex_arr + [ con_start_ex,con_end_ex ] >\n <bind name=\"${con_start_ex}\" value=\"${ifNotEmptyConditionWithAlias(mtmCascadeExt.alias+\'Start\',cascadeField)}\" />\n <bind name=\"${con_end_ex}\" value=\"${ifNotEmptyConditionWithAlias(mtmCascadeExt.alias+\'End\',cascadeField)}\" />\n </#if>\n </#list>\n <if test=\"${con_ex_arr?join(\' or \')} \">\n and exists(\n select 1 from ${wrapMysqlKeyword(otherEntity.tableName)} ${table_m}\n inner join ${wrapMysqlKeyword(mtm.tableName)} ${table_r}\n on ${table_m}.${wrapMysqlKeyword(otherEntity.pkField.fieldName)}=${table_r}.${other_fk_id}\n where ${table_r}.${the_fk_id}=t.${wrapPkFieldName}\n <#if otherEntity.delField??>\n and ${table_m}.${wrapMysqlKeyword(otherEntity.delField.fieldName)}=0\n </#if>\n <#list mtmCascadeExts as mtmCascadeExt>\n <#assign cascadeField=mtmCascadeExt.cascadeField>\n <#--非between类型-->\n <#if !QueryType.isBetween(cascadeField.queryType)>\n <#assign con_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(mtmCascadeExt.alias,false)}_con_ex\">\n <if test=\"${con_ex}\">\n <#if QueryType.isLike(cascadeField.queryType)>\n <bind name=\"${mtmCascadeExt.alias}_pattern\" value=\"\'%\' + ${mtmCascadeExt.alias} + \'%\'\" />\n and ${table_m}.${wrapMysqlKeyword(cascadeField.fieldName)} ${QueryType.mapperSymbol(cascadeField.queryType)} ${r\'#\'}{${mtmCascadeExt.alias}_pattern}\n <#elseIf QueryType.isIn(cascadeField.queryType)>\n and ${table_m}.${wrapMysqlKeyword(cascadeField.fieldName)} in\n <foreach collection=\"${mtmCascadeExt.alias}\" item=\"_value\" open=\"(\" separator=\",\" close=\")\">\n ${r\'#\'}{_value}\n </foreach>\n <#else>\n and ${table_m}.${wrapMysqlKeyword(cascadeField.fieldName)} ${QueryType.mapperSymbol(cascadeField.queryType)} ${r\'#\'}{${mtmCascadeExt.alias}}\n </#if>\n </if>\n <#else>\n <#--between类型-->\n <#assign con_start_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(mtmCascadeExt.alias,false)}_start_con_ex\">\n <#assign con_end_ex=\"${CommonTemplateFunction.camelCaseToSnakeCase(mtmCascadeExt.alias,false)}_end_con_ex\">\n <if test=\"${con_start_ex}\">\n and ${table_m}.${wrapMysqlKeyword(cascadeField.fieldName)} >= ${r\'#\'}{${mtmCascadeExt.alias}Start}\n </if>\n <if test=\"${con_end_ex}\">\n and ${table_m}.${wrapMysqlKeyword(cascadeField.fieldName)} &lt;= ${r\'#\'}{${mtmCascadeExt.alias}End}\n </if>\n </#if>\n </#list>\n )\n </if>\n </#list>\n </sql>\n\n <sql id=\"orderCondition\">\n order by\n <#list this.listSortFields as id,field>\n <if test=\"${field.jfieldName}SortSign != null and ${field.jfieldName}SortSign != 0\">\n t.${wrapMysqlKeyword(field.fieldName)} <if test=\"${field.jfieldName}SortSign > 0\">asc</if><if test=\"${field.jfieldName}SortSign &lt; 0\">desc</if>,\n </if>\n </#list>\n <#--默认按【操作日期/创建日期/主键】降序排序-->\n <#if this.operatedTimeField??>\n t.${wrapMysqlKeyword(this.operatedTimeField.fieldName)} desc\n <#elseIf this.createdTimeField??>\n t.${wrapMysqlKeyword(this.createdTimeField.fieldName)} desc\n <#else>\n t.${wrapPkFieldName} desc\n </#if>\n </sql>\n\n <select id=\"findCountByQuery\" parameterType=\"${this.className}QO\" resultType=\"int\">\n select count(1) from ${wrapTableName} t\n <where>\n <#if delField??>\n and t.${wrapDelFieldName}=0\n </#if>\n <include refid=\"queryCondition\"/>\n </where>\n </select>\n\n <select id=\"findListByQuery\" parameterType=\"${this.className}QO\" resultType=\"${this.className}ListVO\">\n select\n <include refid=\"${this.classNameLower}Columns\"><property name=\"alias\" value=\"t\"/></include>\n <#assign cascadeIndex=0>\n <#list this.fkFields as id,field>\n <#if field.cascadeListExts?? && field.cascadeListExts?size &gt; 0>\n <#assign cascadeIndex=cascadeIndex+1>\n <#list field.cascadeListExts as cascadeExt>\n ,c${cascadeIndex}.${wrapMysqlKeyword(cascadeExt.cascadeField.fieldName)} as ${cascadeExt.alias}\n </#list>\n </#if>\n </#list>\n from ${wrapTableName} t\n <#assign cascadeIndex=0>\n <#list this.fkFields as id,field>\n <#if field.cascadeListExts?? && field.cascadeListExts?size &gt; 0>\n <#assign cascadeIndex=cascadeIndex+1>\n left outer join ${wrapMysqlKeyword(field.foreignEntity.tableName)} c${cascadeIndex}\n on c${cascadeIndex}.${wrapMysqlKeyword(field.foreignEntity.pkField.fieldName)} = t.${wrapMysqlKeyword(field.fieldName)}\n <#if field.foreignEntity.delField??>\n and c${cascadeIndex}.${wrapMysqlKeyword(field.foreignEntity.delField.fieldName)}=0\n </#if>\n </#if>\n </#list>\n <where>\n <#if delField??>\n and t.${wrapDelFieldName}=0\n </#if>\n <include refid=\"queryCondition\"/>\n </where>\n <include refid=\"orderCondition\"/>\n <#if this.pageSign>\n limit ${r\'#\'}{startIndex},${r\'#\'}{pageSize}\n </#if>\n </select>\n\n<#if this.titleField??>\n <select id=\"findOptions\" parameterType=\"OptionQO\" resultType=\"OptionVO\">\n select\n ${getSelectFieldWithAlias(this.pk,\"t\",\"key\")},\n ${getSelectFieldWithAlias(this.titleField,\"t\",\"value\")}\n from ${wrapTableName} t\n <where>\n <#if delField??>\n and t.${wrapDelFieldName}=0\n </#if>\n <if test=\"lastKey != null\">\n and t.${wrapMysqlKeyword(this.pk.fieldName)} > ${r\'#\'}{lastKey}\n </if>\n <#if QueryType.isLike(this.titleField.queryType)>\n <#--like类型查询-->\n <if test=\"${ifNotEmptyConditionWithAlias(\"matchValue\",this.titleField)}\">\n <bind name=\"matchValue_pattern\" value=\"\'%\' + matchValue + \'%\'\" />\n and t.${wrapMysqlKeyword(this.titleField.fieldName)} like ${r\'#\'}{matchValue_pattern}\n </if>\n <#else>\n <#--其他类型查询-->\n <if test=\"${ifNotEmptyConditionWithAlias(\"matchValue\",this.titleField)}\">\n and t.${wrapMysqlKeyword(this.titleField.fieldName)} ${QueryType.mapperSymbol(this.titleField.queryType)} ${r\'#\'}{matchValue}\n </if>\n </#if>\n </where>\n order by t.${wrapMysqlKeyword(this.pk.fieldName)} asc\n limit ${r\'#\'}{limit}\n </select>\n\n</#if>\n<#list this.fkFields as id,field>\n <#assign wrapFieldName=wrapMysqlKeyword(field.fieldName)>\n <select id=\"getCountBy${field.jfieldName?capFirst}\" parameterType=\"${field.jfieldType}\" resultType=\"int\">\n select count(1)\n from ${wrapTableName} t\n where\n t.${wrapFieldName}=${r\'#\'}{arg0}\n <#if delField??>\n and t.${wrapDelFieldName}=0\n </#if>\n </select>\n\n</#list>\n<#list this.holds! as otherEntity,mtm>\n <#assign otherCName=otherEntity.className>\n <#assign otherType=otherEntity.pkField.jfieldType>\n <#assign otherFkId=mtm.getFkAlias(otherEntity.entityId,false)>\n <#assign theFkId=mtm.getFkAlias(this.entityId,false)>\n <#assign other_fk_id=mtm.getFkAlias(otherEntity.entityId,true)>\n <#assign the_fk_id=mtm.getFkAlias(this.entityId,true)>\n <#assign wrapMtmTableName=wrapMysqlKeyword(mtm.tableName)>\n <select id=\"getCountBy${otherCName}\" parameterType=\"${otherType}\" resultType=\"int\">\n select count(1)\n from ${wrapTableName} t\n inner join ${wrapMtmTableName} r\n on t.${wrapPkFieldName}=r.${the_fk_id}\n where\n r.${other_fk_id}=${r\'#\'}{arg0}\n <#if delField??>\n and t.${wrapDelFieldName}=0\n </#if>\n </select>\n\n <insert id=\"add${otherCName}\" parameterType=\"map\">\n insert into ${mtm.tableName}(\n ${the_fk_id},\n ${other_fk_id},\n created_time\n )values(\n ${r\'#\'}{${theFkId},jdbcType=${JFieldType.mapperJdbcType(this.pk.jfieldType)}},\n ${r\'#\'}{${otherFkId},jdbcType=${JFieldType.mapperJdbcType(otherType)}},\n now()\n )\n </insert>\n\n <delete id=\"remove${otherCName}\" parameterType=\"map\">\n delete from ${mtm.tableName}\n where ${the_fk_id}=${r\'#\'}{${theFkId},jdbcType=${JFieldType.mapperJdbcType(this.pk.jfieldType)}} and ${other_fk_id} in\n <foreach collection=\"${otherFkId}\" item=\"_id\" open=\"(\" separator=\",\" close=\")\">\n ${r\'#\'}{_id}\n </foreach>\n </delete>\n\n <delete id=\"removeAll${otherCName}\">\n delete from ${wrapMtmTableName}\n where ${the_fk_id}=${r\'#\'}{arg0}\n </delete>\n\n</#list>\n<#list mtmEntitiesForOpp as otherEntity>\n <#assign mtm=mtmsForOpp[otherEntity?index]/>\n <#assign otherCName=otherEntity.className>\n <#assign otherType=otherEntity.pkField.jfieldType>\n <#assign other_fk_id=mtm.getFkAlias(otherEntity.entityId,true)>\n <#assign the_fk_id=mtm.getFkAlias(this.entityId,true)>\n <#assign wrapMtmTableName=wrapMysqlKeyword(mtm.tableName)>\n <select id=\"findBy${otherCName}\" parameterType=\"${otherType}\" resultType=\"${this.className}PO\">\n select\n <include refid=\"${this.classNameLower}Columns\"><property name=\"alias\" value=\"t\"/></include>\n from ${wrapTableName} t\n inner join ${wrapMtmTableName} r\n on t.${wrapPkFieldName}=r.${the_fk_id}\n where\n r.${other_fk_id}=${r\'#\'}{arg0}\n <#if delField??>\n and t.${wrapDelFieldName}=0\n </#if>\n order by\n <#if mtm.needId>\n r.id\n <#else>\n r.created_time\n </#if>\n </select>\n\n</#list>\n<#list this.metaEntity.checkUniqueIndexes as index>\n <#assign suffix=(index?index == 0)?string(\'\',\'\'+index?index)>\n <select id=\"notUnique${suffix}\" resultType=\"boolean\">\n select count(1) from ${wrapTableName} t\n <where>\n <#if delField??>\n and t.${wrapDelFieldName}=0\n </#if>\n <#list index.fields as field>\n and t.${wrapMysqlKeyword(field.fieldName)} = ${r\'#\'}{${field.jfieldName}}\n </#list>\n <if test=\"${this.id} != null \">\n and t.${wrapPkFieldName} != ${r\'#\'}{${this.id}}\n </if>\n </where>\n </select>\n\n</#list>\n\n\n <!-- 以上是自动生成的代码,尽量不要手动修改,新的sql请写在本行注释以下区域 -->\n\n\n</mapper>\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(150,'__dir.ftl','/{webModule}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${webModule}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(151,'pom.xml.ftl','/{webModule}',1,1,1,'<#include \"/abstracted/common.ftl\">\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n <parent>\n <artifactId>${this.originProjectName}</artifactId>\n <groupId>${this.groupId}</groupId>\n <version>1.0.0-SNAPSHOT</version>\n </parent>\n <modelVersion>4.0.0</modelVersion>\n\n <artifactId>${this.originProjectName}-web</artifactId>\n <packaging>war</packaging>\n\n <dependencies>\n\n <dependency>\n <groupId>${r\'$\'}{project.groupId}</groupId>\n <artifactId>${this.originProjectName}-core</artifactId>\n </dependency>\n\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-web</artifactId>\n </dependency>\n\n <!-- spring-boot 单元测试-->\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-test</artifactId>\n <scope>test</scope>\n </dependency>\n <!-- 正式环境使用mysql数据库 -->\n <dependency>\n <groupId>mysql</groupId>\n <artifactId>mysql-connector-java</artifactId>\n <scope>runtime</scope>\n </dependency>\n <!-- 单元测试使用H2内存数据库 -->\n <dependency>\n <groupId>com.h2database</groupId>\n <artifactId>h2</artifactId>\n <scope>test</scope>\n </dependency>\n <!-- 单元测试中mysql脚本转H2 -->\n <dependency>\n <groupId>com.parmet</groupId>\n <artifactId>mysql2h2-parser</artifactId>\n <scope>test</scope>\n </dependency>\n <!-- swagger依赖 -->\n <dependency>\n <groupId>io.springfox</groupId>\n <artifactId>springfox-boot-starter</artifactId>\n </dependency>\n </dependencies>\n <build>\n <plugins>\n <plugin>\n <groupId>org.apache.maven.plugins</groupId>\n <artifactId>maven-compiler-plugin</artifactId>\n <configuration>\n <source>${r\'$\'}{java.version}</source>\n <target>${r\'$\'}{java.version}</target>\n </configuration>\n </plugin>\n <plugin>\n <groupId>org.apache.maven.plugins</groupId>\n <artifactId>maven-surefire-plugin</artifactId>\n <configuration>\n <skip>true</skip>\n </configuration>\n </plugin>\n <plugin>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-maven-plugin</artifactId>\n </plugin>\n </plugins>\n </build>\n\n</project>\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(152,'__dir.ftl','/{webModule}/src/main/java/{packageName}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${packageNamePath}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(153,'__{ProjectName}App.java.ftl','/{webModule}/src/main/java/{packageName}',1,1,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.projectNameUpper}App.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(154,'{ProjectName}App.java.ftl','/{webModule}/src/main/java/{packageName}',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.optimistic.EnableOptimisticLock\")/>\n<@call this.addImport(\"org.springframework.boot.SpringApplication\")/>\n<@call this.addImport(\"org.springframework.boot.autoconfigure.SpringBootApplication\")/>\n<@call this.addImport(\"org.springframework.boot.builder.SpringApplicationBuilder\")/>\n<@call this.addImport(\"org.springframework.boot.web.servlet.support.SpringBootServletInitializer\")/>\n<@call this.printClassCom(\"启动类\")/>\n@SpringBootApplication\n@EnableOptimisticLock\npublic class ${this.projectNameUpper}App extends SpringBootServletInitializer {\n\n public static void main(String[] args) {\n SpringApplication app = new SpringApplication(${this.projectNameUpper}App.class);\n app.run(args);\n }\n\n /**\n * 兼容tomcat部署模式\n *\n * @param application\n * @return\n */\n @Override\n protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {\n return application.sources(${this.projectNameUpper}App.class);\n }\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(155,'AbstractController.java.ftl','/{webModule}/src/main/java/{packageName}/web',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.convert.MyCustomDateEditor\")/>\n<@call this.addImport(\"${this.commonPackage}.convert.MyCustomLocalDateEditor\")/>\n<@call this.addImport(\"${this.commonPackage}.convert.MyCustomLocalDateTimeEditor\")/>\n<@call this.addImport(\"org.springframework.web.bind.WebDataBinder\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.InitBinder\")/>\n<@call this.addImport(\"java.util.Date\")/>\n<@call this.addImport(\"java.time.LocalDate\")/>\n<@call this.addImport(\"java.time.LocalDateTime\")/>\n<@call this.printClassCom(\"抽象controller\")/>\npublic abstract class AbstractController {\n\n @InitBinder\n public void initBinder(WebDataBinder binder) {\n binder.registerCustomEditor(Date.class, new MyCustomDateEditor());\n binder.registerCustomEditor(LocalDate.class, new MyCustomLocalDateEditor());\n binder.registerCustomEditor(LocalDateTime.class, new MyCustomLocalDateTimeEditor());\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.web;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(156,'UserLoginController.java.ftl','/{webModule}/src/main/java/{packageName}/web',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.pojo.vo.ReplyVO\")/>\n<@call this.addImport(\"${this.packageName}.pojo.dto.UserLoginDTO\")/>\n<@call this.addImport(\"${this.packageName}.pojo.vo.UserLoginVO\")/>\n<@call this.addImport(\"${this.packageName}.web.constant.WebConst\")/>\n<@call this.addImport(\"org.springframework.http.ResponseEntity\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.GetMapping\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.PostMapping\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.RequestMapping\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.RestController\")/>\n<@call this.addImport(\"java.util.Arrays\")/>\n<@call this.printClassCom(\"用户登录控制器\",\"当前并没有真正实现用户登录功能,只是Mock登录接口而已\")/>\n@RestController\n@RequestMapping(WebConst.API_PATH + \"/_user\")\npublic class UserLoginController extends AbstractController {\n\n @PostMapping(value = \"/login\")\n public ResponseEntity<ReplyVO<String>> login(UserLoginDTO userLoginDTO) {\n return ResponseEntity.ok(ReplyVO.success(\"this_is_token\"));\n }\n\n @GetMapping(value = \"/info\")\n public ResponseEntity<ReplyVO<UserLoginVO>> info(String token) {\n UserLoginVO userLoginVO = new UserLoginVO();\n userLoginVO.setRoles(Arrays.asList(\"admin\"));\n userLoginVO.setIntroduction(\"I am a super administrator\");\n userLoginVO.setAvatar(\"https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif\");\n userLoginVO.setName(\"admin\");\n return ResponseEntity.ok(ReplyVO.success(userLoginVO));\n }\n\n @PostMapping(value = \"/logout\")\n public ResponseEntity<ReplyVO<Void>> logout() {\n return ResponseEntity.ok(ReplyVO.success());\n }\n\n}\n\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.web;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(157,'ExceptionTranslator.java.ftl','/{webModule}/src/main/java/{packageName}/web/advice',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.constant.ErrorCode\")/>\n<@call this.addImport(\"${this.commonPackage}.exception.BusinessException\")/>\n<@call this.addImport(\"${this.commonPackage}.pojo.vo.ReplyVO\")/>\n<@call this.addImport(\"${this.commonPackage}.util.JsonUtil\")/>\n<@call this.addImport(\"${this.commonPackage}.util.MessageSourceUtil\")/>\n<@call this.addImport(\"org.apache.commons.collections4.CollectionUtils\")/>\n<@call this.addImport(\"org.slf4j.Logger\")/>\n<@call this.addImport(\"org.slf4j.LoggerFactory\")/>\n<@call this.addImport(\"org.springframework.core.annotation.AnnotationUtils\")/>\n<@call this.addImport(\"org.springframework.dao.ConcurrencyFailureException\")/>\n<@call this.addImport(\"org.springframework.dao.DuplicateKeyException\")/>\n<@call this.addImport(\"org.springframework.http.HttpStatus\")/>\n<@call this.addImport(\"org.springframework.http.ResponseEntity\")/>\n<@call this.addImport(\"org.springframework.http.converter.HttpMessageNotReadableException\")/>\n<@call this.addImport(\"org.springframework.validation.BindException\")/>\n<@call this.addImport(\"org.springframework.validation.BindingResult\")/>\n<@call this.addImport(\"org.springframework.validation.ObjectError\")/>\n<@call this.addImport(\"org.springframework.web.HttpRequestMethodNotSupportedException\")/>\n<@call this.addImport(\"org.springframework.web.bind.MethodArgumentNotValidException\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.ControllerAdvice\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.ExceptionHandler\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.ResponseBody\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.ResponseStatus\")/>\n<@call this.addImport(\"javax.validation.ConstraintViolationException\")/>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.addImport(\"java.util.stream.Collectors\")/>\n\n<@call this.printClassCom(\"异常信息展示\")/>\n@ControllerAdvice\npublic class ExceptionTranslator {\n\n private final static Logger LOGGER = LoggerFactory.getLogger(ExceptionTranslator.class);\n\n\n /**\n * 自定义参数校验失败\n *\n * @param ex\n * @return\n */\n @ExceptionHandler(ConstraintViolationException.class)\n @ResponseStatus(HttpStatus.BAD_REQUEST)\n @ResponseBody\n public ReplyVO processValidationError(ConstraintViolationException ex) {\n ReplyVO replyVO = new ReplyVO();\n replyVO.setCode(ErrorCode.ERR_VALIDATION.getValue());\n replyVO.setMessage(ex.getMessage());\n return replyVO;\n }\n\n /**\n * body参数校验失败\n *\n * @param ex\n * @return\n */\n @ExceptionHandler(MethodArgumentNotValidException.class)\n @ResponseStatus(HttpStatus.BAD_REQUEST)\n @ResponseBody\n public ReplyVO processValidationError(MethodArgumentNotValidException ex) {\n BindingResult result = ex.getBindingResult();\n return processBindingResult(result);\n }\n\n /**\n * param参数校验失败\n *\n * @param ex\n * @return\n */\n @ExceptionHandler(BindException.class)\n @ResponseStatus(HttpStatus.BAD_REQUEST)\n @ResponseBody\n public ReplyVO processValidationError(BindException ex) {\n BindingResult result = ex.getBindingResult();\n return processBindingResult(result);\n }\n\n private ReplyVO processBindingResult(BindingResult result) {\n List<ObjectError> errors = result.getAllErrors();\n ReplyVO replyVO = new ReplyVO();\n replyVO.setCode(ErrorCode.ERR_VALIDATION.getValue());\n replyVO.setMessage(ErrorCode.ERR_VALIDATION.getDesc());\n if (CollectionUtils.isNotEmpty(errors)) {\n List<String> errorMsgs = errors.stream()\n .map(error -> error.getDefaultMessage())\n .collect(Collectors.toList());\n LOGGER.warn(JsonUtil.toJSONString(errorMsgs));\n String message = errorMsgs.stream()\n .collect(Collectors.joining(\";\"));\n replyVO.setMessage(message);\n }\n return replyVO;\n }\n\n\n /**\n * http method有误\n *\n * @param exception\n * @return\n */\n @ExceptionHandler(HttpRequestMethodNotSupportedException.class)\n @ResponseBody\n @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)\n public ReplyVO processMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {\n return ReplyVO.fail(ErrorCode.METHOD_NOT_SUPPORTED);\n }\n\n /**\n * 未传requestbody\n *\n * @param exception\n * @return\n */\n @ExceptionHandler(HttpMessageNotReadableException.class)\n @ResponseBody\n @ResponseStatus(HttpStatus.BAD_REQUEST)\n public ReplyVO processHttpMessageNotReadableException(HttpMessageNotReadableException exception) {\n return ReplyVO.fail(\"HttpMessageNotReadableException\");\n }\n\n /**\n * 线程异常\n *\n * @param ex\n * @return\n */\n @ExceptionHandler(ConcurrencyFailureException.class)\n @ResponseStatus(HttpStatus.CONFLICT)\n @ResponseBody\n public ReplyVO processConcurencyError(ConcurrencyFailureException ex) {\n return ReplyVO.fail(ErrorCode.CONCURRENCY_FAILURE);\n }\n\n\n /**\n * 唯一键重复\n *\n * @param ex\n * @return\n */\n @ExceptionHandler(DuplicateKeyException.class)\n @ResponseStatus(HttpStatus.CONFLICT)\n @ResponseBody\n public ReplyVO processDuplicateKeyException(DuplicateKeyException ex) {\n return ReplyVO.fail(ErrorCode.DUPLICATE_KEY);\n }\n\n /**\n * 自定义异常捕获\n *\n * @param ex\n * @return\n */\n @ExceptionHandler(BusinessException.class)\n @ResponseBody\n public ResponseEntity<ReplyVO> processBusinessException(BusinessException ex) {\n LOGGER.error(\"业务异常\", ex);\n ErrorCode code = ex.getErrorCode();\n ResponseEntity.BodyBuilder builder = ResponseEntity.status(Integer.parseInt(code.getValue()));\n ReplyVO replyVO = new ReplyVO(code.getValue(), ex.getMessage());\n return builder.body(replyVO);\n }\n\n\n /**\n * 普通异常捕获\n *\n * @param ex\n * @return\n */\n @ExceptionHandler(Exception.class)\n @ResponseBody\n public ResponseEntity<ReplyVO> processRuntimeException(Exception ex) {\n LOGGER.error(\"系统内部错误\", ex);\n ResponseEntity.BodyBuilder builder;\n ReplyVO replyVO;\n ResponseStatus responseStatus = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class);\n if (responseStatus != null) {\n builder = ResponseEntity.status(responseStatus.value());\n replyVO = new ReplyVO(responseStatus.value().value() + \"\", MessageSourceUtil.getMessage(responseStatus.reason()));\n } else {\n builder = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);\n replyVO = ReplyVO.fail(ErrorCode.INTERNAL_SERVER_ERROR);\n }\n return builder.body(replyVO);\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.web.advice;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(158,'__dir.ftl','/{webModule}/src/main/java/{packageName}/web/api/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(159,'__{ChartName}API.java.ftl','/{webModule}/src/main/java/{packageName}/web/api/{module}',1,4,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}API.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(160,'__{ClassName}API.java.ftl','/{webModule}/src/main/java/{packageName}/web/api/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}API.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(161,'{ChartName}API.java.ftl','/{webModule}/src/main/java/{packageName}/web/api/{module}',1,4,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForChart.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"io.swagger.annotations.Api\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiOperation\")/>\n<@call this.addImport(\"org.springframework.http.ResponseEntity\")/>\n<@call this.addImport(\"${qoPackageName}.${this.chartName}QO\")/>\n<@call this.printClassCom(\"【${this.title}】图表API\" \"swagger接口文档\")/>\n@Api(tags = \"【${this.title}】图表API\")\npublic interface ${this.chartName}API {\n\n<#if isChartType(ChartType.DETAIL_LIST) || isChartType(ChartType.AGG_TABLE)>\n <@call this.addImport(\"${voPackageName}.${this.chartName}VO\")/>\n /**\n * 查询明细表\n */\n @ApiOperation(value = \"查询明细表\")\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.PageVO\")/>\n ResponseEntity<PageVO<${this.chartName}VO>> findList(${this.chartName}QO qo);\n\n <#if this.excelExport>\n <@call this.addImport(\"javax.servlet.http.HttpServletResponse\")/>\n /**\n * 导出excel\n */\n @ApiOperation(value = \"导出excel\")\n void exportExcel(${this.chartName}QO qo, HttpServletResponse response) throws Exception;\n </#if>\n<#else>\n /**\n * 查询图表数据\n */\n @ApiOperation(value = \"查询图表数据\")\n <@call this.addImport(\"java.util.List\")/>\n ResponseEntity<List<Object[]>> findChartData(${this.chartName}QO qo);\n</#if>\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${apiPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(162,'{ClassName}API.java.ftl','/{webModule}/src/main/java/{packageName}/web/api/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/checkFeatureForRest.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForShow.ftl\">\n<#--判断如果不需要生成当前文件,则直接跳过-->\n<#if !getGenRest(this.metaEntity)>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"io.swagger.annotations.Api\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiImplicitParam\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiImplicitParams\")/>\n<@call this.addImport(\"io.swagger.annotations.ApiOperation\")/>\n<@call this.addImport(\"org.springframework.http.ResponseEntity\")/>\n<@call this.printClassCom(\"【${this.title}】API\" \"swagger接口文档\")/>\n@Api(tags = \"【${this.title}】API\")\npublic interface ${this.className}API {\n\n<#if this.entityFeature.save>\n <@call this.addImport(\"${dtoPackageName}.${this.className}AddDTO\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ShowVO\")/>\n /**\n * 新增【${this.title}】\n */\n @ApiOperation(value = \"新增【${this.title}】\")\n @ApiImplicitParams({\n @ApiImplicitParam(name = \"${this.classNameLower}AddDTO\", dataTypeClass = ${this.className}AddDTO.class, value = \"新增【${this.title}】参数\", paramType = \"body\"),\n })\n ResponseEntity<${this.className}ShowVO> save(${this.className}AddDTO ${this.classNameLower}AddDTO) throws Exception;\n\n</#if>\n<#if this.entityFeature.update>\n <@call this.addImport(\"${dtoPackageName}.${this.className}UpdateDTO\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ShowVO\")/>\n /**\n * 修改【${this.title}】\n */\n @ApiOperation(value = \"修改【${this.title}】\")\n @ApiImplicitParams({\n @ApiImplicitParam(name = \"${this.classNameLower}UpdateDTO\", dataTypeClass = ${this.className}UpdateDTO.class, value = \"修改【${this.title}】参数\", paramType = \"body\"),\n })\n ResponseEntity<${this.className}ShowVO> update(${this.className}UpdateDTO ${this.classNameLower}UpdateDTO);\n\n</#if>\n<#if this.entityFeature.list>\n <@call this.addImport(\"${qoPackageName}.${this.className}QO\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ListVO\")/>\n <#if this.pageSign>\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.PageVO\")/>\n /**\n * 分页查询【${this.title}】\n */\n @ApiOperation(value = \"分页查询【${this.title}】\")\n ResponseEntity<PageVO<${this.className}ListVO>> list(${this.className}QO ${this.classNameLower}QO);\n <#else>\n <@call this.addImport(\"java.util.List\")/>\n /**\n * 列表查询【${this.title}】\n */\n @ApiOperation(value = \"列表查询【${this.title}】\")\n ResponseEntity<List<${this.className}ListVO>> list(${this.className}QO ${this.classNameLower}QO);\n </#if>\n\n</#if>\n<#if this.titleField??>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.OptionVO\")/>\n <@call this.addImport(\"${this.commonPackage}.pojo.qo.OptionQO\")/>\n /**\n * 查询【${this.title}】选项列表\n */\n @ApiOperation(value = \"查询【${this.title}】选项列表\")\n ResponseEntity<List<OptionVO<${this.type}, ${this.titleField.jfieldType}>>> findOptions(OptionQO<${this.type}, ${this.titleField.jfieldType}> qo);\n\n</#if>\n<#if this.entityFeature.show>\n <@call this.addImport(\"${voPackageName}.${this.className}ShowVO\")/>\n /**\n * 查看【${this.title}】详情\n */\n @ApiOperation(value = \"查看【${this.title}】详情\")\n @ApiImplicitParams({\n @ApiImplicitParam(name = \"${this.id}\", dataTypeClass = ${this.type}.class, value = \"【${this.title}】id\", paramType = \"path\"),\n })\n ResponseEntity<${this.className}ShowVO> show(${this.type} ${this.id});\n\n</#if>\n<#if this.entityFeature.delete>\n /**\n * 删除单个【${this.title}】\n */\n @ApiOperation(value = \"删除单个【${this.title}】\")\n @ApiImplicitParams({\n @ApiImplicitParam(name = \"${this.id}\", dataTypeClass = ${this.type}.class, value = \"【${this.title}】id\", paramType = \"path\"),\n })\n ResponseEntity<Integer> delete(${this.type} ${this.id});\n\n</#if>\n<#if this.entityFeature.deleteBatch>\n /**\n * 批量删除【${this.title}】\n */\n @ApiOperation(value = \"批量删除【${this.title}】\")\n @ApiImplicitParams({\n @ApiImplicitParam(name = \"id\", dataTypeClass = ${this.type}.class, allowMultiple = true, value = \"id数组\", paramType = \"body\"),\n })\n ResponseEntity<Integer> deleteBatch(${this.type}[] id);\n\n</#if>\n<#list this.holds! as otherEntity,mtm>\n <#assign otherPk=otherEntity.pkField>\n <#assign otherCName=otherEntity.className>\n <#assign otherFkId=mtm.getFkAlias(otherEntity.entityId,false)>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.addRemove || entityFeature.set>\n <@call this.addImport(\"java.util.List\")/>\n <#assign index=getMtmCascadeEntityIndexForShow(otherEntity.entityId)>\n <#--如果存在级联扩展,则返回值为级联扩展VO-->\n <#if entityFeature.addRemove>\n <@call this.addImport(\"${voPackageName}.${otherCName}ListVO\")/>\n <#assign resultType=\"${otherCName}ListVO\">\n <#elseIf index &gt; -1>\n <@call this.addImport(\"${voPackageName}.${this.className}ShowVO\")/>\n <#assign resultType=\"${this.className}ShowVO.${otherCName}VO\">\n <#else>\n <#assign resultType=otherPk.jfieldType>\n </#if>\n /**\n * 获取【${otherEntity.title}】关联\n */\n @ApiOperation(value = \"获取【${otherEntity.title}】关联\")\n @ApiImplicitParams({\n @ApiImplicitParam(name = \"${this.id}\", dataTypeClass = ${this.type}.class, value = \"【${this.title}】id\", paramType = \"path\"),\n })\n ResponseEntity<List<${resultType}>> fetch${otherCName}List(${this.type} ${this.id});\n\n </#if>\n <#if entityFeature.addRemove>\n /**\n * 添加【${otherEntity.title}】关联\n */\n @ApiOperation(value = \"添加【${otherEntity.title}】关联\")\n @ApiImplicitParams({\n @ApiImplicitParam(name = \"${this.id}\", dataTypeClass = ${this.type}.class, value = \"【${this.title}】id\", paramType = \"path\"),\n @ApiImplicitParam(name = \"${otherFkId}\", dataTypeClass = ${otherPk.jfieldType}.class, value = \"【${otherEntity.title}】id数组\", paramType = \"body\"),\n })\n ResponseEntity<Integer> add${otherCName}(${this.type} ${this.id},${otherPk.jfieldType}[] ${otherFkId});\n\n /**\n * 移除【${otherEntity.title}】关联\n */\n @ApiOperation(value = \"移除【${otherEntity.title}】关联\")\n @ApiImplicitParams({\n @ApiImplicitParam(name = \"${this.id}\", dataTypeClass = ${this.type}.class, value = \"【${this.title}】id\", paramType = \"path\"),\n @ApiImplicitParam(name = \"${otherFkId}\", dataTypeClass = ${otherPk.jfieldType}.class, value = \"【${otherEntity.title}】id数组\", paramType = \"body\"),\n })\n ResponseEntity<Integer> remove${otherCName}(${this.type} ${this.id},${otherPk.jfieldType}[] ${otherFkId});\n\n <#elseIf entityFeature.set>\n\n /**\n * 设置【${otherEntity.title}】关联\n */\n @ApiOperation(value = \"设置【${otherEntity.title}】关联\")\n @ApiImplicitParams({\n @ApiImplicitParam(name = \"${this.id}\", dataTypeClass = ${this.type}.class, value = \"【${this.title}】id\", paramType = \"path\"),\n @ApiImplicitParam(name = \"${otherFkId}\", dataTypeClass = ${otherPk.jfieldType}.class, value = \"【${otherEntity.title}】id数组\", paramType = \"body\"),\n })\n ResponseEntity<Integer> set${otherCName}(${this.type} ${this.id},${otherPk.jfieldType}[] ${otherFkId});\n\n </#if>\n</#list>\n<#if this.entityFeature.excelExport>\n <@call this.addImport(\"${qoPackageName}.${this.className}QO\")/>\n <@call this.addImport(\"javax.servlet.http.HttpServletResponse\")/>\n /**\n * 导出【${this.title}】excel\n */\n @ApiOperation(value = \"导出【${this.title}】excel\")\n void exportExcel(${this.className}QO ${this.classNameLower}QO, HttpServletResponse response) throws Exception;\n\n</#if>\n<#if this.entityFeature.excelImport>\n <@call this.addImport(\"javax.servlet.http.HttpServletResponse\")/>\n <@call this.addImport(\"org.springframework.web.multipart.MultipartFile\")/>\n /**\n * 导入【${this.title}】excel\n */\n @ApiOperation(value = \"导入【${this.title}】excel\")\n ResponseEntity<Integer> importExcel(MultipartFile file) throws Exception;\n\n /**\n * 下载【${this.title}】excel模板\n */\n @ApiOperation(value = \"下载【${this.title}】excel模板\")\n void downloadExcelTemplate(HttpServletResponse response) throws Exception;\n\n</#if>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${apiPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(163,'StartLogCommandLineRunner.java.ftl','/{webModule}/src/main/java/{packageName}/web/config',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.packageName}.web.util.IpUtil\")/>\n<@call this.addImport(\"org.apache.commons.lang3.ArrayUtils\")/>\n<@call this.addImport(\"org.slf4j.Logger\")/>\n<@call this.addImport(\"org.slf4j.LoggerFactory\")/>\n<@call this.addImport(\"org.springframework.boot.CommandLineRunner\")/>\n<@call this.addImport(\"org.springframework.core.Ordered\")/>\n<@call this.addImport(\"org.springframework.core.env.Environment\")/>\n<@call this.addImport(\"org.springframework.stereotype.Component\")/>\n<@call this.addImport(\"org.springframework.beans.factory.annotation.Value\")/>\n<@call this.addImport(\"java.util.Arrays\")/>\n<@call this.addImport(\"java.util.stream.Collectors\")/>\n<@call this.printClassCom(\"打印启动日志\")/>\n@Component\npublic class StartLogCommandLineRunner implements CommandLineRunner, Ordered {\n\n private static final Logger LOG = LoggerFactory.getLogger(StartLogCommandLineRunner.class);\n\n private final Environment env;\n\n @Value(\"${r\'$\'}{springfox.documentation.enabled:true}\")\n private boolean swaggerEnabled;\n\n public StartLogCommandLineRunner(Environment env) {\n this.env = env;\n }\n\n @Override\n public void run(String... args) throws Exception {\n String port = env.getProperty(\"server.port\", \"8080\");\n String contextPath = env.getProperty(\"server.servlet.context-path\", \"/\");\n String applicationName = env.getProperty(\"spring.application.name\", \"\");\n String profiles = \"\";\n if (ArrayUtils.isNotEmpty(env.getActiveProfiles())) {\n profiles = Arrays.stream(env.getActiveProfiles()).collect(Collectors.joining(\",\"));\n }\n StringBuilder sb = new StringBuilder();\n sb.append(\"\\n----------------------------------------------------------\\n\")\n .append(\"\\t应用【\").append(applicationName).append(\"】已经启动!\\n\")\n .append(\"\\t激活profile:\\t\").append(profiles).append(\"\\n\")\n .append(\"\\t访问路径:\\n\")\n .append(\"\\t本地: \\thttp://localhost:\").append(port).append(contextPath).append(\"\\n\")\n .append(\"\\t外部: \\thttp://\").append(IpUtil.getLocalIp()).append(\":\").append(port).append(contextPath).append(\"\\n\");\n if (swaggerEnabled) {\n sb.append(\"\\t文档:\\thttp://\").append(IpUtil.getLocalIp()).append(\":\").append(port).append(contextPath).append(\"swagger-ui/index.html\");\n }\n sb.append(\"\\n----------------------------------------------------------\");\n LOG.info(sb.toString());\n\n }\n\n @Override\n public int getOrder() {\n return Ordered.LOWEST_PRECEDENCE;\n }\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.web.config;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(164,'SwaggerConfig.java.ftl','/{webModule}/src/main/java/{packageName}/web/config',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.springframework.boot.autoconfigure.condition.ConditionalOnProperty\")/>\n<@call this.addImport(\"org.springframework.context.annotation.Configuration\")/>\n<@call this.addImport(\"org.springframework.context.annotation.Bean\")/>\n<@call this.addImport(\"springfox.documentation.builders.PathSelectors\")/>\n<@call this.addImport(\"springfox.documentation.spi.DocumentationType\")/>\n<@call this.addImport(\"springfox.documentation.spring.web.plugins.Docket\")/>\n<@call this.printClassCom(\"swagger配置\")/>\n@Configuration\n@ConditionalOnProperty(\n value = \"springfox.documentation.enabled\",\n havingValue = \"true\",\n matchIfMissing = true\n)\npublic class SwaggerConfig {\n\n @Bean\n public Docket createRestApi() {\n return new Docket(DocumentationType.OAS_30)\n .select()\n .paths(PathSelectors.ant(\"/api/**\"))\n .build();\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.web.config;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(165,'WebConfig.java.ftl','/{webModule}/src/main/java/{packageName}/web/config',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.xss.JacksonXSSDeserializer\")/>\n<@call this.addImport(\"${this.commonPackage}.xss.WebXSSFilter\")/>\n<@call this.addImport(\"org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer\")/>\n<@call this.addImport(\"org.springframework.boot.web.servlet.FilterRegistrationBean\")/>\n<@call this.addImport(\"org.springframework.context.annotation.Bean\")/>\n<@call this.addImport(\"org.springframework.context.annotation.Configuration\")/>\n<@call this.addImport(\"org.springframework.web.servlet.LocaleResolver\")/>\n<@call this.addImport(\"org.springframework.web.servlet.config.annotation.InterceptorRegistry\")/>\n<@call this.addImport(\"org.springframework.web.servlet.config.annotation.WebMvcConfigurer\")/>\n<@call this.addImport(\"org.springframework.web.servlet.i18n.CookieLocaleResolver\")/>\n<@call this.addImport(\"org.springframework.web.servlet.i18n.LocaleChangeInterceptor\")/>\n<@call this.addImport(\"java.util.ArrayList\")/>\n<@call this.addImport(\"java.util.List\")/>\n<@call this.addImport(\"java.util.Locale\")/>\n<@call this.printClassCom(\"web相关配置\")/>\n@Configuration\npublic class WebConfig {\n\n /**\n * 防止通过parameter传入XSS脚本\n *\n * @return\n */\n @Bean\n public FilterRegistrationBean webXSSFilterBean() {\n FilterRegistrationBean registrationBean = new FilterRegistrationBean();\n WebXSSFilter filter = new WebXSSFilter();\n registrationBean.setFilter(filter);\n List<String> urlPatterns = new ArrayList<>();\n urlPatterns.add(\"/*\");\n registrationBean.setUrlPatterns(urlPatterns);\n return registrationBean;\n }\n\n /**\n * 防止通过body传入XSS脚本\n *\n * @return\n */\n @Bean\n public Jackson2ObjectMapperBuilderCustomizer jacksonXSSCustomizer() {\n return jacksonObjectMapperBuilder ->\n jacksonObjectMapperBuilder.deserializerByType(String.class, new JacksonXSSDeserializer());\n }\n\n\n /**\n * 国际化解析器,默认中文\n *\n * @return\n */\n @Bean\n public LocaleResolver localeResolver() {\n CookieLocaleResolver slr = new CookieLocaleResolver();\n slr.setCookieMaxAge(3600);\n slr.setDefaultLocale(Locale.CHINA);\n return slr;\n }\n\n /**\n * 配置语言切换拦截器\n *\n * @return\n */\n @Bean\n public WebMvcConfigurer webMvcConfigurer() {\n return new WebMvcConfigurer() {\n // 拦截器\n @Override\n public void addInterceptors(InterceptorRegistry registry) {\n LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();\n // 自定义语言切换参数,默认是locale\n localeChangeInterceptor.setParamName(\"lang\");\n registry.addInterceptor(localeChangeInterceptor).addPathPatterns(\"/**\");\n }\n };\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.web.config;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(166,'WebConst.java.ftl','/{webModule}/src/main/java/{packageName}/web/constant',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/checkFeatureForRest.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.printClassCom(\"web常量\")/>\npublic class WebConst {\n\n /**\n * 接口路径前缀\n */\n public static final String API_PATH = \"/api\";\n\n<#list modulesForRest>\n /**\n * 各个模块的路径\n */\n public static class ModulePath {\n\n <#items as module>\n public static final String ${module?upperCase} = API_PATH + \"/${module}\";\n\n </#items>\n }\n\n</#list>\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.web.constant;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(167,'WebLoginContext.java.ftl','/{webModule}/src/main/java/{packageName}/web/context',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.commonPackage}.context.LoginContext\")/>\n<@call this.addImport(\"org.springframework.stereotype.Component\")/>\n<@call this.printClassCom(\"web登录用户上下文\")/>\n@Component\npublic class WebLoginContext implements LoginContext {\n\n /**\n * 获取当前操作员id\n *\n * @return\n */\n @Override\n public String getCurrentUser() {\n return \"admin\";\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.web.context;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(168,'__dir.ftl','/{webModule}/src/main/java/{packageName}/web/rest/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(169,'__{ChartName}Controller.java.ftl','/{webModule}/src/main/java/{packageName}/web/rest/{module}',1,4,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}Controller.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(170,'__{ClassName}Controller.java.ftl','/{webModule}/src/main/java/{packageName}/web/rest/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}Controller.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(171,'{ChartName}Controller.java.ftl','/{webModule}/src/main/java/{packageName}/web/rest/{module}',1,4,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForChart.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.packageName}.web.AbstractController\")/>\n<@call this.addImport(\"${apiPackageName}.${this.chartName}API\")/>\n<@call this.addImport(\"${servicePackageName}.${this.chartName}Service\")/>\n<@call this.addImport(\"org.springframework.beans.factory.annotation.Autowired\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.*\")/>\n<@call this.addImport(\"org.springframework.http.ResponseEntity\")/>\n<@call this.addImport(\"${qoPackageName}.${this.chartName}QO\")/>\n<@call this.addImport(\"javax.validation.Valid\")/>\n<@call this.printClassCom(\"【${this.title}】图表控制器\")/>\n@RestController\n@RequestMapping(${renderApiPathForChart(this.chart, \"\")})\npublic class ${this.chartName}Controller extends AbstractController implements ${this.chartName}API {\n\n @Autowired\n private ${this.chartName}Service ${this.chartNameLower}Service;\n\n<#if isChartType(ChartType.DETAIL_LIST) || isChartType(ChartType.AGG_TABLE)>\n <@call this.addImport(\"${voPackageName}.${this.chartName}VO\")/>\n @Override\n @GetMapping\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.PageVO\")/>\n public ResponseEntity<PageVO<${this.chartName}VO>> findList(@Valid ${this.chartName}QO qo) {\n PageVO<${this.chartName}VO> page = ${this.chartNameLower}Service.findList(qo);\n return ResponseEntity.ok(page);\n }\n\n <#if this.excelExport>\n <@call this.addImport(\"javax.servlet.http.HttpServletResponse\")/>\n <@call this.addImport(\"com.alibaba.excel.EasyExcel\")/>\n <@call this.addImport(\"java.net.URLEncoder\")/>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${mapperPackageName}.${this.chartName}Mapper\")/>\n <@call this.addImport(\"${voPackageName}.${this.chartName}ExcelVO\")/>\n @Override\n @GetMapping(\"/export\")\n public void exportExcel(@Valid ${this.chartName}QO qo, HttpServletResponse response) throws Exception {\n qo.setPageSize(Integer.MAX_VALUE);\n qo.setPageNo(1);\n List<${this.chartName}VO> list = ${this.chartNameLower}Service.findList(qo).getList();\n response.setContentType(\"application/vnd.ms-excel\");\n response.setCharacterEncoding(\"utf-8\");\n String fileName = URLEncoder.encode(\"${this.title}\", \"utf-8\");\n response.setHeader(\"Content-disposition\", \"attachment;filename=\" + fileName + \".xlsx\");\n EasyExcel.write(response.getOutputStream(), ${this.chartName}ExcelVO.class)\n .sheet()\n .doWrite(${this.chartName}Mapper.INSTANCE.toExcelVOList(list));\n }\n </#if>\n<#else>\n @Override\n @GetMapping\n <@call this.addImport(\"java.util.List\")/>\n public ResponseEntity<List<Object[]>> findChartData(@Valid ${this.chartName}QO qo) {\n List<Object[]> list = ${this.chartNameLower}Service.findChartData(qo);\n return ResponseEntity.ok(list);\n }\n</#if>\n\n}\n\n</#assign>\n<#--开始渲染代码-->\npackage ${restPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(172,'{ClassName}Controller.java.ftl','/{webModule}/src/main/java/{packageName}/web/rest/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/checkFeatureForRest.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForShow.ftl\">\n<#include \"/abstracted/forEntityInsert.ftl\">\n<#--判断如果不需要生成当前文件,则直接跳过-->\n<#if !getGenRest(this.metaEntity)>\n <@call this.skipCurrent()/>\n</#if>\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.packageName}.web.AbstractController\")/>\n<@call this.addImport(\"${apiPackageName}.${this.className}API\")/>\n<@call this.addImport(\"org.springframework.http.HttpStatus\")/>\n<@call this.addImport(\"org.springframework.http.ResponseEntity\")/>\n<@call this.addImport(\"org.springframework.web.bind.annotation.*\")/>\n<@call this.addImport(\"javax.validation.Valid\")/>\n<@call this.addImport(\"java.net.URI\")/>\n<@call this.printClassCom(\"【${this.title}】控制器\")/>\n@RestController\n@RequestMapping(${renderApiPath(this.metaEntity, \"\")})\npublic class ${this.className}Controller extends AbstractController implements ${this.className}API {\n\n <@call this.addAutowired(\"${servicePackageName}\" \"${this.className}Service\")/>\n <#if this.entityFeature.excelImport>\n <@call this.addAutowired(\"javax.validation\" \"Validator\")/>\n </#if>\n <@call this.printAutowired()/>\n\n<#if this.entityFeature.save>\n <@call this.addImport(\"${dtoPackageName}.${this.className}AddDTO\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ShowVO\")/>\n <@call this.addImport(\"${mapperPackageName}.${this.className}Mapper\")/>\n <@call this.addImport(\"${poPackageName}.${this.className}PO\")/>\n @Override\n @PostMapping\n @ResponseStatus(HttpStatus.CREATED)\n public ResponseEntity<${this.className}ShowVO> save(@Valid @RequestBody ${this.className}AddDTO ${this.classNameLower}AddDTO) throws Exception {\n ${this.className}PO ${this.classNameLower} = ${this.classNameLower}Service.save(${this.classNameLower}AddDTO);\n return ResponseEntity.created(new URI(${renderApiPath(this.metaEntity, \"/\")} + ${this.classNameLower}.get${this.idUpper}()))\n .body(${this.className}Mapper.INSTANCE.toShowVO(${this.classNameLower}));\n }\n\n</#if>\n<#if this.entityFeature.update>\n <@call this.addImport(\"${dtoPackageName}.${this.className}UpdateDTO\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ShowVO\")/>\n <@call this.addImport(\"${mapperPackageName}.${this.className}Mapper\")/>\n <@call this.addImport(\"${poPackageName}.${this.className}PO\")/>\n @Override\n @PutMapping\n public ResponseEntity<${this.className}ShowVO> update(@Valid @RequestBody ${this.className}UpdateDTO ${this.classNameLower}UpdateDTO) {\n ${this.className}PO ${this.classNameLower} = ${this.classNameLower}Service.update(${this.classNameLower}UpdateDTO);\n return ResponseEntity.ok(${this.className}Mapper.INSTANCE.toShowVO(${this.classNameLower}));\n }\n\n</#if>\n<#if this.entityFeature.list>\n <@call this.addImport(\"${qoPackageName}.${this.className}QO\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ListVO\")/>\n <#if this.pageSign>\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.PageVO\")/>\n @Override\n @GetMapping\n public ResponseEntity<PageVO<${this.className}ListVO>> list(@Valid ${this.className}QO ${this.classNameLower}QO) {\n PageVO<${this.className}ListVO> page = ${this.classNameLower}Service.list(${this.classNameLower}QO);\n return ResponseEntity.ok(page);\n }\n <#else>\n <@call this.addImport(\"java.util.List\")/>\n @Override\n @GetMapping\n public ResponseEntity<List<${this.className}ListVO>> list(@Valid ${this.className}QO ${this.classNameLower}QO) {\n List<${this.className}ListVO> list = ${this.classNameLower}Service.list(${this.classNameLower}QO);\n return ResponseEntity.ok(list);\n }\n </#if>\n\n</#if>\n<#if this.titleField??>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${this.commonPackage}.pojo.vo.OptionVO\")/>\n <@call this.addImport(\"${this.commonPackage}.pojo.qo.OptionQO\")/>\n @Override\n @GetMapping(value = \"/options\")\n public ResponseEntity<List<OptionVO<${this.type}, ${this.titleField.jfieldType}>>> findOptions(OptionQO<${this.type}, ${this.titleField.jfieldType}> qo) {\n List<OptionVO<${this.type}, ${this.titleField.jfieldType}>> options = ${this.classNameLower}Service.findOptions(qo);\n return ResponseEntity.ok(options);\n }\n\n</#if>\n<#if this.entityFeature.show>\n <@call this.addImport(\"${voPackageName}.${this.className}ShowVO\")/>\n @Override\n @GetMapping(value = \"/{${this.id}}\")\n public ResponseEntity<${this.className}ShowVO> show(@PathVariable ${this.type} ${this.id}) {\n ${this.className}ShowVO ${this.classNameLower}ShowVO = ${this.classNameLower}Service.show(${this.id});\n return ResponseEntity.ok(${this.classNameLower}ShowVO);\n }\n\n</#if>\n<#if this.entityFeature.delete>\n @Override\n @DeleteMapping(value = \"/{${this.id}}\")\n public ResponseEntity<Integer> delete(@PathVariable ${this.type} ${this.id}) {\n int count = ${this.classNameLower}Service.delete(${this.id});\n return ResponseEntity.ok(count);\n }\n\n</#if>\n<#if this.entityFeature.deleteBatch>\n <@call this.addImport(\"${this.commonPackage}.exception.BusinessException\")/>\n <@call this.addImport(\"${this.commonPackage}.constant.ErrorCode\")/>\n @Override\n @DeleteMapping\n public ResponseEntity<Integer> deleteBatch(@RequestBody ${this.type}[] id) {\n <@call this.addImport(\"org.apache.commons.lang3.ArrayUtils\")/>\n if (ArrayUtils.isEmpty(id)) {\n throw new BusinessException(ErrorCode.PARAM_IS_NULL);\n }\n int count = ${this.classNameLower}Service.delete(id);\n return ResponseEntity.ok(count);\n }\n\n</#if>\n<#list this.holds! as otherEntity,mtm>\n <#assign otherPk=otherEntity.pkField>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign otherFkId=mtm.getFkAlias(otherEntity.entityId,false)>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.addRemove || entityFeature.set>\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${poPackageName}.${otherCName}PO\")/>\n <@call this.addImport(\"${poPackageName}.${this.className}PO\")/>\n <#assign index=getMtmCascadeEntityIndexForShow(otherEntity.entityId)>\n <#--如果存在级联扩展,则返回值为级联扩展VO-->\n <#if entityFeature.addRemove>\n <@call this.addImport(\"${voPackageName}.${otherCName}ListVO\")/>\n <#assign resultType=\"${otherCName}ListVO\">\n <#elseIf index &gt; -1>\n <@call this.addImport(\"${voPackageName}.${this.className}ShowVO\")/>\n <#assign resultType=\"${this.className}ShowVO.${otherCName}VO\">\n <#else>\n <#assign resultType=otherPk.jfieldType>\n </#if>\n @Override\n @GetMapping(value = \"/{${this.id}}/${othercName}\")\n public ResponseEntity<List<${resultType}>> fetch${otherCName}List(@PathVariable ${this.type} ${this.id}) {\n <#assign withFalseCode=\"\">\n <#list this.holds! as otherHoldEntity,mtm>\n <#if otherEntity == otherHoldEntity>\n <#assign withCode=withFalseCode+\"true, \">\n <#else>\n <#assign withCode=withFalseCode+\"false, \">\n </#if>\n </#list>\n ${this.className}PO ${this.classNameLower} = ${this.classNameLower}Service.get${this.className}(${this.id}, ${withCode}true);\n List<${otherCName}PO> list = ${this.classNameLower}.get${otherCName}POList();\n <#if entityFeature.addRemove>\n <@call this.addImport(\"${mapperPackageName}.${otherCName}Mapper\")/>\n return ResponseEntity.ok(${otherCName}Mapper.INSTANCE.toListVOList(list));\n <#elseIf index &gt; -1>\n <@call this.addImport(\"${mapperPackageName}.${otherCName}Mapper\")/>\n return ResponseEntity.ok(${otherCName}Mapper.INSTANCE.to${otherCName}VOFor${this.className}Show(list));\n <#else>\n <@call this.addImport(\"java.util.stream.Collectors\")/>\n return ResponseEntity.ok(list.stream()\n .map(t -> t.get${otherPk.jfieldName?capFirst}())\n .collect(Collectors.toList()));\n </#if>\n }\n\n </#if>\n <#if entityFeature.addRemove>\n <@call this.addImport(\"${voPackageName}.${otherCName}ListVO\")/>\n @Override\n @PostMapping(value = \"/{${this.id}}/${othercName}\")\n public ResponseEntity<Integer> add${otherCName}(@PathVariable ${this.type} ${this.id},\n @RequestBody ${otherPk.jfieldType}[] ${otherFkId}) {\n int count = ${this.classNameLower}Service.add${otherCName}(${this.id}, ${otherFkId});\n return ResponseEntity.ok(count);\n }\n\n @Override\n @DeleteMapping(value = \"/{${this.id}}/${othercName}\")\n public ResponseEntity<Integer> remove${otherCName}(@PathVariable ${this.type} ${this.id},\n @RequestBody ${otherPk.jfieldType}[] ${otherFkId}) {\n int count = ${this.classNameLower}Service.remove${otherCName}(${this.id}, ${otherFkId});\n return ResponseEntity.ok(count);\n }\n\n <#elseIf entityFeature.set>\n @Override\n @PutMapping(value = \"/{${this.id}}/${othercName}\")\n public ResponseEntity<Integer> set${otherCName}(@PathVariable ${this.type} ${this.id},\n @RequestBody ${otherPk.jfieldType}[] ${otherFkId}) {\n int count = ${this.classNameLower}Service.set${otherCName}(${this.id}, ${otherFkId});\n return ResponseEntity.ok(count);\n }\n\n </#if>\n</#list>\n<#if this.entityFeature.excelExport>\n @Override\n @GetMapping(\"/export\")\n <@call this.addImport(\"${qoPackageName}.${this.className}QO\")/>\n <@call this.addImport(\"javax.servlet.http.HttpServletResponse\")/>\n public void exportExcel(@Valid ${this.className}QO ${this.classNameLower}QO, HttpServletResponse response) throws Exception {\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ListVO\")/>\n <#if this.pageSign>\n ${this.classNameLower}QO.setPageSize(Integer.MAX_VALUE);\n ${this.classNameLower}QO.setPageNo(1);\n List<${this.className}ListVO> list = ${this.classNameLower}Service.list(${this.classNameLower}QO).getList();\n <#else>\n List<${this.className}ListVO> list = ${this.classNameLower}Service.list(${this.classNameLower}QO);\n </#if>\n response.setContentType(\"application/vnd.ms-excel\");\n response.setCharacterEncoding(\"utf-8\");\n <@call this.addImport(\"java.net.URLEncoder\")/>\n String fileName = URLEncoder.encode(\"${this.title}导出\", \"utf-8\");\n response.setHeader(\"Content-disposition\", \"attachment;filename=\" + fileName + \".xlsx\");\n <@call this.addImport(\"com.alibaba.excel.EasyExcel\")/>\n <@call this.addImport(\"${voPackageName}.${this.className}ExcelVO\")/>\n EasyExcel.write(response.getOutputStream(), ${this.className}ExcelVO.class)\n .sheet()\n <@call this.addImport(\"${mapperPackageName}.${this.className}Mapper\")/>\n .doWrite(${this.className}Mapper.INSTANCE.toExcelVOList(list));\n }\n\n</#if>\n<#if this.entityFeature.excelImport>\n @Override\n @PostMapping(\"/import\")\n <@call this.addImport(\"org.springframework.web.multipart.MultipartFile\")/>\n public ResponseEntity<Integer> importExcel(@RequestPart MultipartFile file) throws Exception {\n <@call this.addImport(\"java.util.List\")/>\n <@call this.addImport(\"${dtoPackageName}.${this.className}AddDTO\")/>\n <@call this.addImport(\"com.alibaba.excel.EasyExcel\")/>\n <@call this.addImport(\"${this.packageName}.excel.listener.SyncReadExcelListener\")/>\n <@call this.addImport(\"${dtoPackageName}.${this.className}ExcelDTO\")/>\n SyncReadExcelListener<${this.className}ExcelDTO> excelListener = new SyncReadExcelListener();\n EasyExcel.read(file.getInputStream())\n .head(${this.className}ExcelDTO.class)\n .sheet()\n .headRowNumber(3)\n .registerReadListener(excelListener)\n .doRead();\n List<${this.className}AddDTO> list = excelListener.getList().stream()\n .map(excelDTO -> {\n <@call this.addImport(\"${mapperPackageName}.${this.className}Mapper\")/>\n ${this.className}AddDTO addDTO = ${this.className}Mapper.INSTANCE.fromExcelDTO(excelDTO);\n // 校验数据\n <@call this.addImport(\"java.util.Set\")/>\n <@call this.addImport(\"javax.validation.ConstraintViolation\")/>\n Set<ConstraintViolation<${this.className}AddDTO>> set = validator.validate(addDTO);\n if (!set.isEmpty()) {\n ConstraintViolation<${this.className}AddDTO> violation = set.stream().findFirst().get();\n String errorMsg = \"第\" + (excelDTO.getRowIndex() + 1) + \"行数据不合法:\" + violation.getMessage();\n <@call this.addImport(\"javax.validation.ConstraintViolationException\")/>\n throw new ConstraintViolationException(errorMsg, set);\n }\n return addDTO;\n })\n <@call this.addImport(\"java.util.stream.Collectors\")/>\n .collect(Collectors.toList());\n int count = ${this.classNameLower}Service.batchSave(list);\n return ResponseEntity.ok(count);\n }\n\n <#assign dicSet = CommonTemplateFunction.createHashSet()>\n <#list this.insertFields as id,field>\n <#if field.dicType??>\n <@justCall dicSet.add(field.dicType)/>\n </#if>\n </#list>\n @Override\n @GetMapping(\"/template\")\n <@call this.addImport(\"javax.servlet.http.HttpServletResponse\")/>\n public void downloadExcelTemplate(HttpServletResponse response) throws Exception {\n response.setContentType(\"application/vnd.ms-excel\");\n response.setCharacterEncoding(\"utf-8\");\n <@call this.addImport(\"java.util.Date\")/>\n <@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n String title = \"${this.title}导入模板(\" + DateUtil.getDateStr(new Date()) + \")\";\n <@call this.addImport(\"java.net.URLEncoder\")/>\n String fileName = URLEncoder.encode(title, \"utf-8\");\n response.setHeader(\"Content-disposition\", \"attachment;filename=\" + fileName + \".xlsx\");\n String[] description = new String[]{\n \"模版前三行标题请勿修改\",\n \"带“*”号为必填项\",\n <#if fkFieldsForInsert?hasContent>\n <#assign fkFieldNames = \"\">\n <#list fkFieldsForInsert as fkField>\n <#assign fkFieldNames += \"“${fkField.fieldDesc}”\">\n <#if fkField?hasNext>\n <#assign fkFieldNames += \"、\">\n </#if>\n </#list>\n \"${fkFieldNames}请填入id值\",\n </#if>\n <#if withinEntityList?hasContent>\n <#assign withinTitles = \"\">\n <#list withinEntityList as otherEntity>\n <#assign withinTitles += \"“${otherEntity.title}”\">\n <#if otherEntity?hasNext>\n <#assign withinTitles += \"、\">\n </#if>\n </#list>\n \"${withinTitles}支持一次性填入多个id(请用英文逗号分隔)\",\n </#if>\n };\n <#list dicSet as dic>\n <@call this.addImport(\"java.util.Arrays\")/>\n <@call this.addConstImport(dic)/>\n String[] ${dic?uncapFirst}Constraint = Arrays.stream(${dic}.values()).map(${dic}::getDesc).toArray(String[]::new);\n </#list>\n <@call this.addImport(\"com.alibaba.excel.ExcelWriter\")/>\n ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())\n <#list this.insertFields as id,field>\n <#if field.dicType??>\n <@call this.addImport(\"${this.packageName}.excel.handler.ConstConstraintHandler\")/>\n .registerWriteHandler(new ConstConstraintHandler(${field.dicType?uncapFirst}Constraint, 3, 3, ${field?index}, ${field?index}))\n </#if>\n </#list>\n // 第一行是标题,第二行是说明\n <@call this.addImport(\"${this.packageName}.excel.handler.TitleDescriptionWriteHandler\")/>\n .registerWriteHandler(new TitleDescriptionWriteHandler(title, description, ${this.className}ExcelDTO.class))\n // 自定义模板单元格样式\n <@call this.addImport(\"${this.packageName}.excel.handler.TemplateCellStyleStrategy\")/>\n .registerWriteHandler(new TemplateCellStyleStrategy())\n .build();\n <@call this.addImport(\"com.alibaba.excel.write.metadata.WriteSheet\")/>\n WriteSheet writeSheet = EasyExcel.writerSheet(0, \"Sheet1\")\n .head(${this.className}ExcelDTO.class)\n // 从第三行开始写表头\n .relativeHeadRowIndex(2)\n .build();\n <@call this.addImport(\"java.util.Arrays\")/>\n excelWriter.write(Arrays.asList(${this.className}ExcelDTO.example()), writeSheet);\n\n excelWriter.finish();\n }\n\n</#if>\n}\n\n</#assign>\n<#--开始渲染代码-->\npackage ${restPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(173,'IpUtil.java.ftl','/{webModule}/src/main/java/{packageName}/web/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.slf4j.Logger\")/>\n<@call this.addImport(\"org.slf4j.LoggerFactory\")/>\n<@call this.addImport(\"javax.servlet.http.HttpServletRequest\")/>\n<@call this.addImport(\"java.net.InetAddress\")/>\n<@call this.addImport(\"java.net.NetworkInterface\")/>\n<@call this.addImport(\"java.net.SocketException\")/>\n<@call this.addImport(\"java.util.Enumeration\")/>\n<@call this.addImport(\"java.util.regex.Matcher\")/>\n<@call this.addImport(\"java.util.regex.Pattern\")/>\n<@call this.printClassCom(\"IP工具\")/>\npublic class IpUtil {\n\n private static final Logger LOGGER = LoggerFactory.getLogger(IpUtil.class);\n\n /**\n * 获取客户端ip\n *\n * @param request request\n * @return\n */\n public static String getIpAddr(HttpServletRequest request) {\n String ip = request.getHeader(\"x-forwarded-for\");\n if (ip != null && ip.length() != 0 && !\"unknown\".equalsIgnoreCase(ip)) {\n if (ip.indexOf(\",\") != -1) {\n ip = ip.split(\",\")[0];\n }\n }\n if (ip == null || ip.length() == 0 || \"unknown\".equalsIgnoreCase(ip)) {\n ip = request.getHeader(\"Proxy-Client-IP\");\n }\n if (ip == null || ip.length() == 0 || \"unknown\".equalsIgnoreCase(ip)) {\n ip = request.getHeader(\"WL-Proxy-Client-IP\");\n }\n if (ip == null || ip.length() == 0 || \"unknown\".equalsIgnoreCase(ip)) {\n ip = request.getHeader(\"HTTP_CLIENT_IP\");\n }\n if (ip == null || ip.length() == 0 || \"unknown\".equalsIgnoreCase(ip)) {\n ip = request.getHeader(\"HTTP_X_FORWARDED_FOR\");\n }\n if (ip == null || ip.length() == 0 || \"unknown\".equalsIgnoreCase(ip)) {\n ip = request.getHeader(\"X-Real-IP\");\n }\n if (ip == null || ip.length() == 0 || \"unknown\".equalsIgnoreCase(ip)) {\n ip = request.getRemoteAddr();\n }\n return ip;\n }\n\n /**\n * 是否是ipv4\n *\n * @param ipAddress\n * @return\n */\n public static boolean isIpv4(String ipAddress) {\n\n String ip = \"^(1\\\\d{2}|2[0-4]\\\\d|25[0-5]|[1-9]\\\\d|[1-9])\\\\.\"\n + \"(00?\\\\d|1\\\\d{2}|2[0-4]\\\\d|25[0-5]|[1-9]\\\\d|\\\\d)\\\\.\"\n + \"(00?\\\\d|1\\\\d{2}|2[0-4]\\\\d|25[0-5]|[1-9]\\\\d|\\\\d)\\\\.\"\n + \"(00?\\\\d|1\\\\d{2}|2[0-4]\\\\d|25[0-5]|[1-9]\\\\d|\\\\d)$\";\n\n Pattern pattern = Pattern.compile(ip);\n Matcher matcher = pattern.matcher(ipAddress);\n return matcher.matches();\n\n }\n\n /**\n * 获取本地ip\n *\n * @return\n */\n public static String getLocalIp() {\n String localip = null;\n String netip = null;\n try {\n Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces();\n InetAddress ip = null;\n boolean finded = false;\n do {\n NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement();\n Enumeration address = ni.getInetAddresses();\n while (address.hasMoreElements()) {\n ip = (InetAddress) address.nextElement();\n\n if ((!ip.isSiteLocalAddress()) && (!ip.isLoopbackAddress()) &&\n (ip.getHostAddress().indexOf(\":\") == -1)) {\n netip = ip.getHostAddress();\n finded = true;\n break;\n }\n if ((ip.isSiteLocalAddress()) &&\n (!ip.isLoopbackAddress()) &&\n (ip.getHostAddress().indexOf(\":\") == -1)) {\n localip = ip.getHostAddress();\n }\n }\n if (!netInterfaces.hasMoreElements()) {\n break;\n }\n } while (!finded);\n } catch (SocketException e) {\n LOGGER.error(\"获取本地ip异常\", e);\n }\n if ((netip != null) && (!\"\".equals(netip))) {\n return netip;\n }\n return localip;\n }\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.web.util;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(174,'application.yml.ftl','/{webModule}/src/main/resources',1,1,1,'<#include \"/abstracted/common.ftl\">\nserver:\n servlet:\n context-path: /\n encoding:\n # 强制指定响应头content-type是utf-8编码\n force: true\n port: 8080\nspring:\n application:\n name: ${this.originProjectName}\n profiles:\n active: local\n\nspringfox:\n documentation:\n enabled: false\n\n\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(175,'application-local.yml.ftl','/{webModule}/src/main/resources',1,1,1,'<#include \"/abstracted/common.ftl\">\nspring:\n datasource:\n url: jdbc:mysql://localhost:3306/${this.originProjectName}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai\n username: root\n password: root\nspringfox:\n documentation:\n enabled: true\n\nlogging:\n level:\n ${this.packageName}: debug\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(176,'__dir.ftl','/{webModule}/src/test/java/{packageName}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${packageNamePath}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(177,'AbstractTest.java.ftl','/{webModule}/src/test/java/{packageName}',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.junit.Before\")/>\n<@call this.addImport(\"org.junit.runner.RunWith\")/>\n<@call this.addImport(\"org.springframework.beans.factory.annotation.Autowired\")/>\n<@call this.addImport(\"org.springframework.beans.factory.annotation.Value\")/>\n<@call this.addImport(\"org.springframework.boot.test.context.SpringBootTest\")/>\n<@call this.addImport(\"org.springframework.test.context.junit4.SpringRunner\")/>\n<@call this.printClassCom(\"单元测试抽象类\")/>\n@RunWith(SpringRunner.class)\n@SpringBootTest(classes = ${this.projectNameUpper}App.class)\npublic class AbstractTest {\n\n @Autowired(required = false)\n protected H2Flusher h2Flusher;\n\n @Value(\"${r\'$\'}{spring.datasource.url}\")\n private String jdbcUrl;\n\n @Before\n public void setUp() throws Exception {\n if (!jdbcUrl.startsWith(\"jdbc:h2:mem:\")) {\n return;\n }\n if (h2Flusher == null) {\n throw new RuntimeException(\"请使用H2内存数据库作为数据源\");\n }\n // 每次执行单元测试之前都要刷新数据库\n h2Flusher.flushDB();\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(178,'H2Flusher.java.ftl','/{webModule}/src/test/java/{packageName}',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.packageName}.util.H2Util\")/>\n<@call this.addImport(\"org.h2.engine.Mode\")/>\n<@call this.addImport(\"org.springframework.beans.factory.InitializingBean\")/>\n<@call this.addImport(\"org.springframework.jdbc.core.JdbcTemplate\")/>\n<@call this.addImport(\"java.util.HashMap\")/>\n<@call this.addImport(\"java.util.Map\")/>\n<@call this.printClassCom(\"H2数据库刷新器\")/>\npublic class H2Flusher implements InitializingBean {\n\n /**\n * 数据库脚本文件保存路径\n */\n private final Map<String, String> scriptFilePath;\n\n private final JdbcTemplate jdbcTemplate;\n\n public H2Flusher(JdbcTemplate jdbcTemplate, String... scriptFiles) {\n this.jdbcTemplate = jdbcTemplate;\n this.scriptFilePath = new HashMap<>();\n for (String scriptFile : scriptFiles) {\n scriptFilePath.put(scriptFile, H2Util.getH2Script(scriptFile));\n }\n }\n\n /**\n * 刷新H2数据库\n */\n public void flushDB() {\n jdbcTemplate.execute(\"drop all objects;\");\n for (String key : scriptFilePath.keySet()) {\n jdbcTemplate.execute(\"runscript from \'\" + scriptFilePath.get(key) + \"\'\");\n }\n }\n\n @Override\n public void afterPropertiesSet() throws Exception {\n // 修改H2数据库配置\n Mode mode = Mode.getInstance(\"MYSQL\");\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(179,'Main.java.ftl','/{webModule}/src/test/java/{packageName}',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/checkFeatureForRest.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.junit.runner.RunWith\")/>\n<@call this.addImport(\"org.junit.runners.Suite\")/>\n<@call this.printClassCom(\"合并测试类\")/>\n@RunWith(Suite.class)\n@Suite.SuiteClasses({\n<#list this.metaEntities as metaEntity>\n <#if getGenRest(metaEntity)>\n <#if metaEntity.module?hasContent>\n <@call this.addImport(\"${this.packageName}.web.rest.${metaEntity.module}.${metaEntity.className}ControllerTest\")/>\n <#else>\n <@call this.addImport(\"${this.packageName}.web.rest.${metaEntity.className}ControllerTest\")/>\n </#if>\n ${metaEntity.className}ControllerTest.class,\n </#if>\n</#list>\n})\npublic class Main {\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(180,'TestConfiguration.java.ftl','/{webModule}/src/test/java/{packageName}',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"org.springframework.context.annotation.Bean\")/>\n<@call this.addImport(\"org.springframework.context.annotation.Configuration\")/>\n<@call this.addImport(\"org.springframework.jdbc.core.JdbcTemplate\")/>\n<@call this.printClassCom(\"测试配置类\")/>\n@Configuration\npublic class TestConfiguration {\n\n @Bean\n public H2Flusher h2Flusher(JdbcTemplate jdbcTemplate) {\n return new H2Flusher(jdbcTemplate, \"DB/${this.projectName}.sql\");\n }\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(181,'__dir.ftl','/{webModule}/src/test/java/{packageName}/help/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(182,'__{ClassName}Helper.java.ftl','/{webModule}/src/test/java/{packageName}/help/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}Helper.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(183,'{ClassName}Helper.java.ftl','/{webModule}/src/test/java/{packageName}/help/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${dtoPackageName}.*\")/>\n<@call this.addImport(\"${poPackageName}.*\")/>\n<@call this.addImport(\"org.springframework.stereotype.Component\")/>\n<@call this.addStaticImport(\"${examplePackageName}.${this.className}Example.*\")/>\n@Component\npublic class ${this.className}Helper {\n\n <@call this.addAutowired(\"${servicePackageName}\" \"${this.className}Service\")/>\n <@call this.printAutowired()/>\n\n <#--定义外键字段参数串-->\n <#assign foreignArg=\"\">\n <#assign foreignArg2=\"\">\n <#list this.insertFields as id,field>\n <#if field.foreignKey>\n <#assign foreignArg=foreignArg+\"${field.jfieldType} ${field.jfieldName}, \">\n <#assign foreignArg2=foreignArg2+\"${field.jfieldName}, \">\n </#if>\n </#list>\n <#if foreignArg?length gt 0>\n <#assign foreignArg=foreignArg?substring(0,foreignArg?length-2)>\n <#assign foreignArg2=foreignArg2?substring(0,foreignArg2?length-2)>\n </#if>\n /**\n * 生成add测试数据\n *\n * @return\n */\n public ${this.className}AddDTO get${this.className}AddDTO(${foreignArg}) {\n ${this.className}AddDTO dto = new ${this.className}AddDTO();\n <#list this.insertFields as id,field>\n <#--字段名转下划线大写-->\n <#assign jfieldNameSnakeCase = CommonTemplateFunction.camelCaseToSnakeCase(field.jfieldName,true)>\n <#assign arg=\"\">\n <#if field.foreignKey>\n <#assign arg=\"${field.jfieldName}\">\n <#elseIf field.jfieldType == JFieldType.STRING.getJavaType()>\n <#assign arg=\"E_${jfieldNameSnakeCase}\">\n <#elseIf field.jfieldType == JFieldType.DATE.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n <#assign arg=\"DateUtil.parseDate(E_${jfieldNameSnakeCase})\">\n <#elseIf field.jfieldType == JFieldType.LOCALDATE.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n <#assign arg=\"DateUtil.parseLocalDate(E_${jfieldNameSnakeCase})\">\n <#elseIf field.jfieldType == JFieldType.LOCALDATETIME.getJavaType()>\n <@call this.addImport(\"${this.commonPackage}.util.DateUtil\")/>\n <#assign arg=\"DateUtil.parseLocalDateTime(E_${jfieldNameSnakeCase})\">\n <#elseIf field.jfieldType == JFieldType.BIGDECIMAL.getJavaType()>\n <@call this.addImport(\"java.math.BigDecimal\")/>\n <@call this.addImport(\"${this.commonPackage}.util.SafeUtil\")/>\n <#assign arg=\"SafeUtil.get${field.jfieldType}(E_${jfieldNameSnakeCase})\">\n <#else>\n <@call this.addImport(\"${this.commonPackage}.util.SafeUtil\")/>\n <#assign arg=\"SafeUtil.get${field.jfieldType}(E_${jfieldNameSnakeCase})\">\n </#if>\n dto.set${field.jfieldName?capFirst}(${arg});\n </#list>\n return dto;\n }\n\n\n /**\n * 生成update测试数据\n *\n * @return\n */\n public ${this.className}UpdateDTO get${this.className}UpdateDTO(${this.className}PO ${this.classNameLower}) {\n ${this.className}UpdateDTO dto = new ${this.className}UpdateDTO();\n dto.set${this.idUpper}(${this.classNameLower}.get${this.idUpper}());\n <#list this.updateFields as id,field>\n dto.set${field.jfieldName?capFirst}(${this.classNameLower}.get${field.jfieldName?capFirst}());\n </#list>\n return dto;\n }\n\n /**\n * 保存示例\n *\n * @return\n */\n public ${this.className}PO save${this.className}Example(${foreignArg}) {\n ${this.className}AddDTO addDTO = this.get${this.className}AddDTO(${foreignArg2});\n return ${this.classNameLower}Service.save(addDTO);\n }\n\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${helpPackageName};\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(184,'H2Util.java.ftl','/{webModule}/src/test/java/{packageName}/util',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n <@call this.addImport(\"${this.commonPackage}.util.TempDirUtil\")/>\n <@call this.addImport(\"com.google.common.base.Joiner\")/>\n <@call this.addImport(\"com.granveaud.mysql2h2converter.SQLParserManager\")/>\n <@call this.addImport(\"com.granveaud.mysql2h2converter.sql.*\")/>\n <@call this.addImport(\"org.apache.commons.io.FileUtils\")/>\n <@call this.addImport(\"org.slf4j.Logger\")/>\n <@call this.addImport(\"org.slf4j.LoggerFactory\")/>\n <@call this.addImport(\"java.io.BufferedReader\")/>\n <@call this.addImport(\"java.io.File\")/>\n <@call this.addImport(\"java.io.InputStream\")/>\n <@call this.addImport(\"java.io.InputStreamReader\")/>\n <@call this.addImport(\"java.net.URL\")/>\n <@call this.addImport(\"java.nio.charset.StandardCharsets\")/>\n <@call this.addImport(\"java.util.*\")/>\n <@call this.printClassCom(\"H2数据库工具类\")/>\npublic class H2Util {\n\n /**\n * 修改数据库脚本并保存到临时目录\n *\n * @param pathInClass 文件在classpath下路径\n * @return 临时文件路径\n */\n public static String getH2Script(String pathInClass) {\n String tempFolder = TempDirUtil.getTmpDir(null, true, false);\n String path = tempFolder + File.separator + pathInClass;\n File file = new File(path);\n File parentFile = file.getParentFile();\n if (!parentFile.exists()) {\n parentFile.mkdirs();\n }\n try {\n ClassLoader classLoader = H2Util.class.getClassLoader();\n URL resource = classLoader.getResource(pathInClass);\n assert resource != null;\n InputStream inputStream = resource.openStream();\n StringBuilder h2Sql = new StringBuilder();\n BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));\n Iterator<SqlStatement> sourceIterator = SQLParserManager.parseScript(reader);\n\n // conversion and execution\n Iterator<SqlStatement> it = H2Converter.convertScript(sourceIterator);\n while (it.hasNext()) {\n SqlStatement st = it.next();\n h2Sql.append(st.toString()).append(\";\");\n }\n FileUtils.write(file, h2Sql.toString(), StandardCharsets.UTF_8);\n } catch (Exception e) {\n throw new RuntimeException(e);\n }\n return path;\n }\n\n static class H2Converter {\n final static private Logger LOGGER = LoggerFactory.getLogger(H2Converter.class);\n\n static Iterator<SqlStatement> convertScript(Iterator<SqlStatement> sourceIterator) {\n return new ConverterIterator(sourceIterator);\n }\n\n static class ConverterIterator implements Iterator<SqlStatement> {\n private final Map<String, Integer> indexNameOccurrences = new HashMap<>();\n private final List<SqlStatement> delayedStatements = new ArrayList<>();\n\n private final Iterator<SqlStatement> sourceIterator;\n private final List<SqlStatement> nextStatements = new ArrayList<>();\n private Iterator<SqlStatement> nextStatementIterator, delayedStatementsIterator;\n\n ConverterIterator(Iterator<SqlStatement> sourceIterator) {\n this.sourceIterator = sourceIterator;\n loadNextStatements();\n }\n\n private void loadNextStatements() {\n while (true) {\n SqlStatement sourceNextStatement = sourceIterator.next();\n if (sourceNextStatement == null) {\n // finished source statements\n nextStatementIterator = null;\n if (!delayedStatements.isEmpty()) {\n // now iterate on delayed statements\n delayedStatementsIterator = delayedStatements.iterator();\n }\n return;\n }\n nextStatements.clear();\n convertStatement(sourceNextStatement, nextStatements);\n\n if (!nextStatements.isEmpty()) {\n nextStatementIterator = nextStatements.iterator();\n return;\n }\n }\n }\n\n @Override\n public boolean hasNext() {\n return (nextStatementIterator != null) || (delayedStatementsIterator != null && delayedStatementsIterator.hasNext());\n }\n\n @Override\n public SqlStatement next() {\n // iterator is on delayed statements\n if (delayedStatementsIterator != null) {\n return delayedStatementsIterator.next();\n }\n\n // iterator is on conversion of source iterator\n SqlStatement next = nextStatementIterator.next();\n if (!nextStatementIterator.hasNext()) {\n loadNextStatements();\n }\n\n return next;\n }\n\n @Override\n public void remove() {\n throw new UnsupportedOperationException();\n }\n\n private void convertStatement(SqlStatement sourceStatement, List<SqlStatement> result) {\n if (sourceStatement instanceof EmptyStatement) {\n // ignore empty statements\n } else if (sourceStatement instanceof LockTablesStatement || sourceStatement instanceof UnlockTablesStatement) {\n // do not copy, MySQL specific\n } else if (sourceStatement instanceof SetVariableStatement) {\n // do not copy, SET statement are usually MySQL specific\n } else if (sourceStatement instanceof StartTransactionStatement) {\n // replace with H2 equivalent\n result.add(new SetStatement(\"AUTOCOMMIT\", Collections.singletonList(new ExpressionValue(\"OFF\"))));\n } else if (sourceStatement instanceof CommitTransactionStatement) {\n // replace with H2 equivalent\n result.add(new CommitTransactionStatement());\n result.add(new SetStatement(\"AUTOCOMMIT\", Collections.singletonList(new ExpressionValue(\"ON\"))));\n } else if (sourceStatement instanceof UseStatement) {\n // USE dbName => SET SCHEMA dbName\n UseStatement useStatement = (UseStatement) sourceStatement;\n result.add(new SetStatement(\"SCHEMA\", Collections.singletonList(new StringValue(useStatement.getDbName()))));\n\n } else if (sourceStatement instanceof CreateDatabaseStatement) {\n // CREATE DATABASE => CREATE SCHEMA\n CreateDatabaseStatement createStatement = (CreateDatabaseStatement) sourceStatement;\n result.add(new CreateSchemaStatement(createStatement.getDbName(), createStatement.isIfNotExists()));\n\n } else if (sourceStatement instanceof CreateTableStatement) {\n CreateTableStatement createStatement = (CreateTableStatement) sourceStatement;\n\n // ignore MySQL create table specific options\n createStatement.setOptions(null);\n\n // handle duplicate index names in KEY and index names conflicting with reserved keywords\n handleCreateTableIndexNames(createStatement, indexNameOccurrences);\n\n // handle CHARACTER SET and COLLATION column definition, remove ON UPDATE\n handleCreateTableColumnDefinitions(createStatement);\n\n // handle KEY (colName(length)): length cannot be specified with H2\n handleCreateTableKeyColumnNameLength(createStatement);\n\n // 1) handle when foreign key check is disabled: add foreign key constraints at the end\n // 2) remove USING indexType\n handleCreateTableConstraints(createStatement, delayedStatements);\n\n result.add(sourceStatement);\n\n } else if (sourceStatement instanceof InsertStatement) {\n InsertStatement insertStatement = (InsertStatement) sourceStatement;\n\n // handle invalid \'0000-00-00 00:00:00\' datetime and binary values\n if (insertStatement.getValues() != null) {\n handleInsertValues(insertStatement);\n }\n\n result.add(sourceStatement);\n\n } else {\n // general case: add statement unchanged\n result.add(sourceStatement);\n }\n }\n\n private void handleCreateTableIndexNames(CreateTableStatement createStatement, Map<String, Integer> indexNameOccurrences) {\n for (ColumnConstraint constraint : createStatement.getDefinition().getConstraints()) {\n if (constraint.getIndexName() != null) {\n String indexName = DbUtils.unescapeDbObjectName(constraint.getIndexName()).toUpperCase();\n\n // replace with unique name\n Integer occurrence = indexNameOccurrences.getOrDefault(indexName, 0);\n constraint.setIndexName(\"`\" + indexName + \"_\" + occurrence + \"`\");\n\n // increment occurrence for next time\n indexNameOccurrences.put(indexName, occurrence + 1);\n }\n }\n }\n\n private void handleCreateTableConstraints(CreateTableStatement createStatement, List<SqlStatement> delayedStatements) {\n Iterator<ColumnConstraint> it = createStatement.getDefinition().getConstraints().iterator();\n while (it.hasNext()) {\n ColumnConstraint constraint = it.next();\n\n if (\"FOREIGN KEY\".equals(constraint.getType())) {\n delayedStatements.add(new AlterTableStatement(false, createStatement.getTableName(), Collections.singletonList(new AlterTableSpecification(\"ADD\", constraint))));\n it.remove();\n }\n if (\"KEY\".equals(constraint.getType())) {\n // Translate index types\n delayedStatements.add(new CreateIndexStatement(false, null, false, constraint.getIndexName(), createStatement.getTableName(), constraint.getIndexColumnNames()));\n it.remove();\n }\n\n constraint.setIndexType(null);\n }\n }\n\n private void handleCreateTableColumnDefinitions(CreateTableStatement createTableStatement) {\n for (ColumnDefinition def : createTableStatement.getDefinition().getColumnDefinitions()) {\n def.getColumnType().setCharsetName(null);\n def.getColumnType().setCollationName(null);\n def.setUpdateValue(null);\n }\n }\n\n private void handleCreateTableKeyColumnNameLength(CreateTableStatement createTableStatement) {\n for (ColumnConstraint constraint : createTableStatement.getDefinition().getConstraints()) {\n for (ColumnName columnName : constraint.getIndexColumnNames()) {\n if (columnName.getLength() != null) {\n LOGGER.warn(\"Remove length value in key/index column name\");\n columnName.setLength(null);\n }\n }\n }\n }\n\n private void handleInsertValues(InsertStatement insertStatement) {\n for (ValueList valueList : insertStatement.getValues()) {\n for (int i = 0; i < valueList.getValues().size(); i++) {\n Value value = valueList.getValues().get(i);\n if (value instanceof StringValue) {\n StringValue strValue = (StringValue) value;\n if (\"\'0000-00-00 00:00:00\'\".equals(strValue.getValue())) {\n // replace \'0000-00-00 00:00:00\' datetime value\n // this is not correct because \'0000-00-00 00:00:00\' could be a real string value\n LOGGER.warn(\"Replace \'0000-00-00 00:00:00\' with valid H2 datetime (unsafe replacement)\");\n value = new StringValue(\"\'0001-01-01 00:00:00\'\");\n } else if (strValue.getValue().contains(\"\\\\\")) {\n // handle \\n, \\\' ...\n value = DbUtils.transformStringValue(strValue.getValue());\n }\n\n valueList.getValues().set(i, value);\n\n } else if (value instanceof BinaryValue) {\n // be sure to use X\'hex\' format\n ((BinaryValue) value).setFormat(BinaryValue.Format.FORMAT1);\n } else if (value instanceof BitFieldValue) {\n BitFieldValue bitFieldValue = (BitFieldValue) value;\n if (\"1\".equals(bitFieldValue.getBits())) {\n valueList.getValues().set(i, new BooleanValue(true));\n } else if (\"0\".equals(bitFieldValue.getBits())) {\n valueList.getValues().set(i, new BooleanValue(false));\n } else {\n LOGGER.warn(\"Don\'t know how to convert BitFieldValue \" + bitFieldValue.getBits() + \" for H2\");\n }\n }\n }\n }\n }\n }\n }\n\n static class DbUtils {\n\n static String unescapeDbObjectName(String str) {\n if (str.startsWith(\"\\\"\") || str.startsWith(\"`\") || str.startsWith(\"\'\")) {\n return str.substring(1, str.length() - 1);\n }\n return str;\n }\n\n static Value transformStringValue(String str) {\n // we just have to transform \\\' to \'\'. STRINGDECODE will take care of the rest\n StringBuilder sb = new StringBuilder();\n int i = 1;\n while (i < str.length() - 1) {\n char c = str.charAt(i++);\n if (c == \'\\\\\') {\n if (i < str.length() - 1) {\n char nextChar = str.charAt(i++);\n if (nextChar == \'\\\'\') {\n sb.append(\"\'\'\");\n } else {\n sb.append(c).append(nextChar);\n }\n } else {\n sb.append(c);\n }\n } else {\n sb.append(c);\n }\n }\n return new ExpressionValue(\"STRINGDECODE(\'\" + sb.toString() + \"\')\");\n }\n }\n\n static class CreateIndexStatement implements SqlStatement {\n private final boolean unique;\n private final boolean ifNotExists;\n private final String tableName;\n private final String indexType;\n private final String indexName;\n private final List<ColumnName> columnNames;\n\n CreateIndexStatement(boolean unique, String indexType, boolean ifNotExists, String indexName, String tableName, List<ColumnName> columnNames) {\n this.unique = unique;\n this.indexName = indexName;\n this.indexType = indexType;\n this.ifNotExists = ifNotExists;\n this.tableName = tableName;\n this.columnNames = columnNames;\n }\n\n @Override\n public String toString() {\n return \"CREATE\" + (unique ? \" UNIQUE\" : \"\") + (indexType != null ? \" \" + indexType : \"\") + \" INDEX\" + (ifNotExists ? \" IF NOT EXISTS\" : \"\") +\n (indexName != null ? \" \" + indexName : \"\") +\n \" ON \" + tableName + \" (\" + Joiner.on(\',\').join(columnNames) + \")\"\n ;\n }\n }\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.util;\n\n<@call this.printImport()/>\n\n${code}\n\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(185,'AbstractWebTest.java.ftl','/{webModule}/src/test/java/{packageName}/web',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#--定义主体代码-->\n<#assign code>\n<@call this.addImport(\"${this.packageName}.AbstractTest\")/>\n<@call this.addImport(\"org.springframework.beans.factory.annotation.Autowired\")/>\n<@call this.addImport(\"org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc\")/>\n<@call this.addImport(\"org.springframework.test.web.servlet.MockMvc\")/>\n<@call this.printClassCom(\"web单元测试抽象类\")/>\n@AutoConfigureMockMvc(printOnlyOnFailure = false)\npublic abstract class AbstractWebTest extends AbstractTest {\n\n @Autowired\n protected MockMvc restMockMvc;\n\n}\n</#assign>\n<#--开始渲染代码-->\npackage ${this.packageName}.web;\n\n<@call this.printImport()/>\n\n${code}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(186,'__dir.ftl','/{webModule}/src/test/java/{packageName}/web/rest/{module}',1,1,4,'<#-- 当前文件用于渲染目录 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(187,'__{ClassName}ControllerTest.java.ftl','/{webModule}/src/test/java/{packageName}/web/rest/{module}',1,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.className}ControllerTest.java\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(188,'{ClassName}ControllerTest.java.ftl','/{webModule}/src/test/java/{packageName}/web/rest/{module}',1,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/commonForEntity.ftl\">\n<#include \"/abstracted/checkFeatureForRest.ftl\">\n<#--判断如果不需要生成当前文件,则直接跳过-->\n<#if !getGenRest(this.metaEntity)>\n <@call this.skipCurrent()/>\n</#if>\n<@call this.addImport(\"${this.commonPackage}.util.JsonUtil\")/>\n<@call this.addImport(\"${helpPackageName}.${this.className}Helper\")/>\n<@call this.addImport(\"${poPackageName}.${this.className}PO\")/>\n<@call this.addImport(\"${this.packageName}.web.AbstractWebTest\")/>\n<@call this.addImport(\"${this.packageName}.web.constant.WebConst\")/>\n<@call this.addImport(\"org.junit.Test\")/>\n<@call this.addImport(\"org.springframework.beans.factory.annotation.Autowired\")/>\n<@call this.addImport(\"org.springframework.http.MediaType\")/>\n<@call this.addStaticImport(\"org.hamcrest.Matchers.is\")/>\n<@call this.addStaticImport(\"org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*\")/>\n<@call this.addStaticImport(\"org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath\")/>\n<@call this.addStaticImport(\"org.springframework.test.web.servlet.result.MockMvcResultMatchers.status\")/>\n<#--获取保存Example的代码-->\n<#assign saveExampleCode=this.getPrintingSaveExample()/>\n<#--定义方法区代码-->\n<#assign methodCode>\n<#if this.entityFeature.save>\n /**\n * 新增【${this.title}】\n */\n @Test\n public void save() throws Exception {\n <#list saveExampleCode as saveExample>\n <#if saveExample?hasNext>\n ${saveExample}\n </#if>\n </#list>\n <@call this.addImport(\"${dtoPackageName}.${this.className}AddDTO\")/>\n ${this.className}AddDTO addDTO = ${this.classNameLower}Helper.get${this.className}AddDTO(<@call this.printSaveExampleArg(this.metaEntity)/>);\n restMockMvc.perform(post(${renderApiPath(this.metaEntity, \"\")})\n .contentType(MediaType.APPLICATION_JSON)\n .content(JsonUtil.toJSONString(addDTO)))\n .andExpect(status().isCreated());\n }\n\n</#if>\n<#if this.entityFeature.update>\n /**\n * 修改【${this.title}】\n */\n @Test\n public void update() throws Exception {\n <#list saveExampleCode as saveExample>\n ${saveExample}\n </#list>\n <@call this.addImport(\"${dtoPackageName}.${this.className}UpdateDTO\")/>\n ${this.className}UpdateDTO updateDTO = ${this.classNameLower}Helper.get${this.className}UpdateDTO(${this.classNameLower});\n restMockMvc.perform(put(${renderApiPath(this.metaEntity, \"\")})\n .contentType(MediaType.APPLICATION_JSON)\n .content(JsonUtil.toJSONString(updateDTO)))\n .andExpect(status().isOk());\n }\n\n</#if>\n<#if this.entityFeature.list>\n /**\n <#if this.pageSign>\n * 分页查询【${this.title}】\n <#else>\n * 列表查询【${this.title}】\n </#if>\n */\n @Test\n public void list() throws Exception {\n <#list saveExampleCode as saveExample>\n ${saveExample}\n </#list>\n restMockMvc.perform(get(${renderApiPath(this.metaEntity, \"\")}))\n .andExpect(status().isOk())\n <#if this.pageSign>\n .andExpect(jsonPath(\"$.list.length()\").value(is(1)));\n <#else>\n .andExpect(jsonPath(\"$.length()\").value(is(1)));\n </#if>\n }\n\n</#if>\n<#if this.titleField??>\n /**\n * 查询【${this.title}】选项列表\n */\n @Test\n public void findOptions() throws Exception {\n <#list saveExampleCode as saveExample>\n ${saveExample}\n </#list>\n restMockMvc.perform(get(${renderApiPath(this.metaEntity, \"/options\")}))\n .andExpect(status().isOk())\n .andExpect(jsonPath(\"$.length()\").value(is(1)));\n }\n\n</#if>\n<#if this.entityFeature.show>\n /**\n * 查看【${this.title}】详情\n */\n @Test\n public void show() throws Exception {\n <#list saveExampleCode as saveExample>\n ${saveExample}\n </#list>\n restMockMvc.perform(get(${renderApiPath(this.metaEntity, \"/{${this.id}}\")}, ${this.classNameLower}.get${this.idUpper}()))\n .andExpect(status().isOk());\n }\n\n</#if>\n<#if this.entityFeature.delete>\n /**\n * 删除单个【${this.title}】\n */\n @Test\n public void del() throws Exception {\n <#list saveExampleCode as saveExample>\n ${saveExample}\n </#list>\n restMockMvc.perform(delete(${renderApiPath(this.metaEntity, \"/{${this.id}}\")}, ${this.classNameLower}.get${this.idUpper}()))\n .andExpect(status().isOk())\n .andExpect(jsonPath(\"$\").value(is(1)));\n }\n\n</#if>\n<#if this.entityFeature.deleteBatch>\n <@call this.addImport(\"com.google.common.collect.Lists\")/>\n /**\n * 批量删除【${this.title}】\n */\n @Test\n public void deleteBatch() throws Exception {\n <#list saveExampleCode as saveExample>\n ${saveExample}\n </#list>\n restMockMvc.perform(delete(${renderApiPath(this.metaEntity, \"\")})\n .contentType(MediaType.APPLICATION_JSON)\n .content(JsonUtil.toJSONString(Lists.newArrayList(${this.classNameLower}.get${this.idUpper}()))))\n .andExpect(status().isOk())\n .andExpect(jsonPath(\"$\").value(is(1)));\n }\n\n</#if>\n<#list this.holds! as otherEntity,mtm>\n <#assign otherPk=otherEntity.pkField>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign otherFkId=mtm.getFkAlias(otherEntity.entityId,false)>\n <#--获取保存Example的代码-->\n <#assign saveExampleCode=this.getPrintingSaveExampleForMtm(otherEntity)/>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.addRemove>\n <@call this.addImport(\"com.google.common.collect.Lists\")/>\n /**\n * 添加/移除【${otherEntity.title}】关联\n */\n @Test\n public void addRemove${otherCName}2() throws Exception {\n <#list saveExampleCode as saveExample>\n ${saveExample}\n </#list>\n // 先测试添加【${otherEntity.title}】关联\n restMockMvc.perform(post(${renderApiPath(this.metaEntity, \"/{${this.id}}/${othercName}\")},\n ${this.classNameLower}.get${this.idUpper}())\n .contentType(MediaType.APPLICATION_JSON)\n .content(JsonUtil.toJSONString(Lists.newArrayList(${othercName}.get${otherPk.jfieldName?capFirst}()))))\n .andExpect(status().isOk())\n .andExpect(jsonPath(\"$\").value(is(1)));\n // 再测试查询【${otherEntity.title}】关联\n restMockMvc.perform(get(${renderApiPath(this.metaEntity, \"/{${this.id}}/${othercName}\")},\n ${this.classNameLower}.get${this.idUpper}()))\n .andExpect(status().isOk())\n .andExpect(jsonPath(\"$.length()\").value(is(1)));\n // 最后测试移除【${otherEntity.title}】关联\n restMockMvc.perform(delete(${renderApiPath(this.metaEntity, \"/{${this.id}}/${othercName}\")},\n ${this.classNameLower}.get${this.idUpper}())\n .contentType(MediaType.APPLICATION_JSON)\n .content(JsonUtil.toJSONString(Lists.newArrayList(${othercName}.get${otherPk.jfieldName?capFirst}()))))\n .andExpect(status().isOk())\n .andExpect(jsonPath(\"$\").value(is(1)));\n }\n\n </#if>\n <#if entityFeature.set>\n <@call this.addImport(\"com.google.common.collect.Lists\")/>\n /**\n * 设置【${otherEntity.title}】关联\n */\n @Test\n public void set${otherCName}() throws Exception {\n <#list saveExampleCode as saveExample>\n ${saveExample}\n </#list>\n // 先测试设置【${otherEntity.title}】关联\n restMockMvc.perform(put(${renderApiPath(this.metaEntity, \"/{${this.id}}/${othercName}\")},\n ${this.classNameLower}.get${this.idUpper}())\n .contentType(MediaType.APPLICATION_JSON)\n .content(JsonUtil.toJSONString(Lists.newArrayList(${othercName}.get${otherPk.jfieldName?capFirst}()))))\n .andExpect(status().isOk())\n .andExpect(jsonPath(\"$\").value(is(1)));\n // 再测试查询【${otherEntity.title}】关联\n restMockMvc.perform(get(${renderApiPath(this.metaEntity, \"/{${this.id}}/${othercName}\")},\n ${this.classNameLower}.get${this.idUpper}()))\n .andExpect(status().isOk())\n .andExpect(jsonPath(\"$.length()\").value(is(1)));\n }\n\n </#if>\n</#list>\n<#if this.entityFeature.excelImport>\n /**\n * 导入【${this.title}】excel\n */\n @Test\n public void importExcel() throws Exception {\n <@call this.addImport(\"org.springframework.test.web.servlet.MvcResult\")/>\n // 首先下载excel模板\n MvcResult mvcResult = restMockMvc.perform(get(${renderApiPath(this.metaEntity, \"/template\")}))\n .andExpect(status().isOk())\n .andReturn();\n <@call this.addImport(\"org.springframework.mock.web.MockHttpServletResponse\")/>\n MockHttpServletResponse response = mvcResult.getResponse();\n\n <@call this.addImport(\"org.springframework.mock.web.MockMultipartFile\")/>\n // 将模板原封不动导入\n MockMultipartFile file = new MockMultipartFile(\"file\", response.getContentAsByteArray());\n restMockMvc.perform(multipart(${renderApiPath(this.metaEntity, \"/import\")})\n .file(file))\n .andExpect(status().isOk())\n .andExpect(jsonPath(\"$\").value(is(1)));\n }\n\n</#if>\n</#assign>\n<#--开始渲染代码-->\npackage ${restPackageName};\n\n<@call this.printImport()/>\n\n<@call this.printClassCom(\"【${this.title}】单元测试\")/>\npublic class ${this.className}ControllerTest extends AbstractWebTest {\n\n<@call this.printAutowired()/>\n\n\n${methodCode}\n}\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(189,'application-local.yml.ftl','/{webModule}/src/test/resources',1,1,1,'<#include \"/abstracted/common.ftl\">\nspring:\n datasource:\n url: jdbc:h2:mem:testdb;MODE=MYSQL;DB_CLOSE_DELAY=-1\nlogging:\n level:\n root: info\n java:\n sql: debug\n ${this.packageName}: trace\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(190,'__{projectName}.sql.ftl','/{webModule}/src/test/resources/DB',1,1,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.projectName}.sql\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(191,'{projectName}.sql.ftl','/{webModule}/src/test/resources/DB',1,1,1,'<#include \"/abstracted/common.ftl\">\n<#list this.metaEntities as metaEntity>\nDROP TABLE IF EXISTS `${metaEntity.tableName}`;\n\nCREATE TABLE `${metaEntity.tableName}` (\n <#list metaEntity.fields as fieldId,field>\n <#assign comma_holder><#if metaEntity?hasNext || metaEntity.pkField?? || (metaEntity.indexes?? && (metaEntity.indexes?size > 0))>,</#if></#assign>\n `${field.fieldName}` ${field.fieldType}${SqlTemplateFunction.getLengthDisplay(field)}${SqlTemplateFunction.getAutoIncrementDisplay(field)}${SqlTemplateFunction.getNotNullDisplay(field)}${SqlTemplateFunction.getDefaultDisplay(field)}${SqlTemplateFunction.getCommentDisplay(field.fetchComment(),true)}${comma_holder}\n </#list>\n <#if metaEntity.pkField??>\n PRIMARY KEY (`${metaEntity.pkField.fieldName}`)<#if metaEntity.indexes?? && (metaEntity.indexes?size > 0)>,</#if>\n </#if>\n <#list metaEntity.indexes! as index>\n <#if index.unique>UNIQUE </#if>KEY `${index.indexName}` (<#list index.fields as field>`${field.fieldName}`<#if field?hasNext >,</#if></#list>) USING BTREE<#if index?hasNext>,</#if>\n </#list>\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4${SqlTemplateFunction.getCommentDisplay(metaEntity.desc,false)};\n\n</#list>\n<#list this.mtms! as mtm>\n <#assign field1=mtm.refer1.pkField>\n <#assign field2=mtm.refer2.pkField>\nDROP TABLE IF EXISTS `${mtm.tableName}`;\n\nCREATE TABLE `${mtm.tableName}` (\n <#if mtm.needId>\n `id` <#if mtm.bigId>bigint(20)<#else>int(11)</#if> AUTO_INCREMENT COMMENT \'主键\',\n </#if>\n `${mtm.fkAliasForSql1}` ${field1.fieldType}${SqlTemplateFunction.getLengthDisplay(field1)} NOT NULL${SqlTemplateFunction.getCommentDisplay(field1.fetchComment(),true)},\n `${mtm.fkAliasForSql2}` ${field2.fieldType}${SqlTemplateFunction.getLengthDisplay(field2)} NOT NULL${SqlTemplateFunction.getCommentDisplay(field2.fetchComment(),true)},\n `created_time` datetime DEFAULT NULL COMMENT \'创建时间\',\n <#if mtm.needId>\n PRIMARY KEY (`id`),\n </#if>\n KEY `IDX_${mtm.tableName?upperCase}_1` (`${mtm.fkAliasForSql1}`),\n KEY `IDX_${mtm.tableName?upperCase}_2` (`${mtm.fkAliasForSql2}`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4${SqlTemplateFunction.getCommentDisplay(mtm.desc,false)};\n\n</#list>\n','2021-01-08 17:12:50','admin','2021-01-08 17:12:50','admin',1,0),(192,'common.ftl','/abstracted',2,1,2,'<#-- 调用函数,如果存在输出则打印 -->\n<#macro call func><#if func??>${func}</#if></#macro>\n<#-- 仅调用函数,不打印 -->\n<#macro justCall func></#macro>\n\n<#-- 将当前model赋值给this变量 -->\n<#assign this = .dataModel>\n\n<#-- 初始化需要导入的枚举列表 -->\n<#assign importEnums = CommonTemplateFunction.createHashSet()>\n<#-- 初始化需要导入的其他实体列表 -->\n<#assign importOtherEntitys = CommonTemplateFunction.createHashSet()>\n\n\n<#-- 移除最后一个逗号 -->\n<#macro removeLastComma>\n<#local content><#nested></#local>\n${CommonTemplateFunction.removeLastComma(content)}</#macro>\n\n<#-- 首个单词转小写 -->\n<#function lowerFirstWord value>\n <#return \"${CommonTemplateFunction.lowerFirstWord(value)}\" >\n</#function>\n\n<#-- 根据常量名查找常量 -->\n<#function findConst constName>\n <#list this.metaConsts as const>\n <#if const.constName == constName>\n <#return const>\n </#if>\n </#list>\n</#function>\n\n<#-- 获取字段空值 -->\n<#function getFieldEmptyValue field>\n <#-- 日期类型不能用null -->\n <#if field.jfieldType == JFieldType.DATE.javaType\n || field.jfieldType == JFieldType.LOCALDATE.javaType\n || field.jfieldType == JFieldType.LOCALDATETIME.javaType>\n <#return \"\'\'\">\n <#elseIf field.editType == EditType.NUMBER.getValue()>\n <#return \"undefined\">\n <#else>\n <#return \"null\">\n </#if>\n</#function>\n\n\n<#-- 获取范围查询条件的文字提示语后缀 -->\n<#function getRangeQueryTipSuffix field isBetweenStart>\n <#if QueryType.isGe(field.queryType) || QueryType.isGt(field.queryType)>\n <#return \"(开始于)\">\n <#elseIf QueryType.isLe(field.queryType) || QueryType.isLt(field.queryType)>\n <#return \"(结束于)\">\n <#elseIf QueryType.isBetween(field.queryType)>\n <#if isBetweenStart>\n <#return \"(开始于)\">\n <#else>\n <#return \"(结束于)\">\n </#if>\n <#else>\n <#return \"\">\n </#if>\n</#function>\n\n<#-- 获取字段校验触发事件名称 -->\n<#function getRuleTrigger field>\n <#-- 日期类型不能用null -->\n <#if field.editType == EditType.SELECT.getValue()\n || field.editType == EditType.DATE.getValue()\n || field.editType == EditType.DATETIME.getValue()\n || field.editType == EditType.RADIO.getValue()>\n <#return \"change\">\n <#else>\n <#return \"blur\">\n </#if>\n</#function>\n\n<#-- 导入api -->\n<#function importApi className module>\n <#local className = lowerFirstWord(className)>\n <#if module?hasContent>\n <#return \"import ${className}Api from \'@/api/${module}/${className}\'\">\n <#else>\n <#return \"import ${className}Api from \'@/api/${className}\'\">\n </#if>\n</#function>\n\n<#-- 获取模块目录的父目录 -->\n<#function getParentPathForModule entity>\n <#if entity.module?hasContent>\n <#return \"..\">\n <#else>\n <#return \".\">\n </#if>\n</#function>\n\n<#-- 导入mock -->\n<#function importMock basePath entity>\n <#local className = lowerFirstWord(entity.className)>\n <#if entity.module?hasContent>\n <#return \"import ${className} from \'${basePath}/${entity.module}/${className}\'\">\n <#else>\n <#return \"import ${className} from \'${basePath}/${className}\'\">\n </#if>\n</#function>\n\n<#-- 导入view -->\n<#function importView className module>\n <#local name = lowerFirstWord(className)>\n <#if module?hasContent>\n <#return \"import(\'@/views/${module}/${name}\')\">\n <#else>\n <#return \"import(\'@/views/${name}\')\">\n </#if>\n</#function>\n\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(193,'commonForChart.ftl','/abstracted',2,1,2,'<#include \"/abstracted/common.ftl\">\n<#-- 判断当前图表的类型 -->\n<#function isChartType chartTypeEnum>\n <#return this.chartType == chartTypeEnum.getValue()>\n</#function>\n<#-- 柱线图的参数模式 -->\n<#assign barLineParamMode=0>\n<#if isChartType(ChartType.BAR_LINE)>\n <#if this.axisX2??>\n <#assign barLineParamMode=1>\n <#else>\n <#assign barLineParamMode=2>\n </#if>\n</#if>\n<#function buildBarLineSeries chartItem indent=\'\'>\n <#local seriesType = chartItem.seriesType>\n <#local series = \'\'>\n <#if !seriesType?? || seriesType == \'bar\'>\n <#local series = series + indent + \'type: \\\'bar\\\'\'>\n <#elseIf seriesType == \'line\'>\n <#local series = series + indent + \'type: \\\'line\\\'\'>\n <#elseIf seriesType == \'area-stack\'>\n <#local series = series + indent + \'type: \\\'line\\\',\\n\'>\n <#local series = series + indent + \'areaStyle: {},\\n\'>\n <#local series = series + indent + \'stack: \\\'总量\\\'\'>\n <#elseIf seriesType == \'bar-stack\'>\n <#local series = series + indent + \'type: \\\'bar\\\',\\n\'>\n <#local series = series + indent + \'areaStyle: {},\\n\'>\n <#local series = series + indent + \'stack: \\\'总量\\\'\'>\n <#elseIf seriesType == \'line-smooth\'>\n <#local series = series + indent + \'type: \\\'line\\\',\\n\'>\n <#local series = series + indent + \'smooth: true\'>\n </#if>\n <#return series>\n</#function>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(194,'commonForDashboard.ftl','/abstracted',2,1,2,'<#include \"/abstracted/common.ftl\">\n<#-- 图表集合 -->\n<#assign charts = CommonTemplateFunction.createHashSet()>\n<#list this.layout as item>\n <#if item.chart??>\n <@justCall charts.add(item.chart)/>\n </#if>\n</#list>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(195,'mtmCascadeExtsForList.ftl','/abstracted',2,1,2,'<#-- 功能简介:多对多级联扩展字段列表专用 -->\r\n<#include \"/abstracted/common.ftl\">\r\n<#--将所有需要列表展示的级联实体放入数组中-->\r\n<#assign mtmCascadeEntitiesForList = []>\r\n<#--将所有需要列表展示的多对多放入数组中-->\r\n<#assign mtmForList = []>\r\n<#--将所有级联扩展列表字段按级联实体分组放入数组中-->\r\n<#assign groupMtmCascadeExtsForList = []>\r\n<#--组装多对多级联扩展相关的数据结构-->\r\n<#list this.holds as otherEntity,mtm>\r\n <#--初始化当前级联实体对应的级联扩展列表字段-->\r\n <#assign mtmCascadeExts=[]>\r\n <#list mtm.getCascadeExtList(this.entityId) as mtmCascadeExt>\r\n <#assign cascadeField=mtmCascadeExt.cascadeField>\r\n <#--判断是否开启级联列表展示开关-->\r\n <#if mtmCascadeExt.list>\r\n <#assign mtmCascadeExts +=[mtmCascadeExt]>\r\n </#if>\r\n </#list>\r\n <#if mtmCascadeExts?hasContent>\r\n <#assign groupMtmCascadeExtsForList += [mtmCascadeExts]>\r\n <#assign mtmCascadeEntitiesForList += [otherEntity]>\r\n <#assign mtmForList += [mtm]>\r\n </#if>\r\n</#list>\r\n<#--判断级联扩展列表字段中是否有标题字段-->\r\n<#function hasTitleField otherEntity mtmCascadeExts>\r\n <#list mtmCascadeExts as cascadeExt>\r\n <#if otherEntity.titleField?? && otherEntity.titleField == cascadeExt.cascadeField>\r\n <#return true>\r\n </#if>\r\n </#list>\r\n <#return false>\r\n</#function>\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(196,'mtmCascadeExtsForQuery.ftl','/abstracted',2,1,2,'<#-- 功能简介:多对多级联扩展字段查询专用 -->\r\n<#include \"/abstracted/common.ftl\">\r\n<#--将所有级联扩展查询字段放入数组中-->\r\n<#assign mtmCascadeExtsForQuery = []>\r\n<#--将所有需要查询的级联实体放入数组中-->\r\n<#assign mtmCascadeEntitiesForQuery = []>\r\n<#--将所有需要查询的多对多放入数组中-->\r\n<#assign mtmForQuery = []>\r\n<#--将所有级联扩展查询字段按级联实体分组放入数组中-->\r\n<#assign groupMtmCascadeExtsForQuery = []>\r\n<#--定义宏:组装多对多级联扩展相关的数据结构-->\r\n<#macro buildMtmCascadeForQuery holds hostEntityId>\r\n <#list holds as otherEntity,mtm>\r\n <#--初始化当前级联实体对应的级联扩展查询字段-->\r\n <#assign mtmCascadeExts=[]>\r\n <#list mtm.getCascadeExtList(hostEntityId) as mtmCascadeExt>\r\n <#assign cascadeField=mtmCascadeExt.cascadeField>\r\n <#--开启级联查询开关 && (是主键 || 字段支持查询) -->\r\n <#if mtmCascadeExt.query && (cascadeField.primaryKey || cascadeField.query)>\r\n <#assign mtmCascadeExts +=[mtmCascadeExt]>\r\n <#assign mtmCascadeExtsForQuery += [mtmCascadeExt]>\r\n </#if>\r\n </#list>\r\n <#if mtmCascadeExts?hasContent>\r\n <#assign groupMtmCascadeExtsForQuery += [mtmCascadeExts]>\r\n <#assign mtmCascadeEntitiesForQuery += [otherEntity]>\r\n <#assign mtmForQuery += [mtm]>\r\n </#if>\r\n </#list>\r\n</#macro>\r\n<@buildMtmCascadeForQuery this.holds, this.entityId/>\r\n<@buildMtmCascadeForQuery this.unHolds, this.entityId/>\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(197,'mtmCascadeExtsForShow.ftl','/abstracted',2,1,2,'<#-- 功能简介:多对多级联扩展字段详情专用 -->\r\n<#include \"/abstracted/common.ftl\">\r\n<#--将所有需要详情展示的级联实体放入数组中-->\r\n<#assign mtmCascadeEntitiesForShow = []>\r\n<#--将所有需要详情展示的多对多放入数组中-->\r\n<#assign mtmForShow = []>\r\n<#--将所有级联扩展详情字段按级联实体分组放入数组中-->\r\n<#assign groupMtmCascadeExtsForShow = []>\r\n<#--组装多对多级联扩展相关的数据结构-->\r\n<#list this.holds as otherEntity,mtm>\r\n <#--初始化当前级联实体对应的级联扩展详情字段-->\r\n <#assign mtmCascadeExts=[]>\r\n <#list mtm.getCascadeExtList(this.entityId) as mtmCascadeExt>\r\n <#assign cascadeField=mtmCascadeExt.cascadeField>\r\n <#--判断是否开启级联详情展示开关-->\r\n <#if mtmCascadeExt.show>\r\n <#assign mtmCascadeExts +=[mtmCascadeExt]>\r\n </#if>\r\n </#list>\r\n <#if mtmCascadeExts?hasContent>\r\n <#assign groupMtmCascadeExtsForShow += [mtmCascadeExts]>\r\n <#assign mtmCascadeEntitiesForShow += [otherEntity]>\r\n <#assign mtmForShow += [mtm]>\r\n </#if>\r\n</#list>\r\n<#--根据id查询详情展示的级联实体序号-->\r\n<#function getMtmCascadeEntityIndexForShow entityId>\r\n <#list mtmCascadeEntitiesForShow as entity>\r\n <#if entity.entityId == entityId>\r\n <#return entity?index>\r\n </#if>\r\n </#list>\r\n <#return -1>\r\n</#function>\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(198,'table.ftl','/abstracted',2,1,2,'<#-- 功能简介:表格页面数据预处理 -->\r\n<#include \"/abstracted/common.ftl\">\r\n<#--表格是否可选择-->\r\n<#assign tableSelect=this.entityFeature.deleteBatch/>\r\n<#--表格是否可排序-->\r\n<#assign tableSort=this.listSortFields?? && this.listSortFields?size &gt; 0/>\r\n<#--表格是否需要操作列-->\r\n<#assign tableOperate=this.entityFeature.show || this.entityFeature.update || this.entityFeature.delete/>\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(199,'__dir.ftl','/mock/{module}',2,2,4,'<#-- 当前文件用于渲染父路径 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(200,'__{className}.js.ftl','/mock/{module}',2,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.classNameLower}.js\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(201,'{className}.js.ftl','/mock/{module}',2,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/table.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForShow.ftl\">\n<#-- 输出常规字段mock表达式 -->\n<#macro mockGeneralField field alias>\n <#local name = alias?hasContent?string(alias,field.jfieldName)/>\n <#-- 枚举的情况 -->\n <#if field.dicType??>\n <#assign const = findConst(field.dicType)>\n \'${field.jfieldName}|1\': [\n <@removeLastComma>\n <#list const.detailList as detail>\n <#if const.constType==MetaConstType.INTEGER>\n ${detail.detailValue},\n <#elseIf const.constType==MetaConstType.STRING>\n \'${detail.detailValue}\',\n </#if>\n </#list>\n </@removeLastComma>\n ],\n <#elseIf field.jfieldType == JFieldType.BOOLEAN.javaType>\n \'${name}|1\': true,\n <#elseIf field.jfieldType == JFieldType.INTEGER.javaType\n || field.jfieldType == JFieldType.SHORT.javaType\n || field.jfieldType == JFieldType.LONG.javaType>\n \'${name}|0-100\': 1,\n <#elseIf field.jfieldType == JFieldType.DOUBLE.javaType\n || field.jfieldType == JFieldType.FLOAT.javaType\n || field.jfieldType == JFieldType.BIGDECIMAL.javaType>\n \'${name}|0-100.1-2\': 1,\n <#elseIf field.jfieldType == JFieldType.DATE.javaType\n || field.jfieldType == JFieldType.LOCALDATE.javaType\n || field.jfieldType == JFieldType.LOCALDATETIME.javaType>\n <#if field.editType == EditType.DATE.getValue()>\n \'${name}\': \'@date(yyyy-MM-dd)\',\n <#else>\n \'${name}\': \'@date(yyyy-MM-dd) 00:00:00\',\n </#if>\n <#else>\n \'${name}\': \'@word(1, ${[field.fieldLength, 10]?min})\',\n </#if>\n</#macro>\nimport Mock from \'mockjs\'\nimport { <#if this.pageSign>paging, </#if>copy, getUrlPattern } from \'${getParentPathForModule(this.metaEntity)}/mock-util\'\n<#-- 引入依赖的其他mock -->\n<#list this.holds! as otherEntity,mtm>\n${importMock(getParentPathForModule(this.metaEntity), otherEntity)}\n</#list>\n\n/**\n * mock数据缓存\n */\nlet data = null\n\n/**\n * 获取mock数据缓存\n */\nfunction getMockData() {\n return data\n}\n\n/**\n * 初始化mock数据阶段1\n */\nfunction initMockDataStage1() {\n data = Mock.mock({\n \'list|20\': [{\n<@removeLastComma>\n <#list this.fields as id,field>\n <#-- 跳过既不是列表展示,也不是详情展示的字段 -->\n <#if !field.list && !field.show>\n <#continue>\n </#if>\n <#-- 主键的情况 -->\n <#if field.primaryKey>\n \'${field.jfieldName}|+1\': 1,\n <#-- 外键的情况 -->\n <#elseIf field.foreignKey>\n \'${field.jfieldName}|1-20\': 1,\n <#-- 常规情况 -->\n <#else>\n <@mockGeneralField field \"\"/>\n </#if>\n </#list>\n <#-- mock 外键级联扩展字段 -->\n <#list this.fkFields as id,field>\n <#list field.cascadeExts! as cascadeExt>\n <#if cascadeExt.show || cascadeExt.list>\n <@mockGeneralField cascadeExt.cascadeField cascadeExt.alias/>\n </#if>\n </#list>\n </#list>\n</@removeLastComma>\n }]\n })\n}\n\n/**\n * 初始化mock数据阶段2\n */\nfunction initMockDataStage2() {\n<#-- 初始化多对多关联 -->\n<#if this.holds!?hasContent>\n for (const item of data.list) {\n <#list this.holds! as otherEntity,mtm>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n item.${othercName}List = [Mock.Random.pick(${othercName}.getMockData().list)]\n </#list>\n }\n</#if>\n}\n\n<#if this.entityFeature.save>\n/**\n * 新的id生成规则\n */\nconst mockNewIdRule = {\n \'${this.id}|+1\': 21\n}\n\n</#if>\n<#if this.entityFeature.delete || this.entityFeature.deleteBatch>\nfunction removeById(list, ${this.id}) {\n const index = list.findIndex(item => item.${this.id} === ${this.id})\n list.splice(index, 1)\n}\n\n</#if>\n<#if this.module?hasContent>\nconst modulePath = \'${this.module}/${this.classNameLower}\'\n<#else>\nconst modulePath = \'${this.classNameLower}\'\n</#if>\nconst reqMocks = [\n<@removeLastComma>\n <#if this.entityFeature.save>\n // 添加【${this.title}】\n {\n url: getUrlPattern(modulePath, false),\n type: \'post\',\n response: ({ body }) => {\n body.${this.id} = Mock.mock(mockNewIdRule).${this.id}\n data.list.push(body)\n return copy(body)\n }\n },\n </#if>\n <#if this.entityFeature.update>\n // 修改【${this.title}】\n {\n url: getUrlPattern(modulePath, false),\n type: \'put\',\n response: ({ body }) => {\n const obj = data.list.find(item => item.${this.id} === body.${this.id})\n Object.assign(obj, body)\n return copy(obj)\n }\n },\n </#if>\n <#if this.entityFeature.list>\n // ${this.pageSign?string(\'分页\',\'列表\')}查询【${this.title}】\n {\n url: getUrlPattern(modulePath, false),\n type: \'get\',\n response: ({ query }) => {\n <#if this.pageSign>\n // 列表分页\n const page = paging(data.list, query.page, query.limit)\n return {\n total: data.list.length,\n list: copy(page)\n }\n <#else>\n return copy(data.list)\n </#if>\n }\n },\n </#if>\n <#if this.titleField??>\n // 查询【${this.title}】选项列表\n {\n url: getUrlPattern(modulePath, false, \'options\'),\n type: \'get\',\n response: () => {\n return data.list.map(item => ({\n key: item.${this.id},\n value: item.${this.titleField.jfieldName}\n }))\n }\n },\n </#if>\n <#if this.entityFeature.show>\n // 查看【${this.title}】详情\n {\n url: getUrlPattern(modulePath, true),\n type: \'get\',\n response: ({ url }) => {\n const ${this.id} = url.match(getUrlPattern(modulePath, true))[1]\n const obj = data.list.find(item => item.${this.id} === parseInt(${this.id}))\n return copy(obj)\n }\n },\n </#if>\n <#if this.entityFeature.delete>\n // 删除单个【${this.title}】\n {\n url: getUrlPattern(modulePath, true),\n type: \'delete\',\n response: ({ url }) => {\n const ${this.id} = url.match(getUrlPattern(modulePath, true))[1]\n removeById(data.list, parseInt(${this.id}))\n return 1\n }\n },\n </#if>\n <#if this.entityFeature.deleteBatch>\n // 批量删除【${this.title}】\n {\n url: getUrlPattern(modulePath, false),\n type: \'delete\',\n response: ({ body }) => {\n for (var ${this.id} of body) {\n removeById(data.list, ${this.id})\n }\n return body.length\n }\n },\n </#if>\n <#list this.holds! as otherEntity,mtm>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign otherId=otherEntity.pkField.jfieldName>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.addRemove || entityFeature.set>\n <#assign index=getMtmCascadeEntityIndexForShow(otherEntity.entityId)>\n <#assign justReturnOtherId=true>\n <#if entityFeature.addRemove || index &gt; -1>\n <#assign justReturnOtherId=false>\n </#if>\n // 获取【${otherEntity.title}】关联\n {\n url: getUrlPattern(modulePath, true, \'${othercName}\'),\n type: \'get\',\n response: ({ url }) => {\n const ${this.id} = url.match(getUrlPattern(modulePath, true, \'${othercName}\'))[1]\n const obj = data.list.find(item => item.${this.id} === parseInt(${this.id}))\n <#if justReturnOtherId>\n return copy(obj.${othercName}List.map(item => item.${otherId}))\n <#else>\n return copy(obj.${othercName}List)\n </#if>\n }\n },\n </#if>\n <#if entityFeature.addRemove>\n // 添加【${otherEntity.title}】关联\n {\n url: getUrlPattern(modulePath, true, \'${othercName}\'),\n type: \'post\',\n response: ({ url, body }) => {\n const ${this.id} = url.match(getUrlPattern(modulePath, true, \'${othercName}\'))[1]\n const obj = data.list.find(item => item.${this.id} === parseInt(${this.id}))\n ${othercName}.getMockData().list\n // 过滤出需要添加的\n .filter(i => body.findIndex(j => j === i.${otherId}) > -1)\n // 过滤掉之前已经存在的\n .filter(i => obj.${othercName}List.findIndex(j => j === i) < 0)\n .forEach(i => obj.${othercName}List.push(i))\n return body.length\n }\n },\n // 移除【${otherEntity.title}】关联\n {\n url: getUrlPattern(modulePath, true, \'${othercName}\'),\n type: \'delete\',\n response: ({ url, body }) => {\n const ${this.id} = url.match(getUrlPattern(modulePath, true, \'${othercName}\'))[1]\n const obj = data.list.find(item => item.${this.id} === parseInt(${this.id}))\n body.forEach(i => {\n const index = obj.${othercName}List.findIndex(j => j.${otherId} === i)\n if (index > -1) {\n obj.${othercName}List.splice(index, 1)\n }\n })\n return body.length\n }\n },\n <#elseIf entityFeature.set>\n // 设置【${otherEntity.title}】关联\n {\n url: getUrlPattern(modulePath, true, \'${othercName}\'),\n type: \'put\',\n response: ({ url, body }) => {\n const ${this.id} = url.match(getUrlPattern(modulePath, true, \'${othercName}\'))[1]\n const obj = data.list.find(item => item.${this.id} === parseInt(${this.id}))\n const ${othercName}List = ${othercName}.getMockData().list\n .filter(i => body.findIndex(j => j === i.${otherId}) > -1)\n obj.${othercName}List = ${othercName}List\n return body.length\n }\n },\n </#if>\n </#list>\n</@removeLastComma>\n]\n\nexport default {\n initMockDataStage1,\n initMockDataStage2,\n reqMocks,\n getMockData\n}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(202,'__dir.ftl','/src/api/{module}',2,2,4,'<#-- 当前文件用于渲染父路径 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(203,'__{chartName}.js.ftl','/src/api/{module}',2,4,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartNameLower}.js\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(204,'__{className}.js.ftl','/src/api/{module}',2,2,5,'<#-- 当前文件用于渲染文件名 -->\n<#include \"/abstracted/common.ftl\">\n${this.classNameLower}.js\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(205,'{chartName}.js.ftl','/src/api/{module}',2,4,1,'<#include \"/abstracted/commonForChart.ftl\">\nimport request from \'@/utils/request\'\n<#if this.excelExport!false>\nimport { downloadBlob } from \'@/utils/download\'\n</#if>\n<#if this.module?hasContent>\nconst apiPath = \'/${this.module}/${this.chartNameLower}\'\n<#else>\nconst apiPath = \'/${this.chartNameLower}\'\n</#if>\nconst ${this.chartNameLower}Api = {\n<@removeLastComma>\n /**\n * 分页查询【${this.title}】\n */\n fetchList(query) {\n return request.get(apiPath, { params: query })\n },\n <#if this.excelExport!false>\n /**\n * 导出【${this.title}】\n */\n exportExcel(query) {\n return request.get(`${r\'$\'}{apiPath}/export`, { responseType: \'blob\', params: query })\n .then(res => downloadBlob(res, \'${this.chartNameLower}.xlsx\'))\n },\n </#if>\n</@removeLastComma>\n}\nexport default ${this.chartNameLower}Api\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(206,'{className}.js.ftl','/src/api/{module}',2,2,1,'<#include \"/abstracted/common.ftl\">\nimport request from \'@/utils/request\'\n<#if this.entityFeature.excelExport || this.entityFeature.excelImport>\nimport { downloadBlob } from \'@/utils/download\'\n</#if>\n<#if this.module?hasContent>\nconst apiPath = \'/${this.module}/${this.classNameLower}\'\n<#else>\nconst apiPath = \'/${this.classNameLower}\'\n</#if>\nconst ${this.classNameLower}Api = {\n<@removeLastComma>\n <#if this.entityFeature.save>\n /**\n * 新增【${this.title}】\n */\n create(data) {\n return request.post(apiPath, data)\n },\n </#if>\n <#if this.entityFeature.update>\n /**\n * 修改【${this.title}】\n */\n update(data) {\n return request.put(apiPath, data)\n },\n </#if>\n <#if this.entityFeature.list>\n /**\n * ${this.pageSign?string(\'分页\',\'列表\')}查询【${this.title}】\n */\n fetchList(query) {\n return request.get(apiPath, { params: query })\n },\n </#if>\n <#if this.titleField??>\n /**\n * 查询【${this.title}】选项列表\n */\n findOptions(query) {\n return request.get(`${r\'$\'}{apiPath}/options`, { params: query })\n },\n </#if>\n <#if this.entityFeature.show>\n /**\n * 查看【${this.title}】详情\n */\n fetchById(${this.id}) {\n return request.get(`${r\'$\'}{apiPath}/${r\'$\'}{${this.id}}`)\n },\n </#if>\n <#if this.entityFeature.delete>\n /**\n * 删除单个【${this.title}】\n */\n deleteById(${this.id}) {\n return request.delete(`${r\'$\'}{apiPath}/${r\'$\'}{${this.id}}`)\n },\n </#if>\n <#if this.entityFeature.deleteBatch>\n /**\n * 批量删除【${this.title}】\n */\n deleteBatch(ids) {\n return request.delete(apiPath, { data: ids })\n },\n </#if>\n <#list this.holds! as otherEntity,mtm>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.addRemove || entityFeature.set>\n /**\n * 获取【${otherEntity.title}】关联\n */\n fetch${otherCName}List(${this.id}) {\n return request.get(`${r\'$\'}{apiPath}/${r\'$\'}{${this.id}}/${othercName}`)\n },\n </#if>\n <#if entityFeature.addRemove>\n /**\n * 添加【${otherEntity.title}】关联\n */\n add${otherCName}(${this.id}, data) {\n return request.post(`${r\'$\'}{apiPath}/${r\'$\'}{${this.id}}/${othercName}`, data)\n },\n /**\n * 移除【${otherEntity.title}】关联\n */\n remove${otherCName}(${this.id}, data) {\n return request.delete(`${r\'$\'}{apiPath}/${r\'$\'}{${this.id}}/${othercName}`, { data })\n },\n <#elseIf entityFeature.set>\n /**\n * 设置【${otherEntity.title}】关联\n */\n set${otherCName}(${this.id}, data) {\n return request.put(`${r\'$\'}{apiPath}/${r\'$\'}{${this.id}}/${othercName}`, data)\n },\n </#if>\n </#list>\n <#if this.entityFeature.excelExport>\n /**\n * 导出【${this.title}】excel\n */\n exportExcel(query) {\n return request.get(`${r\'$\'}{apiPath}/export`, { responseType: \'blob\', params: query })\n .then(res => downloadBlob(res, \'${this.classNameLower}Export.xlsx\'))\n },\n </#if>\n <#if this.entityFeature.excelImport>\n /**\n * 下载【${this.title}】模板\n */\n downloadTemplate() {\n request.get(`${r\'$\'}{apiPath}/template`, { responseType: \'blob\' })\n .then(res => downloadBlob(res, \'${this.classNameLower}Template.xlsx\'))\n },\n /**\n * 获取【${this.title}】上传路径\n */\n getImportUrl() {\n return request.defaults.baseURL + apiPath + \'/import\'\n },\n </#if>\n</@removeLastComma>\n}\nexport default ${this.classNameLower}Api\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(207,'__dir.ftl','/src/components/Charts/{AggTable}',2,4,4,'<#-- 当前文件用于渲染父路径 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(208,'index.vue.ftl','/src/components/Charts/{AggTable}',2,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#if !isChartType(ChartType.AGG_TABLE)>\n <@call this.skipCurrent()/>\n</#if>\n<template>\n <div :style=\"{height:height,width:width}\">\n <el-table v-loading=\"listLoading\" :data=\"list\"\n border stripe style=\"width: 100%;\"\n size=\"mini\">\n<#list this.dimensionList as chartItem>\n <#assign dimension=chartItem.sourceItem>\n <#assign field=dimension.field>\n <#assign name=chartItem.alias>\n <#assign label=chartItem.titleAlias>\n <el-table-column label=\"${label}\"\n align=\"center\">\n <template slot-scope=\"{row}\">\n <#-- 枚举字段特殊处理 -->\n <#if field.dicType??>\n <#assign const = findConst(field.dicType)>\n <@justCall importEnums.add(const)/>\n <#assign constName = const.constName?uncapFirst>\n <span>{{ row.${name} | findEnumLabel(enums.${constName}) }}</span>\n <#-- 普通字段直接展示 -->\n <#else>\n <span>{{ row.${name} }}</span>\n </#if>\n </template>\n </el-table-column>\n</#list>\n<#list this.metricsList as chartItem>\n <#assign name=chartItem.alias>\n <#assign label=chartItem.titleAlias>\n <el-table-column label=\"${label}\"\n align=\"center\">\n <template slot-scope=\"{row}\">\n <span>{{ row.${name} }}</span>\n </template>\n </el-table-column>\n</#list>\n </el-table>\n<#if this.excelExport!false>\n <el-button size=\"mini\" type=\"text\"\n icon=\"el-icon-download\"\n style=\"float: right;margin-right: 10px;\"\n @click=\"handleExport\">\n excel导出\n </el-button>\n</#if>\n <pagination v-show=\"total>0\" :total=\"total\" :page.sync=\"query.page\"\n :limit.sync=\"query.limit\" @pagination=\"doQueryList\"\n layout=\"prev, pager, next\"\n hide-on-single-page small/>\n </div>\n</template>\n\n<script>\n${importApi(this.chartName,this.module)}\nimport Pagination from \'@/components/Pagination\'\n<#if !importEnums.isEmpty()>\nimport enums from \'@/utils/enums\'\n</#if>\n\nexport default {\n name: \'${this.chartName}\',\n components: {\n Pagination\n },\n props: {\n width: {\n type: String,\n default: \'200px\'\n },\n height: {\n type: String,\n default: \'200px\'\n }\n },\n<#if !importEnums.isEmpty()>\n filters: {\n findEnumLabel: enums.findEnumLabel\n },\n</#if>\n data() {\n return {\n<#if !importEnums.isEmpty()>\n enums: {\n <@removeLastComma>\n <#list importEnums as const>\n ${const.constName?uncapFirst}: enums.get${const.constName}(),\n </#list>\n </@removeLastComma>\n },\n</#if>\n list: [],\n total: 0,\n listLoading: true,\n query: {\n page: 1,\n limit: ${this.defaultPageSize}\n }\n }\n },\n created() {\n this.doQueryList({ page: 1 })\n },\n methods: {\n<@removeLastComma>\n /**\n * 执行列表查询\n */\n doQueryList({ page, limit }) {\n if (page) {\n this.query.page = page\n }\n if (limit) {\n this.query.limit = limit\n }\n this.listLoading = true\n return ${this.chartNameLower}Api.fetchList(this.query)\n .then(data => {\n this.list = data.list\n this.total = data.total\n })\n .finally(() => {\n this.listLoading = false\n })\n },\n <#if this.excelExport!false>\n /**\n * 导出excel\n */\n handleExport() {\n return this.$common.confirm(\'是否确认导出\')\n .then(() => ${this.chartNameLower}Api.exportExcel(this.query))\n },\n </#if>\n</@removeLastComma>\n }\n}\n</script>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(209,'__dir.ftl','/src/components/Charts/{BarLine}',2,4,4,'<#-- 当前文件用于渲染父路径 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(210,'echarts-option.js.ftl','/src/components/Charts/{BarLine}',2,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#if !isChartType(ChartType.BAR_LINE)>\n <@call this.skipCurrent()/>\n</#if>\n<#assign series>\n <#if barLineParamMode == 2>\n [<#lt>\n <@removeLastComma>\n <#list this.axisYList as axisY>\n {\n${buildBarLineSeries(axisY,\' \')}\n },\n </#list>\n </@removeLastComma>\n ]<#rt>\n <#else>\n[]<#t>\n </#if>\n</#assign>\nconst option = ${this.optionTemplate?replace(r\"${source}\",\"[]\")?replace(r\"${series}\",series)}\n\nexport function getOption() {\n return JSON.parse(JSON.stringify(option))\n}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(211,'index.vue.ftl','/src/components/Charts/{BarLine}',2,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#if !isChartType(ChartType.BAR_LINE)>\n <@call this.skipCurrent()/>\n</#if>\n<template>\n <div class=\"${this.chartNameLower}\" :style=\"{height:height,width:width}\">\n <div class=\"barLineChart\"/>\n </div>\n</template>\n\n<script>\n${importApi(this.chartName,this.module)}\nimport echarts from \'echarts\'\n<#if !importEnums.isEmpty()>\nimport enums from \'@/utils/enums\'\n</#if>\nimport { getOption } from \'./echarts-option\'\nimport { getChartSizeInBox } from \'@/utils/chart-util\'\n\nexport default {\n name: \'${this.chartName}\',\n props: {\n width: {\n type: String,\n default: \'200px\'\n },\n height: {\n type: String,\n default: \'200px\'\n }\n },\n data() {\n return {\n listLoading: true,\n option: getOption(),\n // 暂时没有查询参数\n query: {},\n chart: null\n }\n },\n methods: {\n /**\n * 执行列表数据查询\n */\n doQueryList() {\n this.listLoading = true\n return ${this.chartNameLower}Api.fetchList(this.query)\n .then(data => {\n this.option.dataset.source = data\n<#if barLineParamMode == 1>\n const series = []\n const header = data[0]\n for (let i = 0; i < header.length - 1; i++) {\n series.push({\n${buildBarLineSeries(this.axisYList[0],\' \')}\n })\n }\n this.option.series = series\n</#if>\n this.renderChart()\n })\n .finally(() => {\n this.listLoading = false\n })\n },\n /**\n * 渲染图表\n */\n renderChart() {\n const chartEl = this.$el.children[0]\n this.chart = echarts.init(chartEl)\n this.chart.setOption(this.option, true)\n },\n resize() {\n const [width, height] = getChartSizeInBox(this.$parent.$el)\n this.chart.resize({\n width,\n height\n })\n }\n },\n mounted() {\n this.doQueryList()\n .then(() => {\n setTimeout(() => {\n this.resize()\n }, 100)\n })\n }\n}\n</script>\n<style lang=\"scss\">\n.${this.chartNameLower} {\n .barLineChart {\n width: 100%;\n height: 100%;\n }\n}\n</style>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(212,'__dir.ftl','/src/components/Charts/{DetailList}',2,4,4,'<#-- 当前文件用于渲染父路径 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(213,'index.vue.ftl','/src/components/Charts/{DetailList}',2,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#if !isChartType(ChartType.DETAIL_LIST)>\n <@call this.skipCurrent()/>\n</#if>\n<template>\n <div :style=\"{height:height,width:width}\">\n <el-table v-loading=\"listLoading\" :data=\"list\"\n border stripe style=\"width: 100%;\"\n size=\"mini\">\n<#list this.columnList as column>\n <#assign sourceItem=column.sourceItem>\n <#if sourceItem.custom>\n <#--字段名-->\n <#assign name=column.alias>\n <#--字段标题-->\n <#assign label=column.titleAlias>\n <#else>\n <#assign field=sourceItem.field>\n <#if column.alias?hasContent>\n <#assign name=column.alias>\n <#else>\n <#assign name=field.jfieldName>\n </#if>\n <#if column.titleAlias?hasContent>\n <#assign label=column.titleAlias>\n <#else>\n <#assign label=field.fetchComment()?replace(\'\\\"\',\'\\\\\"\')?replace(\'\\n\',\'\\\\n\')>\n </#if>\n </#if>\n <el-table-column label=\"${label}\"\n align=\"center\">\n <template slot-scope=\"{row}\">\n <#-- 枚举字段特殊处理 -->\n <#if !sourceItem.custom && field.dicType??>\n <#assign const = findConst(field.dicType)>\n <@justCall importEnums.add(const)/>\n <#assign constName = const.constName?uncapFirst>\n <span>{{ row.${name} | findEnumLabel(enums.${constName}) }}</span>\n <#-- 普通字段直接展示 -->\n <#else>\n <span>{{ row.${name} }}</span>\n </#if>\n </template>\n </el-table-column>\n</#list>\n </el-table>\n<#if this.excelExport!false>\n <el-button size=\"mini\" type=\"text\"\n icon=\"el-icon-download\"\n style=\"float: right;margin-right: 10px;\"\n @click=\"handleExport\">\n excel导出\n </el-button>\n</#if>\n <pagination v-show=\"total>0\" :total=\"total\" :page.sync=\"query.page\"\n :limit.sync=\"query.limit\" @pagination=\"doQueryList\"\n layout=\"prev, pager, next\"\n hide-on-single-page small/>\n </div>\n</template>\n\n<script>\n${importApi(this.chartName,this.module)}\nimport Pagination from \'@/components/Pagination\'\n<#if !importEnums.isEmpty()>\nimport enums from \'@/utils/enums\'\n</#if>\n\nexport default {\n name: \'${this.chartName}\',\n components: {\n Pagination\n },\n props: {\n width: {\n type: String,\n default: \'200px\'\n },\n height: {\n type: String,\n default: \'200px\'\n }\n },\n<#if !importEnums.isEmpty()>\n filters: {\n findEnumLabel: enums.findEnumLabel\n },\n</#if>\n data() {\n return {\n<#if !importEnums.isEmpty()>\n enums: {\n <@removeLastComma>\n <#list importEnums as const>\n ${const.constName?uncapFirst}: enums.get${const.constName}(),\n </#list>\n </@removeLastComma>\n },\n</#if>\n list: [],\n total: 0,\n listLoading: true,\n query: {\n page: 1,\n limit: ${this.defaultPageSize}\n }\n }\n },\n created() {\n this.doQueryList({ page: 1 })\n },\n methods: {\n<@removeLastComma>\n /**\n * 执行列表查询\n */\n doQueryList({ page, limit }) {\n if (page) {\n this.query.page = page\n }\n if (limit) {\n this.query.limit = limit\n }\n this.listLoading = true\n return ${this.chartNameLower}Api.fetchList(this.query)\n .then(data => {\n this.list = data.list\n this.total = data.total\n })\n .finally(() => {\n this.listLoading = false\n })\n },\n <#if this.excelExport!false>\n /**\n * 导出excel\n */\n handleExport() {\n return this.$common.confirm(\'是否确认导出\')\n .then(() => ${this.chartNameLower}Api.exportExcel(this.query))\n },\n </#if>\n</@removeLastComma>\n }\n}\n</script>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(214,'__dir.ftl','/src/components/Charts/{Pie}',2,4,4,'<#-- 当前文件用于渲染父路径 -->\n<#include \"/abstracted/common.ftl\">\n${this.chartName}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(215,'echarts-option.js.ftl','/src/components/Charts/{Pie}',2,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#if !isChartType(ChartType.PIE)>\n <@call this.skipCurrent()/>\n</#if>\nconst option = ${this.optionTemplate?replace(r\"${source}\",\"[]\")}\n\nexport function getOption() {\n return JSON.parse(JSON.stringify(option))\n}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(216,'index.vue.ftl','/src/components/Charts/{Pie}',2,4,1,'<#include \"/abstracted/commonForChart.ftl\">\n<#if !isChartType(ChartType.PIE)>\n <@call this.skipCurrent()/>\n</#if>\n<template>\n <div class=\"${this.chartNameLower}\" :style=\"{height:height,width:width}\">\n <div class=\"pieChart\"/>\n </div>\n</template>\n\n<script>\n${importApi(this.chartName,this.module)}\nimport echarts from \'echarts\'\n<#if !importEnums.isEmpty()>\nimport enums from \'@/utils/enums\'\n</#if>\nimport { getOption } from \'./echarts-option\'\nimport { getChartSizeInBox } from \'@/utils/chart-util\'\n\nexport default {\n name: \'${this.chartName}\',\n props: {\n width: {\n type: String,\n default: \'200px\'\n },\n height: {\n type: String,\n default: \'200px\'\n }\n },\n data() {\n return {\n listLoading: true,\n option: getOption(),\n // 暂时没有查询参数\n query: {},\n chart: null\n }\n },\n methods: {\n /**\n * 执行列表数据查询\n */\n doQueryList() {\n this.listLoading = true\n return ${this.chartNameLower}Api.fetchList(this.query)\n .then(data => {\n this.option.dataset.source = data\n this.renderChart()\n })\n .finally(() => {\n this.listLoading = false\n })\n },\n /**\n * 渲染图表\n */\n renderChart() {\n const chartEl = this.$el.children[0]\n this.chart = echarts.init(chartEl)\n this.chart.setOption(this.option, true)\n },\n resize() {\n const [width, height] = getChartSizeInBox(this.$parent.$el)\n this.chart.resize({\n width,\n height\n })\n }\n },\n mounted() {\n this.doQueryList()\n .then(() => {\n setTimeout(() => {\n this.resize()\n }, 100)\n })\n }\n}\n</script>\n<style lang=\"scss\">\n.${this.chartNameLower} {\n .pieChart {\n width: 100%;\n height: 100%;\n }\n}\n</style>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(217,'__dir.ftl','/src/views/{module}',2,2,4,'<#-- 当前文件用于渲染父路径 -->\n<#include \"/abstracted/common.ftl\">\n${this.module}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(218,'__dir.ftl','/src/views/{module}/{className}',2,2,4,'<#-- 当前文件用于渲染父路径 -->\n<#include \"/abstracted/common.ftl\">\n${this.classNameLower}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(219,'add.vue.ftl','/src/views/{module}/{className}',2,2,1,'<#include \"/abstracted/common.ftl\">\n<#if !this.entityFeature.save || !this.entityFeature.list>\n <@call this.skipCurrent()/>\n</#if>\n<template>\n <el-dialog title=\"新建${this.title}\" :visible.sync=\"formVisible\">\n <el-form ref=\"dataForm\" :rules=\"formRules\" :model=\"form\"\n label-position=\"left\" size=\"small\"\n label-width=\"100px\" style=\"width: 400px; margin-left:50px;\">\n<#list this.insertFields as id,field>\n <el-form-item label=\"${field.fieldDesc}\" prop=\"${field.jfieldName}\">\n <#if field.editType == EditType.TEXT.getValue()>\n <el-input v-model=\"form.${field.jfieldName}\"/>\n <#elseIf field.editType == EditType.TEXTAREA.getValue()>\n <el-input v-model=\"form.${field.jfieldName}\" type=\"textarea\" :rows=\"2\"></el-input>\n <#elseIf field.editType == EditType.NUMBER.getValue()>\n <el-input-number v-model=\"form.${field.jfieldName}\" style=\"width:100%;\" controls-position=\"right\"></el-input-number>\n <#elseIf field.editType == EditType.DATE.getValue()>\n <el-date-picker v-model=\"form.${field.jfieldName}\"\n type=\"date\"\n value-format=\"yyyy-MM-dd\"\n placeholder=\"选择日期\"></el-date-picker>\n <#elseIf field.editType == EditType.DATETIME.getValue()>\n <el-date-picker v-model=\"form.${field.jfieldName}\"\n type=\"datetime\"\n value-format=\"yyyy-MM-dd HH:mm:ss\"\n placeholder=\"选择日期时间\"></el-date-picker>\n <#elseIf field.editType == EditType.RADIO.getValue()>\n <el-radio-group v-model=\"form.${field.jfieldName}\">\n <#if field.jfieldType == JFieldType.BOOLEAN.javaType>\n <el-radio :label=\"true\">是</el-radio>\n <el-radio :label=\"false\">否</el-radio>\n <#elseIf field.dicType??>\n <#assign const = findConst(field.dicType)>\n <@justCall importEnums.add(const)/>\n <#assign constName = const.constName?uncapFirst>\n <el-radio v-for=\"item in enums.${constName}\"\n :key=\"item.value\"\n :label=\"item.value\">{{ item.label }}</el-radio>\n </#if>\n </el-radio-group>\n <#elseIf field.editType == EditType.SELECT.getValue()>\n <el-select v-model=\"form.${field.jfieldName}\"\n style=\"width:100%;\" placeholder=\"请选择\"\n filterable clearable>\n <#if field.foreignKey>\n <@justCall importOtherEntitys.add(field.foreignEntity)/>\n <el-option v-for=\"item in options.${lowerFirstWord(field.foreignEntity.className)}\"\n :key=\"item.key\"\n :label=\"item.value\"\n :value=\"item.key\">\n </el-option>\n <#elseIf field.dicType??>\n <#assign const = findConst(field.dicType)>\n <@justCall importEnums.add(const)/>\n <#assign constName = const.constName?uncapFirst>\n <el-option v-for=\"item in enums.${constName}\"\n :key=\"item.value\"\n :label=\"item.label\"\n :value=\"item.value\">\n </el-option>\n </#if>\n </el-select>\n </#if>\n </el-form-item>\n</#list>\n<#list this.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.withinEntity>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@justCall importOtherEntitys.add(otherEntity)/>\n <el-form-item label=\"${otherEntity.title}\">\n <el-select v-model=\"form.${othercName}List\"\n style=\"width:100%;\" placeholder=\"请选择\"\n filterable clearable multiple>\n <el-option v-for=\"item in options.${othercName}\"\n :key=\"item.key\"\n :label=\"item.value\"\n :value=\"item.key\">\n </el-option>\n </el-select>\n </el-form-item>\n </#if>\n</#list>\n </el-form>\n <div slot=\"footer\" class=\"dialog-footer\">\n <el-button @click=\"formVisible = false\">\n 取消\n </el-button>\n <el-button type=\"primary\"\n @click=\"doCreate()\">\n 确认\n </el-button>\n </div>\n </el-dialog>\n</template>\n\n<script>\n${importApi(this.metaEntity.className,this.metaEntity.module)}\n<#if !importOtherEntitys.isEmpty()>\n <#list importOtherEntitys as foreignEntity>\n <#if foreignEntity != this.metaEntity>\n${importApi(foreignEntity.className,foreignEntity.module)}\n </#if>\n </#list>\n</#if>\n<#if !importEnums.isEmpty()>\nimport enums from \'@/utils/enums\'\n</#if>\n\nfunction initFormBean() {\n const formBean = {\n<@removeLastComma>\n <#list this.insertFields as id,field>\n ${field.jfieldName}: null,\n </#list>\n <#list this.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.withinEntity>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n ${othercName}List: [],\n </#if>\n </#list>\n</@removeLastComma>\n }\n return formBean\n}\n\nexport default {\n name: \'${this.className}Add\',\n data() {\n return {\n<#if !importEnums.isEmpty()>\n enums: {\n <@removeLastComma>\n <#list importEnums as const>\n ${const.constName?uncapFirst}: enums.get${const.constName}(),\n </#list>\n </@removeLastComma>\n },\n</#if>\n<#if !importOtherEntitys.isEmpty()>\n options: {\n <@removeLastComma>\n <#list importOtherEntitys as foreignEntity>\n ${lowerFirstWord(foreignEntity.className)}: [],\n </#list>\n </@removeLastComma>\n },\n</#if>\n form: initFormBean(),\n formVisible: false,\n formRules: {\n<@removeLastComma>\n <#list this.insertFields as id,field>\n ${field.jfieldName}: [\n <@removeLastComma>\n <#if field.notNull>\n { required: true, message: \'请输入${field.fieldDesc}\', trigger: \'${getRuleTrigger(field)}\' },\n </#if>\n <#if (field.editType == EditType.TEXT.getValue()\n || field.editType == EditType.TEXTAREA.getValue())\n && field.fieldLength &gt; 0>\n { max: ${field.fieldLength}, message: \'长度不能超过${field.fieldLength}个字符\', trigger: \'blur\' },\n </#if>\n </@removeLastComma>\n ],\n </#list>\n</@removeLastComma>\n }\n }\n },\n methods: {\n /**\n * 重置表单\n */\n resetForm() {\n this.form = initFormBean()\n },\n /**\n * 打开新建表单\n */\n handleCreate() {\n this.resetForm()\n<#if !importOtherEntitys.isEmpty()>\n <@removeLastComma>\n <#list importOtherEntitys as foreignEntity>\n <#assign foreignClassName = lowerFirstWord(foreignEntity.className)>\n ${foreignClassName}Api.findOptions().then(data => { this.options.${foreignClassName} = data })\n </#list>\n </@removeLastComma>\n</#if>\n this.formVisible = true\n this.$nextTick(() => {\n this.$refs[\'dataForm\'].clearValidate()\n })\n },\n /**\n * 执行新建操作\n */\n doCreate() {\n this.$refs[\'dataForm\'].validate()\n .then(() => ${this.classNameLower}Api.create(this.form))\n .then(data => {\n this.formVisible = false\n this.$common.showMsg(\'success\', \'创建成功\')\n this.$emit(\'created\', data)\n })\n }\n }\n}\n</script>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(220,'edit.vue.ftl','/src/views/{module}/{className}',2,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForShow.ftl\">\n<#if !this.entityFeature.update || !this.entityFeature.list>\n <@call this.skipCurrent()/>\n</#if>\n<template>\n <el-dialog title=\"编辑${this.title}\" :visible.sync=\"formVisible\">\n <el-form ref=\"dataForm\" :rules=\"formRules\" :model=\"form\"\n label-position=\"left\" size=\"small\"\n label-width=\"100px\" style=\"width: 400px; margin-left:50px;\">\n<#list this.updateFields as id,field>\n <el-form-item label=\"${field.fieldDesc}\" prop=\"${field.jfieldName}\">\n <#if field.editType == EditType.TEXT.getValue()>\n <el-input v-model=\"form.${field.jfieldName}\"/>\n <#elseIf field.editType == EditType.TEXTAREA.getValue()>\n <el-input v-model=\"form.${field.jfieldName}\" type=\"textarea\" :rows=\"2\"></el-input>\n <#elseIf field.editType == EditType.NUMBER.getValue()>\n <el-input-number v-model=\"form.${field.jfieldName}\" style=\"width:100%;\" controls-position=\"right\"></el-input-number>\n <#elseIf field.editType == EditType.DATE.getValue()>\n <el-date-picker v-model=\"form.${field.jfieldName}\"\n type=\"date\"\n value-format=\"yyyy-MM-dd\"\n placeholder=\"选择日期\"></el-date-picker>\n <#elseIf field.editType == EditType.DATETIME.getValue()>\n <el-date-picker v-model=\"form.${field.jfieldName}\"\n type=\"datetime\"\n value-format=\"yyyy-MM-dd HH:mm:ss\"\n placeholder=\"选择日期时间\"></el-date-picker>\n <#elseIf field.editType == EditType.RADIO.getValue()>\n <el-radio-group v-model=\"form.${field.jfieldName}\">\n <#if field.jfieldType == JFieldType.BOOLEAN.javaType>\n <el-radio :label=\"true\">是</el-radio>\n <el-radio :label=\"false\">否</el-radio>\n <#elseIf field.dicType??>\n <#assign const = findConst(field.dicType)>\n <@justCall importEnums.add(const)/>\n <#assign constName = const.constName?uncapFirst>\n <el-radio v-for=\"item in enums.${constName}\"\n :key=\"item.value\"\n :label=\"item.value\">{{ item.label }}</el-radio>\n </#if>\n </el-radio-group>\n <#elseIf field.editType == EditType.SELECT.getValue()>\n <el-select v-model=\"form.${field.jfieldName}\"\n style=\"width:100%;\" placeholder=\"请选择\"\n filterable clearable>\n <#if field.foreignKey>\n <@justCall importOtherEntitys.add(field.foreignEntity)/>\n <el-option v-for=\"item in options.${lowerFirstWord(field.foreignEntity.className)}\"\n :key=\"item.key\"\n :label=\"item.value\"\n :value=\"item.key\">\n </el-option>\n <#elseIf field.dicType??>\n <#assign const = findConst(field.dicType)>\n <@justCall importEnums.add(const)/>\n <#assign constName = const.constName?uncapFirst>\n <el-option v-for=\"item in enums.${constName}\"\n :key=\"item.value\"\n :label=\"item.label\"\n :value=\"item.value\">\n </el-option>\n </#if>\n </el-select>\n </#if>\n </el-form-item>\n</#list>\n<#list this.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.withinEntity>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <@justCall importOtherEntitys.add(otherEntity)/>\n <el-form-item label=\"${otherEntity.title}\">\n <el-select v-model=\"form.${othercName}List\"\n style=\"width:100%;\" placeholder=\"请选择\"\n filterable clearable multiple>\n <el-option v-for=\"item in options.${othercName}\"\n :key=\"item.key\"\n :label=\"item.value\"\n :value=\"item.key\">\n </el-option>\n </el-select>\n </el-form-item>\n </#if>\n</#list>\n </el-form>\n <div slot=\"footer\" class=\"dialog-footer\">\n <el-button @click=\"formVisible = false\">\n 取消\n </el-button>\n <el-button type=\"primary\"\n @click=\"doUpdate()\">\n 确认\n </el-button>\n </div>\n </el-dialog>\n</template>\n\n<script>\n${importApi(this.metaEntity.className,this.metaEntity.module)}\n<#if !importOtherEntitys.isEmpty()>\n <#list importOtherEntitys as foreignEntity>\n <#if foreignEntity != this.metaEntity>\n${importApi(foreignEntity.className,foreignEntity.module)}\n </#if>\n </#list>\n</#if>\n<#if !importEnums.isEmpty()>\nimport enums from \'@/utils/enums\'\n</#if>\n\nfunction initFormBean() {\n const formBean = {\n<@removeLastComma>\n ${this.pk.jfieldName}: null,\n <#list this.updateFields as id,field>\n ${field.jfieldName}: null,\n </#list>\n <#list this.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.withinEntity>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n ${othercName}List: [],\n </#if>\n </#list>\n</@removeLastComma>\n }\n return formBean\n}\n\nexport default {\n name: \'${this.className}Edit\',\n data() {\n return {\n<#if !importEnums.isEmpty()>\n enums: {\n <@removeLastComma>\n <#list importEnums as const>\n ${const.constName?uncapFirst}: enums.get${const.constName}(),\n </#list>\n </@removeLastComma>\n },\n</#if>\n<#if !importOtherEntitys.isEmpty()>\n options: {\n <@removeLastComma>\n <#list importOtherEntitys as foreignEntity>\n ${lowerFirstWord(foreignEntity.className)}: [],\n </#list>\n </@removeLastComma>\n },\n</#if>\n old: initFormBean(),\n form: initFormBean(),\n formVisible: false,\n formRules: {\n<@removeLastComma>\n <#list this.updateFields as id,field>\n ${field.jfieldName}: [\n <@removeLastComma>\n <#if field.notNull>\n { required: true, message: \'请输入${field.fieldDesc}\', trigger: \'${getRuleTrigger(field)}\' },\n </#if>\n <#if (field.editType == EditType.TEXT.getValue()\n || field.editType == EditType.TEXTAREA.getValue())\n && field.fieldLength &gt; 0>\n { max: ${field.fieldLength}, message: \'长度不能超过${field.fieldLength}个字符\', trigger: \'blur\' },\n </#if>\n </@removeLastComma>\n ],\n </#list>\n</@removeLastComma>\n }\n }\n },\n methods: {\n /**\n * 重置表单\n */\n resetForm() {\n for (const key in initFormBean()) {\n this.form[key] = this.old[key]\n }\n },\n /**\n * 打开编辑表单\n */\n handleUpdate(${this.id}) {\n<#if !importOtherEntitys.isEmpty()>\n <@removeLastComma>\n <#list importOtherEntitys as foreignEntity>\n <#assign foreignClassName = lowerFirstWord(foreignEntity.className)>\n ${foreignClassName}Api.findOptions().then(data => { this.options.${foreignClassName} = data })\n </#list>\n </@removeLastComma>\n</#if>\n ${this.classNameLower}Api.fetchById(${this.id})\n .then(data => {\n<#if mtmCascadeEntitiesForShow?size &gt; 0>\n this.old = Object.assign({}, data, {\n <@removeLastComma>\n <#list mtmCascadeEntitiesForShow as otherEntity>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign pkField=otherEntity.pkField>\n ${othercName}List: data.${othercName}List ? data.${othercName}List.map(t => t.${pkField.jfieldName}) : [],\n </#list>\n </@removeLastComma>\n })\n<#else>\n this.old = data\n</#if>\n this.resetForm()\n this.formVisible = true\n this.$nextTick(() => {\n this.$refs[\'dataForm\'].clearValidate()\n })\n })\n },\n /**\n * 执行修改操作\n */\n doUpdate() {\n this.$refs[\'dataForm\'].validate()\n .then(() => ${this.classNameLower}Api.update(this.form))\n .then(data => {\n this.formVisible = false\n this.$common.showMsg(\'success\', \'修改成功\')\n this.$emit(\'updated\', data)\n })\n }\n }\n}\n</script>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(221,'import.vue.ftl','/src/views/{module}/{className}',2,2,1,'<#include \"/abstracted/common.ftl\">\n<#if !this.entityFeature.excelImport || !this.entityFeature.list>\n <@call this.skipCurrent()/>\n</#if>\n<template>\n <el-dialog title=\"${this.title}导入\"\n :visible.sync=\"importFormVisible\"\n v-loading=\"importFormLoading\"\n width=\"400px\">\n <el-upload drag\n :action=\"importUrl\"\n :on-success=\"onImportSuccess\"\n :on-progress=\"onImportProgress\"\n :on-error=\"onImportError\"\n :show-file-list=\"false\">\n <i class=\"el-icon-upload\"></i>\n <div class=\"el-upload__text\">将excel文件拖到此处,或<em>点击上传</em></div>\n </el-upload>\n <el-button @click=\"downloadTemplate\"\n type=\"text\" size=\"medium\">点击下载excel模板</el-button>\n </el-dialog>\n</template>\n<script>\n${importApi(this.metaEntity.className,this.metaEntity.module)}\n\nexport default {\n name: \'${this.className}Import\',\n data() {\n return {\n importFormLoading: false,\n importFormVisible: false,\n importUrl: ${this.classNameLower}Api.getImportUrl()\n }\n },\n created: function() {\n },\n methods: {\n onImportProgress(event, file, fileList) {\n this.importFormLoading = true\n },\n onImportSuccess(response, file, fileList) {\n this.importFormVisible = false\n this.importFormLoading = false\n this.$common.showMsg(\'success\', \'导入成功\')\n this.$emit(\'imported\', response)\n },\n onImportError(error, file, fileList) {\n this.importFormLoading = false\n this.$common.showNotifyError(JSON.parse(error.message))\n },\n show() {\n this.importFormVisible = true\n },\n downloadTemplate() {\n ${this.classNameLower}Api.downloadTemplate()\n }\n }\n}\n</script>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(222,'index.vue.ftl','/src/views/{module}/{className}',2,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/table.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForQuery.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForList.ftl\">\n<#if !this.entityFeature.list>\n <@call this.skipCurrent()/>\n</#if>\n<template>\n <div class=\"app-container\">\n <div class=\"filter-container\">\n<#-- 把渲染搜索字段的逻辑抽象出来 -->\n<#macro displayQueryField field alias>\n <#local name = alias?hasContent?string(alias,field.jfieldName)/>\n <#-- 首先考虑外键的情况 -->\n <#if field.foreignKey>\n <@justCall importOtherEntitys.add(field.foreignEntity)/>\n <#assign foreignClassName = lowerFirstWord(field.foreignEntity.className)>\n <el-select v-model=\"query.${name}\" class=\"filter-item\"\n style=\"width:200px;\" placeholder=\"${field.fieldDesc}\"\n filterable clearable<#if QueryType.isIn(field.queryType)> multiple</#if>>\n <el-option v-for=\"item in options.${foreignClassName}\"\n :key=\"item.key\"\n :label=\"item.value\"\n :value=\"item.key\">\n </el-option>\n </el-select>\n <#-- 其次考虑枚举的情况 -->\n <#elseIf field.dicType??>\n <#assign const = findConst(field.dicType)>\n <@justCall importEnums.add(const)/>\n <#assign constName = const.constName?uncapFirst>\n <el-select v-model=\"query.${name}\" class=\"filter-item\"\n style=\"width:200px;\" placeholder=\"${field.fieldDesc}\"\n filterable clearable<#if QueryType.isIn(field.queryType)> multiple</#if>>\n <el-option v-for=\"item in enums.${constName}\"\n :key=\"item.value\"\n :label=\"item.label\"\n :value=\"item.value\">\n </el-option>\n </el-select>\n <#-- 非Between查询条件 -->\n <#elseIf !QueryType.isBetween(field.queryType)>\n <#if field.editType == EditType.NUMBER.getValue()>\n <el-input-number v-model=\"query.${name}\" placeholder=\"${field.fieldDesc}${getRangeQueryTipSuffix(field,false)}\"\n style=\"width:200px;\" class=\"filter-item\"\n controls-position=\"right\"></el-input-number>\n <#elseIf field.editType == EditType.DATE.getValue()>\n <el-date-picker v-model=\"query.${name}\" type=\"date\"\n style=\"width:200px;\" class=\"filter-item\"\n value-format=\"yyyy-MM-dd\"\n placeholder=\"${field.fieldDesc}${getRangeQueryTipSuffix(field,false)}\"></el-date-picker>\n <#elseIf field.editType == EditType.DATETIME.getValue()>\n <el-date-picker v-model=\"query.${name}\" type=\"datetime\"\n style=\"width:200px;\" class=\"filter-item\"\n value-format=\"yyyy-MM-dd HH:mm:ss\"\n placeholder=\"${field.fieldDesc}${getRangeQueryTipSuffix(field,false)}\"></el-date-picker>\n <#elseIf field.jfieldType == JFieldType.BOOLEAN.javaType>\n <el-select v-model=\"query.${name}\" class=\"filter-item\"\n style=\"width:200px;\" placeholder=\"${field.fieldDesc}\"\n clearable>\n <el-option label=\"是\" :value=\"true\"></el-option>\n <el-option label=\"否\" :value=\"false\"></el-option>\n </el-select>\n <#else>\n <el-input v-model=\"query.${name}\" placeholder=\"${field.fieldDesc}${getRangeQueryTipSuffix(field,false)}\"\n style=\"width: 200px;\" class=\"filter-item\"\n @keyup.enter.native=\"handleQuery\"/>\n </#if>\n <#-- 最后考虑Between查询条件 -->\n <#else>\n <#if field.jfieldType == JFieldType.DATE.javaType\n || field.jfieldType == JFieldType.LOCALDATE.javaType\n || field.jfieldType == JFieldType.LOCALDATETIME.javaType>\n <el-date-picker v-model=\"query.${name}Start\"\n <#if field.editType == EditType.DATE.getValue()>\n type=\"date\"\n value-format=\"yyyy-MM-dd\"\n <#else>\n type=\"datetime\"\n value-format=\"yyyy-MM-dd HH:mm:ss\"\n </#if>\n style=\"width:200px;\" class=\"filter-item\"\n placeholder=\"${field.fieldDesc}${getRangeQueryTipSuffix(field,true)}\"></el-date-picker>\n <el-date-picker v-model=\"query.${name}End\"\n <#if field.editType == EditType.DATE.getValue()>\n type=\"date\"\n value-format=\"yyyy-MM-dd\"\n <#else>\n type=\"datetime\"\n value-format=\"yyyy-MM-dd HH:mm:ss\"\n </#if>\n style=\"width:200px;\" class=\"filter-item\"\n placeholder=\"${field.fieldDesc}${getRangeQueryTipSuffix(field,false)}\"></el-date-picker>\n <#elseIf field.editType == EditType.NUMBER.getValue()>\n <el-input-number v-model=\"query.${name}Start\" placeholder=\"${field.fieldDesc}${getRangeQueryTipSuffix(field,true)}\"\n style=\"width:200px;\" class=\"filter-item\"\n controls-position=\"right\"></el-input-number>\n <el-input-number v-model=\"query.${name}End\" placeholder=\"${field.fieldDesc}${getRangeQueryTipSuffix(field,false)}\"\n style=\"width:200px;\" class=\"filter-item\"\n controls-position=\"right\"></el-input-number>\n <#else>\n <el-input v-model=\"query.${name}Start\" placeholder=\"${field.fieldDesc}${getRangeQueryTipSuffix(field,true)}\"\n style=\"width: 200px;\" class=\"filter-item\"\n @keyup.enter.native=\"handleQuery\"/>\n <el-input v-model=\"query.${name}End\" placeholder=\"${field.fieldDesc}${getRangeQueryTipSuffix(field,false)}\"\n style=\"width: 200px;\" class=\"filter-item\"\n @keyup.enter.native=\"handleQuery\"/>\n </#if>\n </#if>\n</#macro>\n<#assign hasQueryField = false>\n<#--渲染查询输入框-->\n<#list this.queryFields as id,field>\n <#assign hasQueryField = true>\n <@displayQueryField field \"\"/>\n</#list>\n<#--开始渲染【外键级联扩展】字段 -->\n<#list this.fkFields as id,field>\n <#list field.cascadeQueryExts! as cascadeExt>\n <#assign hasQueryField = true>\n <@displayQueryField cascadeExt.cascadeField cascadeExt.alias/>\n </#list>\n</#list>\n<#--开始渲染【多对多级联扩展】字段-->\n<#list mtmCascadeExtsForQuery as mtmCascadeExt>\n <#assign hasQueryField = true>\n <@displayQueryField mtmCascadeExt.cascadeField mtmCascadeExt.alias/>\n</#list>\n<#if hasQueryField>\n <el-button class=\"filter-item\" icon=\"el-icon-search\" type=\"primary\"\n @click=\"handleQuery\">\n 搜索\n </el-button>\n</#if>\n<#if this.entityFeature.save>\n <el-button class=\"filter-item\" style=\"margin-left: 10px;\" type=\"success\"\n icon=\"el-icon-edit\" @click=\"handleCreate\">\n 新建\n </el-button>\n</#if>\n<#if this.entityFeature.deleteBatch>\n <el-button class=\"filter-item\" style=\"margin-left: 10px;\" type=\"danger\"\n icon=\"el-icon-delete\" @click=\"handleDeleteBatch\">\n 删除\n </el-button>\n</#if>\n<#if this.entityFeature.excelExport>\n <el-button class=\"filter-item\" icon=\"el-icon-download\" type=\"warning\"\n @click=\"handleExport\">\n 导出\n </el-button>\n</#if>\n<#if this.entityFeature.excelImport>\n <el-button class=\"filter-item\" icon=\"el-icon-upload2\" type=\"success\"\n @click=\"handleImport\">\n 导入\n </el-button>\n</#if>\n </div>\n\n <el-table v-loading=\"listLoading\" :data=\"list\"\n<#if tableSelect>\n @selection-change=\"selectionChange\"\n</#if>\n<#if tableSort>\n @sort-change=\"sortChange\"\n</#if>\n border stripe style=\"width: 100%;\">\n<#if tableSelect>\n <el-table-column type=\"selection\" width=\"50\" />\n</#if>\n<#-- 把渲染字段的逻辑抽象出来 -->\n<#macro displayTableColumn field alias>\n <#local name = alias?hasContent?string(alias,field.jfieldName)/>\n <el-table-column label=\"${field.fieldDesc}\"\n prop=\"${name}\"\n <#if !(alias?hasContent) && field.listSort>\n sortable=\"custom\"\n </#if>\n align=\"center\"<#if field.columnWidth?? && field.columnWidth &gt; 0> width=\"${field.columnWidth}\"</#if>>\n <template slot-scope=\"{row}\">\n <#-- 枚举字段特殊处理 -->\n <#if field.dicType??>\n <#assign const = findConst(field.dicType)>\n <@justCall importEnums.add(const)/>\n <#assign constName = const.constName?uncapFirst>\n <span>{{ row.${name} | findEnumLabel(enums.${constName}) }}</span>\n <#-- 普通字段直接展示 -->\n <#else>\n <span>{{ row.${name} }}</span>\n </#if>\n </template>\n </el-table-column>\n</#macro>\n<#-- 列表字段 -->\n<#list this.listFields as id,field>\n <@displayTableColumn field \"\"/>\n</#list>\n<#-- 外键级联扩展字段 -->\n<#list this.fkFields as id,field>\n <#list field.cascadeListExts! as cascadeExt>\n <@displayTableColumn cascadeExt.cascadeField cascadeExt.alias/>\n </#list>\n</#list>\n<#--多对多级联扩展列表展示-->\n<#list mtmCascadeEntitiesForList as otherEntity>\n <#assign otherPkField = otherEntity.pkField>\n <#assign mtmCascadeExts = groupMtmCascadeExtsForList[otherEntity?index]>\n <#--级联扩展列表字段中,如果有标题字段,则使用标题字段展示,否则直接展示主键字段-->\n <#if hasTitleField(otherEntity,mtmCascadeExts)>\n <#assign displayField = otherEntity.titleField>\n <#else>\n <#assign displayField = otherPkField>\n </#if>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <el-table-column label=\"${otherEntity.title}\" align=\"center\">\n <template slot-scope=\"{row}\">\n <span v-for=\"item in row.${othercName}List\"\n :key=\"item.${otherPkField.jfieldName}\"\n class=\"table-inner-mtm\">\n {{ item.${displayField.jfieldName} }}\n </span>\n </template>\n </el-table-column>\n</#list>\n<#if tableOperate>\n <el-table-column label=\"操作\" align=\"center\" width=\"230\">\n <template slot-scope=\"{row}\">\n <#if this.entityFeature.show>\n <el-button size=\"mini\"\n @click=\"handleShow(row)\" class=\"table-inner-button\">查看</el-button>\n </#if>\n <#if this.entityFeature.update>\n <el-button type=\"primary\" size=\"mini\"\n @click=\"handleUpdate(row)\" class=\"table-inner-button\">编辑</el-button>\n </#if>\n <#if this.entityFeature.delete>\n <el-button type=\"danger\" size=\"mini\"\n @click=\"handleDeleteSingle(row)\" class=\"table-inner-button\">删除</el-button>\n </#if>\n <#list this.holds! as otherEntity,mtm>\n <#assign otherCName=otherEntity.className>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.addRemove>\n <el-button type=\"success\" size=\"mini\"\n @click=\"handle${otherCName}AddRemove(row)\" class=\"table-inner-button\">配置${otherEntity.title}</el-button>\n <#elseIf entityFeature.set>\n <el-button type=\"success\" size=\"mini\"\n @click=\"handle${otherCName}Setting(row)\" class=\"table-inner-button\">配置${otherEntity.title}</el-button>\n </#if>\n </#list>\n </template>\n </el-table-column>\n</#if>\n </el-table>\n<#if this.pageSign>\n <pagination v-show=\"total>0\" :total=\"total\" :page.sync=\"query.page\"\n :limit.sync=\"query.limit\" @pagination=\"doQueryList\"/>\n</#if>\n<#if this.entityFeature.save>\n <!-- 新建表单 -->\n <${this.classNameLower}-add ref=\"${this.classNameLower}Add\" @created=\"doQueryList({<#if this.pageSign> page: 1 </#if>})\"/>\n</#if>\n<#if this.entityFeature.update>\n <!-- 编辑表单 -->\n <${this.classNameLower}-edit ref=\"${this.classNameLower}Edit\" @updated=\"doQueryList({})\"/>\n</#if>\n<#if this.entityFeature.show>\n <!-- 查看表单 -->\n <${this.classNameLower}-show ref=\"${this.classNameLower}Show\"/>\n</#if>\n<#list this.holds! as otherEntity,mtm>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.addRemove>\n <!-- 添加移除${otherEntity.title} -->\n <${othercName}-add-remove ref=\"${othercName}AddRemove\" @updated=\"doQueryList({})\"/>\n <#elseIf entityFeature.set>\n <!-- 设置${otherEntity.title} -->\n <${othercName}-setting ref=\"${othercName}Setting\" @updated=\"doQueryList({})\"/>\n </#if>\n</#list>\n<#if this.entityFeature.excelImport>\n <!-- 查看表单 -->\n <${this.classNameLower}-import ref=\"${this.classNameLower}Import\" @imported=\"doQueryList({<#if this.pageSign> page: 1 </#if>})\"/>\n</#if>\n </div>\n</template>\n\n<script>\n<#if this.entityFeature.save>\nimport ${this.classNameLower}Add from \'./add\'\n</#if>\n<#if this.entityFeature.update>\nimport ${this.classNameLower}Edit from \'./edit\'\n</#if>\n<#if this.entityFeature.show>\nimport ${this.classNameLower}Show from \'./show\'\n</#if>\n<#list this.holds! as otherEntity,mtm>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.addRemove>\nimport ${othercName}AddRemove from \'./${othercName}AddRemove\'\n <#elseIf entityFeature.set>\nimport ${othercName}Setting from \'./${othercName}Setting\'\n </#if>\n</#list>\n<#if this.entityFeature.excelImport>\nimport ${this.classNameLower}Import from \'./import\'\n</#if>\n${importApi(this.metaEntity.className,this.metaEntity.module)}\n<#if !importOtherEntitys.isEmpty()>\n <#list importOtherEntitys as foreignEntity>\n <#if foreignEntity != this.metaEntity>\n${importApi(foreignEntity.className,foreignEntity.module)}\n </#if>\n </#list>\n</#if>\n<#if !importEnums.isEmpty()>\nimport enums from \'@/utils/enums\'\n</#if>\n<#if this.pageSign>\nimport Pagination from \'@/components/Pagination\'\n</#if>\n\nexport default {\n name: \'${this.className}Table\',\n components: {\n<@removeLastComma>\n <#if this.pageSign>\n Pagination,\n </#if>\n <#if this.entityFeature.save>\n ${this.classNameLower}Add,\n </#if>\n <#if this.entityFeature.update>\n ${this.classNameLower}Edit,\n </#if>\n <#if this.entityFeature.show>\n ${this.classNameLower}Show,\n </#if>\n <#list this.holds! as otherEntity,mtm>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.addRemove>\n ${othercName}AddRemove,\n <#elseIf entityFeature.set>\n ${othercName}Setting,\n </#if>\n </#list>\n <#if this.entityFeature.excelImport>\n ${this.classNameLower}Import,\n </#if>\n</@removeLastComma>\n },\n<#if !importEnums.isEmpty()>\n filters: {\n findEnumLabel: enums.findEnumLabel\n },\n</#if>\n data() {\n return {\n<#if !importEnums.isEmpty()>\n enums: {\n <@removeLastComma>\n <#list importEnums as const>\n ${const.constName?uncapFirst}: enums.get${const.constName}(),\n </#list>\n </@removeLastComma>\n },\n</#if>\n<#if !importOtherEntitys.isEmpty()>\n options: {\n <@removeLastComma>\n <#list importOtherEntitys as foreignEntity>\n ${lowerFirstWord(foreignEntity.className)}: [],\n </#list>\n </@removeLastComma>\n },\n</#if>\n<@removeLastComma>\n list: [],\n total: 0,\n listLoading: true,\n query: {\n <@removeLastComma>\n <#if this.pageSign>\n page: 1,\n limit: 10,\n </#if>\n <#list this.queryFields as id,field>\n <#if QueryType.isIn(field.queryType)>\n ${field.jfieldName}: [],\n <#elseIf !QueryType.isBetween(field.queryType)>\n ${field.jfieldName}: ${getFieldEmptyValue(field)},\n <#else>\n ${field.jfieldName}Start: ${getFieldEmptyValue(field)},\n ${field.jfieldName}End: ${getFieldEmptyValue(field)},\n </#if>\n </#list>\n <#list this.listSortFields as id,field>\n ${field.jfieldName}SortSign: 0,\n </#list>\n </@removeLastComma>\n },\n <#if tableSelect>\n selectItems: [],\n </#if>\n</@removeLastComma>\n }\n },\n created() {\n this.doQueryList(<#if this.pageSign>{ page: 1 }</#if>)\n<#if !importOtherEntitys.isEmpty()>\n <@removeLastComma>\n <#list importOtherEntitys as foreignEntity>\n <#assign foreignClassName = lowerFirstWord(foreignEntity.className)>\n ${foreignClassName}Api.findOptions().then(data => { this.options.${foreignClassName} = data })\n </#list>\n </@removeLastComma>\n</#if>\n },\n methods: {\n<@removeLastComma>\n <#if tableSelect>\n /**\n * 选择框变化\n */\n selectionChange(val) {\n this.selectItems = val\n },\n </#if>\n <#if tableSort>\n /**\n * 触发后端排序\n */\n sortChange({ prop, order }) {\n const sortKeyMap = {\n <@removeLastComma>\n <#list this.listSortFields as id,field>\n \'${field.jfieldName}\': \'${field.jfieldName}SortSign\',\n </#list>\n </@removeLastComma>\n }\n for (var k in sortKeyMap) {\n const sortKey = sortKeyMap[k]\n if (k !== prop) {\n this.query[sortKey] = null\n } else {\n if (order === \'ascending\') {\n this.query[sortKey] = 1\n } else {\n this.query[sortKey] = -1\n }\n }\n }\n this.doQueryList({})\n },\n </#if>\n /**\n * 触发搜索操作\n */\n handleQuery() {\n this.doQueryList(<#if this.pageSign>{ page: 1 }</#if>)\n },\n /**\n * 执行列表查询\n */\n doQueryList(<#if this.pageSign>{ page, limit }</#if>) {\n <#if this.pageSign>\n if (page) {\n this.query.page = page\n }\n if (limit) {\n this.query.limit = limit\n }\n </#if>\n this.listLoading = true\n return ${this.classNameLower}Api.fetchList(this.query)\n .then(data => {\n <#if this.pageSign>\n this.list = data.list\n this.total = data.total\n <#else>\n this.list = data\n </#if>\n })\n .finally(() => {\n this.listLoading = false\n })\n },\n <#if this.entityFeature.delete>\n /**\n * 删除单条记录\n */\n handleDeleteSingle(row) {\n return this.$common.confirm(\'是否确认删除\')\n .then(() => ${this.classNameLower}Api.deleteById(row.${this.id}))\n .then(() => {\n this.$common.showMsg(\'success\', \'删除成功\')\n return this.doQueryList(<#if this.pageSign>{ page: 1 }</#if>)\n })\n },\n </#if>\n <#if this.entityFeature.deleteBatch>\n /**\n * 批量删除记录\n */\n handleDeleteBatch() {\n if (this.selectItems.length <= 0) {\n this.$common.showMsg(\'warning\', \'请选择${this.title}\')\n return\n }\n return this.$common.confirm(\'是否确认删除\')\n .then(() => ${this.classNameLower}Api.deleteBatch(this.selectItems.map(row => row.${this.id})))\n .then(() => {\n this.$common.showMsg(\'success\', \'删除成功\')\n return this.doQueryList(<#if this.pageSign>{ page: 1 }</#if>)\n })\n },\n </#if>\n <#if this.entityFeature.save>\n /**\n * 打开新建表单\n */\n handleCreate() {\n this.$refs.${this.classNameLower}Add.handleCreate()\n },\n </#if>\n <#if this.entityFeature.show>\n /**\n * 打开查看表单\n */\n handleShow(row) {\n this.$refs.${this.classNameLower}Show.handleShow(row.${this.id})\n },\n </#if>\n <#if this.entityFeature.update>\n /**\n * 打开编辑表单\n */\n handleUpdate(row) {\n this.$refs.${this.classNameLower}Edit.handleUpdate(row.${this.id})\n },\n </#if>\n <#list this.holds! as otherEntity,mtm>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if entityFeature.addRemove>\n /**\n * 打开添加移除${otherEntity.title}表单\n */\n handle${otherCName}AddRemove(row) {\n this.$refs.${othercName}AddRemove.handleShow(row.${this.id})\n },\n <#elseIf entityFeature.set>\n /**\n * 打开设置${otherEntity.title}表单\n */\n handle${otherCName}Setting(row) {\n this.$refs.${othercName}Setting.handleShow(row.${this.id})\n },\n </#if>\n </#list>\n <#if this.entityFeature.excelExport>\n /**\n * 导出excel\n */\n handleExport() {\n return this.$common.confirm(\'是否确认导出\')\n .then(() => ${this.classNameLower}Api.exportExcel(this.query))\n },\n </#if>\n <#if this.entityFeature.excelImport>\n /**\n * 打开导入表单\n */\n handleImport() {\n this.$refs.${this.classNameLower}Import.show()\n },\n </#if>\n</@removeLastComma>\n }\n}\n</script>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(223,'mtmAddRemove.ftl','/src/views/{module}/{className}',2,2,1,'<#include \"/abstracted/common.ftl\">\n<#if !this.entityFeature.list>\n <@call this.skipCurrent()/>\n</#if>\n<#list this.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if !entityFeature.addRemove>\n <#continue>\n </#if>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign otherId=otherEntity.pkField.jfieldName>\n <#--定义代码内容-->\n <#assign code>\n<template>\n <el-dialog title=\"配置${otherEntity.title}\" :visible.sync=\"formVisible\" @close=\"handleClose\">\n <el-card class=\"box-card\">\n <div slot=\"header\" class=\"clearfix\">\n <el-form :model=\"form\" :inline=\"true\"\n label-position=\"right\" size=\"small\"\n label-width=\"120px\">\n <el-form-item label=\"${otherEntity.title}:\">\n <el-select v-model=\"form.${othercName}List\"\n style=\"width:400px;\" placeholder=\"请输入关键词\"\n remote :remote-method=\"findOptions\"\n :loading=\"optionsLoading\"\n filterable clearable multiple>\n <el-option v-for=\"item in options.${othercName}\"\n :key=\"item.key\"\n :label=\"item.value\"\n :value=\"item.key\">\n </el-option>\n </el-select>\n </el-form-item>\n <el-form-item>\n <el-button type=\"primary\" @click=\"handleAdd${otherCName}\">添加</el-button>\n </el-form-item>\n </el-form>\n </div>\n <el-table :data=\"form.${othercName}ListRaw\" style=\"width: 100%;\"\n size=\"mini\" border>\n <el-table-column label=\"${otherEntity.titleField.fieldDesc}\" prop=\"${otherEntity.titleField.jfieldName}\"></el-table-column>\n <el-table-column label=\"操作\" align=\"center\" width=\"150\">\n <template slot-scope=\"{row}\">\n <el-button type=\"danger\" size=\"mini\"\n @click=\"handleDeleteSingle(row)\" class=\"table-inner-button\">移除</el-button>\n </template>\n </el-table-column>\n </el-table>\n </el-card>\n </el-dialog>\n</template>\n\n<script>\n${importApi(this.metaEntity.className,this.metaEntity.module)}\n${importApi(otherEntity.className,otherEntity.module)}\n\nexport default {\n name: \'${otherCName}Setting\',\n data() {\n return {\n optionsLoading: false,\n options: {\n ${othercName}: []\n },\n form: {\n ${this.id}: null,\n ${othercName}List: [],\n ${othercName}ListRaw: []\n },\n formUpdated: false,\n formVisible: false\n }\n },\n methods: {\n /**\n * 显示表单\n */\n handleShow(${this.id}) {\n this.form.${this.id} = ${this.id}\n this.form.${othercName}List = []\n this.fetchList()\n .then(() => {\n this.formVisible = true\n })\n },\n findOptions(matchValue) {\n // 输入长度小于2,则不加载\n if (!matchValue || matchValue.length < 2) {\n return\n }\n this.optionsLoading = true\n ${othercName}Api.findOptions({ matchValue })\n .then(data => { this.options.${othercName} = data })\n .finally(() => {\n this.optionsLoading = false\n })\n },\n /**\n * 查询表格数据\n */\n fetchList() {\n return ${this.classNameLower}Api.fetch${otherCName}List(this.form.${this.id})\n .then(data => {\n this.form.${othercName}ListRaw = data\n })\n },\n /**\n * 执行添加操作\n */\n handleAdd${otherCName}() {\n if (!this.form.${othercName}List.length) {\n return\n }\n ${this.classNameLower}Api.add${otherCName}(this.form.${this.id}, this.form.${othercName}List)\n .then(data => {\n this.$common.showMsg(\'success\', \'添加成功\')\n this.formUpdated = true\n this.form.${othercName}List = []\n this.fetchList()\n })\n },\n /**\n * 移除单个\n */\n handleDeleteSingle(row) {\n return this.$common.confirm(\'是否确认移除\')\n .then(() => ${this.classNameLower}Api.remove${otherCName}(this.form.${this.id}, [row.${otherId}]))\n .then(() => {\n this.$common.showMsg(\'success\', \'移除成功\')\n this.formUpdated = true\n this.fetchList()\n })\n },\n /**\n * 表单关闭时触发\n */\n handleClose() {\n if (this.formUpdated) {\n this.$emit(\'updated\')\n }\n }\n }\n}\n</script>\n\n </#assign>\n <#--往当前目录输出额外代码文件-->\n <@justCall this.writeAdditionalFile(\"${othercName}AddRemove.vue\",code)/>\n</#list>\n<#--不需要输出当前文件-->\n<@call this.skipCurrent()/>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(224,'mtmSetting.ftl','/src/views/{module}/{className}',2,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForShow.ftl\">\n<#if !this.entityFeature.list>\n <@call this.skipCurrent()/>\n</#if>\n<#list this.holds! as otherEntity,mtm>\n <#assign entityFeature=mtm.getEntityFeature(this.entityId)>\n <#if !entityFeature.set>\n <#continue>\n </#if>\n <#assign otherCName=otherEntity.className>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <#assign otherId=otherEntity.pkField.jfieldName>\n <#--用于判断是否存在级联扩展-->\n <#assign index=getMtmCascadeEntityIndexForShow(otherEntity.entityId)>\n <#--定义代码内容-->\n <#assign code>\n<template>\n <el-dialog title=\"配置${otherEntity.title}\" :visible.sync=\"formVisible\">\n <el-form ref=\"dataForm\" :model=\"form\"\n label-position=\"left\" size=\"small\"\n label-width=\"100px\" style=\"width: 400px; margin-left:50px;\">\n <el-form-item label=\"${otherEntity.title}\">\n <el-select v-model=\"form.${othercName}List\"\n style=\"width:100%;\" placeholder=\"请选择\"\n filterable clearable multiple>\n <el-option v-for=\"item in options.${othercName}\"\n :key=\"item.key\"\n :label=\"item.value\"\n :value=\"item.key\">\n </el-option>\n </el-select>\n </el-form-item>\n </el-form>\n <div slot=\"footer\" class=\"dialog-footer\">\n <el-button @click=\"formVisible = false\">\n 取消\n </el-button>\n <el-button type=\"primary\"\n @click=\"doUpdate()\">\n 确认\n </el-button>\n </div>\n </el-dialog>\n</template>\n\n<script>\n${importApi(this.metaEntity.className,this.metaEntity.module)}\n${importApi(otherEntity.className,otherEntity.module)}\n\nfunction initFormBean() {\n const formBean = {\n ${this.id}: null,\n ${othercName}List: []\n }\n return formBean\n}\n\nexport default {\n name: \'${otherCName}Setting\',\n data() {\n return {\n options: {\n ${othercName}: []\n },\n old: initFormBean(),\n form: initFormBean(),\n formVisible: false\n }\n },\n methods: {\n /**\n * 重置表单\n */\n resetForm() {\n for (const key in initFormBean()) {\n this.form[key] = this.old[key]\n }\n },\n /**\n * 显示表单\n */\n handleShow(${this.id}) {\n ${othercName}Api.findOptions().then(data => { this.options.${othercName} = data })\n ${this.classNameLower}Api.fetch${otherCName}List(${this.id})\n .then(data => {\n this.old = {\n ${this.id}: ${this.id},\n <#if index &gt; -1>\n ${othercName}List: data.map(item => item.${otherId})\n <#else>\n ${othercName}List: data\n </#if>\n }\n this.resetForm()\n this.formVisible = true\n })\n },\n /**\n * 执行修改操作\n */\n doUpdate() {\n this.$refs[\'dataForm\'].validate()\n .then(() => ${this.classNameLower}Api.set${otherCName}(this.form.${this.id}, this.form.${othercName}List))\n .then(data => {\n this.formVisible = false\n this.$common.showMsg(\'success\', \'配置成功\')\n this.$emit(\'updated\', data)\n })\n }\n }\n}\n</script>\n\n </#assign>\n <#--往当前目录输出额外代码文件-->\n <@justCall this.writeAdditionalFile(\"${othercName}Setting.vue\",code)/>\n</#list>\n<#--不需要输出当前文件-->\n<@call this.skipCurrent()/>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(225,'show.vue.ftl','/src/views/{module}/{className}',2,2,1,'<#include \"/abstracted/common.ftl\">\n<#include \"/abstracted/mtmCascadeExtsForShow.ftl\">\n<#if !this.entityFeature.show || !this.entityFeature.list>\n <@call this.skipCurrent()/>\n</#if>\n<template>\n <el-dialog title=\"查看${this.title}\" :visible.sync=\"formVisible\">\n <el-form ref=\"dataForm\" :model=\"form\"\n label-position=\"left\" size=\"small\"\n label-width=\"100px\" style=\"width: 400px; margin-left:50px;\">\n<#-- 把渲染字段的逻辑抽象出来 -->\n<#macro displayShowField field alias>\n <#-- 不渲染外键字段 -->\n <#if field.foreignKey><#return></#if>\n <#local name = alias?hasContent?string(alias,field.jfieldName)/>\n <el-form-item label=\"${field.fieldDesc}\">\n <span class=\"form-item-show\">\n <#if field.dicType??>\n <#assign const = findConst(field.dicType)>\n <@justCall importEnums.add(const)/>\n <#assign constName = const.constName?uncapFirst>\n {{ form.${name} | findEnumLabel(enums.${constName}) }}\n <#else>\n {{ form.${name} }}\n </#if>\n </span>\n </el-form-item>\n</#macro>\n<#--渲染详情字段-->\n<#list this.showFields as id,field>\n <@displayShowField field \"\"/>\n</#list>\n<#-- 外键级联扩展字段 -->\n<#list this.fkFields as id,field>\n <#list field.cascadeShowExts! as cascadeExt>\n <@displayShowField cascadeExt.cascadeField cascadeExt.alias/>\n </#list>\n</#list>\n<#list mtmCascadeEntitiesForShow as otherEntity>\n <#assign mtmCascadeExts = groupMtmCascadeExtsForShow[otherEntity?index]>\n <#assign othercName=lowerFirstWord(otherEntity.className)>\n <el-form-item label=\"${otherEntity.title}\">\n <el-table :data=\"form.${othercName}List\" style=\"width: 100%;\"\n size=\"mini\" border>\n <#list mtmCascadeExts as cascadeExt>\n <#assign cascadeField = cascadeExt.cascadeField>\n <el-table-column label=\"${cascadeField.fieldDesc}\" prop=\"${cascadeField.jfieldName}\">\n <template slot-scope=\"{row}\">\n <#-- 枚举字段特殊处理 -->\n <#if cascadeField.dicType??>\n <#assign const = findConst(cascadeField.dicType)>\n <@justCall importEnums.add(const)/>\n <#assign constName = const.constName?uncapFirst>\n <span>{{ row.${cascadeField.jfieldName} | findEnumLabel(enums.${constName}) }}</span>\n <#-- 普通字段直接展示 -->\n <#else>\n <span>{{ row.${cascadeField.jfieldName} }}</span>\n </#if>\n </template>\n </el-table-column>\n </#list>\n </el-table>\n </el-form-item>\n</#list>\n </el-form>\n <div slot=\"footer\" class=\"dialog-footer\">\n <el-button @click=\"formVisible = false\">\n 取消\n </el-button>\n </div>\n </el-dialog>\n</template>\n\n<script>\n${importApi(this.metaEntity.className,this.metaEntity.module)}\n<#if !importEnums.isEmpty()>\nimport enums from \'@/utils/enums\'\n</#if>\n\nexport default {\n name: \'${this.className}Show\',\n<#if !importEnums.isEmpty()>\n filters: {\n findEnumLabel: enums.findEnumLabel\n },\n</#if>\n data() {\n return {\n<#if !importEnums.isEmpty()>\n enums: {\n <@removeLastComma>\n <#list importEnums as const>\n ${const.constName?uncapFirst}: enums.get${const.constName}(),\n </#list>\n </@removeLastComma>\n },\n</#if>\n form: {\n<@removeLastComma>\n <#list this.showFields as id,field>\n ${field.jfieldName}: null,\n </#list>\n</@removeLastComma>\n },\n formVisible: false\n }\n },\n methods: {\n /**\n * 打开查看表单\n */\n handleShow(${this.id}) {\n ${this.classNameLower}Api.fetchById(${this.id})\n .then(data => {\n this.form = data\n this.formVisible = true\n })\n }\n }\n}\n</script>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(226,'__dir.ftl','/src/views/{module}/{dashboardName}',2,5,4,'<#-- 当前文件用于渲染父路径 -->\n<#include \"/abstracted/common.ftl\">\n${this.nameLower}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(227,'index.vue.ftl','/src/views/{module}/{dashboardName}',2,5,1,'<#include \"/abstracted/commonForDashboard.ftl\">\n<template>\n <grid-layout\n :layout=\"[]\"\n :col-num=\"12\"\n :row-height=\"30\"\n :margin=\"[10, 10]\"\n :isDraggable=\"false\"\n :isResizable=\"false\"\n :autoSize=\"true\"\n style=\"height: calc(100vh - 50px); overflow-x: hidden;\"\n >\n<#list this.layout as item>\n <#if item.chart??>\n <#assign isTable = item.chart.chartType == ChartType.AGG_TABLE.getValue()\n || item.chart.chartType == ChartType.DETAIL_LIST.getValue()>\n <grid-item :x=\"${item.x}\"\n :y=\"${item.y}\"\n :w=\"${item.w}\"\n :h=\"${item.h}\"\n i=\"${item.chart.chartName}\">\n <el-card class=\"box-card${isTable?string(\' card-table\',\'\')}${item.showCard?string(\'\',\' card-hidden\')}\"\n style=\"height:100%;\"${item.showCard?string(\'\',\' shadow=\"never\"\')}>\n <#if item.showTitle>\n <div slot=\"header\">\n <span style=\"white-space:nowrap;\">${item.chart.title}</span>\n </div>\n </#if>\n <${CommonTemplateFunction.camelCaseToKebabCase(item.chart.chartName, false)} height=\"100%\" width=\"100%\" />\n </el-card>\n </grid-item>\n <#else>\n <grid-item :x=\"${item.x}\"\n :y=\"${item.y}\"\n :w=\"${item.w}\"\n :h=\"${item.h}\"\n i=\"${item.i}\">\n </grid-item>\n </#if>\n</#list>\n </grid-layout>\n</template>\n\n<script>\nimport VueGridLayout from \'vue-grid-layout\'\n<#list charts as chart>\nimport ${chart.chartName} from \'@/components/Charts/${chart.chartName}\'\n</#list>\n\nexport default {\n name: \'${this.name}\',\n components: {\n<@removeLastComma>\n GridLayout: VueGridLayout.GridLayout,\n GridItem: VueGridLayout.GridItem,\n <#list charts as chart>\n ${chart.chartName},\n </#list>\n</@removeLastComma>\n }\n}\n</script>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(228,'mock-util.js.ftl','/mock',2,1,1,'const baseURL = process.env.VUE_APP_BASE_API\r\n\r\nexport function paging(list, page, limit) {\r\n const endIndex = page * limit\r\n const startIndex = (page - 1) * limit\r\n return list.slice(startIndex, endIndex)\r\n}\r\n\r\nexport function copy(obj) {\r\n return JSON.parse(JSON.stringify(obj))\r\n}\r\n\r\nexport function getUrlPattern(module, withId, suffix) {\r\n let pattern = `\\\\${r\'$\'}{baseURL}\\\\/${r\'$\'}{module}`\r\n if (withId) {\r\n pattern += `\\\\/(\\\\d+)`\r\n }\r\n if (suffix) {\r\n pattern += `\\\\/${r\'$\'}{suffix}`\r\n }\r\n pattern += `($|\\\\?)`\r\n return new RegExp(pattern)\r\n}\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(229,'index.vue.ftl','/src/components/Pagination',2,1,1,'<template>\r\n <div :class=\"{\'hidden\':hidden}\" class=\"pagination-container\">\r\n <el-pagination\r\n :background=\"background\"\r\n :current-page.sync=\"currentPage\"\r\n :page-size.sync=\"pageSize\"\r\n :layout=\"layout\"\r\n :page-sizes=\"pageSizes\"\r\n :total=\"total\"\r\n v-bind=\"$attrs\"\r\n @size-change=\"handleSizeChange\"\r\n @current-change=\"handleCurrentChange\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { scrollTo } from \'@/utils/scroll-to\'\r\n\r\nexport default {\r\n name: \'Pagination\',\r\n props: {\r\n total: {\r\n required: true,\r\n type: Number\r\n },\r\n page: {\r\n type: Number,\r\n default: 1\r\n },\r\n limit: {\r\n type: Number,\r\n default: 20\r\n },\r\n pageSizes: {\r\n type: Array,\r\n default() {\r\n return [10, 20, 30, 50]\r\n }\r\n },\r\n layout: {\r\n type: String,\r\n default: \'total, sizes, prev, pager, next, jumper\'\r\n },\r\n background: {\r\n type: Boolean,\r\n default: true\r\n },\r\n autoScroll: {\r\n type: Boolean,\r\n default: true\r\n },\r\n hidden: {\r\n type: Boolean,\r\n default: false\r\n }\r\n },\r\n computed: {\r\n currentPage: {\r\n get() {\r\n return this.page\r\n },\r\n set(val) {\r\n this.$emit(\'update:page\', val)\r\n }\r\n },\r\n pageSize: {\r\n get() {\r\n return this.limit\r\n },\r\n set(val) {\r\n this.$emit(\'update:limit\', val)\r\n }\r\n }\r\n },\r\n methods: {\r\n handleSizeChange(val) {\r\n this.$emit(\'pagination\', { page: this.currentPage, limit: val })\r\n if (this.autoScroll) {\r\n scrollTo(0, 800)\r\n }\r\n },\r\n handleCurrentChange(val) {\r\n this.$emit(\'pagination\', { page: val, limit: this.pageSize })\r\n if (this.autoScroll) {\r\n scrollTo(0, 800)\r\n }\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.pagination-container {\r\n background: #fff;\r\n padding: 32px 16px;\r\n}\r\n.pagination-container.hidden {\r\n display: none;\r\n}\r\n</style>\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(230,'home.svg','/src/icons/svg',2,1,3,'PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjUgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMjAwLjE5NSIgaGVpZ2h0PSIyMDAiPjxkZWZzPjxzdHlsZS8+PC9kZWZzPjxwYXRoIGQ9Ik05MzguOTc4IDEwMjRINjQwLjc2N1Y2ODMuNjQ1aC0yNTUuOHYzMzkuODIySDg1LjY4OXYtMTMuMDdjMC0xNzYuNTggMC0zNTIuODkyLjI2Ny01MjkuNDcyIDAtNS44NjggMy40NjctMTMuODcgOC4wMDItMTcuNjA0IDEzOC40MzYtMTExLjIzIDI3Ny4xMzktMjIyLjE5MiA0MTYuMTA4LTMzMy4xNTQuNTM0LS41MzMgMS42LS44IDMuMjAxLTEuMzMzIDQ1LjM0NSAzNi4yNzYgOTEuMjI0IDcyLjgxOSAxMzYuODM2IDEwOS4zNjEgOTEuNDkgNzMuMzUzIDE4Mi45OCAxNDYuNzA1IDI3NS4wMDUgMjE5LjUyNCAxMC40MDIgOC4yNjkgMTQuNDAzIDE2LjUzOCAxNC40MDMgMjkuODc1LS41MzMgMTczLjkxMi0uMjY2IDM0Ny41NTctLjI2NiA1MjEuNDY5LS4yNjcgNC44MDEtLjI2NyA5Ljg2OS0uMjY3IDE0LjkzN3oiLz48cGF0aCBkPSJNODUuNDIyIDg1Ljg4OWgxNjkuOTExdjExOS40OThDMzQyLjU1NiAxMzUuNzY5IDQyNi44NDQgNjguMjg0IDUxMi4yIDBjMjIuOTQgMTguNDA1IDQ2LjE0NSAzNi44MSA2OS4zNTEgNTUuMjE0IDE0NC41NzEgMTE1Ljc2NCAyODkuMTQyIDIzMS41MjcgNDMzLjk4IDM0Ny4wMjQgNi42NjkgNS4zMzUgOS42MDMgMTAuMTM2IDkuMzM2IDE4LjY3Mi0uOCAxMy42MDMtLjI2NyAyNy4yMDctLjI2NyA0NC4wMTFDODUyLjI5IDMyNy4yODUgNjgyLjY0NCAxOTEuNTE3IDUxMi4yIDU1LjIxNCAzNDIuMDIyIDE5MS41MTcgMTcyLjExMSAzMjcuMjg1LjA2NyA0NjQuOTIxYzAtMTkuMjA1LS4yNjctMzUuNDc2LjI2Ni01MS40OCAwLTMuMiAzLjczNS02LjY2OCA2LjQwMi05LjA2OSAyMi42NzMtMTguNDA1IDQ1LjYxMi0zNi44MSA2OC44MTgtNTQuNjggNy40NjktNS44NyAxMC4xMzYtMTIuMDA0IDkuODctMjEuMzRWMTAxLjYyNiA4NS44OXoiLz48L3N2Zz4=','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(231,'common-plugin.js.ftl','/src/utils',2,1,1,'export default {\r\n install(Vue, options) {\r\n Vue.prototype.$common = {\r\n confirm(msg) {\r\n return Vue.prototype.$confirm(msg, \'提示\', {\r\n confirmButtonText: \'确定\',\r\n cancelButtonText: \'取消\',\r\n type: \'warning\'\r\n })\r\n },\r\n showNotify(type, title, msg) {\r\n let duration = 4500\r\n if (type === \'error\') {\r\n duration = 10000\r\n }\r\n return Vue.prototype.$notify({\r\n title: title,\r\n type: type,\r\n message: msg,\r\n duration\r\n })\r\n },\r\n // 打印常用异常\r\n showNotifyError(error) {\r\n // 表单校验异常\r\n if (error === false) {\r\n return this.showNotify(\'error\', \'出错了\', \'表单校验失败\')\r\n }\r\n // 程序指定字符串异常信息\r\n if ((typeof error === \'string\' && error.constructor === String)) {\r\n // 如果是确认窗口点击取消按钮,则不报任何错\r\n if (error === \'cancel\') {\r\n return\r\n }\r\n return this.showNotify(\'error\', \'出错了\', error)\r\n }\r\n if ((typeof error === \'object\')) {\r\n if (error.constructor === Error) {\r\n if (error.response) {\r\n if (error.response.status >= 400) {\r\n if (error.response.data) {\r\n return this.showErrorVO(error.response.data)\r\n } else {\r\n return this.showErrorVO(error)\r\n }\r\n }\r\n }\r\n if (error.message) {\r\n return this.showNotify(\'error\', \'出错了\', error.message)\r\n }\r\n }\r\n // 远程200返回结果中的异常\r\n if (error.code && error.code !== \'0\') {\r\n return this.showErrorVO(error)\r\n }\r\n }\r\n // 未知异常\r\n return this.showNotify(\'error\', \'出错了\', \'\')\r\n },\r\n\r\n showErrorVO(errorVO) {\r\n return this.showNotify(\'error\', \'出错了\', errorVO.message)\r\n },\r\n\r\n showMsg(type, msg) {\r\n Vue.prototype.$message({\r\n message: msg,\r\n type: type\r\n })\r\n },\r\n // 校验服务器返回结果\r\n checkResult(response) {\r\n return new Promise((resolve, reject) => {\r\n if (response.status >= 200 && response.status < 300) {\r\n return resolve(response.data)\r\n } else {\r\n return reject(new Error(response.data))\r\n }\r\n })\r\n }\r\n }\r\n }\r\n}\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(232,'scroll-to.js.ftl','/src/utils',2,1,1,'Math.easeInOutQuad = function(t, b, c, d) {\r\n t /= d / 2\r\n if (t < 1) {\r\n return c / 2 * t * t + b\r\n }\r\n t--\r\n return -c / 2 * (t * (t - 2) - 1) + b\r\n}\r\n\r\n// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts\r\nvar requestAnimFrame = (function() {\r\n return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }\r\n})()\r\n\r\n/**\r\n * Because it\'s so fucking difficult to detect the scrolling element, just move them all\r\n * @param {number} amount\r\n */\r\nfunction move(amount) {\r\n document.documentElement.scrollTop = amount\r\n document.body.parentNode.scrollTop = amount\r\n document.body.scrollTop = amount\r\n}\r\n\r\nfunction position() {\r\n return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop\r\n}\r\n\r\n/**\r\n * @param {number} to\r\n * @param {number} duration\r\n * @param {Function} callback\r\n */\r\nexport function scrollTo(to, duration, callback) {\r\n const start = position()\r\n const change = to - start\r\n const increment = 20\r\n let currentTime = 0\r\n duration = (typeof (duration) === \'undefined\') ? 500 : duration\r\n var animateScroll = function() {\r\n // increment the time\r\n currentTime += increment\r\n // find the value with the quadratic in-out easing function\r\n var val = Math.easeInOutQuad(currentTime, start, change, duration)\r\n // move the document.body\r\n move(val)\r\n // do the animation unless its over\r\n if (currentTime < duration) {\r\n requestAnimFrame(animateScroll)\r\n } else {\r\n if (callback && typeof (callback) === \'function\') {\r\n // the animation is done so lets callback\r\n callback()\r\n }\r\n }\r\n }\r\n animateScroll()\r\n}\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(233,'download.js.ftl','/src/utils',2,1,1,'export function downloadBlob(res, fileName) {\r\n const blob = new Blob([res], { type: res.type })\r\n const downloadElement = document.createElement(\'a\')\r\n const href = window.URL.createObjectURL(blob)\r\n downloadElement.href = href\r\n downloadElement.download = fileName\r\n document.body.appendChild(downloadElement)\r\n downloadElement.click()\r\n document.body.removeChild(downloadElement)\r\n window.URL.revokeObjectURL(href)\r\n}\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(234,'enums.js.ftl','/src/utils',2,1,1,'<#include \"/abstracted/common.ftl\">\r\n<#list this.metaConsts>\r\n <#items as const>\r\n <#assign isString = const.constType==MetaConstType.STRING>\r\nfunction get${const.constName}() {\r\n return {\r\n <@removeLastComma>\r\n <#list const.detailList as detail>\r\n \'${detail.detailName}\': {\r\n value: <#if isString>\'${detail.detailValue}\'<#else>${detail.detailValue}</#if>,\r\n label: \'${detail.detailRemark}\'\r\n },\r\n </#list>\r\n </@removeLastComma>\r\n }\r\n}\r\n\r\n </#items>\r\n<#else>\r\n <@call this.skipCurrent()/>\r\n</#list>\r\nexport default {\r\n<#list this.metaConsts as const>\r\n get${const.constName},\r\n</#list>\r\n findEnumLabel(value, enums) {\r\n for (const key in enums) {\r\n const item = enums[key]\r\n if (item.value === value) {\r\n return item.label\r\n }\r\n }\r\n return \'\'\r\n }\r\n}\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(235,'index.vue.ftl','/src/views/_home',2,1,1,'<template>\r\n <div class=\"home-container\">\r\n <div class=\"home-text\">\r\n 这是首页\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n name: \'Home\'\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.home {\r\n &-container {\r\n margin: 30px;\r\n }\r\n &-text {\r\n font-size: 30px;\r\n line-height: 46px;\r\n }\r\n}\r\n</style>\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(236,'.editorconfig.ftl','/',2,1,1,'# http://editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.md]\ninsert_final_newline = false\ntrim_trailing_whitespace = false\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(237,'.env.development.ftl','/',2,1,1,'# just a flag\r\nENV = \'development\'\r\n\r\n# base api\r\nVUE_APP_BASE_API = \'/api\'\r\n\r\n# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,\r\n# to control whether the babel-plugin-dynamic-import-node plugin is enabled.\r\n# It only does one thing by converting all import() to require().\r\n# This configuration can significantly increase the speed of hot updates,\r\n# when you have a large number of pages.\r\n# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js\r\n\r\nVUE_CLI_BABEL_TRANSPILE_MODULES = true\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(238,'.env.production.ftl','/',2,1,1,'# just a flag\r\nENV = \'production\'\r\n\r\n# base api\r\nVUE_APP_BASE_API = \'/api\'\r\n\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(239,'.env.staging.ftl','/',2,1,1,'NODE_ENV = production\r\n\r\n# just a flag\r\nENV = \'staging\'\r\n\r\n# base api\r\nVUE_APP_BASE_API = \'/api\'\r\n\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(240,'.eslintignore.ftl','/',2,1,1,'build/*.js\nsrc/assets\npublic\ndist\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(241,'.eslintrc.js.ftl','/',2,1,1,'module.exports = {\r\n root: true,\r\n parserOptions: {\r\n parser: \'babel-eslint\',\r\n sourceType: \'module\'\r\n },\r\n env: {\r\n browser: true,\r\n node: true,\r\n es6: true,\r\n },\r\n extends: [\'plugin:vue/recommended\', \'eslint:recommended\'],\r\n\r\n // add your custom rules here\r\n //it is base on https://github.com/vuejs/eslint-config-vue\r\n rules: {\r\n \"vue/max-attributes-per-line\": [2, {\r\n \"singleline\": 4,\r\n \"multiline\": {\r\n \"max\": 3,\r\n \"allowFirstLine\": true\r\n }\r\n }],\r\n \"vue/html-closing-bracket-spacing\": \"off\",\r\n \"vue/html-closing-bracket-newline\": \"off\",\r\n \"vue/attributes-order\": \"off\",\r\n \"vue/html-self-closing\": \"off\",\r\n \"vue/singleline-html-element-content-newline\": \"off\",\r\n \"vue/multiline-html-element-content-newline\":\"off\",\r\n \"vue/name-property-casing\": [\"error\", \"PascalCase\"],\r\n \"vue/no-v-html\": \"off\",\r\n \'accessor-pairs\': 2,\r\n \'arrow-spacing\': [2, {\r\n \'before\': true,\r\n \'after\': true\r\n }],\r\n \'block-spacing\': [2, \'always\'],\r\n \'brace-style\': [2, \'1tbs\', {\r\n \'allowSingleLine\': true\r\n }],\r\n \'camelcase\': [0, {\r\n \'properties\': \'always\'\r\n }],\r\n \'comma-dangle\': [2, \'never\'],\r\n \'comma-spacing\': [2, {\r\n \'before\': false,\r\n \'after\': true\r\n }],\r\n \'comma-style\': [2, \'last\'],\r\n \'constructor-super\': 2,\r\n \'curly\': [2, \'multi-line\'],\r\n \'dot-location\': [2, \'property\'],\r\n \'eol-last\': 2,\r\n \'eqeqeq\': [\"error\", \"always\", {\"null\": \"ignore\"}],\r\n \'generator-star-spacing\': [2, {\r\n \'before\': true,\r\n \'after\': true\r\n }],\r\n \'handle-callback-err\': [2, \'^(err|error)$\'],\r\n \'indent\': [2, 2, {\r\n \'SwitchCase\': 1\r\n }],\r\n \'jsx-quotes\': [2, \'prefer-single\'],\r\n \'key-spacing\': [2, {\r\n \'beforeColon\': false,\r\n \'afterColon\': true\r\n }],\r\n \'keyword-spacing\': [2, {\r\n \'before\': true,\r\n \'after\': true\r\n }],\r\n \'new-cap\': [2, {\r\n \'newIsCap\': true,\r\n \'capIsNew\': false\r\n }],\r\n \'new-parens\': 2,\r\n \'no-array-constructor\': 2,\r\n \'no-caller\': 2,\r\n \'no-console\': \'off\',\r\n \'no-class-assign\': 2,\r\n \'no-cond-assign\': 2,\r\n \'no-const-assign\': 2,\r\n \'no-control-regex\': 0,\r\n \'no-delete-var\': 2,\r\n \'no-dupe-args\': 2,\r\n \'no-dupe-class-members\': 2,\r\n \'no-dupe-keys\': 2,\r\n \'no-duplicate-case\': 2,\r\n \'no-empty-character-class\': 2,\r\n \'no-empty-pattern\': 2,\r\n \'no-eval\': 2,\r\n \'no-ex-assign\': 2,\r\n \'no-extend-native\': 2,\r\n \'no-extra-bind\': 2,\r\n \'no-extra-boolean-cast\': 2,\r\n \'no-extra-parens\': [2, \'functions\'],\r\n \'no-fallthrough\': 2,\r\n \'no-floating-decimal\': 2,\r\n \'no-func-assign\': 2,\r\n \'no-implied-eval\': 2,\r\n \'no-inner-declarations\': [2, \'functions\'],\r\n \'no-invalid-regexp\': 2,\r\n \'no-irregular-whitespace\': 2,\r\n \'no-iterator\': 2,\r\n \'no-label-var\': 2,\r\n \'no-labels\': [2, {\r\n \'allowLoop\': false,\r\n \'allowSwitch\': false\r\n }],\r\n \'no-lone-blocks\': 2,\r\n \'no-mixed-spaces-and-tabs\': 2,\r\n \'no-multi-spaces\': 2,\r\n \'no-multi-str\': 2,\r\n \'no-multiple-empty-lines\': [2, {\r\n \'max\': 1\r\n }],\r\n \'no-native-reassign\': 2,\r\n \'no-negated-in-lhs\': 2,\r\n \'no-new-object\': 2,\r\n \'no-new-require\': 2,\r\n \'no-new-symbol\': 2,\r\n \'no-new-wrappers\': 2,\r\n \'no-obj-calls\': 2,\r\n \'no-octal\': 2,\r\n \'no-octal-escape\': 2,\r\n \'no-path-concat\': 2,\r\n \'no-proto\': 2,\r\n \'no-redeclare\': 2,\r\n \'no-regex-spaces\': 2,\r\n \'no-return-assign\': [2, \'except-parens\'],\r\n \'no-self-assign\': 2,\r\n \'no-self-compare\': 2,\r\n \'no-sequences\': 2,\r\n \'no-shadow-restricted-names\': 2,\r\n \'no-spaced-func\': 2,\r\n \'no-sparse-arrays\': 2,\r\n \'no-this-before-super\': 2,\r\n \'no-throw-literal\': 2,\r\n \'no-trailing-spaces\': 2,\r\n \'no-undef\': 2,\r\n \'no-undef-init\': 2,\r\n \'no-unexpected-multiline\': 2,\r\n \'no-unmodified-loop-condition\': 2,\r\n \'no-unneeded-ternary\': [2, {\r\n \'defaultAssignment\': false\r\n }],\r\n \'no-unreachable\': 2,\r\n \'no-unsafe-finally\': 2,\r\n \'no-unused-vars\': [2, {\r\n \'vars\': \'all\',\r\n \'args\': \'none\'\r\n }],\r\n \'no-useless-call\': 2,\r\n \'no-useless-computed-key\': 2,\r\n \'no-useless-constructor\': 2,\r\n \'no-useless-escape\': 0,\r\n \'no-whitespace-before-property\': 2,\r\n \'no-with\': 2,\r\n \'one-var\': [2, {\r\n \'initialized\': \'never\'\r\n }],\r\n \'operator-linebreak\': [2, \'after\', {\r\n \'overrides\': {\r\n \'?\': \'before\',\r\n \':\': \'before\'\r\n }\r\n }],\r\n \'padded-blocks\': [2, \'never\'],\r\n \'quotes\': [2, \'single\', {\r\n \'avoidEscape\': true,\r\n \'allowTemplateLiterals\': true\r\n }],\r\n \'semi\': [2, \'never\'],\r\n \'semi-spacing\': [2, {\r\n \'before\': false,\r\n \'after\': true\r\n }],\r\n \'space-before-blocks\': [2, \'always\'],\r\n \'space-before-function-paren\': [2, \'never\'],\r\n \'space-in-parens\': [2, \'never\'],\r\n \'space-infix-ops\': 2,\r\n \'space-unary-ops\': [2, {\r\n \'words\': true,\r\n \'nonwords\': false\r\n }],\r\n \'spaced-comment\': [2, \'always\', {\r\n \'markers\': [\'global\', \'globals\', \'eslint\', \'eslint-disable\', \'*package\', \'!\', \',\']\r\n }],\r\n \'template-curly-spacing\': [2, \'never\'],\r\n \'use-isnan\': 2,\r\n \'valid-typeof\': 2,\r\n \'wrap-iife\': [2, \'any\'],\r\n \'yield-star-spacing\': [2, \'both\'],\r\n \'yoda\': [2, \'never\'],\r\n \'prefer-const\': 2,\r\n \'no-debugger\': process.env.NODE_ENV === \'production\' ? 2 : 0,\r\n \'object-curly-spacing\': [2, \'always\', {\r\n objectsInObjects: false\r\n }],\r\n \'array-bracket-spacing\': [2, \'never\']\r\n }\r\n}\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(242,'.gitignore.ftl','/',2,1,1,'.DS_Store\nnode_modules/\ndist/\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npackage-lock.json\ntests/**/coverage/\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(243,'.travis.yml.ftl','/',2,1,1,'language: node_js\nnode_js: 10\nscript: npm run test\nnotifications:\n email: false\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(244,'babel.config.js.ftl','/',2,1,1,'module.exports = {\n presets: [\n \'@vue/app\'\n ]\n}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(245,'index.js.ftl','/build',2,1,1,'const { run } = require(\'runjs\')\nconst chalk = require(\'chalk\')\nconst config = require(\'../vue.config.js\')\nconst rawArgv = process.argv.slice(2)\nconst args = rawArgv.join(\' \')\n\nif (process.env.npm_config_preview || rawArgv.includes(\'--preview\')) {\n const report = rawArgv.includes(\'--report\')\n\n run(`vue-cli-service build ${r\'$\'}{args}`)\n\n const port = 9526\n const publicPath = config.publicPath\n\n var connect = require(\'connect\')\n var serveStatic = require(\'serve-static\')\n const app = connect()\n\n app.use(\n publicPath,\n serveStatic(\'./dist\', {\n index: [\'index.html\', \'/\']\n })\n )\n\n app.listen(port, function () {\n console.log(chalk.green(`> Preview at http://localhost:${r\'$\'}{port}${r\'$\'}{publicPath}`))\n if (report) {\n console.log(chalk.green(`> Report at http://localhost:${r\'$\'}{port}${r\'$\'}{publicPath}report.html`))\n }\n\n })\n} else {\n run(`vue-cli-service build ${r\'$\'}{args}`)\n}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(246,'jest.config.js.ftl','/',2,1,1,'module.exports = {\n moduleFileExtensions: [\'js\', \'jsx\', \'json\', \'vue\'],\n transform: {\n \'^.+\\\\.vue$\': \'vue-jest\',\n \'.+\\\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$\':\n \'jest-transform-stub\',\n \'^.+\\\\.jsx?$\': \'babel-jest\'\n },\n moduleNameMapper: {\n \'^@/(.*)$\': \'<rootDir>/src/$1\'\n },\n snapshotSerializers: [\'jest-serializer-vue\'],\n testMatch: [\n \'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)\'\n ],\n collectCoverageFrom: [\'src/utils/**/*.{js,vue}\', \'!src/utils/auth.js\', \'!src/utils/request.js\', \'src/components/**/*.{js,vue}\'],\n coverageDirectory: \'<rootDir>/tests/unit/coverage\',\n // \'collectCoverage\': true,\n \'coverageReporters\': [\n \'lcov\',\n \'text-summary\'\n ],\n testURL: \'http://localhost/\'\n}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(247,'jsconfig.json.ftl','/',2,1,1,'{\n \"compilerOptions\": {\n \"baseUrl\": \"./\",\n \"paths\": {\n \"@/*\": [\"src/*\"]\n }\n },\n \"exclude\": [\"node_modules\", \"dist\"]\n}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(248,'LICENSE.ftl','/',2,1,1,'MIT License\n\nCopyright (c) 2017-present PanJiaChen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(249,'index.js.ftl','/mock',2,1,1,'<#include \"/abstracted/common.ftl\">\nimport Mock from \'mockjs\'\nimport { param2Obj } from \'../src/utils\'\n\nimport _user from \'./_user\'\n<#list this.metaEntities as entity>\n${importMock(\".\", entity)}\n</#list>\n\nfunction initMockData() {\n<#list this.metaEntities as entity>\n ${lowerFirstWord(entity.className)}.initMockDataStage1()\n</#list>\n<#list this.metaEntities as entity>\n ${lowerFirstWord(entity.className)}.initMockDataStage2()\n</#list>\n}\n\nconst reqMocks = [\n ..._user,\n<@removeLastComma>\n <#list this.metaEntities as entity>\n ...${lowerFirstWord(entity.className)}.reqMocks,\n </#list>\n</@removeLastComma>\n]\n\n// for front mock\n// please use it cautiously, it will redefine XMLHttpRequest,\n// which will cause many of your third-party libraries to be invalidated(like progress event).\nexport function mockXHR() {\n // mock patch\n // https://github.com/nuysoft/Mock/issues/300\n Mock.setup({\n timeout: \'100-500\'\n })\n Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send\n Mock.XHR.prototype.send = function() {\n if (this.custom.xhr) {\n this.custom.xhr.withCredentials = this.withCredentials || false\n\n if (this.responseType) {\n this.custom.xhr.responseType = this.responseType\n }\n }\n this.proxy_send(...arguments)\n }\n\n function XHR2ExpressReqWrap(respond) {\n return function(options) {\n const { body, type, url } = options\n console.info(`${r\'$\'}{type} ${r\'$\'}{url} ${r\'$\'}{body ? \'body=\' + JSON.stringify(body) : \'\'}`)\n let result = null\n if (respond instanceof Function) {\n // https://expressjs.com/en/4x/api.html#req\n result = respond({\n method: type,\n body: JSON.parse(body),\n query: param2Obj(url),\n url: url\n })\n } else {\n result = respond\n }\n const mockResult = Mock.mock(result)\n console.info(mockResult)\n return mockResult\n }\n }\n // 初始化所有mock数据\n initMockData()\n // 设置异步请求的mock规则\n for (const i of reqMocks) {\n Mock.mock(new RegExp(i.url), i.type || \'get\', XHR2ExpressReqWrap(i.response))\n }\n}\n\n// for mock server\nconst responseFake = (url, type, respond) => {\n return {\n url: new RegExp(`/mock${r\'$\'}{url}`),\n type: type || \'get\',\n response(req, res) {\n res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))\n }\n }\n}\n\nexport default reqMocks.map(route => {\n return responseFake(route.url, route.type, route.response)\n})\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(250,'mock-server.js.ftl','/mock',2,1,1,'const chokidar = require(\'chokidar\')\nconst bodyParser = require(\'body-parser\')\nconst chalk = require(\'chalk\')\nconst path = require(\'path\')\n\nconst mockDir = path.join(process.cwd(), \'mock\')\n\nfunction registerRoutes(app) {\n let mockLastIndex\n const { default: mocks } = require(\'./index.js\')\n for (const mock of mocks) {\n app[mock.type](mock.url, mock.response)\n mockLastIndex = app._router.stack.length\n }\n const mockRoutesLength = Object.keys(mocks).length\n return {\n mockRoutesLength: mockRoutesLength,\n mockStartIndex: mockLastIndex - mockRoutesLength\n }\n}\n\nfunction unregisterRoutes() {\n Object.keys(require.cache).forEach(i => {\n if (i.includes(mockDir)) {\n delete require.cache[require.resolve(i)]\n }\n })\n}\n\nmodule.exports = app => {\n // es6 polyfill\n require(\'@babel/register\')\n\n // parse app.body\n // https://expressjs.com/en/4x/api.html#req.body\n app.use(bodyParser.json())\n app.use(bodyParser.urlencoded({\n extended: true\n }))\n\n const mockRoutes = registerRoutes(app)\n var mockRoutesLength = mockRoutes.mockRoutesLength\n var mockStartIndex = mockRoutes.mockStartIndex\n\n // watch files, hot reload mock server\n chokidar.watch(mockDir, {\n ignored: /mock-server/,\n ignoreInitial: true\n }).on(\'all\', (event, path) => {\n if (event === \'change\' || event === \'add\') {\n try {\n // remove mock routes stack\n app._router.stack.splice(mockStartIndex, mockRoutesLength)\n\n // clear routes cache\n unregisterRoutes()\n\n const mockRoutes = registerRoutes(app)\n mockRoutesLength = mockRoutes.mockRoutesLength\n mockStartIndex = mockRoutes.mockStartIndex\n\n console.log(chalk.magentaBright(`\\n > Mock Server hot reload success! changed ${r\'$\'}{path}`))\n } catch (error) {\n console.log(chalk.redBright(error))\n }\n }\n })\n}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(251,'_user.js.ftl','/mock',2,1,1,'<#include \"/abstracted/common.ftl\">\r\nconst baseURL = process.env.VUE_APP_BASE_API\r\n\r\nconst tokens = {\r\n admin: {\r\n token: \'admin-token\'\r\n },\r\n editor: {\r\n token: \'editor-token\'\r\n }\r\n}\r\n\r\nconst users = {\r\n \'admin-token\': {\r\n roles: [\'admin\'],\r\n introduction: \'I am a super administrator\',\r\n avatar: \'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif\',\r\n name: \'Super Admin\'\r\n },\r\n \'editor-token\': {\r\n roles: [\'editor\'],\r\n introduction: \'I am an editor\',\r\n avatar: \'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif\',\r\n name: \'Normal Editor\'\r\n }\r\n}\r\n\r\nexport default [\r\n // user login\r\n {\r\n url: `${r\'$\'}{baseURL}/_user/login`,\r\n type: \'post\',\r\n response: config => {\r\n const { username } = config.body\r\n const token = tokens[username]\r\n\r\n // mock error\r\n if (!token) {\r\n return {\r\n code: 60204,\r\n message: \'Account and password are incorrect.\'\r\n }\r\n }\r\n\r\n return {\r\n code: 20000,\r\n data: token\r\n }\r\n }\r\n },\r\n\r\n // get user info\r\n {\r\n url: `${r\'$\'}{baseURL}/_user/info\\.*`,\r\n type: \'get\',\r\n response: config => {\r\n const { token } = config.query\r\n const info = users[token]\r\n\r\n // mock error\r\n if (!info) {\r\n return {\r\n code: 50008,\r\n message: \'Login failed, unable to get user details.\'\r\n }\r\n }\r\n\r\n return {\r\n code: 20000,\r\n data: info\r\n }\r\n }\r\n },\r\n\r\n // user logout\r\n {\r\n url: `${r\'$\'}{baseURL}/_user/logout`,\r\n type: \'post\',\r\n response: _ => {\r\n return {\r\n code: 20000,\r\n data: \'success\'\r\n }\r\n }\r\n }\r\n]\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(252,'package.json.ftl','/',2,1,1,'{\n \"name\": \"vue-admin-template\",\n \"version\": \"4.2.1\",\n \"description\": \"A vue admin template with Element UI & axios & iconfont & permission control & lint\",\n \"author\": \"Pan <panfree23@gmail.com>\",\n \"license\": \"MIT\",\n \"scripts\": {\n \"dev\": \"vue-cli-service serve --open\",\n \"dev:joint\": \"vue-cli-service serve --open --mode staging\",\n \"build:prod\": \"vue-cli-service build\",\n \"build:stage\": \"vue-cli-service build --mode staging\",\n \"preview\": \"node build/index.js --preview\",\n \"lint\": \"eslint --ext .js,.vue src\",\n \"test:unit\": \"jest --clearCache && vue-cli-service test:unit\",\n \"test:ci\": \"npm run lint && npm run test:unit\",\n \"svgo\": \"svgo -f src/icons/svg --config=src/icons/svgo.yml\"\n },\n \"dependencies\": {\n \"axios\": \"0.18.1\",\n \"echarts\": \"^4.8.0\",\n \"element-ui\": \"2.13.2\",\n \"js-cookie\": \"2.2.0\",\n \"normalize.css\": \"7.0.0\",\n \"nprogress\": \"0.2.0\",\n \"path-to-regexp\": \"2.4.0\",\n \"qs\": \"^6.7.0\",\n \"vue\": \"2.6.10\",\n \"vue-grid-layout\": \"^2.3.7\",\n \"vue-router\": \"3.0.6\",\n \"vuex\": \"3.1.0\"\n },\n \"devDependencies\": {\n \"@babel/core\": \"7.0.0\",\n \"@babel/register\": \"7.0.0\",\n \"@vue/cli-plugin-babel\": \"3.6.0\",\n \"@vue/cli-plugin-eslint\": \"^3.9.1\",\n \"@vue/cli-plugin-unit-jest\": \"3.6.3\",\n \"@vue/cli-service\": \"3.6.0\",\n \"@vue/test-utils\": \"1.0.0-beta.29\",\n \"autoprefixer\": \"^9.5.1\",\n \"babel-core\": \"7.0.0-bridge.0\",\n \"babel-eslint\": \"10.0.1\",\n \"babel-jest\": \"23.6.0\",\n \"chalk\": \"2.4.2\",\n \"connect\": \"3.6.6\",\n \"eslint\": \"5.15.3\",\n \"eslint-plugin-vue\": \"5.2.2\",\n \"html-webpack-plugin\": \"3.2.0\",\n \"mockjs\": \"1.0.1-beta3\",\n \"node-sass\": \"^4.9.0\",\n \"runjs\": \"^4.3.2\",\n \"sass-loader\": \"^7.1.0\",\n \"script-ext-html-webpack-plugin\": \"2.1.3\",\n \"script-loader\": \"0.7.2\",\n \"serve-static\": \"^1.13.2\",\n \"svg-sprite-loader\": \"4.1.3\",\n \"svgo\": \"1.2.2\",\n \"vue-template-compiler\": \"2.6.10\"\n },\n \"engines\": {\n \"node\": \">=8.9\",\n \"npm\": \">= 3.0.0\"\n },\n \"browserslist\": [\n \"> 1%\",\n \"last 2 versions\"\n ]\n}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(253,'postcss.config.js.ftl','/',2,1,1,'// https://github.com/michael-ciniawsky/postcss-load-config\n\nmodule.exports = {\n \'plugins\': {\n // to edit target browsers: use \"browserslist\" field in package.json\n \'autoprefixer\': {}\n }\n}\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(254,'favicon.ico','/public',2,1,3,'AAABAAEAgIAAAAEAIAAoCAEAFgAAACgAAACAAAAAAAEAAAEAIAAAAAAAAAABAMMOAADDDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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T/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT+qNwE+njcBPWI3BTBCMwU4AiMFJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI2+SwCNwk8AjMBOMo3AT8WNwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE/ojcBPs4zBTmCJwEoQjcFPAYDIRwCNwU4AkrxTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAma42AI3BTxmNwE+hjcBP/I3AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP7I3AT72NwU9hjsBPFo3BTgOMwU4AjMBMAIK6QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI3BTwCMvksFjcBObo3AT/iNwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/ONwE/EjcBPXo3ATx2KwUgDjsFPAIvASwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByvjAAkMJSAYzATjCNwE/ZjcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/6NwE/6jcBPxY3ATmaNwU4lcrkgAY3BTgCQvlEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/P2QCIwEoHjcBPmo3AT/yNwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/I3AT7+NwE5pjcFOIIvCTgCMwU4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi8FNAIzBTjuNwE/ljcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/WNwE+4jcBPZozBThSNwU8AjcFPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLvk4BjcBPmI3AT/uNwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE/ujcBPtI3BT1GNwU8Jjb9MAY3ATwCIvkcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi75KAIu+Ti2NwE/VjcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jb9P/4y/T/+Mv0//jL9P/4y/T/+Mv0//jL9P/42/T/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP6I3AT6KNv042jcBOB4/BUwCLwU0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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T/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE/9jcBPxo2/UEKMwFAEjMFOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI3ATiiNwE/XjcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+OwU//hq9L/2hkO/9cSDb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XUk2/11JNv9qaj3/jb9P/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP2o3BT1aMwU4HjcFOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjcBPMI3AT+uNwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/47CT/+Dp0r/YFE4/11JNv9dSTb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XUg2/2VdOv+Grkv/jcFP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP5IzBTmiNwU4NjcFOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNwE81jcBP+Y3AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jL5P/3mPRf9eSzb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XUg2/11INv9dSTb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/Xks2/3F6QP+MvU7/jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP6o3BTnaNwU4OjcFOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI3ATzeNwE/+jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+Gr0v/ZVw6/11JNv9dSTb/XUk2/11JNv9dSTb/XUk2/11INv9jVzn/ZFo5/15LNv9dSTb/XUk2/11JNv9dSTb/XUk2/11JNv9cRzX/aGU8/4izTP+NwU//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP6o3BTnaNwU0NjcFPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjcBPN43AT/6NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jb9P/36aR/9eSzb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XEc2/21wPv98lUb/Y1k5/11INv9dSTb/XUk2/11JNv9dSTb/XUk2/1xHNv9nYTv/hatL/47BT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP643B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T/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/47CT/95j0X/YFA4/11INv9dSTb/XUk2/11JNv9dSTb/XUk2/11INv9jVzn/f5xI/47CUP+NwE//jcFP/4eyTP9lXjr/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XUk2/15MN/+CpEn/jsJP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE/SjcBPNI/CTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNwE8wjcBP643AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jsJQ/291P/9cRzb/XUk2/11JNv9dSTb/XUk2/11JNv9eSzb/YlY4/3iLRP+MvE7/jcBP/43AT/+NwU//iLJM/2hiO/9dSDb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XUo2/3yXRv+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43A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T/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcFP/4q4Tf9xe0H/XUg2/11JNv9dSTb/XUk2/11JNv9dSTb/XUk2/11JNv9fTjf/gKBI/42/T/+NwE//jcBP/43AT/+NwE//jcBP/43BT/+JtU3/a20+/1xGNf9dSTb/XUk2/11JNv9dSTb/XUk2/15MN/9fTzf/eIxF/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT9+NwE4hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI2+SwCNwE9PjcBP943AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwU//h7FM/2lmPP9dSDb/XUk2/11JNv9dSTb/XUk2/11JNv9dSTb/XUk2/2VcOv+Hskz/jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/47CUP9yfUH/XEg1/11JNv9dSTb/XUk2/11JNv9dSTb/aWc8/2BROP9ucz//i7tO/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP7IzB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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJbFXgCMwU9UjcBP5Y3AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/Y3AT7ONwVAfjbtKAI6/TgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf7s4AI3AThGNwE+wjcBP/Y3AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/6NwE/CjMBOMIXDTQCOwVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkbxMAI3AT1aNwE/pjcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBPyo7ATz6MwE0BjMFPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAir9KCo3AT6qNwE/8jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/o3AT8OOwE9AjsBPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AjsFPP43AT+WNwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/yNwE+sjsBPNH/CQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIjHSwCOwFAIjcBPjY3AT/uNwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE/vjb9OiozBUCGUwFUAnr5dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkr5RAI/FUgCNwE8mjcBOzo3AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE/7jcBPz4zAT1uNvk4Oi8JRAIPARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjsFQAIu+SgONwE5bjcBP8Y3AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP6Y3AT5iMwU4pi79PA4+/TACPvUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoNNuAI7BUBSNwE+WjcBP/I3AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP9Y3AT76NwE9Vjr9QCIrDTQCMwE8AfbxeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjsFQAI3ATzCNwE/IjcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/Y3AT8uNwE93jb9NHY3AUACQv1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAorZbAY3AT1aNwE/kjcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT9uMwE6BjMFOMqCtYQCNv00Ajb9MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRvlEAjcJPCo3BT32NwE/xjcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/I3AT+WNwE+MjcBPOYnCSgiMwU4AjMFOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNwU8Ai8FNEozAT6CNwE/6jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP+Y3AT+CNwE+NjcBPM43BTg2LwU4Ai8FMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACTw1YAjcBPHo3AT7iNwE/+jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP943AT9eNwE+Ni8FNK43BTwiJwU0AjcFOAI+/UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIPARQCQvU0BjcBPMI3AT8WNwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP9I3AT8mNwE+DjsFOK43ATwKIwUoAjcFPAI7AUACSvFEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJG8SwCRvEsBjcBPPY3AT8uNwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP7o3AT7WNwE5xjr5NKI3CUACOwU4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI++TQCIvFgCjcBQQI3AT8uNwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP4Y3AT5mNwE5Wjr9OHYvCTwCOvk0Ajr1NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIu+UgCJvFYCjL9QQI3AT8yNwE/+jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43AT/+NwE//jcBP/43A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TwCNwE8AjcBPAI3ATwCNwE8AjsBPAI3ATgCNwE8AjsFOAI3ATQCMv00AjL9NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////4AD//////////////////wAAD/////////////////gAAAD////////////////gAAAAH///////////////AAAAAAD//////////////gAAAAAAP/////////////wAAAAAAA/////////////4AAAAAAAD////////////8AAAAAAAAP////////////AAAAAAAAA////////////AAAAAAAAAB///////////gAAAAAAAAAH//////////4AAAAAAAAAAf/////////8AAAAAAAAAAB//////////AAAAAAAAAAAP/////////gAAAAAAAAAAA/////////4AAAAAAAAAAAB////////+AAAAAAAAAAAAP////////gAAAAAAAAAAAA////////wAAAAAAAAAAAAH///////8AAAAAAAAAAAAAf///////AAAAAAAAAAAAAD///////gAAAAAAAAAAAAAP//////4AAAAAAAAAAAAAB//////+AAAAAAAAAAAAAAH//////AAAAAAAAAAAAAAA//////wAAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAD/////wAAAAAAAAAAAAAAAf////8AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAf////wAAAAAAAAAAAAAAAD////8AAAAAAAAAAAAAAAAP////AAAAAAAAAAAAAAAAD////wAAAAAAAAAAAAAAAAf///8AAAAAAAAAAAAAAAAH////AAAAAAAAAAAAAAAAA////wAAAAAAAAAAAAAAAAH///8AAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAB///8AAAAAAAAAAAAAAAAAf///AAAAAAAAAAAAAAAAAD///wAAAAAAAAAAAAAAAAA///8AAAAAAAAAAAAAAAAAP///AAAAAAAAAAAAAAAAAD///4AAAAAAAAAAAAAAAAA///+AAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAAAAD///4AAAAAAAAAAAAAAAAA///+AAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAP///4AAAAAAAAAAAAAAAAD///+AAAAAAAAAAAAAAAAA////gAAAAAAAAAAAAAAAAP///4AAAAAAAAAAAAAAAAD////AAAAAAAAAAAAAAAAA////gAAAAAAAAAAAAAAAAf///8AAAAAAAAAAAAAAAAH////AAAAAAAAAAAAAAAAD////4AAAAAAAAAAAAAAAB////+AAAAAAAAAAAAAAAAf////gAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAH/////gAAAAAAAAAAAAAAB/////4AAAAAAAAAAAAAAA//////AAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAD//////gAAAAAAAAAAAAAD//////4AAAAAAAAAAAAAB///////AAAAAAAAAAAAAA///////wAAAAAAAAAAAAAf//////+AAAAAAAAAAAAAP///////wAAAAAAAAAAAAH///////+AAAAAAAAAAAAP////////gAAAAAAAAAAAP////////8AAAAAAAAAAAH/////////gAAAAAAAAAAH/////////8AAAAAAAAAAH//////////AAAAAAAAAAD//////////4AAAAAAAAAP///////////AAAAAAAAAP///////////4AAAAAAAAP////////////AAAAAAAAP////////////4AAAAAAAP/////////////AAAAAAAP/////////////+AAAAAB///////////////wAAAAD////////////////AAAAP////////////////8AAAf/////////////////wAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8=','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(255,'index.html.ftl','/public',2,1,1,'<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\">\n <link rel=\"icon\" href=\"<%= BASE_URL %>favicon.ico\">\n <title><%= webpackConfig.name %></title>\n </head>\n <body>\n <noscript>\n <strong>We\'re sorry but <%= webpackConfig.name %> doesn\'t work properly without JavaScript enabled. Please enable it to continue.</strong>\n </noscript>\n <div id=\"app\"></div>\n <!-- built files will be auto injected -->\n </body>\n</html>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(256,'README-zh.md.ftl','/',2,1,1,'# vue-admin-template\n\n> 这是一个极简的 vue admin 管理后台。它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。\n\n[线上地址](http://panjiachen.github.io/vue-admin-template)\n\n[国内访问](https://panjiachen.gitee.io/vue-admin-template)\n\n目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0),它不依赖 `vue-cli`。\n\n## Extra\n\n如果你想要根据用户角色来动态生成侧边栏和 router,你可以使用该分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)\n\n## 相关项目\n\n- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)\n\n- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)\n\n- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)\n\n- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)\n\n写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:\n\n- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)\n- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)\n- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)\n- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板,专门针对本项目的文章,算作是一篇文档)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)\n- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)\n\n## Build Setup\n\n```bash\n# 克隆项目\ngit clone https://github.com/PanJiaChen/vue-admin-template.git\n\n# 进入项目目录\ncd vue-admin-template\n\n# 安装依赖\nnpm install\n\n# 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题\nnpm install --registry=https://registry.npm.taobao.org\n\n# 启动服务\nnpm run dev\n```\n\n浏览器访问 [http://localhost:9528](http://localhost:9528)\n\n## 发布\n\n```bash\n# 构建测试环境\nnpm run build:stage\n\n# 构建生产环境\nnpm run build:prod\n```\n\n## 其它\n\n```bash\n# 预览发布环境效果\nnpm run preview\n\n# 预览发布环境效果 + 静态资源分析\nnpm run preview -- --report\n\n# 代码格式检查\nnpm run lint\n\n# 代码格式检查并自动修复\nnpm run lint -- --fix\n```\n\n更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)\n\n## Demo\n\n![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)\n\n## Browsers support\n\nModern browsers and Internet Explorer 10+.\n\n| [<img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png\" alt=\"IE / Edge\" width=\"24px\" height=\"24px\" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\" alt=\"Firefox\" width=\"24px\" height=\"24px\" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\" alt=\"Chrome\" width=\"24px\" height=\"24px\" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png\" alt=\"Safari\" width=\"24px\" height=\"24px\" />](http://godban.github.io/browsers-support-badges/)</br>Safari |\n| --------- | --------- | --------- | --------- |\n| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions\n\n## License\n\n[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.\n\nCopyright (c) 2017-present PanJiaChen\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(257,'README.md.ftl','/',2,1,1,'# vue-admin-template\n\nEnglish | [简体中文](./README-zh.md)\n\n> A minimal vue admin template with Element UI & axios & iconfont & permission control & lint\n\n**Live demo:** http://panjiachen.github.io/vue-admin-template\n\n\n**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`**\n\n## Build Setup\n\n\n```bash\n# clone the project\ngit clone https://github.com/PanJiaChen/vue-admin-template.git\n\n# enter the project directory\ncd vue-admin-template\n\n# install dependency\nnpm install\n\n# develop\nnpm run dev\n```\n\nThis will automatically open http://localhost:9528\n\n## Build\n\n```bash\n# build for test environment\nnpm run build:stage\n\n# build for production environment\nnpm run build:prod\n```\n\n## Advanced\n\n```bash\n# preview the release environment effect\nnpm run preview\n\n# preview the release environment effect + static resource analysis\nnpm run preview -- --report\n\n# code format check\nnpm run lint\n\n# code format check and auto fix\nnpm run lint -- --fix\n```\n\nRefer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information\n\n## Demo\n\n![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)\n\n## Extra\n\nIf you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)\n\nFor `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))\n\n## Related Project\n\n- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)\n\n- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)\n\n- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)\n\n- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)\n\n## Browsers support\n\nModern browsers and Internet Explorer 10+.\n\n| [<img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png\" alt=\"IE / Edge\" width=\"24px\" height=\"24px\" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\" alt=\"Firefox\" width=\"24px\" height=\"24px\" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\" alt=\"Chrome\" width=\"24px\" height=\"24px\" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png\" alt=\"Safari\" width=\"24px\" height=\"24px\" />](http://godban.github.io/browsers-support-badges/)</br>Safari |\n| --------- | --------- | --------- | --------- |\n| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions\n\n## License\n\n[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.\n\nCopyright (c) 2017-present PanJiaChen\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(258,'_user.js.ftl','/src/api',2,1,1,'import request from \'@/utils/request\'\r\n\r\nexport function login(data) {\r\n return request({\r\n url: \'/_user/login\',\r\n method: \'post\',\r\n data\r\n })\r\n}\r\n\r\nexport function getInfo(token) {\r\n return request({\r\n url: \'/_user/info\',\r\n method: \'get\',\r\n params: { token }\r\n })\r\n}\r\n\r\nexport function logout() {\r\n return request({\r\n url: \'/_user/logout\',\r\n method: \'post\'\r\n })\r\n}\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(259,'App.vue.ftl','/src',2,1,1,'<template>\n <div id=\"app\">\n <router-view />\n </div>\n</template>\n\n<script>\nexport default {\n name: \'App\'\n}\n</script>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(260,'404.png','/src/assets/404_images',2,1,3,'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','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(261,'404_cloud.png','/src/assets/404_images',2,1,3,'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','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(262,'index.vue.ftl','/src/components/Breadcrumb',2,1,1,'<#include \"/abstracted/common.ftl\">\r\n<template>\r\n <el-breadcrumb class=\"app-breadcrumb\" separator=\"/\">\r\n <transition-group name=\"breadcrumb\">\r\n <el-breadcrumb-item v-for=\"(item,index) in levelList\" :key=\"item.path\">\r\n <span v-if=\"item.redirect===\'noRedirect\'||index==levelList.length-1\" class=\"no-redirect\">{{ item.meta.title }}</span>\r\n <a v-else @click.prevent=\"handleLink(item)\">{{ item.meta.title }}</a>\r\n </el-breadcrumb-item>\r\n </transition-group>\r\n </el-breadcrumb>\r\n</template>\r\n\r\n<script>\r\nimport pathToRegexp from \'path-to-regexp\'\r\n\r\nexport default {\r\n data() {\r\n return {\r\n levelList: null\r\n }\r\n },\r\n watch: {\r\n $route() {\r\n this.getBreadcrumb()\r\n }\r\n },\r\n created() {\r\n this.getBreadcrumb()\r\n },\r\n methods: {\r\n getBreadcrumb() {\r\n // only show routes with meta.title\r\n let matched = this.$route.matched.filter(item => item.meta && item.meta.title)\r\n const first = matched[0]\r\n\r\n if (!this.isHome(first)) {\r\n matched = [{ path: \'/home\', meta: { title: \'首页\' }}].concat(matched)\r\n }\r\n\r\n this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)\r\n },\r\n isHome(route) {\r\n const name = route && route.name\r\n if (!name) {\r\n return false\r\n }\r\n return name.trim().toLocaleLowerCase() === \'Home\'.toLocaleLowerCase()\r\n },\r\n pathCompile(path) {\r\n // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561\r\n const { params } = this.$route\r\n var toPath = pathToRegexp.compile(path)\r\n return toPath(params)\r\n },\r\n handleLink(item) {\r\n const { redirect, path } = item\r\n if (redirect) {\r\n this.$router.push(redirect)\r\n return\r\n }\r\n this.$router.push(this.pathCompile(path))\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.app-breadcrumb.el-breadcrumb {\r\n display: inline-block;\r\n font-size: 14px;\r\n line-height: 50px;\r\n margin-left: 8px;\r\n\r\n .no-redirect {\r\n color: #97a8be;\r\n cursor: text;\r\n }\r\n}\r\n</style>\r\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(263,'index.vue.ftl','/src/components/Hamburger',2,1,1,'<template>\n <div style=\"padding: 0 15px;\" @click=\"toggleClick\">\n <svg\n :class=\"{\'is-active\':isActive}\"\n class=\"hamburger\"\n viewBox=\"0 0 1024 1024\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"64\"\n height=\"64\"\n >\n <path d=\"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z\" />\n </svg>\n </div>\n</template>\n\n<script>\nexport default {\n name: \'Hamburger\',\n props: {\n isActive: {\n type: Boolean,\n default: false\n }\n },\n methods: {\n toggleClick() {\n this.$emit(\'toggleClick\')\n }\n }\n}\n</script>\n\n<style scoped>\n.hamburger {\n display: inline-block;\n vertical-align: middle;\n width: 20px;\n height: 20px;\n}\n\n.hamburger.is-active {\n transform: rotate(180deg);\n}\n</style>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(264,'index.vue.ftl','/src/components/SvgIcon',2,1,1,'<template>\n <div v-if=\"isExternal\" :style=\"styleExternalIcon\" class=\"svg-external-icon svg-icon\" v-on=\"$listeners\" />\n <svg v-else :class=\"svgClass\" aria-hidden=\"true\" v-on=\"$listeners\">\n <use :href=\"iconName\" />\n </svg>\n</template>\n\n<script>\n// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage\nimport { isExternal } from \'@/utils/validate\'\n\nexport default {\n name: \'SvgIcon\',\n props: {\n iconClass: {\n type: String,\n required: true\n },\n className: {\n type: String,\n default: \'\'\n }\n },\n computed: {\n isExternal() {\n return isExternal(this.iconClass)\n },\n iconName() {\n return `#icon-${r\'$\'}{this.iconClass}`\n },\n svgClass() {\n if (this.className) {\n return \'svg-icon \' + this.className\n } else {\n return \'svg-icon\'\n }\n },\n styleExternalIcon() {\n return {\n mask: `url(${r\'$\'}{this.iconClass}) no-repeat 50% 50%`,\n \'-webkit-mask\': `url(${r\'$\'}{this.iconClass}) no-repeat 50% 50%`\n }\n }\n }\n}\n</script>\n\n<style scoped>\n.svg-icon {\n width: 1em;\n height: 1em;\n vertical-align: -0.15em;\n fill: currentColor;\n overflow: hidden;\n}\n\n.svg-external-icon {\n background-color: currentColor;\n mask-size: cover!important;\n display: inline-block;\n}\n</style>\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(265,'index.js.ftl','/src/icons',2,1,1,'import Vue from \'vue\'\nimport SvgIcon from \'@/components/SvgIcon\'// svg component\n\n// register globally\nVue.component(\'svg-icon\', SvgIcon)\n\nconst req = require.context(\'./svg\', false, /\\.svg$/)\nconst requireAll = requireContext => requireContext.keys().map(requireContext)\nrequireAll(req)\n','2021-01-08 17:12:57','admin','2021-01-08 17:12:57','admin',1,0),(266,'dashboard.svg','/src/icons/svg',2,1,3,'PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjcuNDI5IDYzLjYzOGMwLTIuNTA4LS44OTMtNC42NS0yLjY3OS02LjQyNC0xLjc4Ni0xLjc3NS0zLjk0LTIuNjYyLTYuNDY0LTIuNjYyLTIuNTI0IDAtNC42NzkuODg3LTYuNDY1IDIuNjYyLTEuNzg1IDEuNzc0LTIuNjc4IDMuOTE2LTIuNjc4IDYuNDI0IDAgMi41MDguODkzIDQuNjUgMi42NzggNi40MjQgMS43ODYgMS43NzUgMy45NCAyLjY2MiA2LjQ2NSAyLjY2MiAyLjUyNCAwIDQuNjc4LS44ODcgNi40NjQtMi42NjIgMS43ODYtMS43NzUgMi42NzktMy45MTYgMi42NzktNi40MjR6bTEzLjcxNC0zMS44MDFjMC0yLjUwOC0uODkzLTQuNjUtMi42NzktNi40MjQtMS43ODUtMS43NzUtMy45NC0yLjY2Mi02LjQ2NC0yLjY2Mi0yLjUyNCAwLTQuNjc5Ljg4Ny02LjQ2NCAyLjY2Mi0xLjc4NiAxLjc3NC0yLjY3OSAzLjkxNi0yLjY3OSA2LjQyNCAwIDIuNTA4Ljg5MyA0LjY1IDIuNjc5IDYuNDI0IDEuNzg1IDEuNzc0IDMuOTQgMi42NjIgNi40NjQgMi42NjIgMi41MjQgMCA0LjY3OS0uODg4IDYuNDY0LTIuNjYyIDEuNzg2LTEuNzc1IDIuNjc5LTMuOTE2IDIuNjc5LTYuNDI0ek03MS43MTQgNjUuOThsNy4yMTUtMjcuMTE2Yy4yODUtMS4yMy4xMDctMi4zNzgtLjUzNi0zLjQ0My0uNjQzLTEuMDY0LTEuNTYtMS43NjItMi43NS0yLjA5NC0xLjE5LS4zMy0yLjMzMy0uMTc3LTMuNDI5LjQ2Mi0xLjA5NS42MzktMS44MSAxLjU3My0yLjE0MyAyLjgwNGwtNy4yMTQgMjcuMTE2Yy0yLjg1Ny4yMzctNS40MDUgMS4yNjYtNy42NDMgMy4wODgtMi4yMzggMS44MjItMy43MzggNC4xNTItNC41IDYuOTkyLS45NTIgMy42NDQtLjQ3NiA3LjA5OCAxLjQyOSAxMC4zNjQgMS45MDUgMy4yNjUgNC42OSA1LjM3IDguMzU3IDYuMzE3IDMuNjY3Ljk0NyA3LjE0My40NzQgMTAuNDI5LTEuNDIgMy4yODUtMS44OTIgNS40MDQtNC42NiA2LjM1Ny04LjMwNS43NjItMi44NC42MTktNS42MDctLjQyOS04LjMwNS0xLjA0Ny0yLjY5Ny0yLjc2Mi00Ljg1LTUuMTQzLTYuNDZ6bTQ3LjE0My0yLjM0MmMwLTIuNTA4LS44OTMtNC42NS0yLjY3OC02LjQyNC0xLjc4Ni0xLjc3NS0zLjk0LTIuNjYyLTYuNDY1LTIuNjYyLTIuNTI0IDAtNC42NzguODg3LTYuNDY0IDIuNjYyLTEuNzg2IDEuNzc0LTIuNjc5IDMuOTE2LTIuNjc5IDYuNDI0IDAgMi41MDguODkzIDQuNjUgMi42NzkgNi40MjQgMS43ODYgMS43NzUgMy45NCAyLjY2MiA2LjQ2NCAyLjY2MiAyLjUyNCAwIDQuNjc5LS44ODcgNi40NjUtMi42NjIgMS43ODUtMS43NzUgMi42NzgtMy45MTYgMi42NzgtNi40MjR6bS00NS43MTQtNDUuNDNjMC0yLjUwOS0uODkzLTQuNjUtMi42NzktNi40MjVDNjguNjggMTAuMDEgNjYuNTI0IDkuMTIyIDY0IDkuMTIyYy0yLjUyNCAwLTQuNjc5Ljg4Ny02LjQ2NCAyLjY2MS0xLjc4NiAxLjc3NS0yLjY3OSAzLjkxNi0yLjY3OSA2LjQyNSAwIDIuNTA4Ljg5MyA0LjY1IDIuNjc5IDYuNDI0IDEuNzg1IDEuNzc0IDMuOTQgMi42NjIgNi40NjQgMi42NjIgMi41MjQgMCA0LjY3OS0uODg4IDYuNDY0LTIuNjYyIDEuNzg2LTEuNzc1IDIuNjc5LTMuOTE2IDIuNjc5LTYuNDI0em0zMiAxMy42MjljMC0yLjUwOC0uODkzLTQuNjUtMi42NzktNi40MjQtMS43ODUtMS43NzUtMy45NC0yLjY2Mi02LjQ2NC0yLjY2Mi0yLjUyNCAwLTQuNjc5Ljg4Ny02LjQ2NCAyLjY2Mi0xLjc4NiAxLjc3NC0yLjY3OSAzLjkxNi0yLjY3OSA2LjQyNCAwIDIuNTA4Ljg5MyA0LjY1IDIuNjc5IDYuNDI0IDEuNzg1IDEuNzc0IDMuOTQgMi42NjIgNi40NjQgMi42NjIgMi41MjQgMCA0LjY3OS0uODg4IDYuNDY0LTIuNjYyIDEuNzg2LTEuNzc1IDIuNjc5LTMuOTE2IDIuNjc5LTYuNDI0ek0xMjggNjMuNjM4YzAgMTIuMzUxLTMuMzU3IDIzLjc4LTEwLjA3MSAzNC4yODYtLjkwNSAxLjM3Mi0yLjE5IDIuMDU4LTMuODU4IDIuMDU4SDEzLjkzYy0xLjY2NyAwLTIuOTUzLS42ODYtMy44NTgtMi4wNThDMy4zNTcgODcuNDY1IDAgNzYuMDM3IDAgNjMuNjM4YzAtOC42MTMgMS42OS0xNi44NDcgNS4wNzEtMjQuNzAzQzguNDUyIDMxLjA4IDEzIDI0LjMxMiAxOC43MTQgMTguNjM0YzUuNzE1LTUuNjggMTIuNTI0LTEwLjE5OSAyMC40MjktMTMuNTU5QzQ3LjA0OCAxLjcxNSA1NS4zMzMuMDM1IDY0IC4wMzVjOC42NjcgMCAxNi45NTIgMS42OCAyNC44NTcgNS4wNCA3LjkwNSAzLjM2IDE0LjcxNCA3Ljg4IDIwLjQyOSAxMy41NTkgNS43MTQgNS42NzggMTAuMjYyIDEyLjQ0NiAxMy42NDMgMjAuMzAxIDMuMzggNy44NTYgNS4wNzEgMTYuMDkgNS4wNzEgMjQuNzAzeiIvPjwvc3ZnPg==','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(267,'example.svg','/src/icons/svg',2,1,3,'PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOTYuMjU4IDU3LjQ2MmgzMS40MjFDMTI0Ljc5NCAyNy4zMjMgMTAwLjQyNiAyLjk1NiA3MC4yODcuMDd2MzEuNDIyYTMyLjg1NiAzMi44NTYgMCAwIDEgMjUuOTcxIDI1Ljk3em0tMzguNzk2LTI1Ljk3Vi4wN0MyNy4zMjMgMi45NTYgMi45NTYgMjcuMzIzLjA3IDU3LjQ2MmgzMS40MjJhMzIuODU2IDMyLjg1NiAwIDAgMSAyNS45Ny0yNS45N3ptMTIuODI1IDY0Ljc2NnYzMS40MjFjMzAuNDYtMi44ODUgNTQuNTA3LTI3LjI1MyA1Ny43MTMtNTcuNzEySDk2LjU3OWMtMi44ODYgMTMuNDY2LTEzLjE0NiAyMy43MjYtMjYuMjkyIDI2LjI5MXpNMzEuNDkyIDcwLjI4N0guMDdjMi44ODYgMzAuNDYgMjcuMjUzIDU0LjUwNyA1Ny43MTMgNTcuNzEzVjk2LjU3OWMtMTMuNDY2LTIuODg2LTIzLjcyNi0xMy4xNDYtMjYuMjkxLTI2LjI5MnoiLz48L3N2Zz4=','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(268,'eye-open.svg','/src/icons/svg',2,1,3,'PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PGRlZnM+PHN0eWxlLz48L2RlZnM+PHBhdGggZD0iTTUxMiAxMjhxNjkuNjc1IDAgMTM1LjUxIDIxLjE2M3QxMTUuNDk4IDU0Ljk5NyA5My40ODMgNzQuODM3IDczLjY4NSA4Mi4wMDYgNTEuNjcgNzQuODM3IDMyLjE3IDU0LjgyN0wxMDI0IDUxMnEtMi4zNDcgNC45OTItNi4zMTUgMTMuNDgzVDk5OC44NyA1NjAuMTd0LTMxLjY1OCA1MS42NjktNDQuMzMxIDU5Ljk5LTU2LjgzMiA2NC4zNC02OS41MDQgNjAuMTYtODIuMzQ3IDUxLjUtOTQuODQ4IDM0LjY4N1Q1MTIgODk2cS02OS42NzUgMC0xMzUuNTEtMjEuMTYzdC0xMTUuNDk4LTU0LjgyNi05My40ODMtNzQuMzI2LTczLjY4NS04MS40OTMtNTEuNjctNzQuNDk2LTMyLjE3LTU0Ljk5N0wwIDUxMy43MDdxMi4zNDctNC45OTIgNi4zMTUtMTMuNDgzdDE4LjgxNi0zNC44MTYgMzEuNjU4LTUxLjg0IDQ0LjMzMS02MC4zMyA1Ni44MzItNjQuNjgzIDY5LjUwNC02MC4zMzEgODIuMzQ3LTUxLjg0IDk0Ljg0OC0zNC44MTZUNTEyIDEyOC4wODV6bTAgODUuMzMzcS00Ni42NzcgMC05MS42NDggMTIuMzMxdC04MS4xNTIgMzEuODMtNzAuNjU2IDQ3LjE0Ni01OS42NDggNTQuNDg1LTQ4Ljg1MyA1Ny42ODYtMzcuNjc1IDUyLjgyMS0yNi4zMjUgNDMuOTlxMTIuMzMgMjEuNjc0IDI2LjMyNSA0My41MnQzNy42NzUgNTIuMzUxIDQ4Ljg1MyA1Ny4wMDMgNTkuNjQ4IDUzLjg0NVQzMzkuMiA3NjcuMDJ0ODEuMTUyIDMxLjQ4OFQ1MTIgODEwLjY2N3Q5MS42NDgtMTIuMzMxIDgxLjE1Mi0zMS42NTkgNzAuNjU2LTQ2Ljg0OCA1OS42NDgtNTQuMTg2IDQ4Ljg1My01Ny4zNDQgMzcuNjc1LTUyLjY1MVQ5MjcuOTU3IDUxMnEtMTIuMzMtMjEuNjc1LTI2LjMyNS00My42NDh0LTM3LjY3NS01Mi42NS00OC44NTMtNTcuMzQ1LTU5LjY0OC01NC4xODYtNzAuNjU2LTQ2Ljg0OC04MS4xNTItMzEuNjU5VDUxMiAyMTMuMzM0em0wIDEyOHE3MC42NTYgMCAxMjAuNjYxIDUwLjAwNlQ2ODIuNjY3IDUxMiA2MzIuNjYgNjMyLjY2MSA1MTIgNjgyLjY2NyAzOTEuMzM5IDYzMi42NiAzNDEuMzMzIDUxMnQ1MC4wMDYtMTIwLjY2MVQ1MTIgMzQxLjMzM3ptMCA4NS4zMzRxLTM1LjMyOCAwLTYwLjMzIDI1LjAwMlQ0MjYuNjY2IDUxMnQyNS4wMDIgNjAuMzNUNTEyIDU5Ny4zMzR0NjAuMzMtMjUuMDAyVDU5Ny4zMzQgNTEydC0yNS4wMDItNjAuMzNUNTEyIDQyNi42NjZ6Ii8+PC9zdmc+','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(269,'eye.svg','/src/icons/svg',2,1,3,'PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjY0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMjcuMDcyIDcuOTk0YzEuMzctMi4yMDguOTE0LTUuMTUyLS45MTQtNi44Ny0yLjA1Ni0xLjcxNy00Ljc5Ny0xLjIyNi02LjM5Ni45ODItLjIyOS4yNDUtMjUuNTg2IDMyLjM4Mi01NS43NCAzMi4zODItMjkuMjQgMC01NS43NC0zMi4zODItNTUuOTY4LTMyLjYyNy0xLjYtMS45NjMtNC41Ny0yLjIwOC02LjM5Ny0uNDlDLS4xNyAzLjA4Ni0uMzk5IDYuMjc1IDEuMiA4LjIzOGMuNDU3LjczNiA1Ljk0IDcuMzYgMTQuNjIgMTQuNzJMNC4xNyAzNS45NmMtMS44MjggMS45NjMtMS42IDUuMTUyLjIyOCA2Ljg3LjQ1Ny45OCAxLjYgMS40NzEgMi43NDIgMS40NzFzMi4yODQtLjQ5IDMuMTk4LTEuNDcybDEyLjU2NC0xMy45ODNjNS45NCA0LjQxNiAxMy4wMjEgOC41ODcgMjAuNzg4IDExLjUzbC00Ljc5NyAxNy40MThjLS42ODUgMi42OTkuNjg2IDUuMzk3IDMuMTk4IDYuMTMzaDEuMzdjMi4wNTcgMCAzLjg4NC0xLjQ3MiA0LjM0MS0zLjY4TDUyLjYgNDIuODNjMy42NTUuNzM2IDcuNTM4IDEuMjI3IDExLjQyMiAxLjIyNyAzLjg4MyAwIDcuNzY3LS40OSAxMS40MjItMS4yMjdsNC43OTcgMTcuMTczYy40NTcgMi4yMDggMi41MTMgMy42OCA0LjM0IDMuNjguNDU3IDAgLjkxNCAwIDEuMTQzLS4yNDYgMi41MTMtLjczNiAzLjg4My0zLjQzNCAzLjE5OC02LjEzM2wtNC43OTctMTcuMTcyYzcuNzY3LTIuOTQ0IDE0Ljg0OC03LjExNCAyMC43ODgtMTEuNTNsMTIuMzM2IDEzLjczOGMuOTEzLjk4MSAyLjA1NiAxLjQ3MiAzLjE5OCAxLjQ3MnMyLjI4NC0uNDkgMy4xOTgtMS40NzJjMS44MjgtMS45NjMgMS44MjgtNC45MDYuMjI4LTYuODdsLTExLjY1LTEzLjAwMWM5LjM2Ni03LjM2IDE0Ljg0OS0xNC40NzQgMTQuODQ5LTE0LjQ3NHoiLz48L3N2Zz4=','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(270,'form.svg','/src/icons/svg',2,1,3,'PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNODQuMDY4IDIzLjc4NGMtMS4wMiAwLTEuODc3LS4zMi0yLjU3Mi0uOTZhOC41ODggOC41ODggMCAwIDEtMS43MzgtMi4yMzcgMTEuNTI0IDExLjUyNCAwIDAgMS0xLjA0Mi0yLjYyMWMtLjIzMi0uODk1LS4zNDgtMS42NDEtLjM0OC0yLjIzOFYwaC4yNzhjLjgzNCAwIDEuNjIyLjA4NSAyLjM2My4yNTYuNzQyLjE3IDEuNjQ1LjU3NSAyLjcxMSAxLjIxNCAxLjA2Ni42NCAyLjM2MyAxLjUzNSAzLjg5MiAyLjY4NiAxLjUzIDEuMTUgMy40NTMgMi42NjQgNS43NyA0LjU0IDIuNTAyIDIuMDQ1IDQuNDk0IDMuNzcxIDUuOTc3IDUuMTc4IDEuNDgzIDEuNDA2IDIuNjE4IDIuNiAzLjQwNiAzLjU4Ljc4Ny45OCAxLjI3NCAxLjgxMiAxLjQ2IDIuNDk0LjE4NS42ODIuMjc3IDEuMjc4LjI3NyAxLjc5djIuMDQ2SDg0LjA2OHpNMTI3LjMgODQuMDFjLjI3OC42ODIuNDY0IDEuNTM1LjU1NiAyLjU1OC4wOTMgMS4wMjMtLjM3IDIuMDAzLTEuMzkgMi45NC0uNDYzLjQyNy0uODguODMyLTEuMjUgMS4yMTUtLjM3Mi4zODQtLjY5Ni43MDQtLjk3NC45NmE2LjY5IDYuNjkgMCAwIDEtLjk3My43NjdsLTExLjgxNi0xMC43NDFhNDQuMzMxIDQ0LjMzMSAwIDAgMCAxLjg3Ny0xLjUzNSAzMS4wMjggMzEuMDI4IDAgMCAxIDEuNzM3LTEuNDA2YzEuMTEyLS45MzggMi4zMTctMS4zNDMgMy42MTUtMS4yMTUgMS4yOTcuMTI4IDIuMzYzLjQwNSAzLjE5Ny44My45MjcuNDI3IDEuOTIzIDEuMTczIDIuOTg5IDIuMjM5IDEuMDY1IDEuMDY1IDEuODc2IDIuMTk1IDIuNDMyIDMuMzg4ek03OC4yMyA5NS45MDJjMi4wMzggMCAzLjc1Mi0uNTExIDUuMTQzLTEuNTM0bC0yNi45NjkgMjUuODNIMTguMDM3Yy0xLjc2MSAwLTMuNjg0LS40Ny01Ljc3LTEuNDA3YTI0LjU0OSAyNC41NDkgMCAwIDEtNS44MzgtMy43MDkgMjEuMzczIDIxLjM3MyAwIDAgMS00LjUxOC01LjMwNmMtMS4yMDQtMi4wMDMtMS44MDctNC4wNy0xLjgwNy02LjIwMlYxNi40OTVjMC0xLjc5LjQ0LTMuNjY1IDEuMzItNS42MjZBMTguNDEgMTguNDEgMCAwIDEgNS4wNCA1LjU2MmEyMS43OTggMjEuNzk4IDAgMCAxIDUuMjEzLTMuOTY0QzEyLjE5OC41MzMgMTQuMjM3IDAgMTYuMzcgMGg1My4yNHYxNS45ODRjMCAxLjYyLjI3OCAzLjM2Ny44MzQgNS4yNDJhMTYuNzA0IDE2LjcwNCAwIDAgMCAyLjU3MiA1LjE3OWMxLjE1OSAxLjU3NyAyLjY2NSAyLjg5OCA0LjUxOCAzLjk2NCAxLjg1MyAxLjA2NiA0LjA3OCAxLjU5OCA2LjY3MyAxLjU5OGgyMC4yOTV2NDIuMzI1TDg1LjQ1OCA5Mi40NWMxLjAyLTEuMzY0IDEuNTI5LTIuODU2IDEuNTI5LTQuNDc2IDAtMi4yMTYtLjg1Ny00LjExMy0yLjU3Mi01LjY5LTEuNzE0LTEuNTc3LTMuNzc2LTIuMzY2LTYuMTg2LTIuMzY2SDI2LjFjLTIuNDA5IDAtNC40NDguNzg5LTYuMTE2IDIuMzY2LTEuNjY4IDEuNTc3LTIuNTAyIDMuNDc0LTIuNTAyIDUuNjkgMCAyLjIxNy44MzQgNC4wOTIgMi41MDIgNS42MjYgMS42NjggMS41MzUgMy43MDcgMi4zMDIgNi4xMTcgMi4zMDJoNTIuMTN6TTI2LjEgNDcuOTUxYy0yLjQxIDAtNC40NDkuNzg5LTYuMTE3IDIuMzY2LTEuNjY4IDEuNTc3LTIuNTAyIDMuNDczLTIuNTAyIDUuNjkgMCAyLjIxNi44MzQgNC4wOTIgMi41MDIgNS42MjYgMS42NjggMS41MzQgMy43MDcgMi4zMDIgNi4xMTcgMi4zMDJoNTIuMTNjMi40MDkgMCA0LjQ3LS43NjggNi4xODUtMi4zMDIgMS43MTUtMS41MzQgMi41NzItMy40MSAyLjU3Mi01LjYyNiAwLTIuMjE3LS44NTctNC4xMTMtMi41NzItNS42OS0xLjcxNC0xLjU3Ny0zLjc3Ni0yLjM2Ni02LjE4Ni0yLjM2NkgyNi4xem01Mi40MDcgNjQuMDYzbDEuODA3LTEuNjYzIDMuNDc2LTMuMTk2YTQ3OS43NSA0NzkuNzUgMCAwIDAgNC41ODctNC4yODQgNTAwLjc1NyA1MDAuNzU3IDAgMCAxIDUuMDA0LTQuNjY3YzMuOTg1LTMuNjY2IDguNDgtNy43NTggMTMuNDg1LTEyLjI3NmwxMS42NzcgMTAuNzQxLTEzLjQ4NSAxMi40MDQtNS4wMDQgNC42MDMtNC41ODcgNC4yMmExNzkuNDYgMTc5LjQ2IDAgMCAwLTMuMjY3IDMuMDY4Yy0uODguODUzLTEuMzY3IDEuMzIyLTEuNDYgMS40MDctLjQ2My4zNDEtLjk3My43MDMtMS41MjkgMS4wODctLjU1Ni4zODMtMS4xMTIuNzAzLTEuNjY4Ljk1OS0uNTU2LjI1Ni0xLjQxMy41NzUtMi41NzIuOTU5YTgzLjUgODMuNSAwIDAgMS0zLjU0NSAxLjA4NyA3Mi4yIDcyLjIgMCAwIDEtMy40NzUuODk1Yy0xLjExMi4yNTYtMS45NDYuNDI2LTIuNTAyLjUxMS0xLjExMi4xNy0xLjg1NC4wNDMtMi4yMjQtLjM4My0uMzcxLS40MjYtLjQ2NC0xLjE1MS0uMjc4LTIuMTc0LjA5Mi0uNTExLjI3OC0xLjI3OS41NTYtMi4zMDIuMjc4LTEuMDIzLjYwMi0yLjA2Ny45NzMtMy4xMzJsMS4wNDItMy4wMDVjLjMyNS0uOTM4LjU4LTEuNTc3Ljc2NS0xLjkxOGExMC4xNTcgMTAuMTU3IDAgMCAxIDIuMjI0LTIuOTQxeiIvPjwvc3ZnPg==','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(271,'link.svg','/src/icons/svg',2,1,3,'PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTE1LjYyNSAxMjcuOTM3SC4wNjNWMTIuMzc1aDU3Ljc4MXYxMi4zNzRIMTIuNDM4djkwLjgxM2g5MC44MTNWNzAuMTU2aDEyLjM3NHoiLz48cGF0aCBkPSJNMTE2LjQyNiAyLjgyMWw4Ljc1MyA4Ljc1My01Ni43MzQgNTYuNzM0LTguNzUzLTguNzQ1eiIvPjxwYXRoIGQ9Ik0xMjcuODkzIDM3Ljk4MmgtMTIuMzc1VjEyLjM3NUg4OC43MDZWMGgzOS4xODd6Ii8+PC9zdmc+','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(272,'nested.svg','/src/icons/svg',2,1,3,'PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNLjAwMiA5LjJjMCA1LjA0NCAzLjU4IDkuMTMzIDcuOTk4IDkuMTMzIDQuNDE3IDAgNy45OTctNC4wODkgNy45OTctOS4xMzMgMC01LjA0My0zLjU4LTkuMTMyLTcuOTk3LTkuMTMyUy4wMDIgNC4xNTcuMDAyIDkuMnpNMzEuOTk3LjA2Nmg5NS45ODFWMTguMzNIMzEuOTk3Vi4wNjZ6bTAgNDUuNjY5YzAgNS4wNDQgMy41OCA5LjEzMiA3Ljk5OCA5LjEzMiA0LjQxNyAwIDcuOTk3LTQuMDg4IDcuOTk3LTkuMTMyIDAtMy4yNjMtMS41MjQtNi4yNzgtMy45OTgtNy45MS0yLjQ3NS0xLjYzLTUuNTI0LTEuNjMtNy45OTggMC0yLjQ3NSAxLjYzMi00IDQuNjQ3LTQgNy45MXpNNjMuOTkyIDM2LjZoNjMuOTg2djE4LjI2NUg2My45OTJWMzYuNnptLTMxLjk5NSA4Mi4yYzAgNS4wNDMgMy41OCA5LjEzMiA3Ljk5OCA5LjEzMiA0LjQxNyAwIDcuOTk3LTQuMDg5IDcuOTk3LTkuMTMyIDAtNS4wNDQtMy41OC05LjEzMy03Ljk5Ny05LjEzM3MtNy45OTggNC4wODktNy45OTggOS4xMzN6bTMxLjk5NS05LjEzMWg2My45ODZ2MTguMjY1SDYzLjk5MlYxMDkuNjd6bTAtMjcuNDA0YzAgNS4wNDQgMy41OCA5LjEzMyA3Ljk5OCA5LjEzMyA0LjQxNyAwIDcuOTk3LTQuMDg5IDcuOTk3LTkuMTMzIDAtMy4yNjMtMS41MjQtNi4yNzctMy45OTgtNy45MDktMi40NzUtMS42MzEtNS41MjQtMS42MzEtNy45OTggMC0yLjQ3NSAxLjYzMi00IDQuNjQ2LTQgNy45MXptMzEuOTk1LTkuMTNoMzEuOTkxVjkxLjRIOTUuOTg3VjczLjEzNXoiLz48L3N2Zz4=','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(273,'password.svg','/src/icons/svg',2,1,3,'PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTA4LjggNDQuMzIySDg5LjZ2LTUuMzZjMC05LjA0LTMuMzA4LTI0LjE2My0yNS42LTI0LjE2My0yMy4xNDUgMC0yNS42IDE2Ljg4MS0yNS42IDI0LjE2MnY1LjM2MUgxOS4ydi01LjM2QzE5LjIgMTUuMjgxIDM2Ljc5OCAwIDY0IDBjMjcuMjAyIDAgNDQuOCAxNS4yODEgNDQuOCAzOC45NjF2NS4zNjF6bS0zMiAzOS4zNTZjMC01LjQ0LTUuNzYzLTkuODMyLTEyLjgtOS44MzItNy4wMzcgMC0xMi44IDQuMzkyLTEyLjggOS44MzIgMCAzLjY4MiAyLjU2NyA2LjgwOCA2LjQwNyA4LjQ3N3YxMS4yMDVjMCAyLjcxOCAyLjg3NSA0Ljk2MiA2LjQgNC45NjIgMy41MjQgMCA2LjQtMi4yNDQgNi40LTQuOTYyVjkyLjE1NWMzLjgzMy0xLjY2OSA2LjM5My00Ljc5NSA2LjM5My04LjQ3N3pNMTI4IDY0djQ5LjIwMWMwIDguMTU4LTguNjQ1IDE0Ljc5OS0xOS4yIDE0Ljc5OUgxOS4yQzguNjUxIDEyOCAwIDEyMS4zNTkgMCAxMTMuMjAxVjY0YzAtOC4xNTMgOC42NDUtMTQuNzk5IDE5LjItMTQuNzk5aDg5LjZjMTAuNTU1IDAgMTkuMiA2LjY0NiAxOS4yIDE0Ljc5OXoiLz48L3N2Zz4=','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(274,'table.svg','/src/icons/svg',2,1,3,'PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNLjAwNi4wNjRoMTI3Ljk4OHYzMS4xMDRILjAwNlYuMDY0em0wIDM4LjAxNmgzOC4zOTZ2NDEuNDcySC4wMDZWMzguMDh6bTAgNDguMzg0aDM4LjM5NnY0MS40NzJILjAwNlY4Ni40NjR6TTQ0LjgwMiAzOC4wOGgzOC4zOTZ2NDEuNDcySDQ0LjgwMlYzOC4wOHptMCA0OC4zODRoMzguMzk2djQxLjQ3Mkg0NC44MDJWODYuNDY0ek04OS41OTggMzguMDhoMzguMzk2djQxLjQ3Mkg4OS41OTh6bTAgNDguMzg0aDM4LjM5NnY0MS40NzJIODkuNTk4eiIvPjxwYXRoIGQ9Ik0uMDA2LjA2NGgxMjcuOTg4djMxLjEwNEguMDA2Vi4wNjR6bTAgMzguMDE2aDM4LjM5NnY0MS40NzJILjAwNlYzOC4wOHptMCA0OC4zODRoMzguMzk2djQxLjQ3MkguMDA2Vjg2LjQ2NHpNNDQuODAyIDM4LjA4aDM4LjM5NnY0MS40NzJINDQuODAyVjM4LjA4em0wIDQ4LjM4NGgzOC4zOTZ2NDEuNDcySDQ0LjgwMlY4Ni40NjR6TTg5LjU5OCAzOC4wOGgzOC4zOTZ2NDEuNDcySDg5LjU5OHptMCA0OC4zODRoMzguMzk2djQxLjQ3Mkg4OS41OTh6Ii8+PC9zdmc+','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(275,'tree.svg','/src/icons/svg',2,1,3,'PHN2ZyB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTI2LjcxMyA5MC4wMjNjLjg1OC45ODUgMS4yODcgMi4xMzQgMS4yODcgMy40NDd2MjkuNTUzYzAgMS40MjMtLjQyOSAyLjYtMS4yODcgMy41My0uODU4LjkzLTEuOTA3IDEuMzk1LTMuMTQ2IDEuMzk1SDk3LjgyNGMtMS4xNDUgMC0yLjE0Ni0uNDY1LTMuMDA0LTEuMzk1LS44NTgtLjkzLTEuMjg3LTIuMTA3LTEuMjg3LTMuNTNWOTMuNDdjMC0uODc1LjE5LTEuNjk2LjU3Mi0yLjQ2Mi4zODItLjc2Ni45MDYtMS4zNjggMS41NzMtMS44MDZhMy44NCAzLjg0IDAgMCAxIDIuMTQ2LS42NTdoOS43MjVWNjkuMDA3YTMuODQgMy44NCAwIDAgMC0uNDMtMS44MDYgMy41NjkgMy41NjkgMCAwIDAtMS4xNDMtMS4zMTMgMi43MTQgMi43MTQgMCAwIDAtMS41NzMtLjQ5MmgtMzYuNDd2MjMuMTQ5aDkuNzI1YzEuMTQ0IDAgMi4xNDUuNDkyIDMuMDA0IDEuNDc4Ljg1OC45ODUgMS4yODcgMi4xMzQgMS4yODcgMy40NDd2MjkuNTUzYzAgLjg3Ni0uMTkxIDEuNjk2LS41NzMgMi40NjMtLjM4Ljc2Ni0uOTA1IDEuMzY4LTEuNTczIDEuODA2YTMuODQgMy44NCAwIDAgMS0yLjE0NS42NTZINTEuOTE1YTMuODQgMy44NCAwIDAgMS0yLjE0NS0uNjU2Yy0uNjY4LS40MzgtMS4yMTYtMS4wNC0xLjY0NS0xLjgwNmE0Ljk2IDQuOTYgMCAwIDEtLjY0NC0yLjQ2M1Y5My40N2MwLTEuMzEzLjQzLTIuNDYyIDEuMjg4LTMuNDQ3Ljg1OC0uOTg2IDEuOTA3LTEuNDc4IDMuMTQ2LTEuNDc4aDkuNTgydi0yMy4xNWgtMzcuOWMtLjk1MyAwLTEuNzQuMzU2LTIuMzU5IDEuMDY4LS42Mi43MTEtLjkzIDEuNTYtLjkzIDIuNTQ0djE5LjUzOGg5LjcyNmMxLjIzOSAwIDIuMjY0LjQ5MiAzLjA3NCAxLjQ3OC44MS45ODUgMS4yMTYgMi4xMzQgMS4yMTYgMy40NDd2MjkuNTUzYzAgMS40MjMtLjQwNSAyLjYtMS4yMTYgMy41My0uODEuOTMtMS44MzUgMS4zOTUtMy4wNzQgMS4zOTVINC4yOWMtLjQ3NiAwLS45My0uMDgyLTEuMzU4LS4yNDZhNC4xIDQuMSAwIDAgMS0xLjE0NC0uNjU3IDQuNjU4IDQuNjU4IDAgMCAxLS45My0xLjA2NyA1LjE4NiA1LjE4NiAwIDAgMS0uNjQzLTEuMzk1IDUuNTY2IDUuNTY2IDAgMCAxLS4yMTUtMS41NlY5My40N2MwLS40MzcuMDQ4LS44NzUuMTQzLTEuMzEzYTMuOTUgMy45NSAwIDAgMSAuNDI5LTEuMTVjLjE5LS4zMjguNDI5LS42NTYuNzE1LS45ODQuMjg2LS4zMjkuNTcyLS42MDIuODU4LS44MjEuMjg2LS4yMi42Mi0uMzgzIDEuMDAxLS40OTMuMzgyLS4xMS43NjMtLjE2NCAxLjE0NC0uMTY0aDkuNzI2VjYxLjYxOWMwLS45ODUuMzEtMS44MzMuOTMtMi41NDQuNjE5LS43MTIgMS4zNTgtMS4wNjggMi4yMTYtMS4wNjhoNDQuMzM1VjM5LjYyaC05LjU4MmMtMS4yNCAwLTIuMjg4LS40OTItMy4xNDYtMS40NzdhNS4wOSA1LjA5IDAgMCAxLTEuMjg3LTMuNDQ4VjUuMTRjMC0xLjQyMy40MjktMi42MjcgMS4yODctMy42MTIuODU4LS45ODUgMS45MDctMS40NzcgMy4xNDYtMS40NzdoMjUuNzQzYy43NjMgMCAxLjQ3OC4yNDYgMi4xNDUuNzM5YTUuMTcgNS4xNyAwIDAgMSAxLjU3MyAxLjg4OGMuMzgyLjc2Ni41NzMgMS41ODcuNTczIDIuNDYydjI5LjU1M2MwIDEuMzEzLS40MyAyLjQ2My0xLjI4NyAzLjQ0OC0uODU5Ljk4NS0xLjg2IDEuNDc3LTMuMDA0IDEuNDc3aC05LjcyNXYxOC4zODloNDIuNzYyYy45NTQgMCAxLjc0LjM1NSAyLjM2IDEuMDY3LjYyLjcxMS45MyAxLjU2LjkzIDIuNTQ1djI2LjkyNWg5LjU4MmMxLjIzOSAwIDIuMjg4LjQ5MiAzLjE0NiAxLjQ3OHoiLz48L3N2Zz4=','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(276,'user.svg','/src/icons/svg',2,1,3,'PHN2ZyB3aWR0aD0iMTMwIiBoZWlnaHQ9IjEzMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNjMuNDQ0IDY0Ljk5NmMyMC42MzMgMCAzNy4zNTktMTQuMzA4IDM3LjM1OS0zMS45NTMgMC0xNy42NDktMTYuNzI2LTMxLjk1Mi0zNy4zNTktMzEuOTUyLTIwLjYzMSAwLTM3LjM2IDE0LjMwMy0zNy4zNTggMzEuOTUyIDAgMTcuNjQ1IDE2LjcyNyAzMS45NTMgMzcuMzU5IDMxLjk1M3pNODAuNTcgNzUuNjVINDkuNDM0Yy0yNi42NTIgMC00OC4yNiAxOC40NzctNDguMjYgNDEuMjd2Mi42NjRjMCA5LjMxNiAyMS42MDggOS4zMjUgNDguMjYgOS4zMjVIODAuNTdjMjYuNjQ5IDAgNDguMjU2LS4zNDQgNDguMjU2LTkuMzI1di0yLjY2M2MwLTIyLjc5NC0yMS42MDUtNDEuMjcxLTQ4LjI1Ni00MS4yNzF6IiBzdHJva2U9IiM5Nzk3OTciLz48L3N2Zz4=','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(277,'svgo.yml.ftl','/src/icons',2,1,1,'# replace default config\n\n# multipass: true\n# full: true\n\nplugins:\n\n # - name\n #\n # or:\n # - name: false\n # - name: true\n #\n # or:\n # - name:\n # param1: 1\n # param2: 2\n\n- removeAttrs:\n attrs:\n - \'fill\'\n - \'fill-rule\'\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(278,'AppMain.vue.ftl','/src/layout/components',2,1,1,'<template>\n <section class=\"app-main\">\n <transition name=\"fade-transform\" mode=\"out-in\">\n <router-view :key=\"key\" />\n </transition>\n </section>\n</template>\n\n<script>\nexport default {\n name: \'AppMain\',\n computed: {\n key() {\n return this.$route.path\n }\n }\n}\n</script>\n\n<style scoped>\n.app-main {\n /*50 = navbar */\n min-height: calc(100vh - 50px);\n width: 100%;\n position: relative;\n overflow: hidden;\n}\n.fixed-header+.app-main {\n padding-top: 50px;\n}\n</style>\n\n<style lang=\"scss\">\n// fix css style bug in open el-dialog\n.el-popup-parent--hidden {\n .fixed-header {\n padding-right: 15px;\n }\n}\n</style>\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(279,'index.js.ftl','/src/layout/components',2,1,1,'export { default as Navbar } from \'./Navbar\'\nexport { default as Sidebar } from \'./Sidebar\'\nexport { default as AppMain } from \'./AppMain\'\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(280,'Navbar.vue.ftl','/src/layout/components',2,1,1,'<template>\n <div class=\"navbar\">\n <hamburger :is-active=\"sidebar.opened\" class=\"hamburger-container\" @toggleClick=\"toggleSideBar\" />\n\n <breadcrumb class=\"breadcrumb-container\" />\n\n <div class=\"right-menu\">\n <el-dropdown class=\"avatar-container\" trigger=\"click\">\n <div class=\"avatar-wrapper\">\n <img :src=\"avatar+\'?imageView2/1/w/80/h/80\'\" class=\"user-avatar\">\n <i class=\"el-icon-caret-bottom\" />\n </div>\n <el-dropdown-menu slot=\"dropdown\" class=\"user-dropdown\">\n <router-link to=\"/\">\n <el-dropdown-item>\n Home\n </el-dropdown-item>\n </router-link>\n <a target=\"_blank\" href=\"https://github.com/PanJiaChen/vue-admin-template/\">\n <el-dropdown-item>Github</el-dropdown-item>\n </a>\n <a target=\"_blank\" href=\"https://panjiachen.github.io/vue-element-admin-site/#/\">\n <el-dropdown-item>Docs</el-dropdown-item>\n </a>\n <el-dropdown-item divided>\n <span style=\"display:block;\" @click=\"logout\">Log Out</span>\n </el-dropdown-item>\n </el-dropdown-menu>\n </el-dropdown>\n </div>\n </div>\n</template>\n\n<script>\nimport { mapGetters } from \'vuex\'\nimport Breadcrumb from \'@/components/Breadcrumb\'\nimport Hamburger from \'@/components/Hamburger\'\n\nexport default {\n components: {\n Breadcrumb,\n Hamburger\n },\n computed: {\n ...mapGetters([\n \'sidebar\',\n \'avatar\'\n ])\n },\n methods: {\n toggleSideBar() {\n this.$store.dispatch(\'app/toggleSideBar\')\n },\n async logout() {\n await this.$store.dispatch(\'user/logout\')\n this.$router.push(`/login?redirect=${r\'$\'}{this.$route.fullPath}`)\n }\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.navbar {\n height: 50px;\n overflow: hidden;\n position: relative;\n background: #fff;\n box-shadow: 0 1px 4px rgba(0,21,41,.08);\n\n .hamburger-container {\n line-height: 46px;\n height: 100%;\n float: left;\n cursor: pointer;\n transition: background .3s;\n -webkit-tap-highlight-color:transparent;\n\n &:hover {\n background: rgba(0, 0, 0, .025)\n }\n }\n\n .breadcrumb-container {\n float: left;\n }\n\n .right-menu {\n float: right;\n height: 100%;\n line-height: 50px;\n\n &:focus {\n outline: none;\n }\n\n .right-menu-item {\n display: inline-block;\n padding: 0 8px;\n height: 100%;\n font-size: 18px;\n color: #5a5e66;\n vertical-align: text-bottom;\n\n &.hover-effect {\n cursor: pointer;\n transition: background .3s;\n\n &:hover {\n background: rgba(0, 0, 0, .025)\n }\n }\n }\n\n .avatar-container {\n margin-right: 30px;\n\n .avatar-wrapper {\n margin-top: 5px;\n position: relative;\n\n .user-avatar {\n cursor: pointer;\n width: 40px;\n height: 40px;\n border-radius: 10px;\n }\n\n .el-icon-caret-bottom {\n cursor: pointer;\n position: absolute;\n right: -20px;\n top: 25px;\n font-size: 12px;\n }\n }\n }\n }\n}\n</style>\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(281,'FixiOSBug.js.ftl','/src/layout/components/Sidebar',2,1,1,'export default {\n computed: {\n device() {\n return this.$store.state.app.device\n }\n },\n mounted() {\n // In order to fix the click on menu on the ios device will trigger the mouseleave bug\n // https://github.com/PanJiaChen/vue-element-admin/issues/1135\n this.fixBugIniOS()\n },\n methods: {\n fixBugIniOS() {\n const $subMenu = this.$refs.subMenu\n if ($subMenu) {\n const handleMouseleave = $subMenu.handleMouseleave\n $subMenu.handleMouseleave = (e) => {\n if (this.device === \'mobile\') {\n return\n }\n handleMouseleave(e)\n }\n }\n }\n }\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(282,'index.vue.ftl','/src/layout/components/Sidebar',2,1,1,'<template>\n <div :class=\"{\'has-logo\':showLogo}\">\n <logo v-if=\"showLogo\" :collapse=\"isCollapse\" />\n <el-scrollbar wrap-class=\"scrollbar-wrapper\">\n <el-menu\n :default-active=\"activeMenu\"\n :collapse=\"isCollapse\"\n :background-color=\"variables.menuBg\"\n :text-color=\"variables.menuText\"\n :unique-opened=\"false\"\n :active-text-color=\"variables.menuActiveText\"\n :collapse-transition=\"false\"\n mode=\"vertical\"\n >\n <sidebar-item v-for=\"route in routes\" :key=\"route.path\" :item=\"route\" :base-path=\"route.path\" />\n </el-menu>\n </el-scrollbar>\n </div>\n</template>\n\n<script>\nimport { mapGetters } from \'vuex\'\nimport Logo from \'./Logo\'\nimport SidebarItem from \'./SidebarItem\'\nimport variables from \'@/styles/variables.scss\'\n\nexport default {\n components: { SidebarItem, Logo },\n computed: {\n ...mapGetters([\n \'sidebar\'\n ]),\n routes() {\n return this.$router.options.routes\n },\n activeMenu() {\n const route = this.$route\n const { meta, path } = route\n // if set path, the sidebar will highlight the path you set\n if (meta.activeMenu) {\n return meta.activeMenu\n }\n return path\n },\n showLogo() {\n return this.$store.state.settings.sidebarLogo\n },\n variables() {\n return variables\n },\n isCollapse() {\n return !this.sidebar.opened\n }\n }\n}\n</script>\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(283,'Item.vue.ftl','/src/layout/components/Sidebar',2,1,1,'<script>\nexport default {\n name: \'MenuItem\',\n functional: true,\n props: {\n icon: {\n type: String,\n default: \'\'\n },\n title: {\n type: String,\n default: \'\'\n }\n },\n render(h, context) {\n const { icon, title } = context.props\n const vnodes = []\n\n if (icon) {\n vnodes.push(<svg-icon icon-class={icon}/>)\n }\n\n if (title) {\n vnodes.push(<span slot=\'title\'>{(title)}</span>)\n }\n return vnodes\n }\n}\n</script>\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(284,'Link.vue.ftl','/src/layout/components/Sidebar',2,1,1,'\n<template>\n <!-- eslint-disable vue/require-component-is -->\n <component v-bind=\"linkProps(to)\">\n <slot />\n </component>\n</template>\n\n<script>\nimport { isExternal } from \'@/utils/validate\'\n\nexport default {\n props: {\n to: {\n type: String,\n required: true\n }\n },\n methods: {\n linkProps(url) {\n if (isExternal(url)) {\n return {\n is: \'a\',\n href: url,\n target: \'_blank\',\n rel: \'noopener\'\n }\n }\n return {\n is: \'router-link\',\n to: url\n }\n }\n }\n}\n</script>\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(285,'Logo.vue.ftl','/src/layout/components/Sidebar',2,1,1,'<template>\n <div class=\"sidebar-logo-container\" :class=\"{\'collapse\':collapse}\">\n <transition name=\"sidebarLogoFade\">\n <router-link v-if=\"collapse\" key=\"collapse\" class=\"sidebar-logo-link\" to=\"/\">\n <img v-if=\"logo\" :src=\"logo\" class=\"sidebar-logo\">\n <h1 v-else class=\"sidebar-title\">{{ title }} </h1>\n </router-link>\n <router-link v-else key=\"expand\" class=\"sidebar-logo-link\" to=\"/\">\n <img v-if=\"logo\" :src=\"logo\" class=\"sidebar-logo\">\n <h1 class=\"sidebar-title\">{{ title }} </h1>\n </router-link>\n </transition>\n </div>\n</template>\n\n<script>\nexport default {\n name: \'SidebarLogo\',\n props: {\n collapse: {\n type: Boolean,\n required: true\n }\n },\n data() {\n return {\n title: \'Vue Admin Template\',\n logo: \'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png\'\n }\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.sidebarLogoFade-enter-active {\n transition: opacity 1.5s;\n}\n\n.sidebarLogoFade-enter,\n.sidebarLogoFade-leave-to {\n opacity: 0;\n}\n\n.sidebar-logo-container {\n position: relative;\n width: 100%;\n height: 50px;\n line-height: 50px;\n background: #2b2f3a;\n text-align: center;\n overflow: hidden;\n\n & .sidebar-logo-link {\n height: 100%;\n width: 100%;\n\n & .sidebar-logo {\n width: 32px;\n height: 32px;\n vertical-align: middle;\n margin-right: 12px;\n }\n\n & .sidebar-title {\n display: inline-block;\n margin: 0;\n color: #fff;\n font-weight: 600;\n line-height: 50px;\n font-size: 14px;\n font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;\n vertical-align: middle;\n }\n }\n\n &.collapse {\n .sidebar-logo {\n margin-right: 0px;\n }\n }\n}\n</style>\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(286,'SidebarItem.vue.ftl','/src/layout/components/Sidebar',2,1,1,'<template>\n <div v-if=\"!item.hidden\" class=\"menu-wrapper\">\n <template v-if=\"hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow\">\n <app-link v-if=\"onlyOneChild.meta\" :to=\"resolvePath(onlyOneChild.path)\">\n <el-menu-item :index=\"resolvePath(onlyOneChild.path)\" :class=\"{\'submenu-title-noDropdown\':!isNest}\">\n <item :icon=\"onlyOneChild.meta.icon||(item.meta&&item.meta.icon)\" :title=\"onlyOneChild.meta.title\" />\n </el-menu-item>\n </app-link>\n </template>\n\n <el-submenu v-else ref=\"subMenu\" :index=\"resolvePath(item.path)\" popper-append-to-body>\n <template slot=\"title\">\n <item v-if=\"item.meta\" :icon=\"item.meta && item.meta.icon\" :title=\"item.meta.title\" />\n </template>\n <sidebar-item\n v-for=\"child in item.children\"\n :key=\"child.path\"\n :is-nest=\"true\"\n :item=\"child\"\n :base-path=\"resolvePath(child.path)\"\n class=\"nest-menu\"\n />\n </el-submenu>\n </div>\n</template>\n\n<script>\nimport path from \'path\'\nimport { isExternal } from \'@/utils/validate\'\nimport Item from \'./Item\'\nimport AppLink from \'./Link\'\nimport FixiOSBug from \'./FixiOSBug\'\n\nexport default {\n name: \'SidebarItem\',\n components: { Item, AppLink },\n mixins: [FixiOSBug],\n props: {\n // route object\n item: {\n type: Object,\n required: true\n },\n isNest: {\n type: Boolean,\n default: false\n },\n basePath: {\n type: String,\n default: \'\'\n }\n },\n data() {\n // To fix https://github.com/PanJiaChen/vue-admin-template/issues/237\n // TODO: refactor with render function\n this.onlyOneChild = null\n return {}\n },\n methods: {\n hasOneShowingChild(children = [], parent) {\n const showingChildren = children.filter(item => {\n if (item.hidden) {\n return false\n } else {\n // Temp set(will be used if only has one showing child)\n this.onlyOneChild = item\n return true\n }\n })\n\n // When there is only one child router, the child router is displayed by default\n if (showingChildren.length === 1) {\n return true\n }\n\n // Show parent if there are no child router to display\n if (showingChildren.length === 0) {\n this.onlyOneChild = { ... parent, path: \'\', noShowingChildren: true }\n return true\n }\n\n return false\n },\n resolvePath(routePath) {\n if (isExternal(routePath)) {\n return routePath\n }\n if (isExternal(this.basePath)) {\n return this.basePath\n }\n return path.resolve(this.basePath, routePath)\n }\n }\n}\n</script>\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(287,'index.vue.ftl','/src/layout',2,1,1,'<template>\n <div :class=\"classObj\" class=\"app-wrapper\">\n <div v-if=\"device===\'mobile\'&&sidebar.opened\" class=\"drawer-bg\" @click=\"handleClickOutside\" />\n <sidebar class=\"sidebar-container\" />\n <div class=\"main-container\">\n <div :class=\"{\'fixed-header\':fixedHeader}\">\n <navbar />\n </div>\n <app-main />\n </div>\n </div>\n</template>\n\n<script>\nimport { Navbar, Sidebar, AppMain } from \'./components\'\nimport ResizeMixin from \'./mixin/ResizeHandler\'\n\nexport default {\n name: \'Layout\',\n components: {\n Navbar,\n Sidebar,\n AppMain\n },\n mixins: [ResizeMixin],\n computed: {\n sidebar() {\n return this.$store.state.app.sidebar\n },\n device() {\n return this.$store.state.app.device\n },\n fixedHeader() {\n return this.$store.state.settings.fixedHeader\n },\n classObj() {\n return {\n hideSidebar: !this.sidebar.opened,\n openSidebar: this.sidebar.opened,\n withoutAnimation: this.sidebar.withoutAnimation,\n mobile: this.device === \'mobile\'\n }\n }\n },\n methods: {\n handleClickOutside() {\n this.$store.dispatch(\'app/closeSideBar\', { withoutAnimation: false })\n }\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n @import \"~@/styles/mixin.scss\";\n @import \"~@/styles/variables.scss\";\n\n .app-wrapper {\n @include clearfix;\n position: relative;\n height: 100%;\n width: 100%;\n &.mobile.openSidebar{\n position: fixed;\n top: 0;\n }\n }\n .drawer-bg {\n background: #000;\n opacity: 0.3;\n width: 100%;\n top: 0;\n height: 100%;\n position: absolute;\n z-index: 999;\n }\n\n .fixed-header {\n position: fixed;\n top: 0;\n right: 0;\n z-index: 9;\n width: calc(100% - ${r\'#\'}{$sideBarWidth});\n transition: width 0.28s;\n }\n\n .hideSidebar .fixed-header {\n width: calc(100% - 54px)\n }\n\n .mobile .fixed-header {\n width: 100%;\n }\n</style>\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(288,'ResizeHandler.js.ftl','/src/layout/mixin',2,1,1,'import store from \'@/store\'\n\nconst { body } = document\nconst WIDTH = 992 // refer to Bootstrap\'s responsive design\n\nexport default {\n watch: {\n $route(route) {\n if (this.device === \'mobile\' && this.sidebar.opened) {\n store.dispatch(\'app/closeSideBar\', { withoutAnimation: false })\n }\n }\n },\n beforeMount() {\n window.addEventListener(\'resize\', this.$_resizeHandler)\n },\n beforeDestroy() {\n window.removeEventListener(\'resize\', this.$_resizeHandler)\n },\n mounted() {\n const isMobile = this.$_isMobile()\n if (isMobile) {\n store.dispatch(\'app/toggleDevice\', \'mobile\')\n store.dispatch(\'app/closeSideBar\', { withoutAnimation: true })\n }\n },\n methods: {\n // use $_ for mixins properties\n // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential\n $_isMobile() {\n const rect = body.getBoundingClientRect()\n return rect.width - 1 < WIDTH\n },\n $_resizeHandler() {\n if (!document.hidden) {\n const isMobile = this.$_isMobile()\n store.dispatch(\'app/toggleDevice\', isMobile ? \'mobile\' : \'desktop\')\n\n if (isMobile) {\n store.dispatch(\'app/closeSideBar\', { withoutAnimation: true })\n }\n }\n }\n }\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(289,'main.js.ftl','/src',2,1,1,'import Vue from \'vue\'\r\n\r\nimport \'normalize.css/normalize.css\' // A modern alternative to CSS resets\r\n\r\nimport ElementUI from \'element-ui\'\r\nimport \'element-ui/lib/theme-chalk/index.css\'\r\nimport locale from \'element-ui/lib/locale/lang/en\' // lang i18n\r\n\r\nimport CommonPlugin from \'./utils/common-plugin\'\r\n\r\nimport \'@/styles/index.scss\' // global css\r\n\r\nimport App from \'./App\'\r\nimport store from \'./store\'\r\nimport router from \'./router\'\r\n\r\nimport \'@/icons\' // icon\r\nimport \'@/permission\' // permission control\r\n\r\n/**\r\n * If you don\'t want to use mock-server\r\n * you want to use MockJs for mock api\r\n * you can execute: mockXHR()\r\n *\r\n * Currently MockJs will be used in the production environment,\r\n * please remove it before going online! ! !\r\n */\r\nimport { mockXHR } from \'../mock\'\r\nif (process.env.NODE_ENV === \'development\') {\r\n mockXHR()\r\n}\r\n\r\n// set ElementUI lang to EN\r\nVue.use(ElementUI, { locale })\r\nVue.use(CommonPlugin)\r\n// 如果想要中文版 element-ui,按如下方式声明\r\n// Vue.use(ElementUI)\r\n\r\nVue.config.productionTip = false\r\n\r\nnew Vue({\r\n el: \'#app\',\r\n router,\r\n store,\r\n render: h => h(App)\r\n})\r\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(290,'permission.js.ftl','/src',2,1,1,'import router from \'./router\'\nimport store from \'./store\'\nimport { Message } from \'element-ui\'\nimport NProgress from \'nprogress\' // progress bar\nimport \'nprogress/nprogress.css\' // progress bar style\nimport { getToken } from \'@/utils/auth\' // get token from cookie\nimport getPageTitle from \'@/utils/get-page-title\'\n\nNProgress.configure({ showSpinner: false }) // NProgress Configuration\n\nconst whiteList = [\'/login\'] // no redirect whitelist\n\nrouter.beforeEach(async(to, from, next) => {\n // start progress bar\n NProgress.start()\n\n // set page title\n document.title = getPageTitle(to.meta.title)\n\n // determine whether the user has logged in\n const hasToken = getToken()\n\n if (hasToken) {\n if (to.path === \'/login\') {\n // if is logged in, redirect to the home page\n next({ path: \'/\' })\n NProgress.done()\n } else {\n const hasGetUserInfo = store.getters.name\n if (hasGetUserInfo) {\n next()\n } else {\n try {\n // get user info\n await store.dispatch(\'user/getInfo\')\n\n next()\n } catch (error) {\n // remove token and go to login page to re-login\n await store.dispatch(\'user/resetToken\')\n Message.error(error || \'Has Error\')\n next(`/login?redirect=${r\'$\'}{to.path}`)\n NProgress.done()\n }\n }\n }\n } else {\n /* has no token*/\n\n if (whiteList.indexOf(to.path) !== -1) {\n // in the free login whitelist, go directly\n next()\n } else {\n // other pages that do not have permission to access are redirected to the login page.\n next(`/login?redirect=${r\'$\'}{to.path}`)\n NProgress.done()\n }\n }\n})\n\nrouter.afterEach(() => {\n // finish progress bar\n NProgress.done()\n})\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(291,'index.js.ftl','/src/router',2,1,1,'<#include \"/abstracted/common.ftl\">\nimport Vue from \'vue\'\nimport Router from \'vue-router\'\n\nVue.use(Router)\n\n/* Layout */\nimport Layout from \'@/layout\'\n\n/**\n * Note: sub-menu only appear when route children.length >= 1\n * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html\n *\n * hidden: true if set true, item will not show in the sidebar(default is false)\n * alwaysShow: true if set true, will always show the root menu\n * if not set alwaysShow, when item has more than one children route,\n * it will becomes nested mode, otherwise not show the root menu\n * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb\n * name:\'router-name\' the name is used by <keep-alive> (must set!!!)\n * meta : {\n roles: [\'admin\',\'editor\'] control the page roles (you can set multiple roles)\n title: \'title\' the name show in sidebar and breadcrumb (recommend set)\n icon: \'svg-name\' the icon show in the sidebar\n breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)\n activeMenu: \'/example/list\' if set path, the sidebar will highlight the path you set\n }\n */\n\n/**\n * constantRoutes\n * a base page that does not have permission requirements\n * all roles can be accessed\n */\nexport const constantRoutes = [\n {\n path: \'/login\',\n component: () => import(\'@/views/_login/index\'),\n hidden: true\n },\n\n {\n path: \'/404\',\n component: () => import(\'@/views/404\'),\n hidden: true\n },\n\n {\n path: \'/\',\n component: Layout,\n redirect: \'/home\',\n children: [{\n path: \'home\',\n name: \'home\',\n component: () => import(\'@/views/_home/index\'),\n meta: { title: \'首页\', icon: \'home\' }\n }]\n },\n<#list this.metaEntities as entity>\n <#if !entity.entityFeature.list><#continue></#if>\n {\n path: \'/${lowerFirstWord(entity.className)}\',\n component: Layout,\n children: [\n {\n path: \'index\',\n name: \'${entity.className}\',\n component: () => ${importView(entity.className,entity.module)},\n meta: { title: \'${entity.title}管理\', icon: \'table\' }\n }\n ]\n },\n</#list>\n<#list this.dashboards as dashboard>\n {\n path: \'/${lowerFirstWord(dashboard.name)}\',\n component: Layout,\n children: [\n {\n path: \'index\',\n name: \'${dashboard.name}\',\n component: () => ${importView(dashboard.name,dashboard.module)},\n meta: { title: \'${dashboard.title}\', icon: \'table\' }\n }\n ]\n },\n</#list>\n\n // 404 page must be placed at the end !!!\n { path: \'*\', redirect: \'/404\', hidden: true }\n]\n\nconst createRouter = () => new Router({\n // mode: \'history\', // require service support\n scrollBehavior: () => ({ y: 0 }),\n routes: constantRoutes\n})\n\nconst router = createRouter()\n\n// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465\nexport function resetRouter() {\n const newRouter = createRouter()\n router.matcher = newRouter.matcher // reset router\n}\n\nexport default router\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(292,'settings.js.ftl','/src',2,1,1,'<#include \"/abstracted/common.ftl\">\r\nmodule.exports = {\r\n\r\n title: \'${this.projectDesc}\',\r\n\r\n /**\r\n * @type {boolean} true | false\r\n * @description Whether fix the header\r\n */\r\n fixedHeader: false,\r\n\r\n /**\r\n * @type {boolean} true | false\r\n * @description Whether show the logo in sidebar\r\n */\r\n sidebarLogo: false\r\n}\r\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(293,'getters.js.ftl','/src/store',2,1,1,'const getters = {\n sidebar: state => state.app.sidebar,\n device: state => state.app.device,\n token: state => state.user.token,\n avatar: state => state.user.avatar,\n name: state => state.user.name\n}\nexport default getters\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(294,'index.js.ftl','/src/store',2,1,1,'import Vue from \'vue\'\nimport Vuex from \'vuex\'\nimport getters from \'./getters\'\nimport app from \'./modules/app\'\nimport settings from \'./modules/settings\'\nimport user from \'./modules/user\'\n\nVue.use(Vuex)\n\nconst store = new Vuex.Store({\n modules: {\n app,\n settings,\n user\n },\n getters\n})\n\nexport default store\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(295,'app.js.ftl','/src/store/modules',2,1,1,'import Cookies from \'js-cookie\'\n\nconst state = {\n sidebar: {\n opened: Cookies.get(\'sidebarStatus\') ? !!+Cookies.get(\'sidebarStatus\') : true,\n withoutAnimation: false\n },\n device: \'desktop\'\n}\n\nconst mutations = {\n TOGGLE_SIDEBAR: state => {\n state.sidebar.opened = !state.sidebar.opened\n state.sidebar.withoutAnimation = false\n if (state.sidebar.opened) {\n Cookies.set(\'sidebarStatus\', 1)\n } else {\n Cookies.set(\'sidebarStatus\', 0)\n }\n },\n CLOSE_SIDEBAR: (state, withoutAnimation) => {\n Cookies.set(\'sidebarStatus\', 0)\n state.sidebar.opened = false\n state.sidebar.withoutAnimation = withoutAnimation\n },\n TOGGLE_DEVICE: (state, device) => {\n state.device = device\n }\n}\n\nconst actions = {\n toggleSideBar({ commit }) {\n commit(\'TOGGLE_SIDEBAR\')\n },\n closeSideBar({ commit }, { withoutAnimation }) {\n commit(\'CLOSE_SIDEBAR\', withoutAnimation)\n },\n toggleDevice({ commit }, device) {\n commit(\'TOGGLE_DEVICE\', device)\n }\n}\n\nexport default {\n namespaced: true,\n state,\n mutations,\n actions\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(296,'settings.js.ftl','/src/store/modules',2,1,1,'import defaultSettings from \'@/settings\'\n\nconst { showSettings, fixedHeader, sidebarLogo } = defaultSettings\n\nconst state = {\n showSettings: showSettings,\n fixedHeader: fixedHeader,\n sidebarLogo: sidebarLogo\n}\n\nconst mutations = {\n CHANGE_SETTING: (state, { key, value }) => {\n if (state.hasOwnProperty(key)) {\n state[key] = value\n }\n }\n}\n\nconst actions = {\n changeSetting({ commit }, data) {\n commit(\'CHANGE_SETTING\', data)\n }\n}\n\nexport default {\n namespaced: true,\n state,\n mutations,\n actions\n}\n\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(297,'user.js.ftl','/src/store/modules',2,1,1,'import { login, logout, getInfo } from \'@/api/_user\'\r\nimport { getToken, setToken, removeToken } from \'@/utils/auth\'\r\nimport { resetRouter } from \'@/router\'\r\n\r\nconst getDefaultState = () => {\r\n return {\r\n token: getToken(),\r\n name: \'\',\r\n avatar: \'\'\r\n }\r\n}\r\n\r\nconst state = getDefaultState()\r\n\r\nconst mutations = {\r\n RESET_STATE: (state) => {\r\n Object.assign(state, getDefaultState())\r\n },\r\n SET_TOKEN: (state, token) => {\r\n state.token = token\r\n },\r\n SET_NAME: (state, name) => {\r\n state.name = name\r\n },\r\n SET_AVATAR: (state, avatar) => {\r\n state.avatar = avatar\r\n }\r\n}\r\n\r\nconst actions = {\r\n // user login\r\n login({ commit }, userInfo) {\r\n const { username, password } = userInfo\r\n return new Promise((resolve, reject) => {\r\n login({ username: username.trim(), password: password }).then(response => {\r\n const { data } = response\r\n commit(\'SET_TOKEN\', data.token)\r\n setToken(data.token)\r\n resolve()\r\n }).catch(error => {\r\n reject(error)\r\n })\r\n })\r\n },\r\n\r\n // get user info\r\n getInfo({ commit, state }) {\r\n return new Promise((resolve, reject) => {\r\n getInfo(state.token).then(response => {\r\n const { data } = response\r\n\r\n if (!data) {\r\n reject(\'Verification failed, please Login again.\')\r\n }\r\n\r\n const { name, avatar } = data\r\n\r\n commit(\'SET_NAME\', name)\r\n commit(\'SET_AVATAR\', avatar)\r\n resolve(data)\r\n }).catch(error => {\r\n reject(error)\r\n })\r\n })\r\n },\r\n\r\n // user logout\r\n logout({ commit, state }) {\r\n return new Promise((resolve, reject) => {\r\n logout(state.token).then(() => {\r\n removeToken() // must remove token first\r\n resetRouter()\r\n commit(\'RESET_STATE\')\r\n resolve()\r\n }).catch(error => {\r\n reject(error)\r\n })\r\n })\r\n },\r\n\r\n // remove token\r\n resetToken({ commit }) {\r\n return new Promise(resolve => {\r\n removeToken() // must remove token first\r\n commit(\'RESET_STATE\')\r\n resolve()\r\n })\r\n }\r\n}\r\n\r\nexport default {\r\n namespaced: true,\r\n state,\r\n mutations,\r\n actions\r\n}\r\n\r\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(298,'element-ui.scss.ftl','/src/styles',2,1,1,'// cover some element-ui styles\n\n.el-breadcrumb__inner,\n.el-breadcrumb__inner a {\n font-weight: 400 !important;\n}\n\n.el-upload {\n input[type=\"file\"] {\n display: none !important;\n }\n}\n\n.el-upload__input {\n display: none;\n}\n\n\n// to fixed https://github.com/ElemeFE/element/issues/2461\n.el-dialog {\n transform: none;\n left: 0;\n position: relative;\n margin: 0 auto;\n}\n\n// refine element ui upload\n.upload-container {\n .el-upload {\n width: 100%;\n\n .el-upload-dragger {\n width: 100%;\n height: 200px;\n }\n }\n}\n\n// dropdown\n.el-dropdown-menu {\n a {\n display: block\n }\n}\n\n// to fix el-date-picker css style\n.el-range-separator {\n box-sizing: content-box;\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(299,'index.scss.ftl','/src/styles',2,1,1,'@import \'./variables.scss\';\n@import \'./mixin.scss\';\n@import \'./transition.scss\';\n@import \'./element-ui.scss\';\n@import \'./sidebar.scss\';\n\nbody {\n height: 100%;\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n text-rendering: optimizeLegibility;\n font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;\n}\n\nlabel {\n font-weight: 700;\n}\n\nhtml {\n height: 100%;\n box-sizing: border-box;\n}\n\n#app {\n height: 100%;\n}\n\n*,\n*:before,\n*:after {\n box-sizing: inherit;\n}\n\na:focus,\na:active {\n outline: none;\n}\n\na,\na:focus,\na:hover {\n cursor: pointer;\n color: inherit;\n text-decoration: none;\n}\n\ndiv:focus {\n outline: none;\n}\n\n.clearfix {\n &:after {\n visibility: hidden;\n display: block;\n font-size: 0;\n content: \" \";\n clear: both;\n height: 0;\n }\n}\n\n// main-container global css\n.app-container {\n padding: 20px;\n}\n\n.form-item-show {\n font-size: 14px;\n color: #8c8f95;\n}\n\n.filter-container {\n padding-bottom: 10px;\n\n .filter-item {\n vertical-align: middle;\n margin-bottom: 10px;\n }\n}\n\n.table-inner-mtm {\n font-size: 11px;\n color: #FFFFFF;\n padding: 2px;\n border: 2px solid transparent;\n border-radius:4px;\n margin: 2px;\n user-select: none;\n background-color: #FFA500;\n}\n\n.table-inner-button {\n margin-top: 2px;\n margin-bottom: 2px;\n}\n\n.vue-grid-item {\n .el-card__header {\n height: 30px;\n line-height:30px;\n padding: 0px 10px;\n }\n .el-card__body {\n padding: 0px;\n }\n .card-hidden {\n border-style: none;\n .el-card__header {\n border-style: none;\n }\n }\n .card-table {\n overflow-y: auto;\n }\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(300,'mixin.scss.ftl','/src/styles',2,1,1,'@mixin clearfix {\n &:after {\n content: \"\";\n display: table;\n clear: both;\n }\n}\n\n@mixin scrollBar {\n &::-webkit-scrollbar-track-piece {\n background: #d3dce6;\n }\n\n &::-webkit-scrollbar {\n width: 6px;\n }\n\n &::-webkit-scrollbar-thumb {\n background: #99a9bf;\n border-radius: 20px;\n }\n}\n\n@mixin relative {\n position: relative;\n width: 100%;\n height: 100%;\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(301,'sidebar.scss.ftl','/src/styles',2,1,1,'#app {\n\n .main-container {\n min-height: 100%;\n transition: margin-left .28s;\n margin-left: $sideBarWidth;\n position: relative;\n }\n\n .sidebar-container {\n transition: width 0.28s;\n width: $sideBarWidth !important;\n background-color: $menuBg;\n height: 100%;\n position: fixed;\n font-size: 0px;\n top: 0;\n bottom: 0;\n left: 0;\n z-index: 1001;\n overflow: hidden;\n\n // reset element-ui css\n .horizontal-collapse-transition {\n transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;\n }\n\n .scrollbar-wrapper {\n overflow-x: hidden !important;\n }\n\n .el-scrollbar__bar.is-vertical {\n right: 0px;\n }\n\n .el-scrollbar {\n height: 100%;\n }\n\n &.has-logo {\n .el-scrollbar {\n height: calc(100% - 50px);\n }\n }\n\n .is-horizontal {\n display: none;\n }\n\n a {\n display: inline-block;\n width: 100%;\n overflow: hidden;\n }\n\n .svg-icon {\n margin-right: 16px;\n }\n\n .el-menu {\n border: none;\n height: 100%;\n width: 100% !important;\n }\n\n // menu hover\n .submenu-title-noDropdown,\n .el-submenu__title {\n &:hover {\n background-color: $menuHover !important;\n }\n }\n\n .is-active>.el-submenu__title {\n color: $subMenuActiveText !important;\n }\n\n & .nest-menu .el-submenu>.el-submenu__title,\n & .el-submenu .el-menu-item {\n min-width: $sideBarWidth !important;\n background-color: $subMenuBg !important;\n\n &:hover {\n background-color: $subMenuHover !important;\n }\n }\n }\n\n .hideSidebar {\n .sidebar-container {\n width: 54px !important;\n }\n\n .main-container {\n margin-left: 54px;\n }\n\n .submenu-title-noDropdown {\n padding: 0 !important;\n position: relative;\n\n .el-tooltip {\n padding: 0 !important;\n\n .svg-icon {\n margin-left: 20px;\n }\n }\n }\n\n .el-submenu {\n overflow: hidden;\n\n &>.el-submenu__title {\n padding: 0 !important;\n\n .svg-icon {\n margin-left: 20px;\n }\n\n .el-submenu__icon-arrow {\n display: none;\n }\n }\n }\n\n .el-menu--collapse {\n .el-submenu {\n &>.el-submenu__title {\n &>span {\n height: 0;\n width: 0;\n overflow: hidden;\n visibility: hidden;\n display: inline-block;\n }\n }\n }\n }\n }\n\n .el-menu--collapse .el-menu .el-submenu {\n min-width: $sideBarWidth !important;\n }\n\n // mobile responsive\n .mobile {\n .main-container {\n margin-left: 0px;\n }\n\n .sidebar-container {\n transition: transform .28s;\n width: $sideBarWidth !important;\n }\n\n &.hideSidebar {\n .sidebar-container {\n pointer-events: none;\n transition-duration: 0.3s;\n transform: translate3d(-$sideBarWidth, 0, 0);\n }\n }\n }\n\n .withoutAnimation {\n\n .main-container,\n .sidebar-container {\n transition: none;\n }\n }\n}\n\n// when menu collapsed\n.el-menu--vertical {\n &>.el-menu {\n .svg-icon {\n margin-right: 16px;\n }\n }\n\n .nest-menu .el-submenu>.el-submenu__title,\n .el-menu-item {\n &:hover {\n // you can use $subMenuHover\n background-color: $menuHover !important;\n }\n }\n\n // the scroll bar appears when the subMenu is too long\n >.el-menu--popup {\n max-height: 100vh;\n overflow-y: auto;\n\n &::-webkit-scrollbar-track-piece {\n background: #d3dce6;\n }\n\n &::-webkit-scrollbar {\n width: 6px;\n }\n\n &::-webkit-scrollbar-thumb {\n background: #99a9bf;\n border-radius: 20px;\n }\n }\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(302,'transition.scss.ftl','/src/styles',2,1,1,'// global transition css\n\n/* fade */\n.fade-enter-active,\n.fade-leave-active {\n transition: opacity 0.28s;\n}\n\n.fade-enter,\n.fade-leave-active {\n opacity: 0;\n}\n\n/* fade-transform */\n.fade-transform-leave-active,\n.fade-transform-enter-active {\n transition: all .5s;\n}\n\n.fade-transform-enter {\n opacity: 0;\n transform: translateX(-30px);\n}\n\n.fade-transform-leave-to {\n opacity: 0;\n transform: translateX(30px);\n}\n\n/* breadcrumb transition */\n.breadcrumb-enter-active,\n.breadcrumb-leave-active {\n transition: all .5s;\n}\n\n.breadcrumb-enter,\n.breadcrumb-leave-active {\n opacity: 0;\n transform: translateX(20px);\n}\n\n.breadcrumb-move {\n transition: all .5s;\n}\n\n.breadcrumb-leave-active {\n position: absolute;\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(303,'variables.scss.ftl','/src/styles',2,1,1,'// sidebar\n$menuText:#bfcbd9;\n$menuActiveText:#409EFF;\n$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951\n\n$menuBg:#304156;\n$menuHover:#263445;\n\n$subMenuBg:#1f2d3d;\n$subMenuHover:#001528;\n\n$sideBarWidth: 210px;\n\n// the :export directive is the magic sauce for webpack\n// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass\n:export {\n menuText: $menuText;\n menuActiveText: $menuActiveText;\n subMenuActiveText: $subMenuActiveText;\n menuBg: $menuBg;\n menuHover: $menuHover;\n subMenuBg: $subMenuBg;\n subMenuHover: $subMenuHover;\n sideBarWidth: $sideBarWidth;\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(304,'auth.js.ftl','/src/utils',2,1,1,'import Cookies from \'js-cookie\'\n\nconst TokenKey = \'vue_admin_template_token\'\n\nexport function getToken() {\n return Cookies.get(TokenKey)\n}\n\nexport function setToken(token) {\n return Cookies.set(TokenKey, token)\n}\n\nexport function removeToken() {\n return Cookies.remove(TokenKey)\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(305,'chart-util.js.ftl','/src/utils',2,1,1,'export function getChartSizeInBox(box) {\n const parentWidth = box.clientWidth\n const parentHeight = box.clientHeight\n let height = parentHeight\n // 如果存在两个元素,第一个是标题,需要排除\n if (box.childElementCount === 2) {\n height = parentHeight - box.firstElementChild.clientHeight\n }\n return [parentWidth, height]\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(306,'get-page-title.js.ftl','/src/utils',2,1,1,'import defaultSettings from \'@/settings\'\n\nconst title = defaultSettings.title || \'Vue Admin Template\'\n\nexport default function getPageTitle(pageTitle) {\n if (pageTitle) {\n return `${r\'$\'}{pageTitle} - ${r\'$\'}{title}`\n }\n return `${r\'$\'}{title}`\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(307,'index.js.ftl','/src/utils',2,1,1,'/**\n * Created by PanJiaChen on 16/11/18.\n */\n\n/**\n * Parse the time to string\n * @param {(Object|string|number)} time\n * @param {string} cFormat\n * @returns {string | null}\n */\nexport function parseTime(time, cFormat) {\n if (arguments.length === 0) {\n return null\n }\n const format = cFormat || \'{y}-{m}-{d} {h}:{i}:{s}\'\n let date\n if (typeof time === \'object\') {\n date = time\n } else {\n if ((typeof time === \'string\') && (/^[0-9]+$/.test(time))) {\n time = parseInt(time)\n }\n if ((typeof time === \'number\') && (time.toString().length === 10)) {\n time = time * 1000\n }\n date = new Date(time)\n }\n const formatObj = {\n y: date.getFullYear(),\n m: date.getMonth() + 1,\n d: date.getDate(),\n h: date.getHours(),\n i: date.getMinutes(),\n s: date.getSeconds(),\n a: date.getDay()\n }\n const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {\n const value = formatObj[key]\n // Note: getDay() returns 0 on Sunday\n if (key === \'a\') { return [\'日\', \'一\', \'二\', \'三\', \'四\', \'五\', \'六\'][value ] }\n return value.toString().padStart(2, \'0\')\n })\n return time_str\n}\n\n/**\n * @param {number} time\n * @param {string} option\n * @returns {string}\n */\nexport function formatTime(time, option) {\n if ((\'\' + time).length === 10) {\n time = parseInt(time) * 1000\n } else {\n time = +time\n }\n const d = new Date(time)\n const now = Date.now()\n\n const diff = (now - d) / 1000\n\n if (diff < 30) {\n return \'刚刚\'\n } else if (diff < 3600) {\n // less 1 hour\n return Math.ceil(diff / 60) + \'分钟前\'\n } else if (diff < 3600 * 24) {\n return Math.ceil(diff / 3600) + \'小时前\'\n } else if (diff < 3600 * 24 * 2) {\n return \'1天前\'\n }\n if (option) {\n return parseTime(time, option)\n } else {\n return (\n d.getMonth() +\n 1 +\n \'月\' +\n d.getDate() +\n \'日\' +\n d.getHours() +\n \'时\' +\n d.getMinutes() +\n \'分\'\n )\n }\n}\n\n/**\n * @param {string} url\n * @returns {Object}\n */\nexport function param2Obj(url) {\n const search = url.split(\'?\')[1]\n if (!search) {\n return {}\n }\n return JSON.parse(\n \'{\"\' +\n decodeURIComponent(search)\n .replace(/\"/g, \'\\\\\"\')\n .replace(/&/g, \'\",\"\')\n .replace(/=/g, \'\":\"\')\n .replace(/\\+/g, \' \') +\n \'\"}\'\n )\n}\n\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(308,'request.js.ftl','/src/utils',2,1,1,'import axios from \'axios\'\r\nimport qs from \'qs\'\r\nimport { Message } from \'element-ui\'\r\n\r\n// create an axios instance\r\nconst service = axios.create({\r\n baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url\r\n // withCredentials: true, // send cookies when cross-domain requests\r\n timeout: 5000, // request timeout\r\n paramsSerializer(params) {\r\n return qs.stringify(params, {\r\n arrayFormat: \'repeat\'\r\n })\r\n }\r\n})\r\n\r\n// response interceptor\r\nservice.interceptors.response.use(\r\n /**\r\n * If you want to get http information such as headers or status\r\n * Please return response => response\r\n */\r\n\r\n /**\r\n * Determine the request status by custom code\r\n * Here is just an example\r\n * You can also judge the status by HTTP Status Code\r\n */\r\n response => {\r\n const data = response.data\r\n if (response.status >= 200 && response.status < 300) {\r\n return data\r\n } else {\r\n return Promise.reject(new Error(data))\r\n }\r\n },\r\n error => {\r\n let message = error.message\r\n if (error.response && error.response.data && error.response.data.message) {\r\n message = error.response.data.message\r\n }\r\n Message({\r\n message: message,\r\n type: \'error\',\r\n duration: 5 * 1000\r\n })\r\n return Promise.reject(error)\r\n }\r\n)\r\n\r\nexport default service\r\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(309,'validate.js.ftl','/src/utils',2,1,1,'/**\n * Created by PanJiaChen on 16/11/18.\n */\n\n/**\n * @param {string} path\n * @returns {Boolean}\n */\nexport function isExternal(path) {\n return /^(https?:|mailto:|tel:)/.test(path)\n}\n\n/**\n * @param {string} str\n * @returns {Boolean}\n */\nexport function validUsername(str) {\n const valid_map = [\'admin\', \'editor\']\n return valid_map.indexOf(str.trim()) >= 0\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(310,'404.vue.ftl','/src/views',2,1,1,'<template>\n <div class=\"wscn-http404-container\">\n <div class=\"wscn-http404\">\n <div class=\"pic-404\">\n <img class=\"pic-404__parent\" src=\"@/assets/404_images/404.png\" alt=\"404\">\n <img class=\"pic-404__child left\" src=\"@/assets/404_images/404_cloud.png\" alt=\"404\">\n <img class=\"pic-404__child mid\" src=\"@/assets/404_images/404_cloud.png\" alt=\"404\">\n <img class=\"pic-404__child right\" src=\"@/assets/404_images/404_cloud.png\" alt=\"404\">\n </div>\n <div class=\"bullshit\">\n <div class=\"bullshit__oops\">OOPS!</div>\n <div class=\"bullshit__info\">All rights reserved\n <a style=\"color:#20a0ff\" href=\"https://wallstreetcn.com\" target=\"_blank\">wallstreetcn</a>\n </div>\n <div class=\"bullshit__headline\">{{ message }}</div>\n <div class=\"bullshit__info\">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>\n <a href=\"\" class=\"bullshit__return-home\">Back to home</a>\n </div>\n </div>\n </div>\n</template>\n\n<script>\n\nexport default {\n name: \'Page404\',\n computed: {\n message() {\n return \'The webmaster said that you can not enter this page...\'\n }\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wscn-http404-container{\n transform: translate(-50%,-50%);\n position: absolute;\n top: 40%;\n left: 50%;\n}\n.wscn-http404 {\n position: relative;\n width: 1200px;\n padding: 0 50px;\n overflow: hidden;\n .pic-404 {\n position: relative;\n float: left;\n width: 600px;\n overflow: hidden;\n &__parent {\n width: 100%;\n }\n &__child {\n position: absolute;\n &.left {\n width: 80px;\n top: 17px;\n left: 220px;\n opacity: 0;\n animation-name: cloudLeft;\n animation-duration: 2s;\n animation-timing-function: linear;\n animation-fill-mode: forwards;\n animation-delay: 1s;\n }\n &.mid {\n width: 46px;\n top: 10px;\n left: 420px;\n opacity: 0;\n animation-name: cloudMid;\n animation-duration: 2s;\n animation-timing-function: linear;\n animation-fill-mode: forwards;\n animation-delay: 1.2s;\n }\n &.right {\n width: 62px;\n top: 100px;\n left: 500px;\n opacity: 0;\n animation-name: cloudRight;\n animation-duration: 2s;\n animation-timing-function: linear;\n animation-fill-mode: forwards;\n animation-delay: 1s;\n }\n @keyframes cloudLeft {\n 0% {\n top: 17px;\n left: 220px;\n opacity: 0;\n }\n 20% {\n top: 33px;\n left: 188px;\n opacity: 1;\n }\n 80% {\n top: 81px;\n left: 92px;\n opacity: 1;\n }\n 100% {\n top: 97px;\n left: 60px;\n opacity: 0;\n }\n }\n @keyframes cloudMid {\n 0% {\n top: 10px;\n left: 420px;\n opacity: 0;\n }\n 20% {\n top: 40px;\n left: 360px;\n opacity: 1;\n }\n 70% {\n top: 130px;\n left: 180px;\n opacity: 1;\n }\n 100% {\n top: 160px;\n left: 120px;\n opacity: 0;\n }\n }\n @keyframes cloudRight {\n 0% {\n top: 100px;\n left: 500px;\n opacity: 0;\n }\n 20% {\n top: 120px;\n left: 460px;\n opacity: 1;\n }\n 80% {\n top: 180px;\n left: 340px;\n opacity: 1;\n }\n 100% {\n top: 200px;\n left: 300px;\n opacity: 0;\n }\n }\n }\n }\n .bullshit {\n position: relative;\n float: left;\n width: 300px;\n padding: 30px 0;\n overflow: hidden;\n &__oops {\n font-size: 32px;\n font-weight: bold;\n line-height: 40px;\n color: #1482f0;\n opacity: 0;\n margin-bottom: 20px;\n animation-name: slideUp;\n animation-duration: 0.5s;\n animation-fill-mode: forwards;\n }\n &__headline {\n font-size: 20px;\n line-height: 24px;\n color: #222;\n font-weight: bold;\n opacity: 0;\n margin-bottom: 10px;\n animation-name: slideUp;\n animation-duration: 0.5s;\n animation-delay: 0.1s;\n animation-fill-mode: forwards;\n }\n &__info {\n font-size: 13px;\n line-height: 21px;\n color: grey;\n opacity: 0;\n margin-bottom: 30px;\n animation-name: slideUp;\n animation-duration: 0.5s;\n animation-delay: 0.2s;\n animation-fill-mode: forwards;\n }\n &__return-home {\n display: block;\n float: left;\n width: 110px;\n height: 36px;\n background: #1482f0;\n border-radius: 100px;\n text-align: center;\n color: #ffffff;\n opacity: 0;\n font-size: 14px;\n line-height: 36px;\n cursor: pointer;\n animation-name: slideUp;\n animation-duration: 0.5s;\n animation-delay: 0.3s;\n animation-fill-mode: forwards;\n }\n @keyframes slideUp {\n 0% {\n transform: translateY(60px);\n opacity: 0;\n }\n 100% {\n transform: translateY(0);\n opacity: 1;\n }\n }\n }\n}\n</style>\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(311,'index.vue.ftl','/src/views/_login',2,1,1,'<template>\r\n <div class=\"login-container\">\r\n <el-form ref=\"loginForm\" :model=\"loginForm\" :rules=\"loginRules\"\r\n class=\"login-form\" auto-complete=\"on\" label-position=\"left\">\r\n\r\n <div class=\"title-container\">\r\n <h3 class=\"title\">Login Form</h3>\r\n </div>\r\n\r\n <el-form-item prop=\"username\">\r\n <span class=\"svg-container\">\r\n <svg-icon icon-class=\"user\" />\r\n </span>\r\n <el-input\r\n ref=\"username\"\r\n v-model=\"loginForm.username\"\r\n placeholder=\"Username\"\r\n name=\"username\"\r\n type=\"text\"\r\n tabindex=\"1\"\r\n auto-complete=\"on\"\r\n />\r\n </el-form-item>\r\n\r\n <el-form-item prop=\"password\">\r\n <span class=\"svg-container\">\r\n <svg-icon icon-class=\"password\" />\r\n </span>\r\n <el-input\r\n :key=\"passwordType\"\r\n ref=\"password\"\r\n v-model=\"loginForm.password\"\r\n :type=\"passwordType\"\r\n placeholder=\"Password\"\r\n name=\"password\"\r\n tabindex=\"2\"\r\n auto-complete=\"on\"\r\n @keyup.enter.native=\"handleLogin\"\r\n />\r\n <span class=\"show-pwd\" @click=\"showPwd\">\r\n <svg-icon :icon-class=\"passwordType === \'password\' ? \'eye\' : \'eye-open\'\" />\r\n </span>\r\n </el-form-item>\r\n\r\n <el-button :loading=\"loading\" type=\"primary\"\r\n style=\"width:100%;margin-bottom:30px;\" @click.native.prevent=\"handleLogin\">Login</el-button>\r\n\r\n <div class=\"tips\">\r\n <span style=\"margin-right:20px;\">username: admin</span>\r\n <span> password: any</span>\r\n </div>\r\n\r\n </el-form>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { validUsername } from \'@/utils/validate\'\r\n\r\nexport default {\r\n name: \'Login\',\r\n data() {\r\n const validateUsername = (rule, value, callback) => {\r\n if (!validUsername(value)) {\r\n callback(new Error(\'Please enter the correct user name\'))\r\n } else {\r\n callback()\r\n }\r\n }\r\n const validatePassword = (rule, value, callback) => {\r\n if (value.length < 6) {\r\n callback(new Error(\'The password can not be less than 6 digits\'))\r\n } else {\r\n callback()\r\n }\r\n }\r\n return {\r\n loginForm: {\r\n username: \'admin\',\r\n password: \'111111\'\r\n },\r\n loginRules: {\r\n username: [{ required: true, trigger: \'blur\', validator: validateUsername }],\r\n password: [{ required: true, trigger: \'blur\', validator: validatePassword }]\r\n },\r\n loading: false,\r\n passwordType: \'password\',\r\n redirect: undefined\r\n }\r\n },\r\n watch: {\r\n $route: {\r\n handler: function(route) {\r\n this.redirect = route.query && route.query.redirect\r\n },\r\n immediate: true\r\n }\r\n },\r\n methods: {\r\n showPwd() {\r\n if (this.passwordType === \'password\') {\r\n this.passwordType = \'\'\r\n } else {\r\n this.passwordType = \'password\'\r\n }\r\n this.$nextTick(() => {\r\n this.$refs.password.focus()\r\n })\r\n },\r\n handleLogin() {\r\n this.$refs.loginForm.validate(valid => {\r\n if (valid) {\r\n this.loading = true\r\n this.$store.dispatch(\'user/login\', this.loginForm).then(() => {\r\n this.$router.push({ path: this.redirect || \'/\' })\r\n this.loading = false\r\n }).catch(() => {\r\n this.loading = false\r\n })\r\n } else {\r\n console.log(\'error submit!!\')\r\n return false\r\n }\r\n })\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n/* 修复input 背景不协调 和光标变色 */\r\n/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */\r\n\r\n$bg:#283443;\r\n$light_gray:#fff;\r\n$cursor: #fff;\r\n\r\n@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {\r\n .login-container .el-input input {\r\n color: $cursor;\r\n }\r\n}\r\n\r\n/* reset element-ui css */\r\n.login-container {\r\n .el-input {\r\n display: inline-block;\r\n height: 47px;\r\n width: 85%;\r\n\r\n input {\r\n background: transparent;\r\n border: 0px;\r\n -webkit-appearance: none;\r\n border-radius: 0px;\r\n padding: 12px 5px 12px 15px;\r\n color: $light_gray;\r\n height: 47px;\r\n caret-color: $cursor;\r\n\r\n &:-webkit-autofill {\r\n box-shadow: 0 0 0px 1000px $bg inset !important;\r\n -webkit-text-fill-color: $cursor !important;\r\n }\r\n }\r\n }\r\n\r\n .el-form-item {\r\n border: 1px solid rgba(255, 255, 255, 0.1);\r\n background: rgba(0, 0, 0, 0.1);\r\n border-radius: 5px;\r\n color: #454545;\r\n }\r\n}\r\n</style>\r\n\r\n<style lang=\"scss\" scoped>\r\n$bg:#2d3a4b;\r\n$dark_gray:#889aa4;\r\n$light_gray:#eee;\r\n\r\n.login-container {\r\n min-height: 100%;\r\n width: 100%;\r\n background-color: $bg;\r\n overflow: hidden;\r\n\r\n .login-form {\r\n position: relative;\r\n width: 520px;\r\n max-width: 100%;\r\n padding: 160px 35px 0;\r\n margin: 0 auto;\r\n overflow: hidden;\r\n }\r\n\r\n .tips {\r\n font-size: 14px;\r\n color: #fff;\r\n margin-bottom: 10px;\r\n\r\n span {\r\n &:first-of-type {\r\n margin-right: 16px;\r\n }\r\n }\r\n }\r\n\r\n .svg-container {\r\n padding: 6px 5px 6px 15px;\r\n color: $dark_gray;\r\n vertical-align: middle;\r\n width: 30px;\r\n display: inline-block;\r\n }\r\n\r\n .title-container {\r\n position: relative;\r\n\r\n .title {\r\n font-size: 26px;\r\n color: $light_gray;\r\n margin: 0px auto 40px auto;\r\n text-align: center;\r\n font-weight: bold;\r\n }\r\n }\r\n\r\n .show-pwd {\r\n position: absolute;\r\n right: 10px;\r\n top: 7px;\r\n font-size: 16px;\r\n color: $dark_gray;\r\n cursor: pointer;\r\n user-select: none;\r\n }\r\n}\r\n</style>\r\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(312,'.eslintrc.js.ftl','/tests/unit',2,1,1,'module.exports = {\n env: {\n jest: true\n }\n}\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(313,'Breadcrumb.spec.js.ftl','/tests/unit/components',2,1,1,'import { mount, createLocalVue } from \'@vue/test-utils\'\nimport VueRouter from \'vue-router\'\nimport ElementUI from \'element-ui\'\nimport Breadcrumb from \'@/components/Breadcrumb/index.vue\'\n\nconst localVue = createLocalVue()\nlocalVue.use(VueRouter)\nlocalVue.use(ElementUI)\n\nconst routes = [\n {\n path: \'/\',\n name: \'home\',\n children: [{\n path: \'dashboard\',\n name: \'dashboard\'\n }]\n },\n {\n path: \'/menu\',\n name: \'menu\',\n children: [{\n path: \'menu1\',\n name: \'menu1\',\n meta: { title: \'menu1\' },\n children: [{\n path: \'menu1-1\',\n name: \'menu1-1\',\n meta: { title: \'menu1-1\' }\n },\n {\n path: \'menu1-2\',\n name: \'menu1-2\',\n redirect: \'noredirect\',\n meta: { title: \'menu1-2\' },\n children: [{\n path: \'menu1-2-1\',\n name: \'menu1-2-1\',\n meta: { title: \'menu1-2-1\' }\n },\n {\n path: \'menu1-2-2\',\n name: \'menu1-2-2\'\n }]\n }]\n }]\n }]\n\nconst router = new VueRouter({\n routes\n})\n\ndescribe(\'Breadcrumb.vue\', () => {\n const wrapper = mount(Breadcrumb, {\n localVue,\n router\n })\n it(\'dashboard\', () => {\n router.push(\'/dashboard\')\n const len = wrapper.findAll(\'.el-breadcrumb__inner\').length\n expect(len).toBe(1)\n })\n it(\'normal route\', () => {\n router.push(\'/menu/menu1\')\n const len = wrapper.findAll(\'.el-breadcrumb__inner\').length\n expect(len).toBe(2)\n })\n it(\'nested route\', () => {\n router.push(\'/menu/menu1/menu1-2/menu1-2-1\')\n const len = wrapper.findAll(\'.el-breadcrumb__inner\').length\n expect(len).toBe(4)\n })\n it(\'no meta.title\', () => {\n router.push(\'/menu/menu1/menu1-2/menu1-2-2\')\n const len = wrapper.findAll(\'.el-breadcrumb__inner\').length\n expect(len).toBe(3)\n })\n // it(\'click link\', () => {\n // router.push(\'/menu/menu1/menu1-2/menu1-2-2\')\n // const breadcrumbArray = wrapper.findAll(\'.el-breadcrumb__inner\')\n // const second = breadcrumbArray.at(1)\n // console.log(breadcrumbArray)\n // const href = second.find(\'a\').attributes().href\n // expect(href).toBe(\'#/menu/menu1\')\n // })\n // it(\'noRedirect\', () => {\n // router.push(\'/menu/menu1/menu1-2/menu1-2-1\')\n // const breadcrumbArray = wrapper.findAll(\'.el-breadcrumb__inner\')\n // const redirectBreadcrumb = breadcrumbArray.at(2)\n // expect(redirectBreadcrumb.contains(\'a\')).toBe(false)\n // })\n it(\'last breadcrumb\', () => {\n router.push(\'/menu/menu1/menu1-2/menu1-2-1\')\n const breadcrumbArray = wrapper.findAll(\'.el-breadcrumb__inner\')\n const redirectBreadcrumb = breadcrumbArray.at(3)\n expect(redirectBreadcrumb.contains(\'a\')).toBe(false)\n })\n})\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(314,'Hamburger.spec.js.ftl','/tests/unit/components',2,1,1,'import { shallowMount } from \'@vue/test-utils\'\nimport Hamburger from \'@/components/Hamburger/index.vue\'\ndescribe(\'Hamburger.vue\', () => {\n it(\'toggle click\', () => {\n const wrapper = shallowMount(Hamburger)\n const mockFn = jest.fn()\n wrapper.vm.$on(\'toggleClick\', mockFn)\n wrapper.find(\'.hamburger\').trigger(\'click\')\n expect(mockFn).toBeCalled()\n })\n it(\'prop isActive\', () => {\n const wrapper = shallowMount(Hamburger)\n wrapper.setProps({ isActive: true })\n expect(wrapper.contains(\'.is-active\')).toBe(true)\n wrapper.setProps({ isActive: false })\n expect(wrapper.contains(\'.is-active\')).toBe(false)\n })\n})\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(315,'SvgIcon.spec.js.ftl','/tests/unit/components',2,1,1,'import { shallowMount } from \'@vue/test-utils\'\nimport SvgIcon from \'@/components/SvgIcon/index.vue\'\ndescribe(\'SvgIcon.vue\', () => {\n it(\'iconClass\', () => {\n const wrapper = shallowMount(SvgIcon, {\n propsData: {\n iconClass: \'test\'\n }\n })\n expect(wrapper.find(\'use\').attributes().href).toBe(\'#icon-test\')\n })\n it(\'className\', () => {\n const wrapper = shallowMount(SvgIcon, {\n propsData: {\n iconClass: \'test\'\n }\n })\n expect(wrapper.classes().length).toBe(1)\n wrapper.setProps({ className: \'test\' })\n expect(wrapper.classes().includes(\'test\')).toBe(true)\n })\n})\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(316,'formatTime.spec.js.ftl','/tests/unit/utils',2,1,1,'import { formatTime } from \'@/utils/index.js\'\n\ndescribe(\'Utils:formatTime\', () => {\n const d = new Date(\'2018-07-13 17:54:01\') // \"2018-07-13 17:54:01\"\n const retrofit = 5 * 1000\n\n it(\'ten digits timestamp\', () => {\n expect(formatTime((d / 1000).toFixed(0))).toBe(\'7月13日17时54分\')\n })\n it(\'test now\', () => {\n expect(formatTime(+new Date() - 1)).toBe(\'刚刚\')\n })\n it(\'less two minute\', () => {\n expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe(\'2分钟前\')\n })\n it(\'less two hour\', () => {\n expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe(\'2小时前\')\n })\n it(\'less one day\', () => {\n expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe(\'1天前\')\n })\n it(\'more than one day\', () => {\n expect(formatTime(d)).toBe(\'7月13日17时54分\')\n })\n it(\'format\', () => {\n expect(formatTime(d, \'{y}-{m}-{d} {h}:{i}\')).toBe(\'2018-07-13 17:54\')\n expect(formatTime(d, \'{y}-{m}-{d}\')).toBe(\'2018-07-13\')\n expect(formatTime(d, \'{y}/{m}/{d} {h}-{i}\')).toBe(\'2018/07/13 17-54\')\n })\n})\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(317,'parseTime.spec.js.ftl','/tests/unit/utils',2,1,1,'import { parseTime } from \'@/utils/index.js\'\n\ndescribe(\'Utils:parseTime\', () => {\n const d = new Date(\'2018-07-13 17:54:01\') // \"2018-07-13 17:54:01\"\n it(\'timestamp\', () => {\n expect(parseTime(d)).toBe(\'2018-07-13 17:54:01\')\n })\n it(\'ten digits timestamp\', () => {\n expect(parseTime((d / 1000).toFixed(0))).toBe(\'2018-07-13 17:54:01\')\n })\n it(\'new Date\', () => {\n expect(parseTime(new Date(d))).toBe(\'2018-07-13 17:54:01\')\n })\n it(\'format\', () => {\n expect(parseTime(d, \'{y}-{m}-{d} {h}:{i}\')).toBe(\'2018-07-13 17:54\')\n expect(parseTime(d, \'{y}-{m}-{d}\')).toBe(\'2018-07-13\')\n expect(parseTime(d, \'{y}/{m}/{d} {h}-{i}\')).toBe(\'2018/07/13 17-54\')\n })\n it(\'get the day of the week\', () => {\n expect(parseTime(d, \'{a}\')).toBe(\'五\') // 星期五\n })\n it(\'get the day of the week\', () => {\n expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, \'{a}\')).toBe(\'日\') // 星期日\n })\n it(\'empty argument\', () => {\n expect(parseTime()).toBeNull()\n })\n})\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(318,'validate.spec.js.ftl','/tests/unit/utils',2,1,1,'import { validUsername, isExternal } from \'@/utils/validate.js\'\n\ndescribe(\'Utils:validate\', () => {\n it(\'validUsername\', () => {\n expect(validUsername(\'admin\')).toBe(true)\n expect(validUsername(\'editor\')).toBe(true)\n expect(validUsername(\'xxxx\')).toBe(false)\n })\n it(\'isExternal\', () => {\n expect(isExternal(\'https://github.com/PanJiaChen/vue-element-admin\')).toBe(true)\n expect(isExternal(\'http://github.com/PanJiaChen/vue-element-admin\')).toBe(true)\n expect(isExternal(\'github.com/PanJiaChen/vue-element-admin\')).toBe(false)\n expect(isExternal(\'/dashboard\')).toBe(false)\n expect(isExternal(\'./dashboard\')).toBe(false)\n expect(isExternal(\'dashboard\')).toBe(false)\n })\n})\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0),(319,'vue.config.js.ftl','/',2,1,1,'\'use strict\'\r\nconst path = require(\'path\')\r\nconst defaultSettings = require(\'./src/settings.js\')\r\n\r\nfunction resolve(dir) {\r\n return path.join(__dirname, dir)\r\n}\r\n\r\nconst name = defaultSettings.title || \'vue Admin Template\' // page title\r\n\r\n// If your port is set to 80,\r\n// use administrator privileges to execute the command line.\r\n// For example, Mac: sudo npm run\r\n// You can change the port by the following methods:\r\n// port = 9528 npm run dev OR npm run dev --port = 9528\r\nconst port = process.env.port || process.env.npm_config_port || 9528 // dev port\r\n\r\nconst baseURL = process.env.VUE_APP_BASE_API\r\n\r\n// All configuration item explanations can be find in https://cli.vuejs.org/config/\r\nmodule.exports = {\r\n /**\r\n * You will need to set publicPath if you plan to deploy your site under a sub path,\r\n * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,\r\n * then publicPath should be set to \"/bar/\".\r\n * In most cases please use \'/\' !!!\r\n * Detail: https://cli.vuejs.org/config/#publicpath\r\n */\r\n publicPath: \'/\',\r\n outputDir: \'dist\',\r\n assetsDir: \'static\',\r\n lintOnSave: process.env.NODE_ENV === \'development\',\r\n productionSourceMap: false,\r\n devServer: {\r\n port: port,\r\n open: false,\r\n overlay: {\r\n warnings: false,\r\n errors: true\r\n },\r\n proxy: {\r\n // detail: https://cli.vuejs.org/config/#devserver-proxy\r\n [process.env.VUE_APP_BASE_API]: {\r\n target: `http://127.0.0.1:8080/`,\r\n changeOrigin: true,\r\n pathRewrite: {\r\n [\'^\' + baseURL]: baseURL\r\n }\r\n }\r\n }\r\n },\r\n configureWebpack: {\r\n // provide the app\'s title in webpack\'s name field, so that\r\n // it can be accessed in index.html to inject the correct title.\r\n name: name,\r\n resolve: {\r\n alias: {\r\n \'@\': resolve(\'src\')\r\n }\r\n }\r\n },\r\n chainWebpack(config) {\r\n config.plugins.delete(\'preload\') // TODO: need test\r\n config.plugins.delete(\'prefetch\') // TODO: need test\r\n\r\n // set svg-sprite-loader\r\n config.module\r\n .rule(\'svg\')\r\n .exclude.add(resolve(\'src/icons\'))\r\n .end()\r\n config.module\r\n .rule(\'icons\')\r\n .test(/\\.svg$/)\r\n .include.add(resolve(\'src/icons\'))\r\n .end()\r\n .use(\'svg-sprite-loader\')\r\n .loader(\'svg-sprite-loader\')\r\n .options({\r\n symbolId: \'icon-[name]\'\r\n })\r\n .end()\r\n\r\n // set preserveWhitespace\r\n config.module\r\n .rule(\'vue\')\r\n .use(\'vue-loader\')\r\n .loader(\'vue-loader\')\r\n .tap(options => {\r\n options.compilerOptions.preserveWhitespace = true\r\n return options\r\n })\r\n .end()\r\n\r\n config\r\n // https://webpack.js.org/configuration/devtool/#development\r\n .when(process.env.NODE_ENV === \'development\',\r\n config => config.devtool(\'cheap-source-map\')\r\n )\r\n\r\n config\r\n .when(process.env.NODE_ENV !== \'development\',\r\n config => {\r\n config\r\n .plugin(\'ScriptExtHtmlWebpackPlugin\')\r\n .after(\'html\')\r\n .use(\'script-ext-html-webpack-plugin\', [{\r\n // `runtime` must same as runtimeChunk name. default is `runtime`\r\n inline: /runtime\\..*\\.js$/\r\n }])\r\n .end()\r\n config\r\n .optimization.splitChunks({\r\n chunks: \'all\',\r\n cacheGroups: {\r\n libs: {\r\n name: \'chunk-libs\',\r\n test: /[\\\\/]node_modules[\\\\/]/,\r\n priority: 10,\r\n chunks: \'initial\' // only package third parties that are initially dependent\r\n },\r\n elementUI: {\r\n name: \'chunk-elementUI\', // split elementUI into a single package\r\n priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app\r\n test: /[\\\\/]node_modules[\\\\/]_?element-ui(.*)/ // in order to adapt to cnpm\r\n },\r\n commons: {\r\n name: \'chunk-commons\',\r\n test: resolve(\'src/components\'), // can customize your rules\r\n minChunks: 3, // minimum common number\r\n priority: 5,\r\n reuseExistingChunk: true\r\n }\r\n }\r\n })\r\n config.optimization.runtimeChunk(\'single\')\r\n }\r\n )\r\n }\r\n}\r\n','2021-01-08 17:12:58','admin','2021-01-08 17:12:58','admin',1,0);
/*Table structure for table `user_setting` */
DROP TABLE IF EXISTS `user_setting`;
CREATE TABLE `user_setting` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`username` varchar(32) NOT NULL COMMENT '用户名',
`template_enabled` tinyint(4) NOT NULL COMMENT '启用自定义模板',
`created_time` datetime NOT NULL COMMENT '创建时间【yyyy-MM-dd HH:mm:ss】',
`created_by` varchar(20) NOT NULL COMMENT '创建人【最大长度20】',
`operated_time` datetime NOT NULL COMMENT '修改时间【yyyy-MM-dd HH:mm:ss】',
`operated_by` varchar(20) NOT NULL COMMENT '修改人【最大长度20】',
`version` int(11) NOT NULL COMMENT '乐观锁版本号【整型】',
`deleted` tinyint(1) NOT NULL COMMENT '逻辑删除标识【0-未删除,1-已删除】',
PRIMARY KEY (`id`),
KEY `IDX_KM9P3FO` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='用户配置';
/*Data for the table `user_setting` */
insert into `user_setting`(`id`,`username`,`template_enabled`,`created_time`,`created_by`,`operated_time`,`operated_by`,`version`,`deleted`) values (1,'admin',0,'2021-01-08 17:12:16','admin','2021-01-08 17:12:16','admin',1,0);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/low-code-development/youran-source-code.git
git@gitee.com:low-code-development/youran-source-code.git
low-code-development
youran-source-code
youran源码
master

搜索帮助