From 591f1a4e3f1dbf6c2c209032239bec7fcf63fc91 Mon Sep 17 00:00:00 2001
From: fuliqi <fuliqi@qq.com>
Date: 星期二, 20 二月 2024 09:17:30 +0800
Subject: [PATCH] bug修复+引入系统监控
---
ycl-generator/src/main/resources/vm/java/mapper.java.vm | 91
ycl-generator/src/main/resources/vm/vue/v3/index.vue.vm | 590 +++
ycl-pojo/src/main/java/com/ycl/system/server/Jvm.java | 131
ycl-generator/src/main/resources/vm/java/serviceImpl.java.vm | 169 +
ycl-generator/src/main/java/com/ycl/generator/service/IGenTableColumnService.java | 44
ycl-generator/src/main/resources/generator.yml | 10
ycl-generator/src/main/java/com/ycl/generator/util/SqlUtil.java | 70
ycl-generator/src/main/resources/vm/java/domain.java.vm | 103
ycl-generator/pom.xml | 67
ycl-generator/src/main/java/com/ycl/generator/util/DateUtils.java | 188 +
ycl-pojo/src/main/java/com/ycl/system/server/Mem.java | 61
ycl-generator/src/main/java/com/ycl/generator/mapper/GenTableMapper.java | 83
ycl-server/src/main/java/com/ycl/properties/PermitAllUrlProperties.java | 2
sql/ry_20231130.sql | 59
ycl-server/src/main/java/com/ycl/config/RedisConfig.java | 69
ycl-common/src/main/java/constant/GenConstants.java | 117
ycl-pojo/src/main/java/com/ycl/system/server/Sys.java | 84
ycl-server/src/main/java/com/ycl/config/SecurityConfig.java | 4
ycl-generator/src/main/java/com/ycl/generator/util/VelocityInitializer.java | 35
ycl-server/src/main/java/com/ycl/config/FastJson2JsonRedisSerializer.java | 49
ycl-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm | 474 +++
ycl-generator/src/main/java/com/ycl/generator/service/GenTableServiceImpl.java | 522 +++
ycl-server/pom.xml | 7
ycl-generator/src/main/java/com/ycl/generator/exception/UtilException.java | 26
ycl-generator/src/main/java/com/ycl/generator/service/GenTableColumnServiceImpl.java | 69
ycl-generator/src/main/resources/vm/xml/mapper.xml.vm | 135
ycl-common/src/main/java/utils/Arith.java | 114
document/副本1020自贡市局运维考核平台.xlsx | 0
ycl-generator/src/main/resources/mapper/generator/GenTableMapper.xml | 202 +
ycl-pojo/src/main/java/com/ycl/system/server/Cpu.java | 101
ycl-generator/src/main/java/com/ycl/generator/util/GenUtils.java | 258 +
ycl-generator/src/main/resources/vm/java/sub-domain.java.vm | 74
ycl-server/src/main/java/com/ycl/aop/DataScopeAspect.java | 175 +
ycl-server/src/main/java/com/ycl/handler/GlobalExceptionHandler.java | 114
ycl-generator/src/main/java/com/ycl/generator/util/VelocityUtils.java | 402 ++
ycl-generator/src/main/java/com/ycl/generator/controller/GenController.java | 207 +
pom.xml | 23
ycl-server/src/main/java/com/ycl/system/controller/SysLogininforController.java | 77
ycl-server/src/main/java/com/ycl/system/controller/SysOperlogController.java | 64
ycl-generator/src/main/java/com/ycl/generator/util/PageUtils.java | 34
ycl-generator/src/main/resources/vm/vue/index-tree.vue.vm | 505 +++
ycl-common/src/main/java/utils/DateUtils.java | 188 +
ycl-server/src/main/resources/application.yml | 2
ycl-generator/src/main/java/com/ycl/generator/exception/ServiceException.java | 74
ycl-generator/src/main/resources/vm/js/api.js.vm | 44
ycl-common/src/main/java/utils/ip/IpUtils.java | 383 ++
ycl-generator/src/main/java/com/ycl/generator/service/IGenTableService.java | 121
ycl-pojo/src/main/java/com/ycl/system/server/SysFile.java | 114
ycl-generator/src/main/resources/vm/sql/sql.vm | 22
ycl-pojo/pom.xml | 5
ycl-generator/src/main/resources/vm/java/service.java.vm | 61
ycl-server/src/main/java/com/ycl/system/monitor/CacheController.java | 111
ycl-generator/src/main/java/com/ycl/generator/controller/BaseController.java | 203 +
ycl-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml | 127
ycl-generator/src/main/resources/vm/vue/v3/readme.txt | 1
ycl-server/src/main/java/com/ycl/system/monitor/ServerController.java | 27
ycl-generator/src/main/java/com/ycl/generator/config/GenConfig.java | 73
ycl-generator/src/main/java/com/ycl/generator/mapper/GenTableColumnMapper.java | 60
ycl-generator/src/main/resources/vm/vue/index.vue.vm | 602 +++
ycl-generator/src/main/resources/vm/java/controller.java.vm | 115
ycl-server/src/main/java/com/ycl/system/monitor/SysUserOnlineController.java | 80
/dev/null | 30
ycl-generator/src/main/java/com/ycl/generator/domain/GenTableColumn.java | 373 ++
ycl-pojo/src/main/java/com/ycl/system/Server.java | 237 +
ycl-generator/src/main/java/com/ycl/generator/domain/GenTable.java | 373 ++
ycl-generator/src/main/java/com/ycl/generator/util/SecurityUtils.java | 181 +
66 files changed, 9,130 insertions(+), 86 deletions(-)
diff --git "a/document/\345\211\257\346\234\2541020\350\207\252\350\264\241\345\270\202\345\261\200\350\277\220\347\273\264\350\200\203\346\240\270\345\271\263\345\217\260.xlsx" "b/document/\345\211\257\346\234\2541020\350\207\252\350\264\241\345\270\202\345\261\200\350\277\220\347\273\264\350\200\203\346\240\270\345\271\263\345\217\260.xlsx"
new file mode 100644
index 0000000..dfe6322
--- /dev/null
+++ "b/document/\345\211\257\346\234\2541020\350\207\252\350\264\241\345\270\202\345\261\200\350\277\220\347\273\264\350\200\203\346\240\270\345\271\263\345\217\260.xlsx"
Binary files differ
diff --git a/pom.xml b/pom.xml
index ac7f7f8..c6df984 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,6 +19,7 @@
<module>ycl-common</module>
<module>ycl-server</module>
<module>ycl-pojo</module>
+ <module>ycl-generator</module>
</modules>
<properties>
@@ -38,12 +39,15 @@
<jaxb-api.version>2.3.1</jaxb-api.version>
<poi.version>4.1.2</poi.version>
<hutool.version>5.8.22</hutool.version>
+ <oshi.version>6.4.0</oshi.version>
<kaptcha.version>2.3.3</kaptcha.version>
<easyexcel.version>3.3.2</easyexcel.version>
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
<spring-boot.version>3.0.6</spring-boot.version>
<mapstruct-plus.version>1.3.5</mapstruct-plus.version>
<mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
+ <velocity.version>2.3</velocity.version>
+ <commons.collections.version>3.2.2</commons.collections.version>
<!-- 鎻掍欢鐗堟湰 -->
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
<maven-war-plugin.version>3.2.2</maven-war-plugin.version>
@@ -74,19 +78,36 @@
</profiles>
<dependencyManagement>
<dependencies>
+ <!-- 鑾峰彇绯荤粺淇℃伅 -->
+ <dependency>
+ <groupId>com.github.oshi</groupId>
+ <artifactId>oshi-core</artifactId>
+ <version>${oshi.version}</version>
+ </dependency>
<!-- 瑙f瀽瀹㈡埛绔搷浣滅郴缁熴�佹祻瑙堝櫒绛� -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>${bitwalker.version}</version>
</dependency>
-
+ <!-- velocity浠g爜鐢熸垚浣跨敤妯℃澘 -->
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity-engine-core</artifactId>
+ <version>${velocity.version}</version>
+ </dependency>
<!-- io甯哥敤宸ュ叿绫� -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
+ <!-- collections宸ュ叿绫� -->
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>${commons.collections.version}</version>
+ </dependency>
<!-- excel宸ュ叿 -->
<dependency>
<groupId>org.apache.poi</groupId>
diff --git a/sql/ry_20231130.sql b/sql/ry_20231130.sql
index 457bb09..705e32d 100644
--- a/sql/ry_20231130.sql
+++ b/sql/ry_20231130.sql
@@ -910,3 +910,62 @@
insert into sys_config
values (6, '鐢ㄦ埛鐧诲綍-榛戝悕鍗曞垪琛�', 'sys.login.blackIPList', '', 'Y', 'admin', sysdate(), '', null,
'璁剧疆鐧诲綍IP榛戝悕鍗曢檺鍒讹紝澶氫釜鍖归厤椤逛互;鍒嗛殧锛屾敮鎸佸尮閰嶏紙*閫氶厤銆佺綉娈碉級');
+
+
+-- ----------------------------
+-- 18銆佷唬鐮佺敓鎴愪笟鍔¤〃
+-- ----------------------------
+drop table if exists gen_table;
+create table gen_table (
+ table_id bigint(20) not null auto_increment comment '缂栧彿',
+ table_name varchar(200) default '' comment '琛ㄥ悕绉�',
+ table_comment varchar(500) default '' comment '琛ㄦ弿杩�',
+ sub_table_name varchar(64) default null comment '鍏宠仈瀛愯〃鐨勮〃鍚�',
+ sub_table_fk_name varchar(64) default null comment '瀛愯〃鍏宠仈鐨勫閿悕',
+ class_name varchar(100) default '' comment '瀹炰綋绫诲悕绉�',
+ tpl_category varchar(200) default 'crud' comment '浣跨敤鐨勬ā鏉匡紙crud鍗曡〃鎿嶄綔 tree鏍戣〃鎿嶄綔锛�',
+ package_name varchar(100) comment '鐢熸垚鍖呰矾寰�',
+ module_name varchar(30) comment '鐢熸垚妯″潡鍚�',
+ business_name varchar(30) comment '鐢熸垚涓氬姟鍚�',
+ function_name varchar(50) comment '鐢熸垚鍔熻兘鍚�',
+ function_author varchar(50) comment '鐢熸垚鍔熻兘浣滆��',
+ gen_type char(1) default '0' comment '鐢熸垚浠g爜鏂瑰紡锛�0zip鍘嬬缉鍖� 1鑷畾涔夎矾寰勶級',
+ gen_path varchar(200) default '/' comment '鐢熸垚璺緞锛堜笉濉粯璁ら」鐩矾寰勶級',
+ options varchar(1000) comment '鍏跺畠鐢熸垚閫夐」',
+ create_by varchar(64) default '' comment '鍒涘缓鑰�',
+ create_time datetime comment '鍒涘缓鏃堕棿',
+ update_by varchar(64) default '' comment '鏇存柊鑰�',
+ update_time datetime comment '鏇存柊鏃堕棿',
+ remark varchar(500) default null comment '澶囨敞',
+ primary key (table_id)
+) engine=innodb auto_increment=1 comment = '浠g爜鐢熸垚涓氬姟琛�';
+
+-- ----------------------------
+-- 19銆佷唬鐮佺敓鎴愪笟鍔¤〃瀛楁
+-- ----------------------------
+drop table if exists gen_table_column;
+create table gen_table_column (
+ column_id bigint(20) not null auto_increment comment '缂栧彿',
+ table_id varchar(64) comment '褰掑睘琛ㄧ紪鍙�',
+ column_name varchar(200) comment '鍒楀悕绉�',
+ column_comment varchar(500) comment '鍒楁弿杩�',
+ column_type varchar(100) comment '鍒楃被鍨�',
+ java_type varchar(500) comment 'JAVA绫诲瀷',
+ java_field varchar(200) comment 'JAVA瀛楁鍚�',
+ is_pk char(1) comment '鏄惁涓婚敭锛�1鏄級',
+ is_increment char(1) comment '鏄惁鑷锛�1鏄級',
+ is_required char(1) comment '鏄惁蹇呭~锛�1鏄級',
+ is_insert char(1) comment '鏄惁涓烘彃鍏ュ瓧娈碉紙1鏄級',
+ is_edit char(1) comment '鏄惁缂栬緫瀛楁锛�1鏄級',
+ is_list char(1) comment '鏄惁鍒楄〃瀛楁锛�1鏄級',
+ is_query char(1) comment '鏄惁鏌ヨ瀛楁锛�1鏄級',
+ query_type varchar(200) default 'EQ' comment '鏌ヨ鏂瑰紡锛堢瓑浜庛�佷笉绛変簬銆佸ぇ浜庛�佸皬浜庛�佽寖鍥达級',
+ html_type varchar(200) comment '鏄剧ず绫诲瀷锛堟枃鏈銆佹枃鏈煙銆佷笅鎷夋銆佸閫夋銆佸崟閫夋銆佹棩鏈熸帶浠讹級',
+ dict_type varchar(200) default '' comment '瀛楀吀绫诲瀷',
+ sort int comment '鎺掑簭',
+ create_by varchar(64) default '' comment '鍒涘缓鑰�',
+ create_time datetime comment '鍒涘缓鏃堕棿',
+ update_by varchar(64) default '' comment '鏇存柊鑰�',
+ update_time datetime comment '鏇存柊鏃堕棿',
+ primary key (column_id)
+) engine=innodb auto_increment=1 comment = '浠g爜鐢熸垚涓氬姟琛ㄥ瓧娈�';
\ No newline at end of file
diff --git a/ycl-common/src/main/java/constant/GenConstants.java b/ycl-common/src/main/java/constant/GenConstants.java
new file mode 100644
index 0000000..cdcb260
--- /dev/null
+++ b/ycl-common/src/main/java/constant/GenConstants.java
@@ -0,0 +1,117 @@
+package constant;
+
+/**
+ * 浠g爜鐢熸垚閫氱敤甯搁噺
+ *
+ * @author ruoyi
+ */
+public class GenConstants
+{
+ /** 鍗曡〃锛堝鍒犳敼鏌ワ級 */
+ public static final String TPL_CRUD = "crud";
+
+ /** 鏍戣〃锛堝鍒犳敼鏌ワ級 */
+ public static final String TPL_TREE = "tree";
+
+ /** 涓诲瓙琛紙澧炲垹鏀规煡锛� */
+ public static final String TPL_SUB = "sub";
+
+ /** 鏍戠紪鐮佸瓧娈� */
+ public static final String TREE_CODE = "treeCode";
+
+ /** 鏍戠埗缂栫爜瀛楁 */
+ public static final String TREE_PARENT_CODE = "treeParentCode";
+
+ /** 鏍戝悕绉板瓧娈� */
+ public static final String TREE_NAME = "treeName";
+
+ /** 涓婄骇鑿滃崟ID瀛楁 */
+ public static final String PARENT_MENU_ID = "parentMenuId";
+
+ /** 涓婄骇鑿滃崟鍚嶇О瀛楁 */
+ public static final String PARENT_MENU_NAME = "parentMenuName";
+
+ /** 鏁版嵁搴撳瓧绗︿覆绫诲瀷 */
+ public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
+
+ /** 鏁版嵁搴撴枃鏈被鍨� */
+ public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
+
+ /** 鏁版嵁搴撴椂闂寸被鍨� */
+ public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
+
+ /** 鏁版嵁搴撴暟瀛楃被鍨� */
+ public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
+ "bit", "bigint", "float", "double", "decimal" };
+
+ /** 椤甸潰涓嶉渶瑕佺紪杈戝瓧娈� */
+ public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
+
+ /** 椤甸潰涓嶉渶瑕佹樉绀虹殑鍒楄〃瀛楁 */
+ public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
+ "update_time" };
+
+ /** 椤甸潰涓嶉渶瑕佹煡璇㈠瓧娈� */
+ public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
+ "update_time", "remark" };
+
+ /** Entity鍩虹被瀛楁 */
+ public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
+
+ /** Tree鍩虹被瀛楁 */
+ public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };
+
+ /** 鏂囨湰妗� */
+ public static final String HTML_INPUT = "input";
+
+ /** 鏂囨湰鍩� */
+ public static final String HTML_TEXTAREA = "textarea";
+
+ /** 涓嬫媺妗� */
+ public static final String HTML_SELECT = "select";
+
+ /** 鍗曢�夋 */
+ public static final String HTML_RADIO = "radio";
+
+ /** 澶嶉�夋 */
+ public static final String HTML_CHECKBOX = "checkbox";
+
+ /** 鏃ユ湡鎺т欢 */
+ public static final String HTML_DATETIME = "datetime";
+
+ /** 鍥剧墖涓婁紶鎺т欢 */
+ public static final String HTML_IMAGE_UPLOAD = "imageUpload";
+
+ /** 鏂囦欢涓婁紶鎺т欢 */
+ public static final String HTML_FILE_UPLOAD = "fileUpload";
+
+ /** 瀵屾枃鏈帶浠� */
+ public static final String HTML_EDITOR = "editor";
+
+ /** 瀛楃涓茬被鍨� */
+ public static final String TYPE_STRING = "String";
+
+ /** 鏁村瀷 */
+ public static final String TYPE_INTEGER = "Integer";
+
+ /** 闀挎暣鍨� */
+ public static final String TYPE_LONG = "Long";
+
+ /** 娴偣鍨� */
+ public static final String TYPE_DOUBLE = "Double";
+
+ /** 楂樼簿搴﹁绠楃被鍨� */
+ public static final String TYPE_BIGDECIMAL = "BigDecimal";
+
+ /** 鏃堕棿绫诲瀷 */
+ public static final String TYPE_DATE = "Date";
+
+ /** 妯$硦鏌ヨ */
+ public static final String QUERY_LIKE = "LIKE";
+
+ /** 鐩哥瓑鏌ヨ */
+ public static final String QUERY_EQ = "EQ";
+
+ /** 闇�瑕� */
+ public static final String REQUIRE = "1";
+}
diff --git a/ycl-common/src/main/java/json/JacksonObjectMapper.java b/ycl-common/src/main/java/json/JacksonObjectMapper.java
deleted file mode 100644
index 894da8c..0000000
--- a/ycl-common/src/main/java/json/JacksonObjectMapper.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package json;
-
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
-import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
-import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
-import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
-import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
-import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.format.DateTimeFormatter;
-
-import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
-
-/**
- * 瀵硅薄鏄犲皠鍣�:鍩轰簬jackson灏咼ava瀵硅薄杞负json锛屾垨鑰呭皢json杞负Java瀵硅薄
- * 灏咼SON瑙f瀽涓篔ava瀵硅薄鐨勮繃绋嬬О涓� [浠嶫SON鍙嶅簭鍒楀寲Java瀵硅薄]
- * 浠嶫ava瀵硅薄鐢熸垚JSON鐨勮繃绋嬬О涓� [搴忓垪鍖朖ava瀵硅薄鍒癑SON]
- */
-public class JacksonObjectMapper extends ObjectMapper {
-
- public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
- public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
-// public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
- public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
-
- public JacksonObjectMapper() {
- super();
- //鏀跺埌鏈煡灞炴�ф椂涓嶆姤寮傚父
- this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
-
- //鍙嶅簭鍒楀寲鏃讹紝灞炴�т笉瀛樺湪鐨勫吋瀹瑰鐞�
- this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
-
- SimpleModule simpleModule = new SimpleModule()
- .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
- .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
- .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
- .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
- .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
- .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
-
- //娉ㄥ唽鍔熻兘妯″潡 渚嬪锛屽彲浠ユ坊鍔犺嚜瀹氫箟搴忓垪鍖栧櫒鍜屽弽搴忓垪鍖栧櫒
- this.registerModule(simpleModule);
- }
-}
diff --git a/ycl-common/src/main/java/utils/Arith.java b/ycl-common/src/main/java/utils/Arith.java
new file mode 100644
index 0000000..e119b33
--- /dev/null
+++ b/ycl-common/src/main/java/utils/Arith.java
@@ -0,0 +1,114 @@
+package utils;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * 绮剧‘鐨勬诞鐐规暟杩愮畻
+ *
+ * @author ruoyi
+ */
+public class Arith
+{
+
+ /** 榛樿闄ゆ硶杩愮畻绮惧害 */
+ private static final int DEF_DIV_SCALE = 10;
+
+ /** 杩欎釜绫讳笉鑳藉疄渚嬪寲 */
+ private Arith()
+ {
+ }
+
+ /**
+ * 鎻愪緵绮剧‘鐨勫姞娉曡繍绠椼��
+ * @param v1 琚姞鏁�
+ * @param v2 鍔犳暟
+ * @return 涓や釜鍙傛暟鐨勫拰
+ */
+ public static double add(double v1, double v2)
+ {
+ BigDecimal b1 = new BigDecimal(Double.toString(v1));
+ BigDecimal b2 = new BigDecimal(Double.toString(v2));
+ return b1.add(b2).doubleValue();
+ }
+
+ /**
+ * 鎻愪緵绮剧‘鐨勫噺娉曡繍绠椼��
+ * @param v1 琚噺鏁�
+ * @param v2 鍑忔暟
+ * @return 涓や釜鍙傛暟鐨勫樊
+ */
+ public static double sub(double v1, double v2)
+ {
+ BigDecimal b1 = new BigDecimal(Double.toString(v1));
+ BigDecimal b2 = new BigDecimal(Double.toString(v2));
+ return b1.subtract(b2).doubleValue();
+ }
+
+ /**
+ * 鎻愪緵绮剧‘鐨勪箻娉曡繍绠椼��
+ * @param v1 琚箻鏁�
+ * @param v2 涔樻暟
+ * @return 涓や釜鍙傛暟鐨勭Н
+ */
+ public static double mul(double v1, double v2)
+ {
+ BigDecimal b1 = new BigDecimal(Double.toString(v1));
+ BigDecimal b2 = new BigDecimal(Double.toString(v2));
+ return b1.multiply(b2).doubleValue();
+ }
+
+ /**
+ * 鎻愪緵锛堢浉瀵癸級绮剧‘鐨勯櫎娉曡繍绠楋紝褰撳彂鐢熼櫎涓嶅敖鐨勬儏鍐垫椂锛岀簿纭埌
+ * 灏忔暟鐐逛互鍚�10浣嶏紝浠ュ悗鐨勬暟瀛楀洓鑸嶄簲鍏ャ��
+ * @param v1 琚櫎鏁�
+ * @param v2 闄ゆ暟
+ * @return 涓や釜鍙傛暟鐨勫晢
+ */
+ public static double div(double v1, double v2)
+ {
+ return div(v1, v2, DEF_DIV_SCALE);
+ }
+
+ /**
+ * 鎻愪緵锛堢浉瀵癸級绮剧‘鐨勯櫎娉曡繍绠椼�傚綋鍙戠敓闄や笉灏界殑鎯呭喌鏃讹紝鐢眘cale鍙傛暟鎸�
+ * 瀹氱簿搴︼紝浠ュ悗鐨勬暟瀛楀洓鑸嶄簲鍏ャ��
+ * @param v1 琚櫎鏁�
+ * @param v2 闄ゆ暟
+ * @param scale 琛ㄧず琛ㄧず闇�瑕佺簿纭埌灏忔暟鐐逛互鍚庡嚑浣嶃��
+ * @return 涓や釜鍙傛暟鐨勫晢
+ */
+ public static double div(double v1, double v2, int scale)
+ {
+ if (scale < 0)
+ {
+ throw new IllegalArgumentException(
+ "The scale must be a positive integer or zero");
+ }
+ BigDecimal b1 = new BigDecimal(Double.toString(v1));
+ BigDecimal b2 = new BigDecimal(Double.toString(v2));
+ if (b1.compareTo(BigDecimal.ZERO) == 0)
+ {
+ return BigDecimal.ZERO.doubleValue();
+ }
+ return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
+ }
+
+ /**
+ * 鎻愪緵绮剧‘鐨勫皬鏁颁綅鍥涜垗浜斿叆澶勭悊銆�
+ * @param v 闇�瑕佸洓鑸嶄簲鍏ョ殑鏁板瓧
+ * @param scale 灏忔暟鐐瑰悗淇濈暀鍑犱綅
+ * @return 鍥涜垗浜斿叆鍚庣殑缁撴灉
+ */
+ public static double round(double v, int scale)
+ {
+ if (scale < 0)
+ {
+ throw new IllegalArgumentException(
+ "The scale must be a positive integer or zero");
+ }
+ BigDecimal b = new BigDecimal(Double.toString(v));
+ BigDecimal one = BigDecimal.ONE;
+ return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
+ }
+}
diff --git a/ycl-common/src/main/java/utils/DateUtils.java b/ycl-common/src/main/java/utils/DateUtils.java
new file mode 100644
index 0000000..131b9ce
--- /dev/null
+++ b/ycl-common/src/main/java/utils/DateUtils.java
@@ -0,0 +1,188 @@
+package utils;
+
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import java.lang.management.ManagementFactory;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.util.Date;
+
+/**
+ * 鏃堕棿宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils
+{
+ public static String YYYY = "yyyy";
+
+ public static String YYYY_MM = "yyyy-MM";
+
+ public static String YYYY_MM_DD = "yyyy-MM-dd";
+
+ public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+
+ public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
+
+ private static String[] parsePatterns = {
+ "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
+ "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
+ "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
+
+ /**
+ * 鑾峰彇褰撳墠Date鍨嬫棩鏈�
+ *
+ * @return Date() 褰撳墠鏃ユ湡
+ */
+ public static Date getNowDate()
+ {
+ return new Date();
+ }
+
+ /**
+ * 鑾峰彇褰撳墠鏃ユ湡, 榛樿鏍煎紡涓簓yyy-MM-dd
+ *
+ * @return String
+ */
+ public static String getDate()
+ {
+ return dateTimeNow(YYYY_MM_DD);
+ }
+
+ public static final String getTime()
+ {
+ return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
+ }
+
+ public static final String dateTimeNow()
+ {
+ return dateTimeNow(YYYYMMDDHHMMSS);
+ }
+
+ public static final String dateTimeNow(final String format)
+ {
+ return parseDateToStr(format, new Date());
+ }
+
+ public static final String dateTime(final Date date)
+ {
+ return parseDateToStr(YYYY_MM_DD, date);
+ }
+
+ public static final String parseDateToStr(final String format, final Date date)
+ {
+ return new SimpleDateFormat(format).format(date);
+ }
+
+ public static final Date dateTime(final String format, final String ts)
+ {
+ try
+ {
+ return new SimpleDateFormat(format).parse(ts);
+ }
+ catch (ParseException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�2018/08/08
+ */
+ public static final String datePath()
+ {
+ Date now = new Date();
+ return DateFormatUtils.format(now, "yyyy/MM/dd");
+ }
+
+ /**
+ * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�20180808
+ */
+ public static final String dateTime()
+ {
+ Date now = new Date();
+ return DateFormatUtils.format(now, "yyyyMMdd");
+ }
+
+ /**
+ * 鏃ユ湡鍨嬪瓧绗︿覆杞寲涓烘棩鏈� 鏍煎紡
+ */
+ public static Date parseDate(Object str)
+ {
+ if (str == null)
+ {
+ return null;
+ }
+ try
+ {
+ return parseDate(str.toString(), parsePatterns);
+ }
+ catch (ParseException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * 鑾峰彇鏈嶅姟鍣ㄥ惎鍔ㄦ椂闂�
+ */
+ public static Date getServerStartDate()
+ {
+ long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+ return new Date(time);
+ }
+
+ /**
+ * 璁$畻鐩稿樊澶╂暟
+ */
+ public static int differentDaysByMillisecond(Date date1, Date date2)
+ {
+ return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
+ }
+
+ /**
+ * 璁$畻鏃堕棿宸�
+ *
+ * @param endDate 鏈�鍚庢椂闂�
+ * @param startTime 寮�濮嬫椂闂�
+ * @return 鏃堕棿宸紙澶�/灏忔椂/鍒嗛挓锛�
+ */
+ public static String timeDistance(Date endDate, Date startTime)
+ {
+ long nd = 1000 * 24 * 60 * 60;
+ long nh = 1000 * 60 * 60;
+ long nm = 1000 * 60;
+ // long ns = 1000;
+ // 鑾峰緱涓や釜鏃堕棿鐨勬绉掓椂闂村樊寮�
+ long diff = endDate.getTime() - startTime.getTime();
+ // 璁$畻宸灏戝ぉ
+ long day = diff / nd;
+ // 璁$畻宸灏戝皬鏃�
+ long hour = diff % nd / nh;
+ // 璁$畻宸灏戝垎閽�
+ long min = diff % nd % nh / nm;
+ // 璁$畻宸灏戠//杈撳嚭缁撴灉
+ // long sec = diff % nd % nh % nm / ns;
+ return day + "澶�" + hour + "灏忔椂" + min + "鍒嗛挓";
+ }
+
+ /**
+ * 澧炲姞 LocalDateTime ==> Date
+ */
+ public static Date toDate(LocalDateTime temporalAccessor)
+ {
+ ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
+ return Date.from(zdt.toInstant());
+ }
+
+ /**
+ * 澧炲姞 LocalDate ==> Date
+ */
+ public static Date toDate(LocalDate temporalAccessor)
+ {
+ LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
+ ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
+ return Date.from(zdt.toInstant());
+ }
+}
diff --git a/ycl-common/src/main/java/utils/ip/IpUtils.java b/ycl-common/src/main/java/utils/ip/IpUtils.java
new file mode 100644
index 0000000..e42b5cf
--- /dev/null
+++ b/ycl-common/src/main/java/utils/ip/IpUtils.java
@@ -0,0 +1,383 @@
+package utils.ip;
+
+import jakarta.servlet.http.HttpServletRequest;
+import utils.ServletUtils;
+import utils.StringUtils;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 鑾峰彇IP鏂规硶
+ *
+ * @author ruoyi
+ */
+public class IpUtils
+{
+ public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
+ // 鍖归厤 ip
+ public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")";
+ public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))";
+ // 鍖归厤缃戞
+ public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")";
+
+ /**
+ * 鑾峰彇瀹㈡埛绔疘P
+ *
+ * @return IP鍦板潃
+ */
+ public static String getIpAddr()
+ {
+ return getIpAddr(ServletUtils.getRequest());
+ }
+
+ /**
+ * 鑾峰彇瀹㈡埛绔疘P
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @return IP鍦板潃
+ */
+ public static String getIpAddr(HttpServletRequest request)
+ {
+ if (request == null)
+ {
+ return "unknown";
+ }
+ String ip = request.getHeader("x-forwarded-for");
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ {
+ ip = request.getHeader("Proxy-Client-IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ {
+ ip = request.getHeader("X-Forwarded-For");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ {
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ {
+ ip = request.getHeader("X-Real-IP");
+ }
+
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ {
+ ip = request.getRemoteAddr();
+ }
+
+ return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
+ }
+
+ /**
+ * 妫�鏌ユ槸鍚︿负鍐呴儴IP鍦板潃
+ *
+ * @param ip IP鍦板潃
+ * @return 缁撴灉
+ */
+ public static boolean internalIp(String ip)
+ {
+ byte[] addr = textToNumericFormatV4(ip);
+ return internalIp(addr) || "127.0.0.1".equals(ip);
+ }
+
+ /**
+ * 妫�鏌ユ槸鍚︿负鍐呴儴IP鍦板潃
+ *
+ * @param addr byte鍦板潃
+ * @return 缁撴灉
+ */
+ private static boolean internalIp(byte[] addr)
+ {
+ if (StringUtils.isNull(addr) || addr.length < 2)
+ {
+ return true;
+ }
+ final byte b0 = addr[0];
+ final byte b1 = addr[1];
+ // 10.x.x.x/8
+ final byte SECTION_1 = 0x0A;
+ // 172.16.x.x/12
+ final byte SECTION_2 = (byte) 0xAC;
+ final byte SECTION_3 = (byte) 0x10;
+ final byte SECTION_4 = (byte) 0x1F;
+ // 192.168.x.x/16
+ final byte SECTION_5 = (byte) 0xC0;
+ final byte SECTION_6 = (byte) 0xA8;
+ switch (b0)
+ {
+ case SECTION_1:
+ return true;
+ case SECTION_2:
+ if (b1 >= SECTION_3 && b1 <= SECTION_4)
+ {
+ return true;
+ }
+ case SECTION_5:
+ switch (b1)
+ {
+ case SECTION_6:
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * 灏咺Pv4鍦板潃杞崲鎴愬瓧鑺�
+ *
+ * @param text IPv4鍦板潃
+ * @return byte 瀛楄妭
+ */
+ public static byte[] textToNumericFormatV4(String text)
+ {
+ if (text.length() == 0)
+ {
+ return null;
+ }
+
+ byte[] bytes = new byte[4];
+ String[] elements = text.split("\\.", -1);
+ try
+ {
+ long l;
+ int i;
+ switch (elements.length)
+ {
+ case 1:
+ l = Long.parseLong(elements[0]);
+ if ((l < 0L) || (l > 4294967295L))
+ {
+ return null;
+ }
+ bytes[0] = (byte) (int) (l >> 24 & 0xFF);
+ bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
+ bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
+ bytes[3] = (byte) (int) (l & 0xFF);
+ break;
+ case 2:
+ l = Integer.parseInt(elements[0]);
+ if ((l < 0L) || (l > 255L))
+ {
+ return null;
+ }
+ bytes[0] = (byte) (int) (l & 0xFF);
+ l = Integer.parseInt(elements[1]);
+ if ((l < 0L) || (l > 16777215L))
+ {
+ return null;
+ }
+ bytes[1] = (byte) (int) (l >> 16 & 0xFF);
+ bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
+ bytes[3] = (byte) (int) (l & 0xFF);
+ break;
+ case 3:
+ for (i = 0; i < 2; ++i)
+ {
+ l = Integer.parseInt(elements[i]);
+ if ((l < 0L) || (l > 255L))
+ {
+ return null;
+ }
+ bytes[i] = (byte) (int) (l & 0xFF);
+ }
+ l = Integer.parseInt(elements[2]);
+ if ((l < 0L) || (l > 65535L))
+ {
+ return null;
+ }
+ bytes[2] = (byte) (int) (l >> 8 & 0xFF);
+ bytes[3] = (byte) (int) (l & 0xFF);
+ break;
+ case 4:
+ for (i = 0; i < 4; ++i)
+ {
+ l = Integer.parseInt(elements[i]);
+ if ((l < 0L) || (l > 255L))
+ {
+ return null;
+ }
+ bytes[i] = (byte) (int) (l & 0xFF);
+ }
+ break;
+ default:
+ return null;
+ }
+ }
+ catch (NumberFormatException e)
+ {
+ return null;
+ }
+ return bytes;
+ }
+
+ /**
+ * 鑾峰彇IP鍦板潃
+ *
+ * @return 鏈湴IP鍦板潃
+ */
+ public static String getHostIp()
+ {
+ try
+ {
+ return InetAddress.getLocalHost().getHostAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ }
+ return "127.0.0.1";
+ }
+
+ /**
+ * 鑾峰彇涓绘満鍚�
+ *
+ * @return 鏈湴涓绘満鍚�
+ */
+ public static String getHostName()
+ {
+ try
+ {
+ return InetAddress.getLocalHost().getHostName();
+ }
+ catch (UnknownHostException e)
+ {
+ }
+ return "鏈煡";
+ }
+
+ /**
+ * 浠庡绾у弽鍚戜唬鐞嗕腑鑾峰緱绗竴涓潪unknown IP鍦板潃
+ *
+ * @param ip 鑾峰緱鐨処P鍦板潃
+ * @return 绗竴涓潪unknown IP鍦板潃
+ */
+ public static String getMultistageReverseProxyIp(String ip)
+ {
+ // 澶氱骇鍙嶅悜浠g悊妫�娴�
+ if (ip != null && ip.indexOf(",") > 0)
+ {
+ final String[] ips = ip.trim().split(",");
+ for (String subIp : ips)
+ {
+ if (false == isUnknown(subIp))
+ {
+ ip = subIp;
+ break;
+ }
+ }
+ }
+ return StringUtils.substring(ip, 0, 255);
+ }
+
+ /**
+ * 妫�娴嬬粰瀹氬瓧绗︿覆鏄惁涓烘湭鐭ワ紝澶氱敤浜庢娴婬TTP璇锋眰鐩稿叧
+ *
+ * @param checkString 琚娴嬬殑瀛楃涓�
+ * @return 鏄惁鏈煡
+ */
+ public static boolean isUnknown(String checkString)
+ {
+ return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
+ }
+
+ /**
+ * 鏄惁涓篒P
+ */
+ public static boolean isIP(String ip)
+ {
+ return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP);
+ }
+
+ /**
+ * 鏄惁涓篒P锛屾垨 *涓洪棿闅旂殑閫氶厤绗﹀湴鍧�
+ */
+ public static boolean isIpWildCard(String ip)
+ {
+ return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD);
+ }
+
+ /**
+ * 妫�娴嬪弬鏁版槸鍚﹀湪ip閫氶厤绗﹂噷
+ */
+ public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip)
+ {
+ String[] s1 = ipWildCard.split("\\.");
+ String[] s2 = ip.split("\\.");
+ boolean isMatchedSeg = true;
+ for (int i = 0; i < s1.length && !s1[i].equals("*"); i++)
+ {
+ if (!s1[i].equals(s2[i]))
+ {
+ isMatchedSeg = false;
+ break;
+ }
+ }
+ return isMatchedSeg;
+ }
+
+ /**
+ * 鏄惁涓虹壒瀹氭牸寮忓:鈥�10.10.10.1-10.10.10.99鈥濈殑ip娈靛瓧绗︿覆
+ */
+ public static boolean isIPSegment(String ipSeg)
+ {
+ return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG);
+ }
+
+ /**
+ * 鍒ゆ柇ip鏄惁鍦ㄦ寚瀹氱綉娈典腑
+ */
+ public static boolean ipIsInNetNoCheck(String iparea, String ip)
+ {
+ int idx = iparea.indexOf('-');
+ String[] sips = iparea.substring(0, idx).split("\\.");
+ String[] sipe = iparea.substring(idx + 1).split("\\.");
+ String[] sipt = ip.split("\\.");
+ long ips = 0L, ipe = 0L, ipt = 0L;
+ for (int i = 0; i < 4; ++i)
+ {
+ ips = ips << 8 | Integer.parseInt(sips[i]);
+ ipe = ipe << 8 | Integer.parseInt(sipe[i]);
+ ipt = ipt << 8 | Integer.parseInt(sipt[i]);
+ }
+ if (ips > ipe)
+ {
+ long t = ips;
+ ips = ipe;
+ ipe = t;
+ }
+ return ips <= ipt && ipt <= ipe;
+ }
+
+ /**
+ * 鏍¢獙ip鏄惁绗﹀悎杩囨护涓茶鍒�
+ *
+ * @param filter 杩囨护IP鍒楄〃,鏀寔鍚庣紑'*'閫氶厤,鏀寔缃戞濡�:`10.10.10.1-10.10.10.99`
+ * @param ip 鏍¢獙IP鍦板潃
+ * @return boolean 缁撴灉
+ */
+ public static boolean isMatchedIp(String filter, String ip)
+ {
+ if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip))
+ {
+ return false;
+ }
+ String[] ips = filter.split(";");
+ for (String iStr : ips)
+ {
+ if (isIP(iStr) && iStr.equals(ip))
+ {
+ return true;
+ }
+ else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip))
+ {
+ return true;
+ }
+ else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/ycl-generator/.gitignore b/ycl-generator/.gitignore
deleted file mode 100644
index 25137b1..0000000
--- a/ycl-generator/.gitignore
+++ /dev/null
@@ -1,22 +0,0 @@
-# Created by .ignore support plugin (hsz.mobi)
-### Example user template template
-# IntelliJ project files11
-.idea
-*.iml
-out
-gen
-*.class
-/target/
-/*/target/
-
-# Log file
-*.log
-
-# BlueJ files
-*.ctxt
-
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
diff --git a/ycl-generator/README.md b/ycl-generator/README.md
deleted file mode 100644
index 9827c76..0000000
--- a/ycl-generator/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-## Mybatis plus CodeGenerator浠g爜鐢熸垚鍣�
-> 鏈暀绋嬪弬鑰冨畼缃戦噸鏂板畾涔夌紪鍐欙紝鑳藉蹇�熸惌寤洪」鐩剼鎵嬫灦
-### 浠g爜鐢熸垚璇存槑
-褰撴湁涓�涓柊鐨勪笟鍔″疄鐜版椂锛屽鎺ュ彛鐨勫姛鑳藉疄鐜颁笂锛屾垜浠�氬父鏉ヨ闇�瑕佹瀯寤轰笅闈㈢殑淇℃伅锛�
-
-- PO绫�
-
- 鏁版嵁搴撹〃鍜屽疄浣撶被鐨勬槧灏� Java Bean銆�
-
-- DAO灞�
-
- 闇�瑕佺紪鍐欐帴鍙� Mapper 锛屾帴鍙� Mapper 闇�瑕佸幓缁ф壙 MP 涓殑 BaseMapper 鎺ュ彛銆�
-
-- Service灞�
-
- 缂栧啓 Service 灞傛帴鍙e拰瀹炵幇绫汇�備笟鍔℃帴鍙i渶瑕佸幓缁ф壙 MP 涓殑 IService锛屼笟鍔″疄鐜扮被闇�瑕佺户鎵� MP 涓殑 ServiceImpl 鍜� 瀹炵幇涓氬姟鎺ュ彛銆�
-
-- Controller灞�
-
- 缂栧啓 Controller 骞舵爣娉� Spring MVC 涓殑鐩稿叧娉ㄨВ銆�
-
-鈥� 浠庝笂闈㈢殑鍚勭被浠g爜涓彲浠ユ斁涓嬶紝浠g爜閮芥槸妯℃澘鎬х殑锛屽鏋滅敤鎵嬪伐copy銆佷慨鏀圭殑鏂瑰紡鏉ュ疄鐜帮紝澶儲浜轰篃娌℃晥鐜囷紝鑰岃繖鏃跺氨鏄唬鐮佺敓鎴愬櫒灏忓睍韬墜鐨勬椂鍊欙紝**浣跨敤浠g爜鐢熸垚鍣ㄧ敓鎴愭ā鏉挎�х殑浠g爜锛屽噺灏戞墜宸ユ搷浣滅殑绻佺悙锛岄泦涓簿鍔涘湪涓氬姟寮�鍙戜笂锛屾彁鍗囧紑鍙戞晥鐜囥��**
-
-鈥� AutoGenerator 鏄� MyBatis-Plus 鐨勪唬鐮佺敓鎴愬櫒锛岄�氳繃 AutoGenerator 鍙互蹇�熺敓鎴� Mapper鎺ュ彛銆丒ntity瀹炰綋绫汇�丮apper XML銆丼ervice銆丆ontroller 绛夊悇涓ā鍧楃殑浠g爜锛屾瀬澶х殑鎻愬崌浜嗗紑鍙戞晥鐜囥��
-
-### 鍏蜂綋浣跨敤姝ラ
-1. 鎵撳紑 CodeGenerator 绫�
-2. 淇敼瀵瑰簲鐨勫弬鏁板嵆鍙�
- 鐩稿叧鍙傛暟浠嬬粛锛�
- ```yaml
- DB_TYPE: 鏁版嵁搴撶被鍨嬶紝 榛樿鏄� MySQL
- DB_NAME: 鏁版嵁搴撳悕锛岀敤鎴蜂慨鏀逛负鑷繁鐨勬暟鎹簱
- HOST_NAME: 鏁版嵁搴揑P锛� 榛樿 localhost
- JDBC_USERNAME: 鏁版嵁搴撶敤鎴峰悕锛� 榛樿锛歳oot
- JDBC_PASSWORD: 鏁版嵁搴撳瘑鐮侊紝榛樿锛歳oot
- TABLES: 闇�瑕佺敓鎴愪唬鐮佺殑琛紝 鏁扮粍
- PACKAGE_PARENT_NAME: 浠g爜鐢熸垚鐨勫寘缁撴瀯
- IS_DTO: 鏄惁鐢熸垚DTO锛� 榛樿锛歠alse
- AUTHOR: 浣滆�呭悕绉帮紝 榛樿锛歩theima
-
-3. 杩愯main鏂规硶鎵ц鐢熸垚浠g爜
-4. 鎷疯礉鍒拌嚜宸辩殑椤圭洰涓嵆鍙�
-
-
-
diff --git a/ycl-generator/pom.xml b/ycl-generator/pom.xml
index 8da5f1e..1b40e42 100644
--- a/ycl-generator/pom.xml
+++ b/ycl-generator/pom.xml
@@ -2,69 +2,38 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>ycl-generator</artifactId>
- <version>1.0-SNAPSHOT</version>
-
<parent>
<artifactId>zgyw</artifactId>
<groupId>com.ycl</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
+ <modelVersion>4.0.0</modelVersion>
- <properties>
- <maven.compiler.source>17</maven.compiler.source>
- <maven.compiler.target>17</maven.compiler.target>
- </properties>
+ <artifactId>ycl-generator</artifactId>
+
+ <description>
+ generator浠g爜鐢熸垚
+ </description>
<dependencies>
+
+ <!--velocity浠g爜鐢熸垚浣跨敤妯℃澘 -->
<dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <scope>runtime</scope>
- <version>5.1.49</version>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity-engine-core</artifactId>
</dependency>
- <!--mybatis plus 璧锋渚濊禆-->
+ <!-- collections宸ュ叿绫� -->
<dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- <version>3.4.2</version>
- </dependency>
-
- <!--mp 浠g爜鐢熸垚鍣�-->
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-generator</artifactId>
- <version>3.4.1</version>
- </dependency>
-
-
- <dependency>
- <groupId>io.swagger</groupId>
- <artifactId>swagger-annotations</artifactId>
- <version>1.5.20</version>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
</dependency>
<dependency>
- <groupId>org.freemarker</groupId>
- <artifactId>freemarker</artifactId>
- <version>2.3.30</version>
+ <groupId>com.ycl</groupId>
+ <artifactId>ycl-pojo</artifactId>
+ <version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
-</project>
+
+</project>
\ No newline at end of file
diff --git a/ycl-generator/src/main/java/CodeGenerator.java b/ycl-generator/src/main/java/CodeGenerator.java
deleted file mode 100644
index 465c2bf..0000000
--- a/ycl-generator/src/main/java/CodeGenerator.java
+++ /dev/null
@@ -1,258 +0,0 @@
-import com.baomidou.mybatisplus.annotation.DbType;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.generator.AutoGenerator;
-import com.baomidou.mybatisplus.generator.InjectionConfig;
-import com.baomidou.mybatisplus.generator.config.*;
-import com.baomidou.mybatisplus.generator.config.po.TableInfo;
-import com.baomidou.mybatisplus.generator.config.rules.DateType;
-import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
-import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
-
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @Description: 浠g爜鐢熸垚宸ュ叿
- */
-public class CodeGenerator {
-
- // ================= 鑷畾涔夐厤缃� =================
-
- private static final DbType DB_TYPE = DbType.MYSQL;
- private static final String DB_NAME = "";
- private static final String HOST_NAME = "";
- private static final String JDBC_URL = "jdbc:mysql://" + HOST_NAME + ":3306/" + DB_NAME + "?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8";
- private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
-
- private static final String JDBC_USERNAME = "root";
- private static final String JDBC_PASSWORD = "root";
-
- /**
- * 闇�瑕佺敓鎴愪唬鐮佺殑鏁版嵁搴撹〃鍚�(鍙互鑷富娣诲姞)
- */
- private static String[] TABLES = new String[]{};
- /**
- * 鐢熸垚鏂囦欢鏍圭洰褰曞強鍖呭悕
- */
- private static final String ROOT_DIR = System.getProperty("user.dir") + "/src/main/java";
- //java鏂囦欢澶逛笅璺緞
- private static final String PACKAGE_PARENT_NAME = "com.ycl.ycl-server";
-
- private static final String PACKAGE_CONTROLLER_NAME = "controller";
- private static final String PACKAGE_SERVICE_NAME = "service";
- private static final String PACKAGE_SERVICEIMPL_NAME = "service.impl";
- //entity
- private static final String PACKAGE_ENTITY_NAME = "pojo";
- // 涓�鑸儏鍐典笅瑕佸厛鐢熸垚 DTO绫� 鐒跺悗淇敼姝ゅ弬鏁板啀鐢熸垚 PO 绫汇��
- private static final Boolean IS_DTO = false;
-
- private static final String PACKAGE_MAPPER_NAME = "mapper";
- private static final String RESOURCES_DIR = System.getProperty("user.dir") + "/src/main/resources";
- private static final String MAPPER_XML_PATH = "mapper";
- /**
- * 鐢熸垚浠g爜鐨凘author
- */
- private static final String AUTHOR = "ycl";
-
- /**
- * 鏁版嵁搴撹〃鍚嶅墠缂�
- */
- private static final String[] TABLE_PREFIXS = new String[]{"tb_"};
-
-
- public static void main(String[] args) {
- AutoGenerator mpg = new AutoGenerator();
-
- mpg.setDataSource(getDataSourceConfig());
- // 灏佽闇�瑕佺敓鎴愮殑鏁版嵁搴撶殑鎵�鏈夌殑琛紝 濡傛灉鎯冲崟鐙寚瀹氳〃锛屽彲浠ユ敞閲�
- getDbAllTables(getDataSourceConfig());
-
- mpg.setGlobalConfig(getGlobalConfig());
- mpg.setStrategy(getStrategyConfig());
- mpg.setPackageInfo(getPackageConfig());
- mpg.setCfg(getInjectionConfig());
- // 閫夋嫨 freemarker 寮曟搸锛岄粯璁� Velocity
- mpg.setTemplateEngine(new FreemarkerTemplateEngine());
- mpg.setTemplate(getTemplateConfig());
- // 鎵ц鐢熸垚
- mpg.execute();
- }
-
- /**
- * 鑾峰彇鏁版嵁搴撲腑鐨勬墍鏈夌殑琛紝灏佽鍒版暟缁勶紝寰呯敓鎴愪唬鐮�
- *
- * @param dataSourceConfig
- */
- private static void getDbAllTables(DataSourceConfig dataSourceConfig) {
-
- List<String> dbTables = new ArrayList<>();
-
- Connection conn = dataSourceConfig.getConn();
- try {
- DatabaseMetaData metaData = conn.getMetaData();
-
- ResultSet resultSet = metaData.getTables(null, null, null, new String[]{"TABLE"});
-
- while (resultSet.next()) {
- dbTables.add(resultSet.getString("TABLE_NAME"));
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- if (dbTables.size() == 0) {
- throw new RuntimeException("褰撳墠鏁版嵁搴撲笅鏃犺〃");
- }
-
- TABLES = dbTables.toArray(new String[dbTables.size()]);
- System.out.println("鏁版嵁搴撹〃锛�");
- System.out.println(dbTables);
- }
-
- /**
- * 鏁版嵁婧愰厤缃�
- *
- * @return
- */
- private static DataSourceConfig getDataSourceConfig() {
- DataSourceConfig dsc = new DataSourceConfig();
- dsc.setDbType(DB_TYPE);
- dsc.setDriverName(JDBC_DRIVER);
- dsc.setUrl(JDBC_URL);
- dsc.setUsername(JDBC_USERNAME);
- dsc.setPassword(JDBC_PASSWORD);
- return dsc;
- }
-
- /**
- * 鍏ㄥ眬閰嶇疆
- *
- * @return
- */
- private static GlobalConfig getGlobalConfig() {
- GlobalConfig gc = new GlobalConfig();
- //鐢熸垚鍚庢槸鍚︽墦寮�璧勬簮绠$悊鍣�
- gc.setOpen(false);
- gc.setOutputDir(ROOT_DIR);
- //閲嶆柊鐢熸垚鏃舵枃浠舵槸鍚﹁鐩�
- gc.setFileOverride(true);
- //AR 妯″紡
- gc.setActiveRecord(false);
- //涓婚敭绛栫暐
- gc.setIdType(IdType.AUTO);
- //瀹氫箟鐢熸垚鐨勫疄浣撶被涓棩鏈熺被鍨�
- gc.setDateType(DateType.ONLY_DATE);
- //寮�鍚疭wagger2妯″紡
- gc.setSwagger2(true);
- if (IS_DTO) {
- gc.setEntityName("%sDTO");
- }
-
- // XML 浜岀骇缂撳瓨
- gc.setEnableCache(false);
- // XML ResultMap
- gc.setBaseResultMap(true);
- // XML columList
- gc.setBaseColumnList(true);
- gc.setAuthor(AUTHOR);
- gc.setMapperName("%sMapper");
- gc.setXmlName("%sMapper");
- gc.setServiceName("%sService");
- gc.setServiceImplName("%sServiceImpl");
- gc.setControllerName("%sController");
- return gc;
- }
-
- /**
- * 鐢熸垚绛栫暐閰嶇疆
- *
- * @return
- */
- private static StrategyConfig getStrategyConfig() {
- StrategyConfig strategy = new StrategyConfig();
- // 姝ゅ鍙互淇敼涓烘偍鐨勮〃鍓嶇紑
- strategy.setTablePrefix(TABLE_PREFIXS);
- // 琛ㄥ悕鐢熸垚绛栫暐
- strategy.setNaming(NamingStrategy.underline_to_camel);
- // 闇�瑕佺敓鎴愮殑琛�
- strategy.setInclude(TABLES);
- // 鏋勫缓鑰呮ā鍨�
- strategy.setChainModel(true);
-
- // lombok 妯″瀷 @Accessors(chain = true) setter閾惧紡鎿嶄綔
- strategy.setEntityLombokModel(true);
- //restful api椋庢牸鎺у埗鍣�
- strategy.setRestControllerStyle(true);
- //url涓┘宄拌浆杩炲瓧绗�
- strategy.setControllerMappingHyphenStyle(true);
-
- return strategy;
- }
-
- /**
- * 鐢熸垚鍖呭悕璁剧疆
- *
- * @return
- */
- private static PackageConfig getPackageConfig() {
- // 4.鐢熸垚鏂囦欢鎵�鍦ㄥ寘閰嶇疆锛�
- PackageConfig pc = new PackageConfig();
-// pc.setModuleName(DB_NAME);
- pc.setParent(PACKAGE_PARENT_NAME);
- pc.setController(PACKAGE_CONTROLLER_NAME);
- pc.setService(PACKAGE_SERVICE_NAME);
- pc.setServiceImpl(PACKAGE_SERVICEIMPL_NAME);
- pc.setEntity(PACKAGE_ENTITY_NAME);
- pc.setMapper(PACKAGE_MAPPER_NAME);
- return pc;
- }
-
- /**
- * xml鏂囦欢閰嶇疆
- *
- * @return
- */
- private static InjectionConfig getInjectionConfig() {
- InjectionConfig cfg = new InjectionConfig() {
- @Override
- public void initMap() {
- Map<String, Object> map = new HashMap<String, Object>();
- //map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-rb");
- this.setMap(map);
- }
- };
- //xml鐢熸垚璺緞
- List<FileOutConfig> focList = new ArrayList<>();
- // 濡傛灉妯℃澘寮曟搸鏄� freemarker
- //String templatePath = "/templates/mapper.xml.ftl";
- // 濡傛灉妯℃澘寮曟搸鏄� velocity
- // String templatePath = "/templates/mapper.xml.vm";
- focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
- @Override
- public String outputFile(TableInfo tableInfo) {
- return RESOURCES_DIR + "/" + MAPPER_XML_PATH + "/" + tableInfo.getEntityName() + "Mapper.xml";
- }
- });
-
- cfg.setFileOutConfigList(focList);
-
- return cfg;
- }
-
- /**
- * 鍏抽棴榛樿 xml 鐢熸垚
- *
- * @return
- */
- private static TemplateConfig getTemplateConfig() {
- TemplateConfig tc = new TemplateConfig();
-// tc.setXml(null);
- return tc;
- }
-}
-
diff --git a/ycl-generator/src/main/java/com/ycl/generator/config/GenConfig.java b/ycl-generator/src/main/java/com/ycl/generator/config/GenConfig.java
new file mode 100644
index 0000000..a2d2a0a
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/config/GenConfig.java
@@ -0,0 +1,73 @@
+package com.ycl.generator.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
+
+/**
+ * 璇诲彇浠g爜鐢熸垚鐩稿叧閰嶇疆
+ *
+ * @author ruoyi
+ */
+@Component
+@ConfigurationProperties(prefix = "gen")
+@PropertySource(value = { "classpath:generator.yml" })
+public class GenConfig
+{
+ /** 浣滆�� */
+ public static String author;
+
+ /** 鐢熸垚鍖呰矾寰� */
+ public static String packageName;
+
+ /** 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸false */
+ public static boolean autoRemovePre;
+
+ /** 琛ㄥ墠缂�(绫诲悕涓嶄細鍖呭惈琛ㄥ墠缂�) */
+ public static String tablePrefix;
+
+ public static String getAuthor()
+ {
+ return author;
+ }
+
+ @Value("${author}")
+ public void setAuthor(String author)
+ {
+ GenConfig.author = author;
+ }
+
+ public static String getPackageName()
+ {
+ return packageName;
+ }
+
+ @Value("${packageName}")
+ public void setPackageName(String packageName)
+ {
+ GenConfig.packageName = packageName;
+ }
+
+ public static boolean getAutoRemovePre()
+ {
+ return autoRemovePre;
+ }
+
+ @Value("${autoRemovePre}")
+ public void setAutoRemovePre(boolean autoRemovePre)
+ {
+ GenConfig.autoRemovePre = autoRemovePre;
+ }
+
+ public static String getTablePrefix()
+ {
+ return tablePrefix;
+ }
+
+ @Value("${tablePrefix}")
+ public void setTablePrefix(String tablePrefix)
+ {
+ GenConfig.tablePrefix = tablePrefix;
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/controller/BaseController.java b/ycl-generator/src/main/java/com/ycl/generator/controller/BaseController.java
new file mode 100644
index 0000000..6049ea4
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/controller/BaseController.java
@@ -0,0 +1,203 @@
+package com.ycl.generator.controller;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.ycl.generator.util.DateUtils;
+import com.ycl.generator.util.PageUtils;
+import com.ycl.generator.util.SecurityUtils;
+import com.ycl.generator.util.SqlUtil;
+import com.ycl.system.AjaxResult;
+import com.ycl.system.model.LoginUser;
+import com.ycl.system.page.PageDomain;
+import com.ycl.system.page.TableDataInfo;
+import com.ycl.system.page.TableSupport;
+import constant.HttpStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import utils.StringUtils;
+
+import java.beans.PropertyEditorSupport;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * web灞傞�氱敤鏁版嵁澶勭悊
+ *
+ * @author ruoyi
+ */
+public class BaseController
+{
+ protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ /**
+ * 灏嗗墠鍙颁紶閫掕繃鏉ョ殑鏃ユ湡鏍煎紡鐨勫瓧绗︿覆锛岃嚜鍔ㄨ浆鍖栦负Date绫诲瀷
+ */
+ @InitBinder
+ public void initBinder(WebDataBinder binder)
+ {
+ // Date 绫诲瀷杞崲
+ binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
+ {
+ @Override
+ public void setAsText(String text)
+ {
+ setValue(DateUtils.parseDate(text));
+ }
+ });
+ }
+
+ /**
+ * 璁剧疆璇锋眰鍒嗛〉鏁版嵁
+ */
+ protected void startPage()
+ {
+ PageUtils.startPage();
+ }
+
+ /**
+ * 璁剧疆璇锋眰鎺掑簭鏁版嵁
+ */
+ protected void startOrderBy()
+ {
+ PageDomain pageDomain = TableSupport.buildPageRequest();
+ if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
+ {
+ String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
+ PageHelper.orderBy(orderBy);
+ }
+ }
+
+ /**
+ * 娓呯悊鍒嗛〉鐨勭嚎绋嬪彉閲�
+ */
+ protected void clearPage()
+ {
+ PageUtils.clearPage();
+ }
+
+ /**
+ * 鍝嶅簲璇锋眰鍒嗛〉鏁版嵁
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected TableDataInfo getDataTable(List<?> list)
+ {
+ TableDataInfo rspData = new TableDataInfo();
+ rspData.setCode(HttpStatus.SUCCESS);
+ rspData.setMsg("鏌ヨ鎴愬姛");
+ rspData.setRows(list);
+ rspData.setTotal(new PageInfo(list).getTotal());
+ return rspData;
+ }
+
+ /**
+ * 杩斿洖鎴愬姛
+ */
+ public AjaxResult success()
+ {
+ return AjaxResult.success();
+ }
+
+ /**
+ * 杩斿洖澶辫触娑堟伅
+ */
+ public AjaxResult error()
+ {
+ return AjaxResult.error();
+ }
+
+ /**
+ * 杩斿洖鎴愬姛娑堟伅
+ */
+ public AjaxResult success(String message)
+ {
+ return AjaxResult.success(message);
+ }
+
+ /**
+ * 杩斿洖鎴愬姛娑堟伅
+ */
+ public AjaxResult success(Object data)
+ {
+ return AjaxResult.success(data);
+ }
+
+ /**
+ * 杩斿洖澶辫触娑堟伅
+ */
+ public AjaxResult error(String message)
+ {
+ return AjaxResult.error(message);
+ }
+
+ /**
+ * 杩斿洖璀﹀憡娑堟伅
+ */
+ public AjaxResult warn(String message)
+ {
+ return AjaxResult.warn(message);
+ }
+
+ /**
+ * 鍝嶅簲杩斿洖缁撴灉
+ *
+ * @param rows 褰卞搷琛屾暟
+ * @return 鎿嶄綔缁撴灉
+ */
+ protected AjaxResult toAjax(int rows)
+ {
+ return rows > 0 ? AjaxResult.success() : AjaxResult.error();
+ }
+
+ /**
+ * 鍝嶅簲杩斿洖缁撴灉
+ *
+ * @param result 缁撴灉
+ * @return 鎿嶄綔缁撴灉
+ */
+ protected AjaxResult toAjax(boolean result)
+ {
+ return result ? success() : error();
+ }
+
+ /**
+ * 椤甸潰璺宠浆
+ */
+ public String redirect(String url)
+ {
+ return StringUtils.format("redirect:{}", url);
+ }
+
+ /**
+ * 鑾峰彇鐢ㄦ埛缂撳瓨淇℃伅
+ */
+ public LoginUser getLoginUser()
+ {
+ return SecurityUtils.getLoginUser();
+ }
+
+ /**
+ * 鑾峰彇鐧诲綍鐢ㄦ埛id
+ */
+ public Long getUserId()
+ {
+ return getLoginUser().getUserId();
+ }
+
+ /**
+ * 鑾峰彇鐧诲綍閮ㄩ棬id
+ */
+ public Long getDeptId()
+ {
+ return getLoginUser().getDeptId();
+ }
+
+ /**
+ * 鑾峰彇鐧诲綍鐢ㄦ埛鍚�
+ */
+ public String getUsername()
+ {
+ return getLoginUser().getUsername();
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/controller/GenController.java b/ycl-generator/src/main/java/com/ycl/generator/controller/GenController.java
new file mode 100644
index 0000000..b5f8060
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/controller/GenController.java
@@ -0,0 +1,207 @@
+package com.ycl.generator.controller;
+
+import annotation.Log;
+import com.ycl.generator.domain.GenTable;
+import com.ycl.generator.domain.GenTableColumn;
+import com.ycl.generator.service.IGenTableColumnService;
+import com.ycl.generator.service.IGenTableService;
+import com.ycl.system.AjaxResult;
+import com.ycl.system.page.TableDataInfo;
+import enumeration.BusinessType;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import utils.text.Convert;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 浠g爜鐢熸垚 鎿嶄綔澶勭悊
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/tool/gen")
+public class GenController extends BaseController
+{
+ @Autowired
+ private IGenTableService genTableService;
+
+ @Autowired
+ private IGenTableColumnService genTableColumnService;
+
+ /**
+ * 鏌ヨ浠g爜鐢熸垚鍒楄〃
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:list')")
+ @GetMapping("/list")
+ public TableDataInfo genList(GenTable genTable)
+ {
+ startPage();
+ List<GenTable> list = genTableService.selectGenTableList(genTable);
+ return getDataTable(list);
+ }
+
+ /**
+ * 淇敼浠g爜鐢熸垚涓氬姟
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:query')")
+ @GetMapping(value = "/{tableId}")
+ public AjaxResult getInfo(@PathVariable Long tableId)
+ {
+ GenTable table = genTableService.selectGenTableById(tableId);
+ List<GenTable> tables = genTableService.selectGenTableAll();
+ List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(tableId);
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("info", table);
+ map.put("rows", list);
+ map.put("tables", tables);
+ return success(map);
+ }
+
+ /**
+ * 鏌ヨ鏁版嵁搴撳垪琛�
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:list')")
+ @GetMapping("/db/list")
+ public TableDataInfo dataList(GenTable genTable)
+ {
+ startPage();
+ List<GenTable> list = genTableService.selectDbTableList(genTable);
+ return getDataTable(list);
+ }
+
+ /**
+ * 鏌ヨ鏁版嵁琛ㄥ瓧娈靛垪琛�
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:list')")
+ @GetMapping(value = "/column/{tableId}")
+ public TableDataInfo columnList(Long tableId)
+ {
+ TableDataInfo dataInfo = new TableDataInfo();
+ List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(tableId);
+ dataInfo.setRows(list);
+ dataInfo.setTotal(list.size());
+ return dataInfo;
+ }
+
+ /**
+ * 瀵煎叆琛ㄧ粨鏋勶紙淇濆瓨锛�
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:import')")
+ @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.IMPORT)
+ @PostMapping("/importTable")
+ public AjaxResult importTableSave(String tables)
+ {
+ String[] tableNames = Convert.toStrArray(tables);
+ // 鏌ヨ琛ㄤ俊鎭�
+ List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
+ genTableService.importGenTable(tableList);
+ return success();
+ }
+
+ /**
+ * 淇敼淇濆瓨浠g爜鐢熸垚涓氬姟
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:edit')")
+ @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.UPDATE)
+ @PutMapping
+ public AjaxResult editSave(@Validated @RequestBody GenTable genTable)
+ {
+ genTableService.validateEdit(genTable);
+ genTableService.updateGenTable(genTable);
+ return success();
+ }
+
+ /**
+ * 鍒犻櫎浠g爜鐢熸垚
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:remove')")
+ @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{tableIds}")
+ public AjaxResult remove(@PathVariable Long[] tableIds)
+ {
+ genTableService.deleteGenTableByIds(tableIds);
+ return success();
+ }
+
+ /**
+ * 棰勮浠g爜
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:preview')")
+ @GetMapping("/preview/{tableId}")
+ public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException
+ {
+ Map<String, String> dataMap = genTableService.previewCode(tableId);
+ return success(dataMap);
+ }
+
+ /**
+ * 鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:code')")
+ @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE)
+ @GetMapping("/download/{tableName}")
+ public void download(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException
+ {
+ byte[] data = genTableService.downloadCode(tableName);
+ genCode(response, data);
+ }
+
+ /**
+ * 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛�
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:code')")
+ @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE)
+ @GetMapping("/genCode/{tableName}")
+ public AjaxResult genCode(@PathVariable("tableName") String tableName)
+ {
+ genTableService.generatorCode(tableName);
+ return success();
+ }
+
+ /**
+ * 鍚屾鏁版嵁搴�
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:edit')")
+ @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.UPDATE)
+ @GetMapping("/synchDb/{tableName}")
+ public AjaxResult synchDb(@PathVariable("tableName") String tableName)
+ {
+ genTableService.synchDb(tableName);
+ return success();
+ }
+
+ /**
+ * 鎵归噺鐢熸垚浠g爜
+ */
+ @PreAuthorize("@ss.hasPermi('tool:gen:code')")
+ @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE)
+ @GetMapping("/batchGenCode")
+ public void batchGenCode(HttpServletResponse response, String tables) throws IOException
+ {
+ String[] tableNames = Convert.toStrArray(tables);
+ byte[] data = genTableService.downloadCode(tableNames);
+ genCode(response, data);
+ }
+
+ /**
+ * 鐢熸垚zip鏂囦欢
+ */
+ private void genCode(HttpServletResponse response, byte[] data) throws IOException
+ {
+ response.reset();
+ response.addHeader("Access-Control-Allow-Origin", "*");
+ response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
+ response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\"");
+ response.addHeader("Content-Length", "" + data.length);
+ response.setContentType("application/octet-stream; charset=UTF-8");
+ IOUtils.write(data, response.getOutputStream());
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/domain/GenTable.java b/ycl-generator/src/main/java/com/ycl/generator/domain/GenTable.java
new file mode 100644
index 0000000..1e807d3
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/domain/GenTable.java
@@ -0,0 +1,373 @@
+package com.ycl.generator.domain;
+
+import com.ycl.system.entity.BaseEntity;
+import constant.GenConstants;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotBlank;
+import org.apache.commons.lang3.ArrayUtils;
+import utils.StringUtils;
+
+import java.util.List;
+
+/**
+ * 涓氬姟琛� gen_table
+ *
+ * @author ruoyi
+ */
+public class GenTable extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 缂栧彿 */
+ private Long tableId;
+
+ /** 琛ㄥ悕绉� */
+ @NotBlank(message = "琛ㄥ悕绉颁笉鑳戒负绌�")
+ private String tableName;
+
+ /** 琛ㄦ弿杩� */
+ @NotBlank(message = "琛ㄦ弿杩颁笉鑳戒负绌�")
+ private String tableComment;
+
+ /** 鍏宠仈鐖惰〃鐨勮〃鍚� */
+ private String subTableName;
+
+ /** 鏈〃鍏宠仈鐖惰〃鐨勫閿悕 */
+ private String subTableFkName;
+
+ /** 瀹炰綋绫诲悕绉�(棣栧瓧姣嶅ぇ鍐�) */
+ @NotBlank(message = "瀹炰綋绫诲悕绉颁笉鑳戒负绌�")
+ private String className;
+
+ /** 浣跨敤鐨勬ā鏉匡紙crud鍗曡〃鎿嶄綔 tree鏍戣〃鎿嶄綔 sub涓诲瓙琛ㄦ搷浣滐級 */
+ private String tplCategory;
+
+ /** 鐢熸垚鍖呰矾寰� */
+ @NotBlank(message = "鐢熸垚鍖呰矾寰勪笉鑳戒负绌�")
+ private String packageName;
+
+ /** 鐢熸垚妯″潡鍚� */
+ @NotBlank(message = "鐢熸垚妯″潡鍚嶄笉鑳戒负绌�")
+ private String moduleName;
+
+ /** 鐢熸垚涓氬姟鍚� */
+ @NotBlank(message = "鐢熸垚涓氬姟鍚嶄笉鑳戒负绌�")
+ private String businessName;
+
+ /** 鐢熸垚鍔熻兘鍚� */
+ @NotBlank(message = "鐢熸垚鍔熻兘鍚嶄笉鑳戒负绌�")
+ private String functionName;
+
+ /** 鐢熸垚浣滆�� */
+ @NotBlank(message = "浣滆�呬笉鑳戒负绌�")
+ private String functionAuthor;
+
+ /** 鐢熸垚浠g爜鏂瑰紡锛�0zip鍘嬬缉鍖� 1鑷畾涔夎矾寰勶級 */
+ private String genType;
+
+ /** 鐢熸垚璺緞锛堜笉濉粯璁ら」鐩矾寰勶級 */
+ private String genPath;
+
+ /** 涓婚敭淇℃伅 */
+ private GenTableColumn pkColumn;
+
+ /** 瀛愯〃淇℃伅 */
+ private GenTable subTable;
+
+ /** 琛ㄥ垪淇℃伅 */
+ @Valid
+ private List<GenTableColumn> columns;
+
+ /** 鍏跺畠鐢熸垚閫夐」 */
+ private String options;
+
+ /** 鏍戠紪鐮佸瓧娈� */
+ private String treeCode;
+
+ /** 鏍戠埗缂栫爜瀛楁 */
+ private String treeParentCode;
+
+ /** 鏍戝悕绉板瓧娈� */
+ private String treeName;
+
+ /** 涓婄骇鑿滃崟ID瀛楁 */
+ private String parentMenuId;
+
+ /** 涓婄骇鑿滃崟鍚嶇О瀛楁 */
+ private String parentMenuName;
+
+ public Long getTableId()
+ {
+ return tableId;
+ }
+
+ public void setTableId(Long tableId)
+ {
+ this.tableId = tableId;
+ }
+
+ public String getTableName()
+ {
+ return tableName;
+ }
+
+ public void setTableName(String tableName)
+ {
+ this.tableName = tableName;
+ }
+
+ public String getTableComment()
+ {
+ return tableComment;
+ }
+
+ public void setTableComment(String tableComment)
+ {
+ this.tableComment = tableComment;
+ }
+
+ public String getSubTableName()
+ {
+ return subTableName;
+ }
+
+ public void setSubTableName(String subTableName)
+ {
+ this.subTableName = subTableName;
+ }
+
+ public String getSubTableFkName()
+ {
+ return subTableFkName;
+ }
+
+ public void setSubTableFkName(String subTableFkName)
+ {
+ this.subTableFkName = subTableFkName;
+ }
+
+ public String getClassName()
+ {
+ return className;
+ }
+
+ public void setClassName(String className)
+ {
+ this.className = className;
+ }
+
+ public String getTplCategory()
+ {
+ return tplCategory;
+ }
+
+ public void setTplCategory(String tplCategory)
+ {
+ this.tplCategory = tplCategory;
+ }
+
+ public String getPackageName()
+ {
+ return packageName;
+ }
+
+ public void setPackageName(String packageName)
+ {
+ this.packageName = packageName;
+ }
+
+ public String getModuleName()
+ {
+ return moduleName;
+ }
+
+ public void setModuleName(String moduleName)
+ {
+ this.moduleName = moduleName;
+ }
+
+ public String getBusinessName()
+ {
+ return businessName;
+ }
+
+ public void setBusinessName(String businessName)
+ {
+ this.businessName = businessName;
+ }
+
+ public String getFunctionName()
+ {
+ return functionName;
+ }
+
+ public void setFunctionName(String functionName)
+ {
+ this.functionName = functionName;
+ }
+
+ public String getFunctionAuthor()
+ {
+ return functionAuthor;
+ }
+
+ public void setFunctionAuthor(String functionAuthor)
+ {
+ this.functionAuthor = functionAuthor;
+ }
+
+ public String getGenType()
+ {
+ return genType;
+ }
+
+ public void setGenType(String genType)
+ {
+ this.genType = genType;
+ }
+
+ public String getGenPath()
+ {
+ return genPath;
+ }
+
+ public void setGenPath(String genPath)
+ {
+ this.genPath = genPath;
+ }
+
+ public GenTableColumn getPkColumn()
+ {
+ return pkColumn;
+ }
+
+ public void setPkColumn(GenTableColumn pkColumn)
+ {
+ this.pkColumn = pkColumn;
+ }
+
+ public GenTable getSubTable()
+ {
+ return subTable;
+ }
+
+ public void setSubTable(GenTable subTable)
+ {
+ this.subTable = subTable;
+ }
+
+ public List<GenTableColumn> getColumns()
+ {
+ return columns;
+ }
+
+ public void setColumns(List<GenTableColumn> columns)
+ {
+ this.columns = columns;
+ }
+
+ public String getOptions()
+ {
+ return options;
+ }
+
+ public void setOptions(String options)
+ {
+ this.options = options;
+ }
+
+ public String getTreeCode()
+ {
+ return treeCode;
+ }
+
+ public void setTreeCode(String treeCode)
+ {
+ this.treeCode = treeCode;
+ }
+
+ public String getTreeParentCode()
+ {
+ return treeParentCode;
+ }
+
+ public void setTreeParentCode(String treeParentCode)
+ {
+ this.treeParentCode = treeParentCode;
+ }
+
+ public String getTreeName()
+ {
+ return treeName;
+ }
+
+ public void setTreeName(String treeName)
+ {
+ this.treeName = treeName;
+ }
+
+ public String getParentMenuId()
+ {
+ return parentMenuId;
+ }
+
+ public void setParentMenuId(String parentMenuId)
+ {
+ this.parentMenuId = parentMenuId;
+ }
+
+ public String getParentMenuName()
+ {
+ return parentMenuName;
+ }
+
+ public void setParentMenuName(String parentMenuName)
+ {
+ this.parentMenuName = parentMenuName;
+ }
+
+ public boolean isSub()
+ {
+ return isSub(this.tplCategory);
+ }
+
+ public static boolean isSub(String tplCategory)
+ {
+ return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory);
+ }
+
+ public boolean isTree()
+ {
+ return isTree(this.tplCategory);
+ }
+
+ public static boolean isTree(String tplCategory)
+ {
+ return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory);
+ }
+
+ public boolean isCrud()
+ {
+ return isCrud(this.tplCategory);
+ }
+
+ public static boolean isCrud(String tplCategory)
+ {
+ return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory);
+ }
+
+ public boolean isSuperColumn(String javaField)
+ {
+ return isSuperColumn(this.tplCategory, javaField);
+ }
+
+ public static boolean isSuperColumn(String tplCategory, String javaField)
+ {
+ if (isTree(tplCategory))
+ {
+ return StringUtils.equalsAnyIgnoreCase(javaField,
+ ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY));
+ }
+ return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY);
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/domain/GenTableColumn.java b/ycl-generator/src/main/java/com/ycl/generator/domain/GenTableColumn.java
new file mode 100644
index 0000000..cb66384
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/domain/GenTableColumn.java
@@ -0,0 +1,373 @@
+package com.ycl.generator.domain;
+
+import com.ycl.system.entity.BaseEntity;
+import jakarta.validation.constraints.NotBlank;
+import utils.StringUtils;
+
+/**
+ * 浠g爜鐢熸垚涓氬姟瀛楁琛� gen_table_column
+ *
+ * @author ruoyi
+ */
+public class GenTableColumn extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 缂栧彿 */
+ private Long columnId;
+
+ /** 褰掑睘琛ㄧ紪鍙� */
+ private Long tableId;
+
+ /** 鍒楀悕绉� */
+ private String columnName;
+
+ /** 鍒楁弿杩� */
+ private String columnComment;
+
+ /** 鍒楃被鍨� */
+ private String columnType;
+
+ /** JAVA绫诲瀷 */
+ private String javaType;
+
+ /** JAVA瀛楁鍚� */
+ @NotBlank(message = "Java灞炴�т笉鑳戒负绌�")
+ private String javaField;
+
+ /** 鏄惁涓婚敭锛�1鏄級 */
+ private String isPk;
+
+ /** 鏄惁鑷锛�1鏄級 */
+ private String isIncrement;
+
+ /** 鏄惁蹇呭~锛�1鏄級 */
+ private String isRequired;
+
+ /** 鏄惁涓烘彃鍏ュ瓧娈碉紙1鏄級 */
+ private String isInsert;
+
+ /** 鏄惁缂栬緫瀛楁锛�1鏄級 */
+ private String isEdit;
+
+ /** 鏄惁鍒楄〃瀛楁锛�1鏄級 */
+ private String isList;
+
+ /** 鏄惁鏌ヨ瀛楁锛�1鏄級 */
+ private String isQuery;
+
+ /** 鏌ヨ鏂瑰紡锛圗Q绛変簬銆丯E涓嶇瓑浜庛�丟T澶т簬銆丩T灏忎簬銆丩IKE妯$硦銆丅ETWEEN鑼冨洿锛� */
+ private String queryType;
+
+ /** 鏄剧ず绫诲瀷锛坕nput鏂囨湰妗嗐�乼extarea鏂囨湰鍩熴�乻elect涓嬫媺妗嗐�乧heckbox澶嶉�夋銆乺adio鍗曢�夋銆乨atetime鏃ユ湡鎺т欢銆乮mage鍥剧墖涓婁紶鎺т欢銆乽pload鏂囦欢涓婁紶鎺т欢銆乪ditor瀵屾枃鏈帶浠讹級 */
+ private String htmlType;
+
+ /** 瀛楀吀绫诲瀷 */
+ private String dictType;
+
+ /** 鎺掑簭 */
+ private Integer sort;
+
+ public void setColumnId(Long columnId)
+ {
+ this.columnId = columnId;
+ }
+
+ public Long getColumnId()
+ {
+ return columnId;
+ }
+
+ public void setTableId(Long tableId)
+ {
+ this.tableId = tableId;
+ }
+
+ public Long getTableId()
+ {
+ return tableId;
+ }
+
+ public void setColumnName(String columnName)
+ {
+ this.columnName = columnName;
+ }
+
+ public String getColumnName()
+ {
+ return columnName;
+ }
+
+ public void setColumnComment(String columnComment)
+ {
+ this.columnComment = columnComment;
+ }
+
+ public String getColumnComment()
+ {
+ return columnComment;
+ }
+
+ public void setColumnType(String columnType)
+ {
+ this.columnType = columnType;
+ }
+
+ public String getColumnType()
+ {
+ return columnType;
+ }
+
+ public void setJavaType(String javaType)
+ {
+ this.javaType = javaType;
+ }
+
+ public String getJavaType()
+ {
+ return javaType;
+ }
+
+ public void setJavaField(String javaField)
+ {
+ this.javaField = javaField;
+ }
+
+ public String getJavaField()
+ {
+ return javaField;
+ }
+
+ public String getCapJavaField()
+ {
+ return StringUtils.capitalize(javaField);
+ }
+
+ public void setIsPk(String isPk)
+ {
+ this.isPk = isPk;
+ }
+
+ public String getIsPk()
+ {
+ return isPk;
+ }
+
+ public boolean isPk()
+ {
+ return isPk(this.isPk);
+ }
+
+ public boolean isPk(String isPk)
+ {
+ return isPk != null && StringUtils.equals("1", isPk);
+ }
+
+ public String getIsIncrement()
+ {
+ return isIncrement;
+ }
+
+ public void setIsIncrement(String isIncrement)
+ {
+ this.isIncrement = isIncrement;
+ }
+
+ public boolean isIncrement()
+ {
+ return isIncrement(this.isIncrement);
+ }
+
+ public boolean isIncrement(String isIncrement)
+ {
+ return isIncrement != null && StringUtils.equals("1", isIncrement);
+ }
+
+ public void setIsRequired(String isRequired)
+ {
+ this.isRequired = isRequired;
+ }
+
+ public String getIsRequired()
+ {
+ return isRequired;
+ }
+
+ public boolean isRequired()
+ {
+ return isRequired(this.isRequired);
+ }
+
+ public boolean isRequired(String isRequired)
+ {
+ return isRequired != null && StringUtils.equals("1", isRequired);
+ }
+
+ public void setIsInsert(String isInsert)
+ {
+ this.isInsert = isInsert;
+ }
+
+ public String getIsInsert()
+ {
+ return isInsert;
+ }
+
+ public boolean isInsert()
+ {
+ return isInsert(this.isInsert);
+ }
+
+ public boolean isInsert(String isInsert)
+ {
+ return isInsert != null && StringUtils.equals("1", isInsert);
+ }
+
+ public void setIsEdit(String isEdit)
+ {
+ this.isEdit = isEdit;
+ }
+
+ public String getIsEdit()
+ {
+ return isEdit;
+ }
+
+ public boolean isEdit()
+ {
+ return isInsert(this.isEdit);
+ }
+
+ public boolean isEdit(String isEdit)
+ {
+ return isEdit != null && StringUtils.equals("1", isEdit);
+ }
+
+ public void setIsList(String isList)
+ {
+ this.isList = isList;
+ }
+
+ public String getIsList()
+ {
+ return isList;
+ }
+
+ public boolean isList()
+ {
+ return isList(this.isList);
+ }
+
+ public boolean isList(String isList)
+ {
+ return isList != null && StringUtils.equals("1", isList);
+ }
+
+ public void setIsQuery(String isQuery)
+ {
+ this.isQuery = isQuery;
+ }
+
+ public String getIsQuery()
+ {
+ return isQuery;
+ }
+
+ public boolean isQuery()
+ {
+ return isQuery(this.isQuery);
+ }
+
+ public boolean isQuery(String isQuery)
+ {
+ return isQuery != null && StringUtils.equals("1", isQuery);
+ }
+
+ public void setQueryType(String queryType)
+ {
+ this.queryType = queryType;
+ }
+
+ public String getQueryType()
+ {
+ return queryType;
+ }
+
+ public String getHtmlType()
+ {
+ return htmlType;
+ }
+
+ public void setHtmlType(String htmlType)
+ {
+ this.htmlType = htmlType;
+ }
+
+ public void setDictType(String dictType)
+ {
+ this.dictType = dictType;
+ }
+
+ public String getDictType()
+ {
+ return dictType;
+ }
+
+ public void setSort(Integer sort)
+ {
+ this.sort = sort;
+ }
+
+ public Integer getSort()
+ {
+ return sort;
+ }
+
+ public boolean isSuperColumn()
+ {
+ return isSuperColumn(this.javaField);
+ }
+
+ public static boolean isSuperColumn(String javaField)
+ {
+ return StringUtils.equalsAnyIgnoreCase(javaField,
+ // BaseEntity
+ "createBy", "createTime", "updateBy", "updateTime", "remark",
+ // TreeEntity
+ "parentName", "parentId", "orderNum", "ancestors");
+ }
+
+ public boolean isUsableColumn()
+ {
+ return isUsableColumn(javaField);
+ }
+
+ public static boolean isUsableColumn(String javaField)
+ {
+ // isSuperColumn()涓殑鍚嶅崟鐢ㄤ簬閬垮厤鐢熸垚澶氫綑Domain灞炴�э紝鑻ユ煇浜涘睘鎬у湪鐢熸垚椤甸潰鏃堕渶瑕佺敤鍒颁笉鑳藉拷鐣ワ紝鍒欐斁鍦ㄦ澶勭櫧鍚嶅崟
+ return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark");
+ }
+
+ public String readConverterExp()
+ {
+ String remarks = StringUtils.substringBetween(this.columnComment, "锛�", "锛�");
+ StringBuffer sb = new StringBuffer();
+ if (StringUtils.isNotEmpty(remarks))
+ {
+ for (String value : remarks.split(" "))
+ {
+ if (StringUtils.isNotEmpty(value))
+ {
+ Object startStr = value.subSequence(0, 1);
+ String endStr = value.substring(1);
+ sb.append("").append(startStr).append("=").append(endStr).append(",");
+ }
+ }
+ return sb.deleteCharAt(sb.length() - 1).toString();
+ }
+ else
+ {
+ return this.columnComment;
+ }
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/exception/ServiceException.java b/ycl-generator/src/main/java/com/ycl/generator/exception/ServiceException.java
new file mode 100644
index 0000000..c8b2a7c
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/exception/ServiceException.java
@@ -0,0 +1,74 @@
+package com.ycl.generator.exception;
+
+/**
+ * 涓氬姟寮傚父
+ *
+ * @author ruoyi
+ */
+public final class ServiceException extends RuntimeException
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 閿欒鐮�
+ */
+ private Integer code;
+
+ /**
+ * 閿欒鎻愮ず
+ */
+ private String message;
+
+ /**
+ * 閿欒鏄庣粏锛屽唴閮ㄨ皟璇曢敊璇�
+ *
+ * 鍜� {@link CommonResult#getDetailMessage()} 涓�鑷寸殑璁捐
+ */
+ private String detailMessage;
+
+ /**
+ * 绌烘瀯閫犳柟娉曪紝閬垮厤鍙嶅簭鍒楀寲闂
+ */
+ public ServiceException()
+ {
+ }
+
+ public ServiceException(String message)
+ {
+ this.message = message;
+ }
+
+ public ServiceException(String message, Integer code)
+ {
+ this.message = message;
+ this.code = code;
+ }
+
+ public String getDetailMessage()
+ {
+ return detailMessage;
+ }
+
+ @Override
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public Integer getCode()
+ {
+ return code;
+ }
+
+ public ServiceException setMessage(String message)
+ {
+ this.message = message;
+ return this;
+ }
+
+ public ServiceException setDetailMessage(String detailMessage)
+ {
+ this.detailMessage = detailMessage;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/ycl-generator/src/main/java/com/ycl/generator/exception/UtilException.java b/ycl-generator/src/main/java/com/ycl/generator/exception/UtilException.java
new file mode 100644
index 0000000..0f300f6
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/exception/UtilException.java
@@ -0,0 +1,26 @@
+package com.ycl.generator.exception;
+
+/**
+ * 宸ュ叿绫诲紓甯�
+ *
+ * @author ruoyi
+ */
+public class UtilException extends RuntimeException
+{
+ private static final long serialVersionUID = 8247610319171014183L;
+
+ public UtilException(Throwable e)
+ {
+ super(e.getMessage(), e);
+ }
+
+ public UtilException(String message)
+ {
+ super(message);
+ }
+
+ public UtilException(String message, Throwable throwable)
+ {
+ super(message, throwable);
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/mapper/GenTableColumnMapper.java b/ycl-generator/src/main/java/com/ycl/generator/mapper/GenTableColumnMapper.java
new file mode 100644
index 0000000..ed12dd3
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/mapper/GenTableColumnMapper.java
@@ -0,0 +1,60 @@
+package com.ycl.generator.mapper;
+
+import java.util.List;
+import com.ycl.generator.domain.GenTableColumn;
+
+/**
+ * 涓氬姟瀛楁 鏁版嵁灞�
+ *
+ * @author ruoyi
+ */
+public interface GenTableColumnMapper
+{
+ /**
+ * 鏍规嵁琛ㄥ悕绉版煡璇㈠垪淇℃伅
+ *
+ * @param tableName 琛ㄥ悕绉�
+ * @return 鍒椾俊鎭�
+ */
+ public List<GenTableColumn> selectDbTableColumnsByName(String tableName);
+
+ /**
+ * 鏌ヨ涓氬姟瀛楁鍒楄〃
+ *
+ * @param tableId 涓氬姟瀛楁缂栧彿
+ * @return 涓氬姟瀛楁闆嗗悎
+ */
+ public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId);
+
+ /**
+ * 鏂板涓氬姟瀛楁
+ *
+ * @param genTableColumn 涓氬姟瀛楁淇℃伅
+ * @return 缁撴灉
+ */
+ public int insertGenTableColumn(GenTableColumn genTableColumn);
+
+ /**
+ * 淇敼涓氬姟瀛楁
+ *
+ * @param genTableColumn 涓氬姟瀛楁淇℃伅
+ * @return 缁撴灉
+ */
+ public int updateGenTableColumn(GenTableColumn genTableColumn);
+
+ /**
+ * 鍒犻櫎涓氬姟瀛楁
+ *
+ * @param genTableColumns 鍒楁暟鎹�
+ * @return 缁撴灉
+ */
+ public int deleteGenTableColumns(List<GenTableColumn> genTableColumns);
+
+ /**
+ * 鎵归噺鍒犻櫎涓氬姟瀛楁
+ *
+ * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID
+ * @return 缁撴灉
+ */
+ public int deleteGenTableColumnByIds(Long[] ids);
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/mapper/GenTableMapper.java b/ycl-generator/src/main/java/com/ycl/generator/mapper/GenTableMapper.java
new file mode 100644
index 0000000..757a424
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/mapper/GenTableMapper.java
@@ -0,0 +1,83 @@
+package com.ycl.generator.mapper;
+
+import java.util.List;
+import com.ycl.generator.domain.GenTable;
+
+/**
+ * 涓氬姟 鏁版嵁灞�
+ *
+ * @author ruoyi
+ */
+public interface GenTableMapper
+{
+ /**
+ * 鏌ヨ涓氬姟鍒楄〃
+ *
+ * @param genTable 涓氬姟淇℃伅
+ * @return 涓氬姟闆嗗悎
+ */
+ public List<GenTable> selectGenTableList(GenTable genTable);
+
+ /**
+ * 鏌ヨ鎹簱鍒楄〃
+ *
+ * @param genTable 涓氬姟淇℃伅
+ * @return 鏁版嵁搴撹〃闆嗗悎
+ */
+ public List<GenTable> selectDbTableList(GenTable genTable);
+
+ /**
+ * 鏌ヨ鎹簱鍒楄〃
+ *
+ * @param tableNames 琛ㄥ悕绉扮粍
+ * @return 鏁版嵁搴撹〃闆嗗悎
+ */
+ public List<GenTable> selectDbTableListByNames(String[] tableNames);
+
+ /**
+ * 鏌ヨ鎵�鏈夎〃淇℃伅
+ *
+ * @return 琛ㄤ俊鎭泦鍚�
+ */
+ public List<GenTable> selectGenTableAll();
+
+ /**
+ * 鏌ヨ琛↖D涓氬姟淇℃伅
+ *
+ * @param id 涓氬姟ID
+ * @return 涓氬姟淇℃伅
+ */
+ public GenTable selectGenTableById(Long id);
+
+ /**
+ * 鏌ヨ琛ㄥ悕绉颁笟鍔′俊鎭�
+ *
+ * @param tableName 琛ㄥ悕绉�
+ * @return 涓氬姟淇℃伅
+ */
+ public GenTable selectGenTableByName(String tableName);
+
+ /**
+ * 鏂板涓氬姟
+ *
+ * @param genTable 涓氬姟淇℃伅
+ * @return 缁撴灉
+ */
+ public int insertGenTable(GenTable genTable);
+
+ /**
+ * 淇敼涓氬姟
+ *
+ * @param genTable 涓氬姟淇℃伅
+ * @return 缁撴灉
+ */
+ public int updateGenTable(GenTable genTable);
+
+ /**
+ * 鎵归噺鍒犻櫎涓氬姟
+ *
+ * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID
+ * @return 缁撴灉
+ */
+ public int deleteGenTableByIds(Long[] ids);
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/service/GenTableColumnServiceImpl.java b/ycl-generator/src/main/java/com/ycl/generator/service/GenTableColumnServiceImpl.java
new file mode 100644
index 0000000..efc66b8
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/service/GenTableColumnServiceImpl.java
@@ -0,0 +1,69 @@
+package com.ycl.generator.service;
+
+import com.ycl.generator.domain.GenTableColumn;
+import com.ycl.generator.mapper.GenTableColumnMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import utils.text.Convert;
+
+import java.util.List;
+
+/**
+ * 涓氬姟瀛楁 鏈嶅姟灞傚疄鐜�
+ *
+ * @author ruoyi
+ */
+@Service
+public class GenTableColumnServiceImpl implements IGenTableColumnService
+{
+ @Autowired
+ private GenTableColumnMapper genTableColumnMapper;
+
+ /**
+ * 鏌ヨ涓氬姟瀛楁鍒楄〃
+ *
+ * @param tableId 涓氬姟瀛楁缂栧彿
+ * @return 涓氬姟瀛楁闆嗗悎
+ */
+ @Override
+ public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId)
+ {
+ return genTableColumnMapper.selectGenTableColumnListByTableId(tableId);
+ }
+
+ /**
+ * 鏂板涓氬姟瀛楁
+ *
+ * @param genTableColumn 涓氬姟瀛楁淇℃伅
+ * @return 缁撴灉
+ */
+ @Override
+ public int insertGenTableColumn(GenTableColumn genTableColumn)
+ {
+ return genTableColumnMapper.insertGenTableColumn(genTableColumn);
+ }
+
+ /**
+ * 淇敼涓氬姟瀛楁
+ *
+ * @param genTableColumn 涓氬姟瀛楁淇℃伅
+ * @return 缁撴灉
+ */
+ @Override
+ public int updateGenTableColumn(GenTableColumn genTableColumn)
+ {
+ return genTableColumnMapper.updateGenTableColumn(genTableColumn);
+ }
+
+ /**
+ * 鍒犻櫎涓氬姟瀛楁瀵硅薄
+ *
+ * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID
+ * @return 缁撴灉
+ */
+ @Override
+ public int deleteGenTableColumnByIds(String ids)
+ {
+ return genTableColumnMapper.deleteGenTableColumnByIds(Convert.toLongArray(ids));
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/service/GenTableServiceImpl.java b/ycl-generator/src/main/java/com/ycl/generator/service/GenTableServiceImpl.java
new file mode 100644
index 0000000..b93a708
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/service/GenTableServiceImpl.java
@@ -0,0 +1,522 @@
+package com.ycl.generator.service;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ycl.generator.domain.GenTable;
+import com.ycl.generator.domain.GenTableColumn;
+import com.ycl.generator.exception.ServiceException;
+import com.ycl.generator.mapper.GenTableColumnMapper;
+import com.ycl.generator.mapper.GenTableMapper;
+import com.ycl.generator.util.GenUtils;
+import com.ycl.generator.util.SecurityUtils;
+import com.ycl.generator.util.VelocityInitializer;
+import com.ycl.generator.util.VelocityUtils;
+import constant.Constants;
+import constant.GenConstants;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import utils.StringUtils;
+import utils.text.CharsetKit;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * 涓氬姟 鏈嶅姟灞傚疄鐜�
+ *
+ * @author ruoyi
+ */
+@Service
+public class GenTableServiceImpl implements IGenTableService
+{
+ private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class);
+
+ @Autowired
+ private GenTableMapper genTableMapper;
+
+ @Autowired
+ private GenTableColumnMapper genTableColumnMapper;
+
+ /**
+ * 鏌ヨ涓氬姟淇℃伅
+ *
+ * @param id 涓氬姟ID
+ * @return 涓氬姟淇℃伅
+ */
+ @Override
+ public GenTable selectGenTableById(Long id)
+ {
+ GenTable genTable = genTableMapper.selectGenTableById(id);
+ setTableFromOptions(genTable);
+ return genTable;
+ }
+
+ /**
+ * 鏌ヨ涓氬姟鍒楄〃
+ *
+ * @param genTable 涓氬姟淇℃伅
+ * @return 涓氬姟闆嗗悎
+ */
+ @Override
+ public List<GenTable> selectGenTableList(GenTable genTable)
+ {
+ return genTableMapper.selectGenTableList(genTable);
+ }
+
+ /**
+ * 鏌ヨ鎹簱鍒楄〃
+ *
+ * @param genTable 涓氬姟淇℃伅
+ * @return 鏁版嵁搴撹〃闆嗗悎
+ */
+ @Override
+ public List<GenTable> selectDbTableList(GenTable genTable)
+ {
+ return genTableMapper.selectDbTableList(genTable);
+ }
+
+ /**
+ * 鏌ヨ鎹簱鍒楄〃
+ *
+ * @param tableNames 琛ㄥ悕绉扮粍
+ * @return 鏁版嵁搴撹〃闆嗗悎
+ */
+ @Override
+ public List<GenTable> selectDbTableListByNames(String[] tableNames)
+ {
+ return genTableMapper.selectDbTableListByNames(tableNames);
+ }
+
+ /**
+ * 鏌ヨ鎵�鏈夎〃淇℃伅
+ *
+ * @return 琛ㄤ俊鎭泦鍚�
+ */
+ @Override
+ public List<GenTable> selectGenTableAll()
+ {
+ return genTableMapper.selectGenTableAll();
+ }
+
+ /**
+ * 淇敼涓氬姟
+ *
+ * @param genTable 涓氬姟淇℃伅
+ * @return 缁撴灉
+ */
+ @Override
+ @Transactional
+ public void updateGenTable(GenTable genTable)
+ {
+ String options = JSON.toJSONString(genTable.getParams());
+ genTable.setOptions(options);
+ int row = genTableMapper.updateGenTable(genTable);
+ if (row > 0)
+ {
+ for (GenTableColumn cenTableColumn : genTable.getColumns())
+ {
+ genTableColumnMapper.updateGenTableColumn(cenTableColumn);
+ }
+ }
+ }
+
+ /**
+ * 鍒犻櫎涓氬姟瀵硅薄
+ *
+ * @param tableIds 闇�瑕佸垹闄ょ殑鏁版嵁ID
+ * @return 缁撴灉
+ */
+ @Override
+ @Transactional
+ public void deleteGenTableByIds(Long[] tableIds)
+ {
+ genTableMapper.deleteGenTableByIds(tableIds);
+ genTableColumnMapper.deleteGenTableColumnByIds(tableIds);
+ }
+
+ /**
+ * 瀵煎叆琛ㄧ粨鏋�
+ *
+ * @param tableList 瀵煎叆琛ㄥ垪琛�
+ */
+ @Override
+ @Transactional
+ public void importGenTable(List<GenTable> tableList)
+ {
+ String operName = SecurityUtils.getUsername();
+ try
+ {
+ for (GenTable table : tableList)
+ {
+ String tableName = table.getTableName();
+ GenUtils.initTable(table, operName);
+ int row = genTableMapper.insertGenTable(table);
+ if (row > 0)
+ {
+ // 淇濆瓨鍒椾俊鎭�
+ List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
+ for (GenTableColumn column : genTableColumns)
+ {
+ GenUtils.initColumnField(column, table);
+ genTableColumnMapper.insertGenTableColumn(column);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new ServiceException("瀵煎叆澶辫触锛�" + e.getMessage());
+ }
+ }
+
+ /**
+ * 棰勮浠g爜
+ *
+ * @param tableId 琛ㄧ紪鍙�
+ * @return 棰勮鏁版嵁鍒楄〃
+ */
+ @Override
+ public Map<String, String> previewCode(Long tableId)
+ {
+ Map<String, String> dataMap = new LinkedHashMap<>();
+ // 鏌ヨ琛ㄤ俊鎭�
+ GenTable table = genTableMapper.selectGenTableById(tableId);
+ // 璁剧疆涓诲瓙琛ㄤ俊鎭�
+ setSubTable(table);
+ // 璁剧疆涓婚敭鍒椾俊鎭�
+ setPkColumn(table);
+ VelocityInitializer.initVelocity();
+
+ VelocityContext context = VelocityUtils.prepareContext(table);
+
+ // 鑾峰彇妯℃澘鍒楄〃
+ List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
+ for (String template : templates)
+ {
+ // 娓叉煋妯℃澘
+ StringWriter sw = new StringWriter();
+ Template tpl = Velocity.getTemplate(template, Constants.UTF8);
+ tpl.merge(context, sw);
+ dataMap.put(template, sw.toString());
+ }
+ return dataMap;
+ }
+
+ /**
+ * 鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
+ *
+ * @param tableName 琛ㄥ悕绉�
+ * @return 鏁版嵁
+ */
+ @Override
+ public byte[] downloadCode(String tableName)
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ZipOutputStream zip = new ZipOutputStream(outputStream);
+ generatorCode(tableName, zip);
+ IOUtils.closeQuietly(zip);
+ return outputStream.toByteArray();
+ }
+
+ /**
+ * 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛�
+ *
+ * @param tableName 琛ㄥ悕绉�
+ */
+ @Override
+ public void generatorCode(String tableName)
+ {
+ // 鏌ヨ琛ㄤ俊鎭�
+ GenTable table = genTableMapper.selectGenTableByName(tableName);
+ // 璁剧疆涓诲瓙琛ㄤ俊鎭�
+ setSubTable(table);
+ // 璁剧疆涓婚敭鍒椾俊鎭�
+ setPkColumn(table);
+
+ VelocityInitializer.initVelocity();
+
+ VelocityContext context = VelocityUtils.prepareContext(table);
+
+ // 鑾峰彇妯℃澘鍒楄〃
+ List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
+ for (String template : templates)
+ {
+ if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm"))
+ {
+ // 娓叉煋妯℃澘
+ StringWriter sw = new StringWriter();
+ Template tpl = Velocity.getTemplate(template, Constants.UTF8);
+ tpl.merge(context, sw);
+ try
+ {
+ String path = getGenPath(table, template);
+ FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8);
+ }
+ catch (IOException e)
+ {
+ throw new ServiceException("娓叉煋妯℃澘澶辫触锛岃〃鍚嶏細" + table.getTableName());
+ }
+ }
+ }
+ }
+
+ /**
+ * 鍚屾鏁版嵁搴�
+ *
+ * @param tableName 琛ㄥ悕绉�
+ */
+ @Override
+ @Transactional
+ public void synchDb(String tableName)
+ {
+ GenTable table = genTableMapper.selectGenTableByName(tableName);
+ List<GenTableColumn> tableColumns = table.getColumns();
+ Map<String, GenTableColumn> tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity()));
+
+ List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
+ if (StringUtils.isEmpty(dbTableColumns))
+ {
+ throw new ServiceException("鍚屾鏁版嵁澶辫触锛屽師琛ㄧ粨鏋勪笉瀛樺湪");
+ }
+ List<String> dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
+
+ dbTableColumns.forEach(column -> {
+ GenUtils.initColumnField(column, table);
+ if (tableColumnMap.containsKey(column.getColumnName()))
+ {
+ GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName());
+ column.setColumnId(prevColumn.getColumnId());
+ if (column.isList())
+ {
+ // 濡傛灉鏄垪琛紝缁х画淇濈暀鏌ヨ鏂瑰紡/瀛楀吀绫诲瀷閫夐」
+ column.setDictType(prevColumn.getDictType());
+ column.setQueryType(prevColumn.getQueryType());
+ }
+ if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk()
+ && (column.isInsert() || column.isEdit())
+ && ((column.isUsableColumn()) || (!column.isSuperColumn())))
+ {
+ // 濡傛灉鏄�(鏂板/淇敼&闈炰富閿�/闈炲拷鐣ュ強鐖跺睘鎬�)锛岀户缁繚鐣欏繀濉�/鏄剧ず绫诲瀷閫夐」
+ column.setIsRequired(prevColumn.getIsRequired());
+ column.setHtmlType(prevColumn.getHtmlType());
+ }
+ genTableColumnMapper.updateGenTableColumn(column);
+ }
+ else
+ {
+ genTableColumnMapper.insertGenTableColumn(column);
+ }
+ });
+
+ List<GenTableColumn> delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList());
+ if (StringUtils.isNotEmpty(delColumns))
+ {
+ genTableColumnMapper.deleteGenTableColumns(delColumns);
+ }
+ }
+
+ /**
+ * 鎵归噺鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
+ *
+ * @param tableNames 琛ㄦ暟缁�
+ * @return 鏁版嵁
+ */
+ @Override
+ public byte[] downloadCode(String[] tableNames)
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ZipOutputStream zip = new ZipOutputStream(outputStream);
+ for (String tableName : tableNames)
+ {
+ generatorCode(tableName, zip);
+ }
+ IOUtils.closeQuietly(zip);
+ return outputStream.toByteArray();
+ }
+
+ /**
+ * 鏌ヨ琛ㄤ俊鎭苟鐢熸垚浠g爜
+ */
+ private void generatorCode(String tableName, ZipOutputStream zip)
+ {
+ // 鏌ヨ琛ㄤ俊鎭�
+ GenTable table = genTableMapper.selectGenTableByName(tableName);
+ // 璁剧疆涓诲瓙琛ㄤ俊鎭�
+ setSubTable(table);
+ // 璁剧疆涓婚敭鍒椾俊鎭�
+ setPkColumn(table);
+
+ VelocityInitializer.initVelocity();
+
+ VelocityContext context = VelocityUtils.prepareContext(table);
+
+ // 鑾峰彇妯℃澘鍒楄〃
+ List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
+ for (String template : templates)
+ {
+ // 娓叉煋妯℃澘
+ StringWriter sw = new StringWriter();
+ Template tpl = Velocity.getTemplate(template, Constants.UTF8);
+ tpl.merge(context, sw);
+ try
+ {
+ // 娣诲姞鍒皕ip
+ zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
+ IOUtils.write(sw.toString(), zip, Constants.UTF8);
+ IOUtils.closeQuietly(sw);
+ zip.flush();
+ zip.closeEntry();
+ }
+ catch (IOException e)
+ {
+ log.error("娓叉煋妯℃澘澶辫触锛岃〃鍚嶏細" + table.getTableName(), e);
+ }
+ }
+ }
+
+ /**
+ * 淇敼淇濆瓨鍙傛暟鏍¢獙
+ *
+ * @param genTable 涓氬姟淇℃伅
+ */
+ @Override
+ public void validateEdit(GenTable genTable)
+ {
+ if (GenConstants.TPL_TREE.equals(genTable.getTplCategory()))
+ {
+ String options = JSON.toJSONString(genTable.getParams());
+ JSONObject paramsObj = JSON.parseObject(options);
+ if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE)))
+ {
+ throw new ServiceException("鏍戠紪鐮佸瓧娈典笉鑳戒负绌�");
+ }
+ else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE)))
+ {
+ throw new ServiceException("鏍戠埗缂栫爜瀛楁涓嶈兘涓虹┖");
+ }
+ else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME)))
+ {
+ throw new ServiceException("鏍戝悕绉板瓧娈典笉鑳戒负绌�");
+ }
+ else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory()))
+ {
+ if (StringUtils.isEmpty(genTable.getSubTableName()))
+ {
+ throw new ServiceException("鍏宠仈瀛愯〃鐨勮〃鍚嶄笉鑳戒负绌�");
+ }
+ else if (StringUtils.isEmpty(genTable.getSubTableFkName()))
+ {
+ throw new ServiceException("瀛愯〃鍏宠仈鐨勫閿悕涓嶈兘涓虹┖");
+ }
+ }
+ }
+ }
+
+ /**
+ * 璁剧疆涓婚敭鍒椾俊鎭�
+ *
+ * @param table 涓氬姟琛ㄤ俊鎭�
+ */
+ public void setPkColumn(GenTable table)
+ {
+ for (GenTableColumn column : table.getColumns())
+ {
+ if (column.isPk())
+ {
+ table.setPkColumn(column);
+ break;
+ }
+ }
+ if (StringUtils.isNull(table.getPkColumn()))
+ {
+ table.setPkColumn(table.getColumns().get(0));
+ }
+ if (GenConstants.TPL_SUB.equals(table.getTplCategory()))
+ {
+ for (GenTableColumn column : table.getSubTable().getColumns())
+ {
+ if (column.isPk())
+ {
+ table.getSubTable().setPkColumn(column);
+ break;
+ }
+ }
+ if (StringUtils.isNull(table.getSubTable().getPkColumn()))
+ {
+ table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0));
+ }
+ }
+ }
+
+ /**
+ * 璁剧疆涓诲瓙琛ㄤ俊鎭�
+ *
+ * @param table 涓氬姟琛ㄤ俊鎭�
+ */
+ public void setSubTable(GenTable table)
+ {
+ String subTableName = table.getSubTableName();
+ if (StringUtils.isNotEmpty(subTableName))
+ {
+ table.setSubTable(genTableMapper.selectGenTableByName(subTableName));
+ }
+ }
+
+ /**
+ * 璁剧疆浠g爜鐢熸垚鍏朵粬閫夐」鍊�
+ *
+ * @param genTable 璁剧疆鍚庣殑鐢熸垚瀵硅薄
+ */
+ public void setTableFromOptions(GenTable genTable)
+ {
+ JSONObject paramsObj = JSON.parseObject(genTable.getOptions());
+ if (StringUtils.isNotNull(paramsObj))
+ {
+ String treeCode = paramsObj.getString(GenConstants.TREE_CODE);
+ String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE);
+ String treeName = paramsObj.getString(GenConstants.TREE_NAME);
+ String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID);
+ String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME);
+
+ genTable.setTreeCode(treeCode);
+ genTable.setTreeParentCode(treeParentCode);
+ genTable.setTreeName(treeName);
+ genTable.setParentMenuId(parentMenuId);
+ genTable.setParentMenuName(parentMenuName);
+ }
+ }
+
+ /**
+ * 鑾峰彇浠g爜鐢熸垚鍦板潃
+ *
+ * @param table 涓氬姟琛ㄤ俊鎭�
+ * @param template 妯℃澘鏂囦欢璺緞
+ * @return 鐢熸垚鍦板潃
+ */
+ public static String getGenPath(GenTable table, String template)
+ {
+ String genPath = table.getGenPath();
+ if (StringUtils.equals(genPath, "/"))
+ {
+ return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
+ }
+ return genPath + File.separator + VelocityUtils.getFileName(template, table);
+ }
+}
\ No newline at end of file
diff --git a/ycl-generator/src/main/java/com/ycl/generator/service/IGenTableColumnService.java b/ycl-generator/src/main/java/com/ycl/generator/service/IGenTableColumnService.java
new file mode 100644
index 0000000..2d66f8f
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/service/IGenTableColumnService.java
@@ -0,0 +1,44 @@
+package com.ycl.generator.service;
+
+import java.util.List;
+import com.ycl.generator.domain.GenTableColumn;
+
+/**
+ * 涓氬姟瀛楁 鏈嶅姟灞�
+ *
+ * @author ruoyi
+ */
+public interface IGenTableColumnService
+{
+ /**
+ * 鏌ヨ涓氬姟瀛楁鍒楄〃
+ *
+ * @param tableId 涓氬姟瀛楁缂栧彿
+ * @return 涓氬姟瀛楁闆嗗悎
+ */
+ public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId);
+
+ /**
+ * 鏂板涓氬姟瀛楁
+ *
+ * @param genTableColumn 涓氬姟瀛楁淇℃伅
+ * @return 缁撴灉
+ */
+ public int insertGenTableColumn(GenTableColumn genTableColumn);
+
+ /**
+ * 淇敼涓氬姟瀛楁
+ *
+ * @param genTableColumn 涓氬姟瀛楁淇℃伅
+ * @return 缁撴灉
+ */
+ public int updateGenTableColumn(GenTableColumn genTableColumn);
+
+ /**
+ * 鍒犻櫎涓氬姟瀛楁淇℃伅
+ *
+ * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID
+ * @return 缁撴灉
+ */
+ public int deleteGenTableColumnByIds(String ids);
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/service/IGenTableService.java b/ycl-generator/src/main/java/com/ycl/generator/service/IGenTableService.java
new file mode 100644
index 0000000..ed9aaaf
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/service/IGenTableService.java
@@ -0,0 +1,121 @@
+package com.ycl.generator.service;
+
+import java.util.List;
+import java.util.Map;
+import com.ycl.generator.domain.GenTable;
+
+/**
+ * 涓氬姟 鏈嶅姟灞�
+ *
+ * @author ruoyi
+ */
+public interface IGenTableService
+{
+ /**
+ * 鏌ヨ涓氬姟鍒楄〃
+ *
+ * @param genTable 涓氬姟淇℃伅
+ * @return 涓氬姟闆嗗悎
+ */
+ public List<GenTable> selectGenTableList(GenTable genTable);
+
+ /**
+ * 鏌ヨ鎹簱鍒楄〃
+ *
+ * @param genTable 涓氬姟淇℃伅
+ * @return 鏁版嵁搴撹〃闆嗗悎
+ */
+ public List<GenTable> selectDbTableList(GenTable genTable);
+
+ /**
+ * 鏌ヨ鎹簱鍒楄〃
+ *
+ * @param tableNames 琛ㄥ悕绉扮粍
+ * @return 鏁版嵁搴撹〃闆嗗悎
+ */
+ public List<GenTable> selectDbTableListByNames(String[] tableNames);
+
+ /**
+ * 鏌ヨ鎵�鏈夎〃淇℃伅
+ *
+ * @return 琛ㄤ俊鎭泦鍚�
+ */
+ public List<GenTable> selectGenTableAll();
+
+ /**
+ * 鏌ヨ涓氬姟淇℃伅
+ *
+ * @param id 涓氬姟ID
+ * @return 涓氬姟淇℃伅
+ */
+ public GenTable selectGenTableById(Long id);
+
+ /**
+ * 淇敼涓氬姟
+ *
+ * @param genTable 涓氬姟淇℃伅
+ * @return 缁撴灉
+ */
+ public void updateGenTable(GenTable genTable);
+
+ /**
+ * 鍒犻櫎涓氬姟淇℃伅
+ *
+ * @param tableIds 闇�瑕佸垹闄ょ殑琛ㄦ暟鎹甀D
+ * @return 缁撴灉
+ */
+ public void deleteGenTableByIds(Long[] tableIds);
+
+ /**
+ * 瀵煎叆琛ㄧ粨鏋�
+ *
+ * @param tableList 瀵煎叆琛ㄥ垪琛�
+ */
+ public void importGenTable(List<GenTable> tableList);
+
+ /**
+ * 棰勮浠g爜
+ *
+ * @param tableId 琛ㄧ紪鍙�
+ * @return 棰勮鏁版嵁鍒楄〃
+ */
+ public Map<String, String> previewCode(Long tableId);
+
+ /**
+ * 鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
+ *
+ * @param tableName 琛ㄥ悕绉�
+ * @return 鏁版嵁
+ */
+ public byte[] downloadCode(String tableName);
+
+ /**
+ * 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛�
+ *
+ * @param tableName 琛ㄥ悕绉�
+ * @return 鏁版嵁
+ */
+ public void generatorCode(String tableName);
+
+ /**
+ * 鍚屾鏁版嵁搴�
+ *
+ * @param tableName 琛ㄥ悕绉�
+ */
+ public void synchDb(String tableName);
+
+ /**
+ * 鎵归噺鐢熸垚浠g爜锛堜笅杞芥柟寮忥級
+ *
+ * @param tableNames 琛ㄦ暟缁�
+ * @return 鏁版嵁
+ */
+ public byte[] downloadCode(String[] tableNames);
+
+ /**
+ * 淇敼淇濆瓨鍙傛暟鏍¢獙
+ *
+ * @param genTable 涓氬姟淇℃伅
+ */
+ public void validateEdit(GenTable genTable);
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/util/DateUtils.java b/ycl-generator/src/main/java/com/ycl/generator/util/DateUtils.java
new file mode 100644
index 0000000..46c492d
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/util/DateUtils.java
@@ -0,0 +1,188 @@
+package com.ycl.generator.util;
+
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import java.lang.management.ManagementFactory;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.util.Date;
+
+/**
+ * 鏃堕棿宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils
+{
+ public static String YYYY = "yyyy";
+
+ public static String YYYY_MM = "yyyy-MM";
+
+ public static String YYYY_MM_DD = "yyyy-MM-dd";
+
+ public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+
+ public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
+
+ private static String[] parsePatterns = {
+ "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
+ "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
+ "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
+
+ /**
+ * 鑾峰彇褰撳墠Date鍨嬫棩鏈�
+ *
+ * @return Date() 褰撳墠鏃ユ湡
+ */
+ public static Date getNowDate()
+ {
+ return new Date();
+ }
+
+ /**
+ * 鑾峰彇褰撳墠鏃ユ湡, 榛樿鏍煎紡涓簓yyy-MM-dd
+ *
+ * @return String
+ */
+ public static String getDate()
+ {
+ return dateTimeNow(YYYY_MM_DD);
+ }
+
+ public static final String getTime()
+ {
+ return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
+ }
+
+ public static final String dateTimeNow()
+ {
+ return dateTimeNow(YYYYMMDDHHMMSS);
+ }
+
+ public static final String dateTimeNow(final String format)
+ {
+ return parseDateToStr(format, new Date());
+ }
+
+ public static final String dateTime(final Date date)
+ {
+ return parseDateToStr(YYYY_MM_DD, date);
+ }
+
+ public static final String parseDateToStr(final String format, final Date date)
+ {
+ return new SimpleDateFormat(format).format(date);
+ }
+
+ public static final Date dateTime(final String format, final String ts)
+ {
+ try
+ {
+ return new SimpleDateFormat(format).parse(ts);
+ }
+ catch (ParseException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�2018/08/08
+ */
+ public static final String datePath()
+ {
+ Date now = new Date();
+ return DateFormatUtils.format(now, "yyyy/MM/dd");
+ }
+
+ /**
+ * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�20180808
+ */
+ public static final String dateTime()
+ {
+ Date now = new Date();
+ return DateFormatUtils.format(now, "yyyyMMdd");
+ }
+
+ /**
+ * 鏃ユ湡鍨嬪瓧绗︿覆杞寲涓烘棩鏈� 鏍煎紡
+ */
+ public static Date parseDate(Object str)
+ {
+ if (str == null)
+ {
+ return null;
+ }
+ try
+ {
+ return parseDate(str.toString(), parsePatterns);
+ }
+ catch (ParseException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * 鑾峰彇鏈嶅姟鍣ㄥ惎鍔ㄦ椂闂�
+ */
+ public static Date getServerStartDate()
+ {
+ long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+ return new Date(time);
+ }
+
+ /**
+ * 璁$畻鐩稿樊澶╂暟
+ */
+ public static int differentDaysByMillisecond(Date date1, Date date2)
+ {
+ return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
+ }
+
+ /**
+ * 璁$畻鏃堕棿宸�
+ *
+ * @param endDate 鏈�鍚庢椂闂�
+ * @param startTime 寮�濮嬫椂闂�
+ * @return 鏃堕棿宸紙澶�/灏忔椂/鍒嗛挓锛�
+ */
+ public static String timeDistance(Date endDate, Date startTime)
+ {
+ long nd = 1000 * 24 * 60 * 60;
+ long nh = 1000 * 60 * 60;
+ long nm = 1000 * 60;
+ // long ns = 1000;
+ // 鑾峰緱涓や釜鏃堕棿鐨勬绉掓椂闂村樊寮�
+ long diff = endDate.getTime() - startTime.getTime();
+ // 璁$畻宸灏戝ぉ
+ long day = diff / nd;
+ // 璁$畻宸灏戝皬鏃�
+ long hour = diff % nd / nh;
+ // 璁$畻宸灏戝垎閽�
+ long min = diff % nd % nh / nm;
+ // 璁$畻宸灏戠//杈撳嚭缁撴灉
+ // long sec = diff % nd % nh % nm / ns;
+ return day + "澶�" + hour + "灏忔椂" + min + "鍒嗛挓";
+ }
+
+ /**
+ * 澧炲姞 LocalDateTime ==> Date
+ */
+ public static Date toDate(LocalDateTime temporalAccessor)
+ {
+ ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
+ return Date.from(zdt.toInstant());
+ }
+
+ /**
+ * 澧炲姞 LocalDate ==> Date
+ */
+ public static Date toDate(LocalDate temporalAccessor)
+ {
+ LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
+ ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
+ return Date.from(zdt.toInstant());
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/util/GenUtils.java b/ycl-generator/src/main/java/com/ycl/generator/util/GenUtils.java
new file mode 100644
index 0000000..a923808
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/util/GenUtils.java
@@ -0,0 +1,258 @@
+package com.ycl.generator.util;
+
+import com.ycl.generator.config.GenConfig;
+import com.ycl.generator.domain.GenTable;
+import com.ycl.generator.domain.GenTableColumn;
+import constant.GenConstants;
+import org.apache.commons.lang3.RegExUtils;
+import utils.StringUtils;
+
+import java.util.Arrays;
+
+/**
+ * 浠g爜鐢熸垚鍣� 宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+public class GenUtils
+{
+ /**
+ * 鍒濆鍖栬〃淇℃伅
+ */
+ public static void initTable(GenTable genTable, String operName)
+ {
+ genTable.setClassName(convertClassName(genTable.getTableName()));
+ genTable.setPackageName(GenConfig.getPackageName());
+ genTable.setModuleName(getModuleName(GenConfig.getPackageName()));
+ genTable.setBusinessName(getBusinessName(genTable.getTableName()));
+ genTable.setFunctionName(replaceText(genTable.getTableComment()));
+ genTable.setFunctionAuthor(GenConfig.getAuthor());
+ genTable.setCreateBy(operName);
+ }
+
+ /**
+ * 鍒濆鍖栧垪灞炴�у瓧娈�
+ */
+ public static void initColumnField(GenTableColumn column, GenTable table)
+ {
+ String dataType = getDbType(column.getColumnType());
+ String columnName = column.getColumnName();
+ column.setTableId(table.getTableId());
+ column.setCreateBy(table.getCreateBy());
+ // 璁剧疆java瀛楁鍚�
+ column.setJavaField(StringUtils.toCamelCase(columnName));
+ // 璁剧疆榛樿绫诲瀷
+ column.setJavaType(GenConstants.TYPE_STRING);
+ column.setQueryType(GenConstants.QUERY_EQ);
+
+ if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType))
+ {
+ // 瀛楃涓查暱搴﹁秴杩�500璁剧疆涓烘枃鏈煙
+ Integer columnLength = getColumnLength(column.getColumnType());
+ String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
+ column.setHtmlType(htmlType);
+ }
+ else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType))
+ {
+ column.setJavaType(GenConstants.TYPE_DATE);
+ column.setHtmlType(GenConstants.HTML_DATETIME);
+ }
+ else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType))
+ {
+ column.setHtmlType(GenConstants.HTML_INPUT);
+
+ // 濡傛灉鏄诞鐐瑰瀷 缁熶竴鐢˙igDecimal
+ String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ",");
+ if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0)
+ {
+ column.setJavaType(GenConstants.TYPE_BIGDECIMAL);
+ }
+ // 濡傛灉鏄暣褰�
+ else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10)
+ {
+ column.setJavaType(GenConstants.TYPE_INTEGER);
+ }
+ // 闀挎暣褰�
+ else
+ {
+ column.setJavaType(GenConstants.TYPE_LONG);
+ }
+ }
+
+ // 鎻掑叆瀛楁锛堥粯璁ゆ墍鏈夊瓧娈甸兘闇�瑕佹彃鍏ワ級
+ column.setIsInsert(GenConstants.REQUIRE);
+
+ // 缂栬緫瀛楁
+ if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk())
+ {
+ column.setIsEdit(GenConstants.REQUIRE);
+ }
+ // 鍒楄〃瀛楁
+ if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk())
+ {
+ column.setIsList(GenConstants.REQUIRE);
+ }
+ // 鏌ヨ瀛楁
+ if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk())
+ {
+ column.setIsQuery(GenConstants.REQUIRE);
+ }
+
+ // 鏌ヨ瀛楁绫诲瀷
+ if (StringUtils.endsWithIgnoreCase(columnName, "name"))
+ {
+ column.setQueryType(GenConstants.QUERY_LIKE);
+ }
+ // 鐘舵�佸瓧娈佃缃崟閫夋
+ if (StringUtils.endsWithIgnoreCase(columnName, "status"))
+ {
+ column.setHtmlType(GenConstants.HTML_RADIO);
+ }
+ // 绫诲瀷&鎬у埆瀛楁璁剧疆涓嬫媺妗�
+ else if (StringUtils.endsWithIgnoreCase(columnName, "type")
+ || StringUtils.endsWithIgnoreCase(columnName, "sex"))
+ {
+ column.setHtmlType(GenConstants.HTML_SELECT);
+ }
+ // 鍥剧墖瀛楁璁剧疆鍥剧墖涓婁紶鎺т欢
+ else if (StringUtils.endsWithIgnoreCase(columnName, "image"))
+ {
+ column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD);
+ }
+ // 鏂囦欢瀛楁璁剧疆鏂囦欢涓婁紶鎺т欢
+ else if (StringUtils.endsWithIgnoreCase(columnName, "file"))
+ {
+ column.setHtmlType(GenConstants.HTML_FILE_UPLOAD);
+ }
+ // 鍐呭瀛楁璁剧疆瀵屾枃鏈帶浠�
+ else if (StringUtils.endsWithIgnoreCase(columnName, "content"))
+ {
+ column.setHtmlType(GenConstants.HTML_EDITOR);
+ }
+ }
+
+ /**
+ * 鏍¢獙鏁扮粍鏄惁鍖呭惈鎸囧畾鍊�
+ *
+ * @param arr 鏁扮粍
+ * @param targetValue 鍊�
+ * @return 鏄惁鍖呭惈
+ */
+ public static boolean arraysContains(String[] arr, String targetValue)
+ {
+ return Arrays.asList(arr).contains(targetValue);
+ }
+
+ /**
+ * 鑾峰彇妯″潡鍚�
+ *
+ * @param packageName 鍖呭悕
+ * @return 妯″潡鍚�
+ */
+ public static String getModuleName(String packageName)
+ {
+ int lastIndex = packageName.lastIndexOf(".");
+ int nameLength = packageName.length();
+ return StringUtils.substring(packageName, lastIndex + 1, nameLength);
+ }
+
+ /**
+ * 鑾峰彇涓氬姟鍚�
+ *
+ * @param tableName 琛ㄥ悕
+ * @return 涓氬姟鍚�
+ */
+ public static String getBusinessName(String tableName)
+ {
+ int lastIndex = tableName.lastIndexOf("_");
+ int nameLength = tableName.length();
+ return StringUtils.substring(tableName, lastIndex + 1, nameLength);
+ }
+
+ /**
+ * 琛ㄥ悕杞崲鎴怞ava绫诲悕
+ *
+ * @param tableName 琛ㄥ悕绉�
+ * @return 绫诲悕
+ */
+ public static String convertClassName(String tableName)
+ {
+ boolean autoRemovePre = GenConfig.getAutoRemovePre();
+ String tablePrefix = GenConfig.getTablePrefix();
+ if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix))
+ {
+ String[] searchList = StringUtils.split(tablePrefix, ",");
+ tableName = replaceFirst(tableName, searchList);
+ }
+ return StringUtils.convertToCamelCase(tableName);
+ }
+
+ /**
+ * 鎵归噺鏇挎崲鍓嶇紑
+ *
+ * @param replacementm 鏇挎崲鍊�
+ * @param searchList 鏇挎崲鍒楄〃
+ * @return
+ */
+ public static String replaceFirst(String replacementm, String[] searchList)
+ {
+ String text = replacementm;
+ for (String searchString : searchList)
+ {
+ if (replacementm.startsWith(searchString))
+ {
+ text = replacementm.replaceFirst(searchString, "");
+ break;
+ }
+ }
+ return text;
+ }
+
+ /**
+ * 鍏抽敭瀛楁浛鎹�
+ *
+ * @param text 闇�瑕佽鏇挎崲鐨勫悕瀛�
+ * @return 鏇挎崲鍚庣殑鍚嶅瓧
+ */
+ public static String replaceText(String text)
+ {
+ return RegExUtils.replaceAll(text, "(?:琛▅鑻ヤ緷)", "");
+ }
+
+ /**
+ * 鑾峰彇鏁版嵁搴撶被鍨嬪瓧娈�
+ *
+ * @param columnType 鍒楃被鍨�
+ * @return 鎴彇鍚庣殑鍒楃被鍨�
+ */
+ public static String getDbType(String columnType)
+ {
+ if (StringUtils.indexOf(columnType, "(") > 0)
+ {
+ return StringUtils.substringBefore(columnType, "(");
+ }
+ else
+ {
+ return columnType;
+ }
+ }
+
+ /**
+ * 鑾峰彇瀛楁闀垮害
+ *
+ * @param columnType 鍒楃被鍨�
+ * @return 鎴彇鍚庣殑鍒楃被鍨�
+ */
+ public static Integer getColumnLength(String columnType)
+ {
+ if (StringUtils.indexOf(columnType, "(") > 0)
+ {
+ String length = StringUtils.substringBetween(columnType, "(", ")");
+ return Integer.valueOf(length);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/util/PageUtils.java b/ycl-generator/src/main/java/com/ycl/generator/util/PageUtils.java
new file mode 100644
index 0000000..9b71898
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/util/PageUtils.java
@@ -0,0 +1,34 @@
+package com.ycl.generator.util;
+
+import com.github.pagehelper.PageHelper;
+import com.ycl.system.page.PageDomain;
+import com.ycl.system.page.TableSupport;
+
+/**
+ * 鍒嗛〉宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+public class PageUtils extends PageHelper
+{
+ /**
+ * 璁剧疆璇锋眰鍒嗛〉鏁版嵁
+ */
+ public static void startPage()
+ {
+ PageDomain pageDomain = TableSupport.buildPageRequest();
+ Integer pageNum = pageDomain.getPageNum();
+ Integer pageSize = pageDomain.getPageSize();
+ String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
+ Boolean reasonable = pageDomain.getReasonable();
+ PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
+ }
+
+ /**
+ * 娓呯悊鍒嗛〉鐨勭嚎绋嬪彉閲�
+ */
+ public static void clearPage()
+ {
+ PageHelper.clearPage();
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/util/SecurityUtils.java b/ycl-generator/src/main/java/com/ycl/generator/util/SecurityUtils.java
new file mode 100644
index 0000000..c2b3841
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/util/SecurityUtils.java
@@ -0,0 +1,181 @@
+package com.ycl.generator.util;
+
+
+import com.ycl.generator.exception.ServiceException;
+import com.ycl.system.entity.SysRole;
+import com.ycl.system.model.LoginUser;
+import constant.Constants;
+import constant.HttpStatus;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.util.PatternMatchUtils;
+import utils.StringUtils;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 瀹夊叏鏈嶅姟宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+public class SecurityUtils
+{
+
+ /**
+ * 鐢ㄦ埛ID
+ **/
+ public static Long getUserId()
+ {
+ try
+ {
+ return getLoginUser().getUserId();
+ }
+ catch (Exception e)
+ {
+ throw new ServiceException("鑾峰彇鐢ㄦ埛ID寮傚父", HttpStatus.UNAUTHORIZED);
+ }
+ }
+
+ /**
+ * 鑾峰彇閮ㄩ棬ID
+ **/
+ public static Long getDeptId()
+ {
+ try
+ {
+ return getLoginUser().getDeptId();
+ }
+ catch (Exception e)
+ {
+ throw new ServiceException("鑾峰彇閮ㄩ棬ID寮傚父", HttpStatus.UNAUTHORIZED);
+ }
+ }
+
+ /**
+ * 鑾峰彇鐢ㄦ埛璐︽埛
+ **/
+ public static String getUsername()
+ {
+ try
+ {
+ return getLoginUser().getUsername();
+ }
+ catch (Exception e)
+ {
+ throw new ServiceException("鑾峰彇鐢ㄦ埛璐︽埛寮傚父", HttpStatus.UNAUTHORIZED);
+ }
+ }
+
+ /**
+ * 鑾峰彇鐢ㄦ埛
+ **/
+ public static LoginUser getLoginUser()
+ {
+ try
+ {
+ return (LoginUser) getAuthentication().getPrincipal();
+ }
+ catch (Exception e)
+ {
+ throw new ServiceException("鑾峰彇鐢ㄦ埛淇℃伅寮傚父", HttpStatus.UNAUTHORIZED);
+ }
+ }
+
+ /**
+ * 鑾峰彇Authentication
+ */
+ public static Authentication getAuthentication()
+ {
+ return SecurityContextHolder.getContext().getAuthentication();
+ }
+
+ /**
+ * 鐢熸垚BCryptPasswordEncoder瀵嗙爜
+ *
+ * @param password 瀵嗙爜
+ * @return 鍔犲瘑瀛楃涓�
+ */
+ public static String encryptPassword(String password)
+ {
+ BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
+ return passwordEncoder.encode(password);
+ }
+
+ /**
+ * 鍒ゆ柇瀵嗙爜鏄惁鐩稿悓
+ *
+ * @param rawPassword 鐪熷疄瀵嗙爜
+ * @param encodedPassword 鍔犲瘑鍚庡瓧绗�
+ * @return 缁撴灉
+ */
+ public static boolean matchesPassword(String rawPassword, String encodedPassword)
+ {
+ BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
+ return passwordEncoder.matches(rawPassword, encodedPassword);
+ }
+
+ /**
+ * 鏄惁涓虹鐞嗗憳
+ *
+ * @param userId 鐢ㄦ埛ID
+ * @return 缁撴灉
+ */
+ public static boolean isAdmin(Long userId)
+ {
+ return userId != null && 1L == userId;
+ }
+
+ /**
+ * 楠岃瘉鐢ㄦ埛鏄惁鍏峰鏌愭潈闄�
+ *
+ * @param permission 鏉冮檺瀛楃涓�
+ * @return 鐢ㄦ埛鏄惁鍏峰鏌愭潈闄�
+ */
+ public static boolean hasPermi(String permission)
+ {
+ return hasPermi(getLoginUser().getPermissions(), permission);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁鍖呭惈鏉冮檺
+ *
+ * @param authorities 鏉冮檺鍒楄〃
+ * @param permission 鏉冮檺瀛楃涓�
+ * @return 鐢ㄦ埛鏄惁鍏峰鏌愭潈闄�
+ */
+ public static boolean hasPermi(Collection<String> authorities, String permission)
+ {
+ return authorities.stream().filter(StringUtils::hasText)
+ .anyMatch(x -> Constants.ALL_PERMISSION.equals(x) || PatternMatchUtils.simpleMatch(x, permission));
+ }
+
+ /**
+ * 楠岃瘉鐢ㄦ埛鏄惁鎷ユ湁鏌愪釜瑙掕壊
+ *
+ * @param role 瑙掕壊鏍囪瘑
+ * @return 鐢ㄦ埛鏄惁鍏峰鏌愯鑹�
+ */
+ public static boolean hasRole(String role)
+ {
+ List<SysRole> roleList = getLoginUser().getUser().getRoles();
+ Collection<String> roles = roleList.stream().map(SysRole::getRoleKey).collect(Collectors.toSet());
+ return hasRole(roles, role);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁鍖呭惈瑙掕壊
+ *
+ * @param roles 瑙掕壊鍒楄〃
+ * @param role 瑙掕壊
+ * @return 鐢ㄦ埛鏄惁鍏峰鏌愯鑹叉潈闄�
+ */
+ public static boolean hasRole(Collection<String> roles, String role)
+ {
+ return roles.stream().filter(StringUtils::hasText)
+ .anyMatch(x -> Constants.SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role));
+ }
+
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/util/SqlUtil.java b/ycl-generator/src/main/java/com/ycl/generator/util/SqlUtil.java
new file mode 100644
index 0000000..e1b9bef
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/util/SqlUtil.java
@@ -0,0 +1,70 @@
+package com.ycl.generator.util;
+
+import com.ycl.generator.exception.UtilException;
+import utils.StringUtils;
+
+/**
+ * sql鎿嶄綔宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+public class SqlUtil
+{
+ /**
+ * 瀹氫箟甯哥敤鐨� sql鍏抽敭瀛�
+ */
+ public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()";
+
+ /**
+ * 浠呮敮鎸佸瓧姣嶃�佹暟瀛椼�佷笅鍒掔嚎銆佺┖鏍笺�侀�楀彿銆佸皬鏁扮偣锛堟敮鎸佸涓瓧娈垫帓搴忥級
+ */
+ public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
+
+ /**
+ * 闄愬埗orderBy鏈�澶ч暱搴�
+ */
+ private static final int ORDER_BY_MAX_LENGTH = 500;
+
+ /**
+ * 妫�鏌ュ瓧绗︼紝闃叉娉ㄥ叆缁曡繃
+ */
+ public static String escapeOrderBySql(String value)
+ {
+ if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
+ {
+ throw new UtilException("鍙傛暟涓嶇鍚堣鑼冿紝涓嶈兘杩涜鏌ヨ");
+ }
+ if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
+ {
+ throw new UtilException("鍙傛暟宸茶秴杩囨渶澶ч檺鍒讹紝涓嶈兘杩涜鏌ヨ");
+ }
+ return value;
+ }
+
+ /**
+ * 楠岃瘉 order by 璇硶鏄惁绗﹀悎瑙勮寖
+ */
+ public static boolean isValidOrderBySql(String value)
+ {
+ return value.matches(SQL_PATTERN);
+ }
+
+ /**
+ * SQL鍏抽敭瀛楁鏌�
+ */
+ public static void filterKeyword(String value)
+ {
+ if (StringUtils.isEmpty(value))
+ {
+ return;
+ }
+ String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
+ for (String sqlKeyword : sqlKeywords)
+ {
+ if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
+ {
+ throw new UtilException("鍙傛暟瀛樺湪SQL娉ㄥ叆椋庨櫓");
+ }
+ }
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/util/VelocityInitializer.java b/ycl-generator/src/main/java/com/ycl/generator/util/VelocityInitializer.java
new file mode 100644
index 0000000..1653a6a
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/util/VelocityInitializer.java
@@ -0,0 +1,35 @@
+package com.ycl.generator.util;
+
+import constant.Constants;
+import org.apache.velocity.app.Velocity;
+
+import java.util.Properties;
+
+/**
+ * VelocityEngine宸ュ巶
+ *
+ * @author ruoyi
+ */
+public class VelocityInitializer
+{
+ /**
+ * 鍒濆鍖杤m鏂规硶
+ */
+ public static void initVelocity()
+ {
+ Properties p = new Properties();
+ try
+ {
+ // 鍔犺浇classpath鐩綍涓嬬殑vm鏂囦欢
+ p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+ // 瀹氫箟瀛楃闆�
+ p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8);
+ // 鍒濆鍖朧elocity寮曟搸锛屾寚瀹氶厤缃甈roperties
+ Velocity.init(p);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/ycl-generator/src/main/java/com/ycl/generator/util/VelocityUtils.java b/ycl-generator/src/main/java/com/ycl/generator/util/VelocityUtils.java
new file mode 100644
index 0000000..8ba1ad6
--- /dev/null
+++ b/ycl-generator/src/main/java/com/ycl/generator/util/VelocityUtils.java
@@ -0,0 +1,402 @@
+package com.ycl.generator.util;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ycl.generator.domain.GenTable;
+import com.ycl.generator.domain.GenTableColumn;
+import constant.GenConstants;
+import org.apache.velocity.VelocityContext;
+import utils.StringUtils;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 妯℃澘澶勭悊宸ュ叿绫�
+ *
+ * @author ruoyi
+ */
+public class VelocityUtils
+{
+ /** 椤圭洰绌洪棿璺緞 */
+ private static final String PROJECT_PATH = "main/java";
+
+ /** mybatis绌洪棿璺緞 */
+ private static final String MYBATIS_PATH = "main/resources/mapper";
+
+ /** 榛樿涓婄骇鑿滃崟锛岀郴缁熷伐鍏� */
+ private static final String DEFAULT_PARENT_MENU_ID = "3";
+
+ /**
+ * 璁剧疆妯℃澘鍙橀噺淇℃伅
+ *
+ * @return 妯℃澘鍒楄〃
+ */
+ public static VelocityContext prepareContext(GenTable genTable)
+ {
+ String moduleName = genTable.getModuleName();
+ String businessName = genTable.getBusinessName();
+ String packageName = genTable.getPackageName();
+ String tplCategory = genTable.getTplCategory();
+ String functionName = genTable.getFunctionName();
+
+ VelocityContext velocityContext = new VelocityContext();
+ velocityContext.put("tplCategory", genTable.getTplCategory());
+ velocityContext.put("tableName", genTable.getTableName());
+ velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "銆愯濉啓鍔熻兘鍚嶇О銆�");
+ velocityContext.put("ClassName", genTable.getClassName());
+ velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName()));
+ velocityContext.put("moduleName", genTable.getModuleName());
+ velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName()));
+ velocityContext.put("businessName", genTable.getBusinessName());
+ velocityContext.put("basePackage", getPackagePrefix(packageName));
+ velocityContext.put("packageName", packageName);
+ velocityContext.put("author", genTable.getFunctionAuthor());
+ velocityContext.put("datetime", DateUtils.getDate());
+ velocityContext.put("pkColumn", genTable.getPkColumn());
+ velocityContext.put("importList", getImportList(genTable));
+ velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
+ velocityContext.put("columns", genTable.getColumns());
+ velocityContext.put("table", genTable);
+ velocityContext.put("dicts", getDicts(genTable));
+ setMenuVelocityContext(velocityContext, genTable);
+ if (GenConstants.TPL_TREE.equals(tplCategory))
+ {
+ setTreeVelocityContext(velocityContext, genTable);
+ }
+ if (GenConstants.TPL_SUB.equals(tplCategory))
+ {
+ setSubVelocityContext(velocityContext, genTable);
+ }
+ return velocityContext;
+ }
+
+ public static void setMenuVelocityContext(VelocityContext context, GenTable genTable)
+ {
+ String options = genTable.getOptions();
+ JSONObject paramsObj = JSON.parseObject(options);
+ String parentMenuId = getParentMenuId(paramsObj);
+ context.put("parentMenuId", parentMenuId);
+ }
+
+ public static void setTreeVelocityContext(VelocityContext context, GenTable genTable)
+ {
+ String options = genTable.getOptions();
+ JSONObject paramsObj = JSON.parseObject(options);
+ String treeCode = getTreecode(paramsObj);
+ String treeParentCode = getTreeParentCode(paramsObj);
+ String treeName = getTreeName(paramsObj);
+
+ context.put("treeCode", treeCode);
+ context.put("treeParentCode", treeParentCode);
+ context.put("treeName", treeName);
+ context.put("expandColumn", getExpandColumn(genTable));
+ if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE))
+ {
+ context.put("tree_parent_code", paramsObj.getString(GenConstants.TREE_PARENT_CODE));
+ }
+ if (paramsObj.containsKey(GenConstants.TREE_NAME))
+ {
+ context.put("tree_name", paramsObj.getString(GenConstants.TREE_NAME));
+ }
+ }
+
+ public static void setSubVelocityContext(VelocityContext context, GenTable genTable)
+ {
+ GenTable subTable = genTable.getSubTable();
+ String subTableName = genTable.getSubTableName();
+ String subTableFkName = genTable.getSubTableFkName();
+ String subClassName = genTable.getSubTable().getClassName();
+ String subTableFkClassName = StringUtils.convertToCamelCase(subTableFkName);
+
+ context.put("subTable", subTable);
+ context.put("subTableName", subTableName);
+ context.put("subTableFkName", subTableFkName);
+ context.put("subTableFkClassName", subTableFkClassName);
+ context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName));
+ context.put("subClassName", subClassName);
+ context.put("subclassName", StringUtils.uncapitalize(subClassName));
+ context.put("subImportList", getImportList(genTable.getSubTable()));
+ }
+
+ /**
+ * 鑾峰彇妯℃澘淇℃伅
+ *
+ * @return 妯℃澘鍒楄〃
+ */
+ public static List<String> getTemplateList(String tplCategory)
+ {
+ List<String> templates = new ArrayList<String>();
+ templates.add("vm/java/domain.java.vm");
+ templates.add("vm/java/mapper.java.vm");
+ templates.add("vm/java/service.java.vm");
+ templates.add("vm/java/serviceImpl.java.vm");
+ templates.add("vm/java/controller.java.vm");
+ templates.add("vm/xml/mapper.xml.vm");
+ templates.add("vm/sql/sql.vm");
+ templates.add("vm/js/api.js.vm");
+ if (GenConstants.TPL_CRUD.equals(tplCategory))
+ {
+ templates.add("vm/vue/index.vue.vm");
+ }
+ else if (GenConstants.TPL_TREE.equals(tplCategory))
+ {
+ templates.add("vm/vue/index-tree.vue.vm");
+ }
+ else if (GenConstants.TPL_SUB.equals(tplCategory))
+ {
+ templates.add("vm/vue/index.vue.vm");
+ templates.add("vm/java/sub-domain.java.vm");
+ }
+ return templates;
+ }
+
+ /**
+ * 鑾峰彇鏂囦欢鍚�
+ */
+ public static String getFileName(String template, GenTable genTable)
+ {
+ // 鏂囦欢鍚嶇О
+ String fileName = "";
+ // 鍖呰矾寰�
+ String packageName = genTable.getPackageName();
+ // 妯″潡鍚�
+ String moduleName = genTable.getModuleName();
+ // 澶у啓绫诲悕
+ String className = genTable.getClassName();
+ // 涓氬姟鍚嶇О
+ String businessName = genTable.getBusinessName();
+
+ String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/");
+ String mybatisPath = MYBATIS_PATH + "/" + moduleName;
+ String vuePath = "vue";
+
+ if (template.contains("domain.java.vm"))
+ {
+ fileName = StringUtils.format("{}/domain/{}.java", javaPath, className);
+ }
+ if (template.contains("sub-domain.java.vm") && StringUtils.equals(GenConstants.TPL_SUB, genTable.getTplCategory()))
+ {
+ fileName = StringUtils.format("{}/domain/{}.java", javaPath, genTable.getSubTable().getClassName());
+ }
+ else if (template.contains("mapper.java.vm"))
+ {
+ fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className);
+ }
+ else if (template.contains("service.java.vm"))
+ {
+ fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className);
+ }
+ else if (template.contains("serviceImpl.java.vm"))
+ {
+ fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className);
+ }
+ else if (template.contains("controller.java.vm"))
+ {
+ fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className);
+ }
+ else if (template.contains("mapper.xml.vm"))
+ {
+ fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className);
+ }
+ else if (template.contains("sql.vm"))
+ {
+ fileName = businessName + "Menu.sql";
+ }
+ else if (template.contains("api.js.vm"))
+ {
+ fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName);
+ }
+ else if (template.contains("index.vue.vm"))
+ {
+ fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
+ }
+ else if (template.contains("index-tree.vue.vm"))
+ {
+ fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName);
+ }
+ return fileName;
+ }
+
+ /**
+ * 鑾峰彇鍖呭墠缂�
+ *
+ * @param packageName 鍖呭悕绉�
+ * @return 鍖呭墠缂�鍚嶇О
+ */
+ public static String getPackagePrefix(String packageName)
+ {
+ int lastIndex = packageName.lastIndexOf(".");
+ return StringUtils.substring(packageName, 0, lastIndex);
+ }
+
+ /**
+ * 鏍规嵁鍒楃被鍨嬭幏鍙栧鍏ュ寘
+ *
+ * @param genTable 涓氬姟琛ㄥ璞�
+ * @return 杩斿洖闇�瑕佸鍏ョ殑鍖呭垪琛�
+ */
+ public static HashSet<String> getImportList(GenTable genTable)
+ {
+ List<GenTableColumn> columns = genTable.getColumns();
+ GenTable subGenTable = genTable.getSubTable();
+ HashSet<String> importList = new HashSet<String>();
+ if (StringUtils.isNotNull(subGenTable))
+ {
+ importList.add("java.util.List");
+ }
+ for (GenTableColumn column : columns)
+ {
+ if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType()))
+ {
+ importList.add("java.util.Date");
+ importList.add("com.fasterxml.jackson.annotation.JsonFormat");
+ }
+ else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType()))
+ {
+ importList.add("java.math.BigDecimal");
+ }
+ }
+ return importList;
+ }
+
+ /**
+ * 鏍规嵁鍒楃被鍨嬭幏鍙栧瓧鍏哥粍
+ *
+ * @param genTable 涓氬姟琛ㄥ璞�
+ * @return 杩斿洖瀛楀吀缁�
+ */
+ public static String getDicts(GenTable genTable)
+ {
+ List<GenTableColumn> columns = genTable.getColumns();
+ Set<String> dicts = new HashSet<String>();
+ addDicts(dicts, columns);
+ if (StringUtils.isNotNull(genTable.getSubTable()))
+ {
+ List<GenTableColumn> subColumns = genTable.getSubTable().getColumns();
+ addDicts(dicts, subColumns);
+ }
+ return StringUtils.join(dicts, ", ");
+ }
+
+ /**
+ * 娣诲姞瀛楀吀鍒楄〃
+ *
+ * @param dicts 瀛楀吀鍒楄〃
+ * @param columns 鍒楅泦鍚�
+ */
+ public static void addDicts(Set<String> dicts, List<GenTableColumn> columns)
+ {
+ for (GenTableColumn column : columns)
+ {
+ if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
+ column.getHtmlType(),
+ new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX }))
+ {
+ dicts.add("'" + column.getDictType() + "'");
+ }
+ }
+ }
+
+ /**
+ * 鑾峰彇鏉冮檺鍓嶇紑
+ *
+ * @param moduleName 妯″潡鍚嶇О
+ * @param businessName 涓氬姟鍚嶇О
+ * @return 杩斿洖鏉冮檺鍓嶇紑
+ */
+ public static String getPermissionPrefix(String moduleName, String businessName)
+ {
+ return StringUtils.format("{}:{}", moduleName, businessName);
+ }
+
+ /**
+ * 鑾峰彇涓婄骇鑿滃崟ID瀛楁
+ *
+ * @param paramsObj 鐢熸垚鍏朵粬閫夐」
+ * @return 涓婄骇鑿滃崟ID瀛楁
+ */
+ public static String getParentMenuId(JSONObject paramsObj)
+ {
+ if (StringUtils.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID)
+ && StringUtils.isNotEmpty(paramsObj.getString(GenConstants.PARENT_MENU_ID)))
+ {
+ return paramsObj.getString(GenConstants.PARENT_MENU_ID);
+ }
+ return DEFAULT_PARENT_MENU_ID;
+ }
+
+ /**
+ * 鑾峰彇鏍戠紪鐮�
+ *
+ * @param paramsObj 鐢熸垚鍏朵粬閫夐」
+ * @return 鏍戠紪鐮�
+ */
+ public static String getTreecode(JSONObject paramsObj)
+ {
+ if (paramsObj.containsKey(GenConstants.TREE_CODE))
+ {
+ return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE));
+ }
+ return StringUtils.EMPTY;
+ }
+
+ /**
+ * 鑾峰彇鏍戠埗缂栫爜
+ *
+ * @param paramsObj 鐢熸垚鍏朵粬閫夐」
+ * @return 鏍戠埗缂栫爜
+ */
+ public static String getTreeParentCode(JSONObject paramsObj)
+ {
+ if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE))
+ {
+ return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE));
+ }
+ return StringUtils.EMPTY;
+ }
+
+ /**
+ * 鑾峰彇鏍戝悕绉�
+ *
+ * @param paramsObj 鐢熸垚鍏朵粬閫夐」
+ * @return 鏍戝悕绉�
+ */
+ public static String getTreeName(JSONObject paramsObj)
+ {
+ if (paramsObj.containsKey(GenConstants.TREE_NAME))
+ {
+ return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME));
+ }
+ return StringUtils.EMPTY;
+ }
+
+ /**
+ * 鑾峰彇闇�瑕佸湪鍝竴鍒椾笂闈㈡樉绀哄睍寮�鎸夐挳
+ *
+ * @param genTable 涓氬姟琛ㄥ璞�
+ * @return 灞曞紑鎸夐挳鍒楀簭鍙�
+ */
+ public static int getExpandColumn(GenTable genTable)
+ {
+ String options = genTable.getOptions();
+ JSONObject paramsObj = JSON.parseObject(options);
+ String treeName = paramsObj.getString(GenConstants.TREE_NAME);
+ int num = 0;
+ for (GenTableColumn column : genTable.getColumns())
+ {
+ if (column.isList())
+ {
+ num++;
+ String columnName = column.getColumnName();
+ if (columnName.equals(treeName))
+ {
+ break;
+ }
+ }
+ }
+ return num;
+ }
+}
diff --git a/ycl-generator/src/main/resources/generator.yml b/ycl-generator/src/main/resources/generator.yml
new file mode 100644
index 0000000..27511ce
--- /dev/null
+++ b/ycl-generator/src/main/resources/generator.yml
@@ -0,0 +1,10 @@
+# 浠g爜鐢熸垚
+gen:
+ # 浣滆��
+ author: ruoyi
+ # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+ packageName: com.ycl.system
+ # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸false
+ autoRemovePre: false
+ # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+ tablePrefix: sys_
\ No newline at end of file
diff --git a/ycl-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml b/ycl-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml
new file mode 100644
index 0000000..9963014
--- /dev/null
+++ b/ycl-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ycl.generator.mapper.GenTableColumnMapper">
+
+ <resultMap type="GenTableColumn" id="GenTableColumnResult">
+ <id property="columnId" column="column_id" />
+ <result property="tableId" column="table_id" />
+ <result property="columnName" column="column_name" />
+ <result property="columnComment" column="column_comment" />
+ <result property="columnType" column="column_type" />
+ <result property="javaType" column="java_type" />
+ <result property="javaField" column="java_field" />
+ <result property="isPk" column="is_pk" />
+ <result property="isIncrement" column="is_increment" />
+ <result property="isRequired" column="is_required" />
+ <result property="isInsert" column="is_insert" />
+ <result property="isEdit" column="is_edit" />
+ <result property="isList" column="is_list" />
+ <result property="isQuery" column="is_query" />
+ <result property="queryType" column="query_type" />
+ <result property="htmlType" column="html_type" />
+ <result property="dictType" column="dict_type" />
+ <result property="sort" column="sort" />
+ <result property="createBy" column="create_by" />
+ <result property="createTime" column="create_time" />
+ <result property="updateBy" column="update_by" />
+ <result property="updateTime" column="update_time" />
+ </resultMap>
+
+ <sql id="selectGenTableColumnVo">
+ select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column
+ </sql>
+
+ <select id="selectGenTableColumnListByTableId" parameterType="Long" resultMap="GenTableColumnResult">
+ <include refid="selectGenTableColumnVo"/>
+ where table_id = #{tableId}
+ order by sort
+ </select>
+
+ <select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
+ select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type
+ from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
+ order by ordinal_position
+ </select>
+
+ <insert id="insertGenTableColumn" parameterType="GenTableColumn" useGeneratedKeys="true" keyProperty="columnId">
+ insert into gen_table_column (
+ <if test="tableId != null and tableId != ''">table_id,</if>
+ <if test="columnName != null and columnName != ''">column_name,</if>
+ <if test="columnComment != null and columnComment != ''">column_comment,</if>
+ <if test="columnType != null and columnType != ''">column_type,</if>
+ <if test="javaType != null and javaType != ''">java_type,</if>
+ <if test="javaField != null and javaField != ''">java_field,</if>
+ <if test="isPk != null and isPk != ''">is_pk,</if>
+ <if test="isIncrement != null and isIncrement != ''">is_increment,</if>
+ <if test="isRequired != null and isRequired != ''">is_required,</if>
+ <if test="isInsert != null and isInsert != ''">is_insert,</if>
+ <if test="isEdit != null and isEdit != ''">is_edit,</if>
+ <if test="isList != null and isList != ''">is_list,</if>
+ <if test="isQuery != null and isQuery != ''">is_query,</if>
+ <if test="queryType != null and queryType != ''">query_type,</if>
+ <if test="htmlType != null and htmlType != ''">html_type,</if>
+ <if test="dictType != null and dictType != ''">dict_type,</if>
+ <if test="sort != null">sort,</if>
+ <if test="createBy != null and createBy != ''">create_by,</if>
+ create_time
+ )values(
+ <if test="tableId != null and tableId != ''">#{tableId},</if>
+ <if test="columnName != null and columnName != ''">#{columnName},</if>
+ <if test="columnComment != null and columnComment != ''">#{columnComment},</if>
+ <if test="columnType != null and columnType != ''">#{columnType},</if>
+ <if test="javaType != null and javaType != ''">#{javaType},</if>
+ <if test="javaField != null and javaField != ''">#{javaField},</if>
+ <if test="isPk != null and isPk != ''">#{isPk},</if>
+ <if test="isIncrement != null and isIncrement != ''">#{isIncrement},</if>
+ <if test="isRequired != null and isRequired != ''">#{isRequired},</if>
+ <if test="isInsert != null and isInsert != ''">#{isInsert},</if>
+ <if test="isEdit != null and isEdit != ''">#{isEdit},</if>
+ <if test="isList != null and isList != ''">#{isList},</if>
+ <if test="isQuery != null and isQuery != ''">#{isQuery},</if>
+ <if test="queryType != null and queryType != ''">#{queryType},</if>
+ <if test="htmlType != null and htmlType != ''">#{htmlType},</if>
+ <if test="dictType != null and dictType != ''">#{dictType},</if>
+ <if test="sort != null">#{sort},</if>
+ <if test="createBy != null and createBy != ''">#{createBy},</if>
+ sysdate()
+ )
+ </insert>
+
+ <update id="updateGenTableColumn" parameterType="GenTableColumn">
+ update gen_table_column
+ <set>
+ <if test="columnComment != null">column_comment = #{columnComment},</if>
+ <if test="javaType != null">java_type = #{javaType},</if>
+ <if test="javaField != null">java_field = #{javaField},</if>
+ <if test="isInsert != null">is_insert = #{isInsert},</if>
+ <if test="isEdit != null">is_edit = #{isEdit},</if>
+ <if test="isList != null">is_list = #{isList},</if>
+ <if test="isQuery != null">is_query = #{isQuery},</if>
+ <if test="isRequired != null">is_required = #{isRequired},</if>
+ <if test="queryType != null">query_type = #{queryType},</if>
+ <if test="htmlType != null">html_type = #{htmlType},</if>
+ <if test="dictType != null">dict_type = #{dictType},</if>
+ <if test="sort != null">sort = #{sort},</if>
+ <if test="updateBy != null">update_by = #{updateBy},</if>
+ update_time = sysdate()
+ </set>
+ where column_id = #{columnId}
+ </update>
+
+ <delete id="deleteGenTableColumnByIds" parameterType="Long">
+ delete from gen_table_column where table_id in
+ <foreach collection="array" item="tableId" open="(" separator="," close=")">
+ #{tableId}
+ </foreach>
+ </delete>
+
+ <delete id="deleteGenTableColumns">
+ delete from gen_table_column where column_id in
+ <foreach collection="list" item="item" open="(" separator="," close=")">
+ #{item.columnId}
+ </foreach>
+ </delete>
+
+</mapper>
\ No newline at end of file
diff --git a/ycl-generator/src/main/resources/mapper/generator/GenTableMapper.xml b/ycl-generator/src/main/resources/mapper/generator/GenTableMapper.xml
new file mode 100644
index 0000000..6edb0c7
--- /dev/null
+++ b/ycl-generator/src/main/resources/mapper/generator/GenTableMapper.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ycl.generator.mapper.GenTableMapper">
+
+ <resultMap type="GenTable" id="GenTableResult">
+ <id property="tableId" column="table_id" />
+ <result property="tableName" column="table_name" />
+ <result property="tableComment" column="table_comment" />
+ <result property="subTableName" column="sub_table_name" />
+ <result property="subTableFkName" column="sub_table_fk_name" />
+ <result property="className" column="class_name" />
+ <result property="tplCategory" column="tpl_category" />
+ <result property="packageName" column="package_name" />
+ <result property="moduleName" column="module_name" />
+ <result property="businessName" column="business_name" />
+ <result property="functionName" column="function_name" />
+ <result property="functionAuthor" column="function_author" />
+ <result property="genType" column="gen_type" />
+ <result property="genPath" column="gen_path" />
+ <result property="options" column="options" />
+ <result property="createBy" column="create_by" />
+ <result property="createTime" column="create_time" />
+ <result property="updateBy" column="update_by" />
+ <result property="updateTime" column="update_time" />
+ <result property="remark" column="remark" />
+ <collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" />
+ </resultMap>
+
+ <resultMap type="GenTableColumn" id="GenTableColumnResult">
+ <id property="columnId" column="column_id" />
+ <result property="tableId" column="table_id" />
+ <result property="columnName" column="column_name" />
+ <result property="columnComment" column="column_comment" />
+ <result property="columnType" column="column_type" />
+ <result property="javaType" column="java_type" />
+ <result property="javaField" column="java_field" />
+ <result property="isPk" column="is_pk" />
+ <result property="isIncrement" column="is_increment" />
+ <result property="isRequired" column="is_required" />
+ <result property="isInsert" column="is_insert" />
+ <result property="isEdit" column="is_edit" />
+ <result property="isList" column="is_list" />
+ <result property="isQuery" column="is_query" />
+ <result property="queryType" column="query_type" />
+ <result property="htmlType" column="html_type" />
+ <result property="dictType" column="dict_type" />
+ <result property="sort" column="sort" />
+ <result property="createBy" column="create_by" />
+ <result property="createTime" column="create_time" />
+ <result property="updateBy" column="update_by" />
+ <result property="updateTime" column="update_time" />
+ </resultMap>
+
+ <sql id="selectGenTableVo">
+ select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table
+ </sql>
+
+ <select id="selectGenTableList" parameterType="GenTable" resultMap="GenTableResult">
+ <include refid="selectGenTableVo"/>
+ <where>
+ <if test="tableName != null and tableName != ''">
+ AND lower(table_name) like lower(concat('%', #{tableName}, '%'))
+ </if>
+ <if test="tableComment != null and tableComment != ''">
+ AND lower(table_comment) like lower(concat('%', #{tableComment}, '%'))
+ </if>
+ <if test="params.beginTime != null and params.beginTime != ''"><!-- 寮�濮嬫椂闂存绱� -->
+ AND date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
+ </if>
+ <if test="params.endTime != null and params.endTime != ''"><!-- 缁撴潫鏃堕棿妫�绱� -->
+ AND date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
+ </if>
+ </where>
+ </select>
+
+ <select id="selectDbTableList" parameterType="GenTable" resultMap="GenTableResult">
+ select table_name, table_comment, create_time, update_time from information_schema.tables
+ where table_schema = (select database())
+ AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%'
+ AND table_name NOT IN (select table_name from gen_table)
+ <if test="tableName != null and tableName != ''">
+ AND lower(table_name) like lower(concat('%', #{tableName}, '%'))
+ </if>
+ <if test="tableComment != null and tableComment != ''">
+ AND lower(table_comment) like lower(concat('%', #{tableComment}, '%'))
+ </if>
+ <if test="params.beginTime != null and params.beginTime != ''"><!-- 寮�濮嬫椂闂存绱� -->
+ AND date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
+ </if>
+ <if test="params.endTime != null and params.endTime != ''"><!-- 缁撴潫鏃堕棿妫�绱� -->
+ AND date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
+ </if>
+ order by create_time desc
+ </select>
+
+ <select id="selectDbTableListByNames" resultMap="GenTableResult">
+ select table_name, table_comment, create_time, update_time from information_schema.tables
+ where table_name NOT LIKE 'qrtz_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database())
+ and table_name in
+ <foreach collection="array" item="name" open="(" separator="," close=")">
+ #{name}
+ </foreach>
+ </select>
+
+ <select id="selectTableByName" parameterType="String" resultMap="GenTableResult">
+ select table_name, table_comment, create_time, update_time from information_schema.tables
+ where table_comment <![CDATA[ <> ]]> '' and table_schema = (select database())
+ and table_name = #{tableName}
+ </select>
+
+ <select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult">
+ SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
+ c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
+ FROM gen_table t
+ LEFT JOIN gen_table_column c ON t.table_id = c.table_id
+ where t.table_id = #{tableId} order by c.sort
+ </select>
+
+ <select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult">
+ SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
+ c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
+ FROM gen_table t
+ LEFT JOIN gen_table_column c ON t.table_id = c.table_id
+ where t.table_name = #{tableName} order by c.sort
+ </select>
+
+ <select id="selectGenTableAll" parameterType="String" resultMap="GenTableResult">
+ SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark,
+ c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
+ FROM gen_table t
+ LEFT JOIN gen_table_column c ON t.table_id = c.table_id
+ order by c.sort
+ </select>
+
+ <insert id="insertGenTable" parameterType="GenTable" useGeneratedKeys="true" keyProperty="tableId">
+ insert into gen_table (
+ <if test="tableName != null">table_name,</if>
+ <if test="tableComment != null and tableComment != ''">table_comment,</if>
+ <if test="className != null and className != ''">class_name,</if>
+ <if test="tplCategory != null and tplCategory != ''">tpl_category,</if>
+ <if test="packageName != null and packageName != ''">package_name,</if>
+ <if test="moduleName != null and moduleName != ''">module_name,</if>
+ <if test="businessName != null and businessName != ''">business_name,</if>
+ <if test="functionName != null and functionName != ''">function_name,</if>
+ <if test="functionAuthor != null and functionAuthor != ''">function_author,</if>
+ <if test="genType != null and genType != ''">gen_type,</if>
+ <if test="genPath != null and genPath != ''">gen_path,</if>
+ <if test="remark != null and remark != ''">remark,</if>
+ <if test="createBy != null and createBy != ''">create_by,</if>
+ create_time
+ )values(
+ <if test="tableName != null">#{tableName},</if>
+ <if test="tableComment != null and tableComment != ''">#{tableComment},</if>
+ <if test="className != null and className != ''">#{className},</if>
+ <if test="tplCategory != null and tplCategory != ''">#{tplCategory},</if>
+ <if test="packageName != null and packageName != ''">#{packageName},</if>
+ <if test="moduleName != null and moduleName != ''">#{moduleName},</if>
+ <if test="businessName != null and businessName != ''">#{businessName},</if>
+ <if test="functionName != null and functionName != ''">#{functionName},</if>
+ <if test="functionAuthor != null and functionAuthor != ''">#{functionAuthor},</if>
+ <if test="genType != null and genType != ''">#{genType},</if>
+ <if test="genPath != null and genPath != ''">#{genPath},</if>
+ <if test="remark != null and remark != ''">#{remark},</if>
+ <if test="createBy != null and createBy != ''">#{createBy},</if>
+ sysdate()
+ )
+ </insert>
+
+ <update id="updateGenTable" parameterType="GenTable">
+ update gen_table
+ <set>
+ <if test="tableName != null">table_name = #{tableName},</if>
+ <if test="tableComment != null and tableComment != ''">table_comment = #{tableComment},</if>
+ <if test="subTableName != null">sub_table_name = #{subTableName},</if>
+ <if test="subTableFkName != null">sub_table_fk_name = #{subTableFkName},</if>
+ <if test="className != null and className != ''">class_name = #{className},</if>
+ <if test="functionAuthor != null and functionAuthor != ''">function_author = #{functionAuthor},</if>
+ <if test="genType != null and genType != ''">gen_type = #{genType},</if>
+ <if test="genPath != null and genPath != ''">gen_path = #{genPath},</if>
+ <if test="tplCategory != null and tplCategory != ''">tpl_category = #{tplCategory},</if>
+ <if test="packageName != null and packageName != ''">package_name = #{packageName},</if>
+ <if test="moduleName != null and moduleName != ''">module_name = #{moduleName},</if>
+ <if test="businessName != null and businessName != ''">business_name = #{businessName},</if>
+ <if test="functionName != null and functionName != ''">function_name = #{functionName},</if>
+ <if test="options != null and options != ''">options = #{options},</if>
+ <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
+ <if test="remark != null">remark = #{remark},</if>
+ update_time = sysdate()
+ </set>
+ where table_id = #{tableId}
+ </update>
+
+ <delete id="deleteGenTableByIds" parameterType="Long">
+ delete from gen_table where table_id in
+ <foreach collection="array" item="tableId" open="(" separator="," close=")">
+ #{tableId}
+ </foreach>
+ </delete>
+
+</mapper>
\ No newline at end of file
diff --git a/ycl-generator/src/main/resources/templates/controller.java.ftl b/ycl-generator/src/main/resources/templates/controller.java.ftl
deleted file mode 100644
index c420637..0000000
--- a/ycl-generator/src/main/resources/templates/controller.java.ftl
+++ /dev/null
@@ -1,44 +0,0 @@
-package ${package.Controller};
-
-import org.springframework.web.bind.annotation.RequestMapping;
-<#if restControllerStyle>
-import org.springframework.web.bind.annotation.RestController;
-<#else>
-import org.springframework.stereotype.Controller;
-</#if>
-<#if superControllerClassPackage??>
-import ${superControllerClassPackage};
-</#if>
-import ${package.Service}.${table.serviceName};
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * <p>
- * ${table.comment!} 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author ${author}
- */
-@Slf4j
-<#if restControllerStyle>
-@RestController
-<#else>
-@Controller
-</#if>
-<#if kotlin>
-class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
-<#else>
-<#if superControllerClass??>
-public class ${table.controllerName} extends ${superControllerClass} {
-<#else>
-@RequestMapping("${entity?uncap_first}")
-public class ${table.controllerName} {
-</#if>
-
- @Autowired
- private ${table.serviceName} ${table.serviceName?uncap_first};
-}
-</#if>
diff --git a/ycl-generator/src/main/resources/templates/default/controller.btl b/ycl-generator/src/main/resources/templates/default/controller.btl
deleted file mode 100644
index a7064ca..0000000
--- a/ycl-generator/src/main/resources/templates/default/controller.btl
+++ /dev/null
@@ -1,37 +0,0 @@
-package ${entity.controllerPackage};
-
-import cn.exrick.xboot.base.XbootBaseController;
-import cn.exrick.xboot.common.utils.PageUtil;
-import cn.exrick.xboot.common.utils.ResultUtil;
-import cn.exrick.xboot.common.vo.PageVo;
-import cn.exrick.xboot.common.vo.Result;
-import ${entity.entityPackage}.${entity.className};
-import ${entity.servicePackage}.${entity.className}Service;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.transaction.annotation.Transactional;
-
-
-/**
- * @author ${entity.author}
- */
-@Slf4j
-@RestController
-@Api(description = "${entity.description}绠$悊鎺ュ彛")
-@RequestMapping("/xboot/${entity.classNameLowerCase}")
-@Transactional
-public class ${entity.className}Controller extends XbootBaseController<${entity.className}, ${entity.primaryKeyType}>{
-
- @Autowired
- private ${entity.className}Service ${entity.classNameLowerCase}Service;
-
- @Override
- public ${entity.className}Service getService() {
- return ${entity.classNameLowerCase}Service;
- }
-
-}
diff --git a/ycl-generator/src/main/resources/templates/default/controller.java.btl b/ycl-generator/src/main/resources/templates/default/controller.java.btl
deleted file mode 100644
index 92b5afa..0000000
--- a/ycl-generator/src/main/resources/templates/default/controller.java.btl
+++ /dev/null
@@ -1,39 +0,0 @@
-package ${package.Controller};
-
-
-import org.springframework.web.bind.annotation.RequestMapping;
-
-<% if(restControllerStyle){ %>
-import org.springframework.web.bind.annotation.RestController;
-<% }else{ %>
-import org.springframework.stereotype.Controller;
-<% } %>
-<% if(isNotEmpty(superControllerClassPackage)){ %>
-import ${superControllerClassPackage};
-<% } %>
-
-/**
- * <p>
- * ${table.comment!} 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-<% if(restControllerStyle){ %>
-@RestController
-<% }else{ %>
-@Controller
-<% } %>
-@RequestMapping("<% if(isNotEmpty(package.ModuleName)){ %>/${package.ModuleName}<% } %>/<% if(isNotEmpty(controllerMappingHyphenStyle)){ %>${controllerMappingHyphen}<% }else{ %>${table.entityPath}<% } %>")
-<% if(kotlin){ %>
-class ${table.controllerName}<% if(isNotEmpty(superControllerClass)){ %> : ${superControllerClass}()<% } %>
-<% }else{ %>
- <% if(isNotEmpty(superControllerClass)){ %>
-public class ${table.controllerName} extends ${superControllerClass} {
- <% }else{ %>
-public class ${table.controllerName} {
- <% } %>
-
-}
-<% } %>
diff --git a/ycl-generator/src/main/resources/templates/default/controller.java.ftl b/ycl-generator/src/main/resources/templates/default/controller.java.ftl
deleted file mode 100644
index 69a9f81..0000000
--- a/ycl-generator/src/main/resources/templates/default/controller.java.ftl
+++ /dev/null
@@ -1,39 +0,0 @@
-package ${package.Controller};
-
-
-import org.springframework.web.bind.annotation.RequestMapping;
-
-<#if restControllerStyle>
-import org.springframework.web.bind.annotation.RestController;
-<#else>
-import org.springframework.stereotype.Controller;
-</#if>
-<#if superControllerClassPackage??>
-import ${superControllerClassPackage};
-</#if>
-
-/**
- * <p>
- * ${table.comment!} 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-<#if restControllerStyle>
-@RestController
-<#else>
-@Controller
-</#if>
-@RequestMapping("<#if package.ModuleName??>/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
-<#if kotlin>
-class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
-<#else>
-<#if superControllerClass??>
-public class ${table.controllerName} extends ${superControllerClass} {
-<#else>
-public class ${table.controllerName} {
-</#if>
-
-}
-</#if>
diff --git a/ycl-generator/src/main/resources/templates/default/controller.java.vm b/ycl-generator/src/main/resources/templates/default/controller.java.vm
deleted file mode 100644
index bbe5936..0000000
--- a/ycl-generator/src/main/resources/templates/default/controller.java.vm
+++ /dev/null
@@ -1,41 +0,0 @@
-package ${package.Controller};
-
-
-import org.springframework.web.bind.annotation.RequestMapping;
-
-#if(${restControllerStyle})
-import org.springframework.web.bind.annotation.RestController;
-#else
-import org.springframework.stereotype.Controller;
-#end
-#if(${superControllerClassPackage})
-import ${superControllerClassPackage};
-#end
-
-/**
- * <p>
- * $!{table.comment} 鍓嶇鎺у埗鍣�
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-#if(${restControllerStyle})
-@RestController
-#else
-@Controller
-#end
-@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
-#if(${kotlin})
-class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end
-
-#else
-#if(${superControllerClass})
-public class ${table.controllerName} extends ${superControllerClass} {
-#else
-public class ${table.controllerName} {
-#end
-
-}
-
-#end
\ No newline at end of file
diff --git a/ycl-generator/src/main/resources/templates/default/dao.btl b/ycl-generator/src/main/resources/templates/default/dao.btl
deleted file mode 100644
index 06772e2..0000000
--- a/ycl-generator/src/main/resources/templates/default/dao.btl
+++ /dev/null
@@ -1,14 +0,0 @@
-package ${entity.daoPackage};
-
-import cn.exrick.xboot.base.XbootBaseDao;
-import ${entity.entityPackage}.${entity.className};
-
-import java.util.List;
-
-/**
- * ${entity.description}鏁版嵁澶勭悊灞�
- * @author ${entity.author}
- */
-public interface ${entity.className}Dao extends XbootBaseDao<${entity.className},${entity.primaryKeyType}> {
-
-}
\ No newline at end of file
diff --git a/ycl-generator/src/main/resources/templates/default/entity.btl b/ycl-generator/src/main/resources/templates/default/entity.btl
deleted file mode 100644
index 6f79a22..0000000
--- a/ycl-generator/src/main/resources/templates/default/entity.btl
+++ /dev/null
@@ -1,24 +0,0 @@
-package ${entity.entityPackage};
-
-import cn.exrick.xboot.base.XbootBaseEntity;
-import com.baomidou.mybatisplus.annotations.TableName;
-import io.swagger.annotations.ApiModelProperty;
-import io.swagger.annotations.ApiModel;
-import lombok.Data;
-
-import javax.persistence.Entity;
-import javax.persistence.Table;
-
-/**
- * @author ${entity.author}
- */
-@Data
-@Entity
-@Table(name = "${entity.tableName}")
-@TableName("${entity.tableName}")
-@ApiModel(value = "${entity.description}")
-public class ${entity.className} extends XbootBaseEntity {
-
- private static final long serialVersionUID = 1L;
-
-}
\ No newline at end of file
diff --git a/ycl-generator/src/main/resources/templates/default/entity.java.btl b/ycl-generator/src/main/resources/templates/default/entity.java.btl
deleted file mode 100644
index a9616c4..0000000
--- a/ycl-generator/src/main/resources/templates/default/entity.java.btl
+++ /dev/null
@@ -1,162 +0,0 @@
-package ${package.Entity};
-<% for(pkg in table.importPackages){ %>
-import ${pkg};
-<% } %>
-<% if(swagger2){ %>
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-<% } %>
-<% if(entityLombokModel){ %>
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
-<% } %>
-/**
- * <p>
- * ${table.comment!}
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-<% if(entityLombokModel){ %>
-@Data
- <% if(isNotEmpty(superEntityClass)){ %>
-@EqualsAndHashCode(callSuper = true)
- <% }else{ %>
-@EqualsAndHashCode(callSuper = false)
- <% } %>
-@Accessors(chain = true)
-<% } %>
-<% if(table.convert){ %>
-@TableName("${table.name}")
-<% } %>
-<% if(swagger2){ %>
-@ApiModel(value="${entity}瀵硅薄", description="${table.comment!''}")
-<% } %>
-<% if(isNotEmpty(superEntityClass)){ %>
-public class ${entity} extends ${superEntityClass}<% if(activeRecord){ %><${entity}><%}%>{
-<% }else if(activeRecord){ %>
-public class ${entity} extends Model<${entity}> {
-<% }else{ %>
-public class ${entity} implements Serializable {
-<% } %>
-
-<% if(entitySerialVersionUID){ %>
- private static final long serialVersionUID = 1L;
-<% } %>
-<% /** -----------BEGIN 瀛楁寰幆閬嶅巻----------- **/ %>
-<% for(field in table.fields){ %>
- <%
- if(field.keyFlag){
- var keyPropertyName = field.propertyName;
- }
- %>
-
- <% if(isNotEmpty(field.comment)){ %>
- <% if(swagger2){ %>
- @ApiModelProperty(value = "${field.comment}")
- <% }else{ %>
- /**
- * ${field.comment}
- */
- <% } %>
- <% } %>
- <% if(field.keyFlag){ %>
- <%
- /*涓婚敭*/
- %>
- <% if(field.keyIdentityFlag){ %>
- @TableId(value = "${field.name}", type = IdType.AUTO)
- <% }else if(isNotEmpty(idType)){ %>
- @TableId(value = "${field.name}", type = IdType.${idType})
- <% }else if(field.convert){ %>
- @TableId("${field.name}")
- <% } %>
- <%
- /*鏅�氬瓧娈�*/
- %>
- <% }else if(isNotEmpty(field.fill)){ %>
- <% if(field.convert){ %>
- @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
- <% }else{ %>
- @TableField(fill = FieldFill.${field.fill})
- <% } %>
- <% }else if(field.convert){ %>
- @TableField("${field.name}")
- <% } %>
- <%
- /*涔愯閿佹敞瑙�*/
- %>
- <% if(versionFieldName!'' == field.name){ %>
- @Version
- <% } %>
- <%
- /*閫昏緫鍒犻櫎娉ㄨВ*/
- %>
- <% if(logicDeleteFieldName!'' == field.name){ %>
- @TableLogic
- <% } %>
- private ${field.propertyType} ${field.propertyName};
-<% } %>
-<% /** -----------END 瀛楁寰幆閬嶅巻----------- **/ %>
-
-<% if(!entityLombokModel){ %>
- <% for(field in table.fields){ %>
- <%
- var getprefix ='';
- if(field.propertyType=='boolean'){
- getprefix='is';
- }else{
- getprefix='get';
- }
- %>
- public ${field.propertyType} ${getprefix}${field.capitalName}() {
- return ${field.propertyName};
- }
-
- <% if(entityBuilderModel){ %>
- public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
- <% }else{ %>
- public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
- <% } %>
- this.${field.propertyName} = ${field.propertyName};
- <% if(entityBuilderModel){ %>
- return this;
- <% } %>
- }
-
- <% } %>
-<% } %>
-<% if(entityColumnConstant){ %>
- <% for(field in table.fields){ %>
- public static final String ${strutil.toUpperCase(field.name)} = "${field.name}";
-
- <% } %>
-<% } %>
-<% if(activeRecord){ %>
- @Override
- protected Serializable pkVal() {
- <% if(isNotEmpty(keyPropertyName)){ %>
- return this.${keyPropertyName};
- <% }else{ %>
- return null;
- <% } %>
- }
-
-<% } %>
-<% if(!entityLombokModel){ %>
- @Override
- public String toString() {
- return "${entity}{" +
- <% for(field in table.fields){ %>
- <% if(fieldLP.index==0){ %>
- "${field.propertyName}=" + ${field.propertyName} +
- <% }else{ %>
- ", ${field.propertyName}=" + ${field.propertyName} +
- <% } %>
- <% } %>
- "}";
- }
-<% } %>
-}
diff --git a/ycl-generator/src/main/resources/templates/default/entity.java.ftl b/ycl-generator/src/main/resources/templates/default/entity.java.ftl
deleted file mode 100644
index e399243..0000000
--- a/ycl-generator/src/main/resources/templates/default/entity.java.ftl
+++ /dev/null
@@ -1,152 +0,0 @@
-package ${package.Entity};
-
-<#list table.importPackages as pkg>
- import ${pkg};
-</#list>
-<#if swagger2>
- import io.swagger.annotations.ApiModel;
- import io.swagger.annotations.ApiModelProperty;
-</#if>
-<#if entityLombokModel>
- import lombok.Data;
- import lombok.EqualsAndHashCode;
- import lombok.experimental.Accessors;
-</#if>
-
-/**
-* <p>
- * ${table.comment!}
- * </p>
-*
-* @author ${author}
-* @since ${date}
-*/
-<#if entityLombokModel>
- @Data
- <#if superEntityClass??>
- @EqualsAndHashCode(callSuper = true)
- <#else>
- @EqualsAndHashCode(callSuper = false)
- </#if>
- @Accessors(chain = true)
-</#if>
-<#if table.convert>
- @TableName("${table.name}")
-</#if>
-<#if swagger2>
- @ApiModel(value="${entity}瀵硅薄", description="${table.comment!}")
-</#if>
-<#if superEntityClass??>
- public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
-<#elseif activeRecord>
- public class ${entity} extends Model<${entity}> {
-<#else>
- public class ${entity} implements Serializable {
-</#if>
-
-<#if entitySerialVersionUID>
- private static final long serialVersionUID = 1L;
-</#if>
-<#-- ---------- BEGIN 瀛楁寰幆閬嶅巻 ---------->
-<#list table.fields as field>
- <#if field.keyFlag>
- <#assign keyPropertyName="${field.propertyName}"/>
- </#if>
-
- <#if field.comment!?length gt 0>
- <#if swagger2>
- @ApiModelProperty(value = "${field.comment}")
- <#else>
- /**
- * ${field.comment}
- */
- </#if>
- </#if>
- <#if field.keyFlag>
- <#-- 涓婚敭 -->
- <#if field.keyIdentityFlag>
- @TableId(value = "${field.name}", type = IdType.AUTO)
- <#elseif idType??>
- @TableId(value = "${field.name}", type = IdType.${idType})
- <#elseif field.convert>
- @TableId("${field.name}")
- </#if>
- <#-- 鏅�氬瓧娈� -->
- <#elseif field.fill??>
- <#-- ----- 瀛樺湪瀛楁濉厖璁剧疆 ----->
- <#if field.convert>
- @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
- <#else>
- @TableField(fill = FieldFill.${field.fill})
- </#if>
- <#elseif field.convert>
- @TableField("${field.name}")
- </#if>
-<#-- 涔愯閿佹敞瑙� -->
- <#if (versionFieldName!"") == field.name>
- @Version
- </#if>
-<#-- 閫昏緫鍒犻櫎娉ㄨВ -->
- <#if (logicDeleteFieldName!"") == field.name>
- @TableLogic
- </#if>
- private ${field.propertyType} ${field.propertyName};
-</#list>
-<#------------ END 瀛楁寰幆閬嶅巻 ---------->
-
-<#if !entityLombokModel>
- <#list table.fields as field>
- <#if field.propertyType == "boolean">
- <#assign getprefix="is"/>
- <#else>
- <#assign getprefix="get"/>
- </#if>
- public ${field.propertyType} ${getprefix}${field.capitalName}() {
- return ${field.propertyName};
- }
-
- <#if entityBuilderModel>
- public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
- <#else>
- public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
- </#if>
- this.${field.propertyName} = ${field.propertyName};
- <#if entityBuilderModel>
- return this;
- </#if>
- }
- </#list>
-</#if>
-
-<#if entityColumnConstant>
- <#list table.fields as field>
- public static final String ${field.name?upper_case} = "${field.name}";
-
- </#list>
-</#if>
-<#if activeRecord>
- @Override
- protected Serializable pkVal() {
- <#if keyPropertyName??>
- return this.${keyPropertyName};
- <#else>
- return null;
- </#if>
- }
-
-</#if>
-<#if !entityLombokModel>
- @Override
- public String toString() {
- return "${entity}{" +
- <#list table.fields as field>
- <#if field_index==0>
- "${field.propertyName}=" + ${field.propertyName} +
- <#else>
- ", ${field.propertyName}=" + ${field.propertyName} +
- </#if>
- </#list>
- "}";
- }
-</#if>
-}
diff --git a/ycl-generator/src/main/resources/templates/default/entity.java.vm b/ycl-generator/src/main/resources/templates/default/entity.java.vm
deleted file mode 100644
index 3b0e551..0000000
--- a/ycl-generator/src/main/resources/templates/default/entity.java.vm
+++ /dev/null
@@ -1,153 +0,0 @@
-package ${package.Entity};
-
-#foreach($pkg in ${table.importPackages})
-import ${pkg};
-#end
-#if(${swagger2})
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-#end
-#if(${entityLombokModel})
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
-#end
-
-/**
- * <p>
- * $!{table.comment}
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-#if(${entityLombokModel})
-@Data
-#if(${superEntityClass})
-@EqualsAndHashCode(callSuper = true)
-#else
-@EqualsAndHashCode(callSuper = false)
-#end
-@Accessors(chain = true)
-#end
-#if(${table.convert})
-@TableName("${table.name}")
-#end
-#if(${swagger2})
-@ApiModel(value="${entity}瀵硅薄", description="$!{table.comment}")
-#end
-#if(${superEntityClass})
-public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
-#elseif(${activeRecord})
-public class ${entity} extends Model<${entity}> {
-#else
-public class ${entity} implements Serializable {
-#end
-
-#if(${entitySerialVersionUID})
-private static final long serialVersionUID=1L;
-#end
-## ---------- BEGIN 瀛楁寰幆閬嶅巻 ----------
-#foreach($field in ${table.fields})
-
-#if(${field.keyFlag})
-#set($keyPropertyName=${field.propertyName})
-#end
-#if("$!field.comment" != "")
-#if(${swagger2})
- @ApiModelProperty(value = "${field.comment}")
-#else
- /**
- * ${field.comment}
- */
-#end
-#end
-#if(${field.keyFlag})
-## 涓婚敭
-#if(${field.keyIdentityFlag})
- @TableId(value = "${field.name}", type = IdType.AUTO)
-#elseif(!$null.isNull(${idType}) && "$!idType" != "")
- @TableId(value = "${field.name}", type = IdType.${idType})
-#elseif(${field.convert})
- @TableId("${field.name}")
-#end
-## 鏅�氬瓧娈�
-#elseif(${field.fill})
-## ----- 瀛樺湪瀛楁濉厖璁剧疆 -----
-#if(${field.convert})
- @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
-#else
- @TableField(fill = FieldFill.${field.fill})
-#end
-#elseif(${field.convert})
- @TableField("${field.name}")
-#end
-## 涔愯閿佹敞瑙�
-#if(${versionFieldName}==${field.name})
- @Version
-#end
-## 閫昏緫鍒犻櫎娉ㄨВ
-#if(${logicDeleteFieldName}==${field.name})
- @TableLogic
-#end
- private ${field.propertyType} ${field.propertyName};
-#end
-## ---------- END 瀛楁寰幆閬嶅巻 ----------
-
-#if(!${entityLombokModel})
-#foreach($field in ${table.fields})
-#if(${field.propertyType.equals("boolean")})
-#set($getprefix="is")
-#else
-#set($getprefix="get")
-#end
-
- public ${field.propertyType} ${getprefix}${field.capitalName}() {
- return ${field.propertyName};
- }
-
-#if(${entityBuilderModel})
- public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
-#else
- public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
-#end
- this.${field.propertyName} = ${field.propertyName};
-#if(${entityBuilderModel})
- return this;
-#end
- }
-#end
-#end
-
-#if(${entityColumnConstant})
-#foreach($field in ${table.fields})
- public static final String ${field.name.toUpperCase()} = "${field.name}";
-
-#end
-#end
-#if(${activeRecord})
- @Override
- protected Serializable pkVal() {
-#if(${keyPropertyName})
- return this.${keyPropertyName};
-#else
- return null;
-#end
- }
-
-#end
-#if(!${entityLombokModel})
- @Override
- public String toString() {
- return "${entity}{" +
-#foreach($field in ${table.fields})
-#if($!{foreach.index}==0)
- "${field.propertyName}=" + ${field.propertyName} +
-#else
- ", ${field.propertyName}=" + ${field.propertyName} +
-#end
-#end
- "}";
- }
-#end
-}
diff --git a/ycl-generator/src/main/resources/templates/default/entity.kt.btl b/ycl-generator/src/main/resources/templates/default/entity.kt.btl
deleted file mode 100644
index 5b6f3e9..0000000
--- a/ycl-generator/src/main/resources/templates/default/entity.kt.btl
+++ /dev/null
@@ -1,124 +0,0 @@
-package ${package.Entity}
-<% for(pkg in table.importPackages){ %>
-import ${pkg}
-<% } %>
-<% if(swagger2){ %>
-import io.swagger.annotations.ApiModel
-import io.swagger.annotations.ApiModelProperty
-<% } %>
-/**
- * <p>
- * ${table.comment!}
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-<% if(table.convert){ %>
-@TableName("${table.name}")
-<% } %>
-<% if(swagger2){ %>
-@ApiModel(value="${entity}瀵硅薄", description="${table.comment!''}")
-<% } %>
-<% if(isNotEmpty(superEntityClass)){ %>
-class ${entity} : ${superEntityClass}<% if(activeRecord){ %><${entity}><%}%>{
-<% }else if(activeRecord){ %>
-class ${entity} : Model<${entity}> {
-<% }else{ %>
-class ${entity} : Serializable {
-<% } %>
-
-<% /** -----------BEGIN 瀛楁寰幆閬嶅巻----------- **/ %>
-<% for(field in table.fields){ %>
- <%
- if(field.keyFlag){
- var keyPropertyName = field.propertyName;
- }
- %>
-
- <% if(isNotEmpty(field.comment)){ %>
- <% if(swagger2){ %>
- @ApiModelProperty(value = "${field.comment}")
- <% }else{ %>
- /**
- * ${field.comment}
- */
- <% } %>
- <% } %>
- <% if(field.keyFlag){ %>
- <%
- /*涓婚敭*/
- %>
- <% if(field.keyIdentityFlag){ %>
- @TableId(value = "${field.name}", type = IdType.AUTO)
- <% }else if(isNotEmpty(idType)){ %>
- @TableId(value = "${field.name}", type = IdType.${idType})
- <% }else if(field.convert){ %>
- @TableId("${field.name}")
- <% } %>
- <%
- /*鏅�氬瓧娈�*/
- %>
- <% }else if(isNotEmpty(field.fill)){ %>
- <% if(field.convert){ %>
- @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
- <% }else{ %>
- @TableField(fill = FieldFill.${field.fill})
- <% } %>
- <% }else if(field.convert){ %>
- @TableField("${field.name}")
- <% } %>
- <%
- /*涔愯閿佹敞瑙�*/
- %>
- <% if(versionFieldName!'' == field.name){ %>
- @Version
- <% } %>
- <%
- /*閫昏緫鍒犻櫎娉ㄨВ*/
- %>
- <% if(logicDeleteFieldName!'' == field.name){ %>
- @TableLogic
- <% } %>
- <% if(field.propertyType == 'Integer'){ %>
- var ${field.propertyName}: Int ? = null
- <% }else{ %>
- var ${field.propertyName}: ${field.propertyType} ? = null
- <% } %>
-<% } %>
-<% /** -----------END 瀛楁寰幆閬嶅巻----------- **/ %>
-
-<% if(entityColumnConstant){ %>
- companion object {
- <% for(field in table.fields){ %>
- const val ${strutil.toUpperCase(field.name)} : String = "${field.name}"
- <% } %>
- }
-<% } %>
-<% if(activeRecord){ %>
- @Override
- override fun pkVal(): Serializable? {
- <% if(isNotEmpty(keyPropertyName)){ %>
- return this.${keyPropertyName}
- <% }else{ %>
- return null;
- <% } %>
- }
-
-<% } %>
-
-<% if(!entityLombokModel){ %>
- @Override
- override fun toString(): String {
- return "${entity}{" +
- <% for(field in table.fields){ %>
- <% if(fieldLP.index==0){ %>
- "${field.propertyName}=" + ${field.propertyName} +
- <% }else{ %>
- ", ${field.propertyName}=" + ${field.propertyName} +
- <% } %>
- <% } %>
- "}"
- }
-<% } %>
-}
diff --git a/ycl-generator/src/main/resources/templates/default/entity.kt.ftl b/ycl-generator/src/main/resources/templates/default/entity.kt.ftl
deleted file mode 100644
index a7b14c4..0000000
--- a/ycl-generator/src/main/resources/templates/default/entity.kt.ftl
+++ /dev/null
@@ -1,115 +0,0 @@
-package ${package.Entity}
-
-<#list table.importPackages as pkg>
-import ${pkg}
-</#list>
-<#if swagger2>
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-</#if>
-/**
- * <p>
- * ${table.comment}
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-<#if table.convert>
-@TableName("${table.name}")
-</#if>
-<#if swagger2>
- @ApiModel(value="${entity}瀵硅薄", description="${table.comment!}")
-</#if>
-<#if superEntityClass??>
-class ${entity} : ${superEntityClass}<#if activeRecord><${entity}></#if> {
-<#elseif activeRecord>
-class ${entity} : Model<${entity}>() {
-<#else>
-class ${entity} : Serializable {
-</#if>
-
-<#-- ---------- BEGIN 瀛楁寰幆閬嶅巻 ---------->
-<#list table.fields as field>
-<#if field.keyFlag>
- <#assign keyPropertyName="${field.propertyName}"/>
-</#if>
-
-<#if field.comment!?length gt 0>
-<#if swagger2>
- @ApiModelProperty(value = "${field.comment}")
-<#else>
- /**
- * ${field.comment}
- */
-</#if>
-</#if>
-<#if field.keyFlag>
-<#-- 涓婚敭 -->
-<#if field.keyIdentityFlag>
- @TableId(value = "${field.name}", type = IdType.AUTO)
-<#elseif idType ??>
- @TableId(value = "${field.name}", type = IdType.${idType})
-<#elseif field.convert>
- @TableId("${field.name}")
-</#if>
-<#-- 鏅�氬瓧娈� -->
-<#elseif field.fill??>
-<#-- ----- 瀛樺湪瀛楁濉厖璁剧疆 ----->
-<#if field.convert>
- @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
-<#else>
- @TableField(fill = FieldFill.${field.fill})
-</#if>
-<#elseif field.convert>
- @TableField("${field.name}")
-</#if>
-<#-- 涔愯閿佹敞瑙� -->
-<#if (versionFieldName!"") == field.name>
- @Version
-</#if>
-<#-- 閫昏緫鍒犻櫎娉ㄨВ -->
-<#if (logicDeleteFieldName!"") == field.name>
- @TableLogic
-</#if>
- <#if field.propertyType == "Integer">
- var ${field.propertyName}: Int? = null
- <#else>
- var ${field.propertyName}: ${field.propertyType}? = null
- </#if>
-</#list>
-<#-- ---------- END 瀛楁寰幆閬嶅巻 ---------->
-
-
-<#if entityColumnConstant>
- companion object {
-<#list table.fields as field>
-
- const val ${field.name.toUpperCase()} : String = "${field.name}"
-
-</#list>
- }
-
-</#if>
-<#if activeRecord>
- override fun pkVal(): Serializable? {
-<#if keyPropertyName??>
- return ${keyPropertyName}
-<#else>
- return null
-</#if>
- }
-
-</#if>
- override fun toString(): String {
- return "${entity}{" +
-<#list table.fields as field>
-<#if field_index==0>
- "${field.propertyName}=" + ${field.propertyName} +
-<#else>
- ", ${field.propertyName}=" + ${field.propertyName} +
-</#if>
-</#list>
- "}"
- }
-}
diff --git a/ycl-generator/src/main/resources/templates/default/entity.kt.vm b/ycl-generator/src/main/resources/templates/default/entity.kt.vm
deleted file mode 100644
index adcef6a..0000000
--- a/ycl-generator/src/main/resources/templates/default/entity.kt.vm
+++ /dev/null
@@ -1,114 +0,0 @@
-package ${package.Entity};
-
-#foreach($pkg in ${table.importPackages})
-import ${pkg};
-#end
-#if(${swagger2})
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-#end
-/**
- * <p>
- * $!{table.comment}
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-#if(${table.convert})
-@TableName("${table.name}")
-#end
-#if(${swagger2})
-@ApiModel(value="${entity}瀵硅薄", description="$!{table.comment}")
-#end
-#if(${superEntityClass})
-class ${entity} : ${superEntityClass}#if(${activeRecord})<${entity}>#end() {
-#elseif(${activeRecord})
-class ${entity} : Model<${entity}>() {
-#else
-class ${entity} : Serializable {
-#end
-
-## ---------- BEGIN 瀛楁寰幆閬嶅巻 ----------
-#foreach($field in ${table.fields})
-#if(${field.keyFlag})
-#set($keyPropertyName=${field.propertyName})
-#end
-#if("$!field.comment" != "")
- #if(${swagger2})
- @ApiModelProperty(value = "${field.comment}")
- #else
- /**
- * ${field.comment}
- */
- #end
-#end
-#if(${field.keyFlag})
-## 涓婚敭
-#if(${field.keyIdentityFlag})
- @TableId(value = "${field.name}", type = IdType.AUTO)
-#elseif(!$null.isNull(${idType}) && "$!idType" != "")
- @TableId(value = "${field.name}", type = IdType.${idType})
-#elseif(${field.convert})
- @TableId("${field.name}")
-#end
-## 鏅�氬瓧娈�
-#elseif(${field.fill})
-## ----- 瀛樺湪瀛楁濉厖璁剧疆 -----
-#if(${field.convert})
- @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
-#else
- @TableField(fill = FieldFill.${field.fill})
-#end
-#elseif(${field.convert})
- @TableField("${field.name}")
-#end
-## 涔愯閿佹敞瑙�
-#if(${versionFieldName}==${field.name})
- @Version
-#end
-## 閫昏緫鍒犻櫎娉ㄨВ
-#if(${logicDeleteFieldName}==${field.name})
- @TableLogic
-#end
- #if(${field.propertyType} == "Integer")
- var ${field.propertyName}: Int? = null
- #else
- var ${field.propertyName}: ${field.propertyType}? = null
- #end
-#end
-## ---------- END 瀛楁寰幆閬嶅巻 ----------
-
-
-#if(${entityColumnConstant})
- companion object {
-#foreach($field in ${table.fields})
-
- const val ${field.name.toUpperCase()} : String = "${field.name}"
-
-#end
- }
-
-#end
-#if(${activeRecord})
- override fun pkVal(): Serializable? {
-#if(${keyPropertyName})
- return ${keyPropertyName}
-#else
- return null
-#end
- }
-
-#end
- override fun toString(): String {
- return "${entity}{" +
-#foreach($field in ${table.fields})
-#if($!{foreach.index}==0)
- "${field.propertyName}=" + ${field.propertyName} +
-#else
- ", ${field.propertyName}=" + ${field.propertyName} +
-#end
-#end
- "}"
- }
-}
diff --git a/ycl-generator/src/main/resources/templates/default/mapper.java.btl b/ycl-generator/src/main/resources/templates/default/mapper.java.btl
deleted file mode 100644
index 95bf7ad..0000000
--- a/ycl-generator/src/main/resources/templates/default/mapper.java.btl
+++ /dev/null
@@ -1,20 +0,0 @@
-package ${package.Mapper};
-
-import ${package.Entity}.${entity};
-import ${superMapperClassPackage};
-
-/**
- * <p>
- * ${table.comment!} Mapper 鎺ュ彛
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-<% if(kotlin){ %>
-interface ${table.mapperName} : ${superMapperClass}<${entity}>
-<% }else{ %>
-public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
-
-}
-<% } %>
diff --git a/ycl-generator/src/main/resources/templates/default/mapper.java.ftl b/ycl-generator/src/main/resources/templates/default/mapper.java.ftl
deleted file mode 100644
index 53da4ae..0000000
--- a/ycl-generator/src/main/resources/templates/default/mapper.java.ftl
+++ /dev/null
@@ -1,20 +0,0 @@
-package ${package.Mapper};
-
-import ${package.Entity}.${entity};
-import ${superMapperClassPackage};
-
-/**
- * <p>
- * ${table.comment!} Mapper 鎺ュ彛
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-<#if kotlin>
-interface ${table.mapperName} : ${superMapperClass}<${entity}>
-<#else>
-public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
-
-}
-</#if>
diff --git a/ycl-generator/src/main/resources/templates/default/mapper.java.vm b/ycl-generator/src/main/resources/templates/default/mapper.java.vm
deleted file mode 100644
index 3a6f3a5..0000000
--- a/ycl-generator/src/main/resources/templates/default/mapper.java.vm
+++ /dev/null
@@ -1,20 +0,0 @@
-package ${package.Mapper};
-
-import ${package.Entity}.${entity};
-import ${superMapperClassPackage};
-
-/**
- * <p>
- * $!{table.comment} Mapper 鎺ュ彛
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-#if(${kotlin})
-interface ${table.mapperName} : ${superMapperClass}<${entity}>
-#else
-public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
-
-}
-#end
diff --git a/ycl-generator/src/main/resources/templates/default/mapper.xml.btl b/ycl-generator/src/main/resources/templates/default/mapper.xml.btl
deleted file mode 100644
index 4de8945..0000000
--- a/ycl-generator/src/main/resources/templates/default/mapper.xml.btl
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="${package.Mapper}.${table.mapperName}">
-
-<% if(enableCache){ %>
- <!-- 寮�鍚簩绾х紦瀛� -->
- <cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
-
-<% } %>
-<% if(baseResultMap){ %>
- <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
- <resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
-<% for(field in table.fields){ %>
- <% /** 鐢熸垚涓婚敭鎺掑湪绗竴浣� **/ %>
- <% if(field.keyFlag){ %>
- <id column="${field.name}" property="${field.propertyName}" />
- <% } %>
-<% } %>
-<% for(field in table.commonFields){ %>
- <% /** 鐢熸垚鍏叡瀛楁 **/ %>
- <result column="${field.name}" property="${field.propertyName}" />
-<% } %>
-<% for(field in table.fields){ %>
- <% /** 鐢熸垚鏅�氬瓧娈� **/ %>
- <% if(!field.keyFlag){ %>
- <result column="${field.name}" property="${field.propertyName}" />
- <% } %>
-<% } %>
- </resultMap>
-<% } %>
-<% if(baseColumnList){ %>
- <!-- 閫氱敤鏌ヨ缁撴灉鍒� -->
- <sql id="Base_Column_List">
-<% for(field in table.commonFields){ %>
- ${field.name},
-<% } %>
- ${table.fieldNames}
- </sql>
-
-<% } %>
-</mapper>
diff --git a/ycl-generator/src/main/resources/templates/default/mapper.xml.ftl b/ycl-generator/src/main/resources/templates/default/mapper.xml.ftl
deleted file mode 100644
index d9ca71c..0000000
--- a/ycl-generator/src/main/resources/templates/default/mapper.xml.ftl
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="${package.Mapper}.${table.mapperName}">
-
-<#if enableCache>
- <!-- 寮�鍚簩绾х紦瀛� -->
- <cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
-
-</#if>
-<#if baseResultMap>
- <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
- <resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
-<#list table.fields as field>
-<#if field.keyFlag><#--鐢熸垚涓婚敭鎺掑湪绗竴浣�-->
- <id column="${field.name}" property="${field.propertyName}" />
-</#if>
-</#list>
-<#list table.commonFields as field><#--鐢熸垚鍏叡瀛楁 -->
- <result column="${field.name}" property="${field.propertyName}" />
-</#list>
-<#list table.fields as field>
-<#if !field.keyFlag><#--鐢熸垚鏅�氬瓧娈� -->
- <result column="${field.name}" property="${field.propertyName}" />
-</#if>
-</#list>
- </resultMap>
-
-</#if>
-<#if baseColumnList>
- <!-- 閫氱敤鏌ヨ缁撴灉鍒� -->
- <sql id="Base_Column_List">
-<#list table.commonFields as field>
- ${field.name},
-</#list>
- ${table.fieldNames}
- </sql>
-
-</#if>
-</mapper>
diff --git a/ycl-generator/src/main/resources/templates/default/mapper.xml.vm b/ycl-generator/src/main/resources/templates/default/mapper.xml.vm
deleted file mode 100644
index 3af28b0..0000000
--- a/ycl-generator/src/main/resources/templates/default/mapper.xml.vm
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="${package.Mapper}.${table.mapperName}">
-
-#if(${enableCache})
- <!-- 寮�鍚簩绾х紦瀛� -->
- <cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
-
-#end
-#if(${baseResultMap})
- <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
- <resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
-#foreach($field in ${table.fields})
-#if(${field.keyFlag})##鐢熸垚涓婚敭鎺掑湪绗竴浣�
- <id column="${field.name}" property="${field.propertyName}" />
-#end
-#end
-#foreach($field in ${table.commonFields})##鐢熸垚鍏叡瀛楁
- <result column="${field.name}" property="${field.propertyName}" />
-#end
-#foreach($field in ${table.fields})
-#if(!${field.keyFlag})##鐢熸垚鏅�氬瓧娈�
- <result column="${field.name}" property="${field.propertyName}" />
-#end
-#end
- </resultMap>
-
-#end
-#if(${baseColumnList})
- <!-- 閫氱敤鏌ヨ缁撴灉鍒� -->
- <sql id="Base_Column_List">
-#foreach($field in ${table.commonFields})
- ${field.name},
-#end
- ${table.fieldNames}
- </sql>
-
-#end
-</mapper>
diff --git a/ycl-generator/src/main/resources/templates/default/service.java.btl b/ycl-generator/src/main/resources/templates/default/service.java.btl
deleted file mode 100644
index 6b9de49..0000000
--- a/ycl-generator/src/main/resources/templates/default/service.java.btl
+++ /dev/null
@@ -1,19 +0,0 @@
-package ${package.Service};
-
-import ${package.Entity}.${entity};
-import ${superServiceClassPackage};
-
-/**
- * <p>
- * ${table.comment!} 鏈嶅姟绫�
- * </p>
- *
- * @author ${author}
- */
-<% if(kotlin){ %>
-interface ${table.serviceName} : ${superServiceClass}<${entity}>
-<% }else{ %>
-public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
-
-}
-<% } %>
diff --git a/ycl-generator/src/main/resources/templates/default/service.java.ftl b/ycl-generator/src/main/resources/templates/default/service.java.ftl
deleted file mode 100644
index f9e01c0..0000000
--- a/ycl-generator/src/main/resources/templates/default/service.java.ftl
+++ /dev/null
@@ -1,19 +0,0 @@
-package ${package.Service};
-
-import ${package.Entity}.${entity};
-import ${superServiceClassPackage};
-
-/**
- * <p>
- * ${table.comment!} 鏈嶅姟绫�
- * </p>
- *
- * @author ${author}
- */
-<#if kotlin>
-interface ${table.serviceName} : ${superServiceClass}<${entity}>
-<#else>
-public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
-
-}
-</#if>
diff --git a/ycl-generator/src/main/resources/templates/default/service.java.vm b/ycl-generator/src/main/resources/templates/default/service.java.vm
deleted file mode 100644
index 1e0c4f0..0000000
--- a/ycl-generator/src/main/resources/templates/default/service.java.vm
+++ /dev/null
@@ -1,19 +0,0 @@
-package ${package.Service};
-
-import ${package.Entity}.${entity};
-import ${superServiceClassPackage};
-
-/**
- * <p>
- * $!{table.comment} 鏈嶅姟绫�
- * </p>
- *
- * @author ${author}
- */
-#if(${kotlin})
-interface ${table.serviceName} : ${superServiceClass}<${entity}>
-#else
-public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
-
-}
-#end
diff --git a/ycl-generator/src/main/resources/templates/default/serviceImpl.btl b/ycl-generator/src/main/resources/templates/default/serviceImpl.btl
deleted file mode 100644
index 010991c..0000000
--- a/ycl-generator/src/main/resources/templates/default/serviceImpl.btl
+++ /dev/null
@@ -1,32 +0,0 @@
-package ${entity.serviceImplPackage};
-
-import ${entity.daoPackage}.${entity.className}Dao;
-import ${entity.entityPackage}.${entity.className};
-import ${entity.servicePackage}.${entity.className}Service;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * ${entity.description}鎺ュ彛瀹炵幇
- * @author ${entity.author}
- */
-@Slf4j
-@Service
-@Transactional
-public class ${entity.className}ServiceImpl implements ${entity.className}Service {
-
- @Autowired
- private ${entity.className}Dao ${entity.classNameLowerCase}Dao;
-
- @Override
- public ${entity.className}Dao getRepository() {
- return ${entity.classNameLowerCase}Dao;
- }
-}
\ No newline at end of file
diff --git a/ycl-generator/src/main/resources/templates/default/serviceImpl.java.btl b/ycl-generator/src/main/resources/templates/default/serviceImpl.java.btl
deleted file mode 100644
index 9a62911..0000000
--- a/ycl-generator/src/main/resources/templates/default/serviceImpl.java.btl
+++ /dev/null
@@ -1,26 +0,0 @@
-package ${package.ServiceImpl};
-
-import ${package.Entity}.${entity};
-import ${package.Mapper}.${table.mapperName};
-import ${package.Service}.${table.serviceName};
-import ${superServiceImplClassPackage};
-import org.springframework.stereotype.Service;
-
-/**
- * <p>
- * ${table.comment!} 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-@Service
-<% if(kotlin){ %>
-open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
-
-}
-<% }else{ %>
-public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
-
-}
-<% } %>
diff --git a/ycl-generator/src/main/resources/templates/default/serviceImpl.java.ftl b/ycl-generator/src/main/resources/templates/default/serviceImpl.java.ftl
deleted file mode 100644
index aeebd14..0000000
--- a/ycl-generator/src/main/resources/templates/default/serviceImpl.java.ftl
+++ /dev/null
@@ -1,26 +0,0 @@
-package ${package.ServiceImpl};
-
-import ${package.Entity}.${entity};
-import ${package.Mapper}.${table.mapperName};
-import ${package.Service}.${table.serviceName};
-import ${superServiceImplClassPackage};
-import org.springframework.stereotype.Service;
-
-/**
- * <p>
- * ${table.comment!} 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-@Service
-<#if kotlin>
-open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
-
-}
-<#else>
-public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
-
-}
-</#if>
diff --git a/ycl-generator/src/main/resources/templates/default/serviceImpl.java.vm b/ycl-generator/src/main/resources/templates/default/serviceImpl.java.vm
deleted file mode 100644
index a5ed504..0000000
--- a/ycl-generator/src/main/resources/templates/default/serviceImpl.java.vm
+++ /dev/null
@@ -1,26 +0,0 @@
-package ${package.ServiceImpl};
-
-import ${package.Entity}.${entity};
-import ${package.Mapper}.${table.mapperName};
-import ${package.Service}.${table.serviceName};
-import ${superServiceImplClassPackage};
-import org.springframework.stereotype.Service;
-
-/**
- * <p>
- * $!{table.comment} 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author ${author}
- * @since ${date}
- */
-@Service
-#if(${kotlin})
-open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
-
-}
-#else
-public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
-
-}
-#end
diff --git a/ycl-generator/src/main/resources/templates/entity.java.ftl b/ycl-generator/src/main/resources/templates/entity.java.ftl
deleted file mode 100644
index 65145ff..0000000
--- a/ycl-generator/src/main/resources/templates/entity.java.ftl
+++ /dev/null
@@ -1,155 +0,0 @@
-package ${package.Entity};
-
-<#list table.importPackages as pkg>
-import ${pkg};
-</#list>
-<#if swagger2>
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-</#if>
-<#if entityLombokModel>
-import lombok.Data;
-</#if>
-<#if chainModel>
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.NoArgsConstructor;
-</#if>
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableName;
-
-/**
- * <p>
- * ${table.comment!}
- * </p>
- *
- * @author ${author}
- */
-<#if entityLombokModel>
-@Data
-</#if>
-<#if chainModel>
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-</#if>
-<#if swagger2>
-@TableName("${table.name}")
-</#if>
-<#if swagger2>
-@ApiModel(value="${entity}", description="${table.comment!}")
-</#if>
-<#if superEntityClass??>
-public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
-<#elseif activeRecord>
-public class ${entity} extends Model<${entity}> {
-<#else>
-public class ${entity} implements Serializable {
-</#if>
-
- private static final long serialVersionUID = 1L;
-<#-- ---------- BEGIN 瀛楁寰幆閬嶅巻 ---------->
-<#list table.fields as field>
- <#if field.keyFlag>
- <#assign keyPropertyName="${field.propertyName}"/>
- </#if>
-
- <#if field.comment!?length gt 0>
- <#if swagger2>
- @ApiModelProperty(value = "${field.comment}")
- <#else>
- /**
- * ${field.comment}
- */
- </#if>
- </#if>
- <#if swagger2>
- <#if field.keyFlag>
- <#-- 涓婚敭 -->
- <#--<#if field.keyIdentityFlag>-->
- <#--@TableId(value = "${field.name}", type = IdType.AUTO)-->
- <#if idType??>
- @TableId(value = "${field.name}", type = IdType.${idType})
- <#elseif field.convert>
- @TableId("${field.name}")
- </#if>
- <#-- 鏅�氬瓧娈� -->
- <#-- <#elseif field.fill??>
- <#– ----- 瀛樺湪瀛楁濉厖璁剧疆 ---–>
- <#if field.convert>
- @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
- <#else>
- @TableField(fill = FieldFill.${field.fill})
- </#if>-->
- <#else>
- @TableField("${field.name}")
- </#if>
- </#if>
-<#-- 涔愯閿佹敞瑙� -->
- <#if (versionFieldName!"") == field.name>
- @Version
- </#if>
-<#-- 閫昏緫鍒犻櫎娉ㄨВ -->
- <#if (logicDeleteFieldName!"") == field.name>
- @TableLogic
- </#if>
- private ${field.propertyType} ${field.propertyName};
-</#list>
-<#------------ END 瀛楁寰幆閬嶅巻 ---------->
-
-<#if !entityLombokModel>
- <#list table.fields as field>
- <#if field.propertyType == "boolean">
- <#assign getprefix="is"/>
- <#else>
- <#assign getprefix="get"/>
- </#if>
- public ${field.propertyType} ${getprefix}${field.capitalName}() {
- return ${field.propertyName};
- }
-
- <#if entityBuilderModel>
- public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
- <#else>
- public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
- </#if>
- this.${field.propertyName} = ${field.propertyName};
- <#if entityBuilderModel>
- return this;
- </#if>
- }
- </#list>
-</#if>
-
-<#if entityColumnConstant>
- <#list table.fields as field>
- public static final String ${field.name?upper_case} = "${field.name}";
-
- </#list>
-</#if>
-<#if activeRecord>
- @Override
- protected Serializable pkVal() {
- <#if keyPropertyName??>
- return this.${keyPropertyName};
- <#else>
- return null;
- </#if>
- }
-
-</#if>
-<#if !entityLombokModel>
- @Override
- public String toString() {
- return "${entity}{" +
- <#list table.fields as field>
- <#if field_index==0>
- "${field.propertyName}=" + ${field.propertyName} +
- <#else>
- ", ${field.propertyName}=" + ${field.propertyName} +
- </#if>
- </#list>
- "}";
- }
-</#if>
-}
diff --git a/ycl-generator/src/main/resources/templates/mapper.java.ftl b/ycl-generator/src/main/resources/templates/mapper.java.ftl
deleted file mode 100644
index d9d9f4f..0000000
--- a/ycl-generator/src/main/resources/templates/mapper.java.ftl
+++ /dev/null
@@ -1,21 +0,0 @@
-package ${package.Mapper};
-
-import ${package.Entity}.${entity};
-import ${superMapperClassPackage};
-import org.apache.ibatis.annotations.Mapper;
-
-/**
- * <p>
- * ${table.comment!} Mapper 鎺ュ彛
- * </p>
- *
- * @author ${author}
- */
-@Mapper
-<#if kotlin>
-interface ${table.mapperName} : ${superMapperClass}<${entity}>
-<#else>
-public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
-
-}
-</#if>
diff --git a/ycl-generator/src/main/resources/templates/service.java.ftl b/ycl-generator/src/main/resources/templates/service.java.ftl
deleted file mode 100644
index f9e01c0..0000000
--- a/ycl-generator/src/main/resources/templates/service.java.ftl
+++ /dev/null
@@ -1,19 +0,0 @@
-package ${package.Service};
-
-import ${package.Entity}.${entity};
-import ${superServiceClassPackage};
-
-/**
- * <p>
- * ${table.comment!} 鏈嶅姟绫�
- * </p>
- *
- * @author ${author}
- */
-<#if kotlin>
-interface ${table.serviceName} : ${superServiceClass}<${entity}>
-<#else>
-public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
-
-}
-</#if>
diff --git a/ycl-generator/src/main/resources/templates/serviceImpl.java.ftl b/ycl-generator/src/main/resources/templates/serviceImpl.java.ftl
deleted file mode 100644
index 8777730..0000000
--- a/ycl-generator/src/main/resources/templates/serviceImpl.java.ftl
+++ /dev/null
@@ -1,30 +0,0 @@
-package ${package.ServiceImpl};
-
-import ${package.Entity}.${entity};
-import ${package.Mapper}.${table.mapperName};
-import ${package.Service}.${table.serviceName};
-import ${superServiceImplClassPackage};
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * <p>
- * ${table.comment!} 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author ${author}
- */
-@Slf4j
-@Service
-@Transactional
-<#if kotlin>
-open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
-
-}
-<#else>
-public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
-
-}
-</#if>
diff --git a/ycl-generator/src/main/resources/vm/java/controller.java.vm b/ycl-generator/src/main/resources/vm/java/controller.java.vm
new file mode 100644
index 0000000..9e32eb7
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/java/controller.java.vm
@@ -0,0 +1,115 @@
+package ${packageName}.controller;
+
+import java.util.List;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ycl.common.annotation.Log;
+import com.ycl.common.core.controller.BaseController;
+import com.ycl.common.core.domain.AjaxResult;
+import com.ycl.common.enums.BusinessType;
+import ${packageName}.domain.${ClassName};
+import ${packageName}.service.I${ClassName}Service;
+import com.ycl.common.utils.poi.ExcelUtil;
+#if($table.crud || $table.sub)
+import com.ycl.common.core.page.TableDataInfo;
+#elseif($table.tree)
+#end
+
+/**
+ * ${functionName}Controller
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+@RestController
+@RequestMapping("/${moduleName}/${businessName}")
+public class ${ClassName}Controller extends BaseController
+{
+ @Autowired
+ private I${ClassName}Service ${className}Service;
+
+ /**
+ * 鏌ヨ${functionName}鍒楄〃
+ */
+ @PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')")
+ @GetMapping("/list")
+#if($table.crud || $table.sub)
+ public TableDataInfo list(${ClassName} ${className})
+ {
+ startPage();
+ List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
+ return getDataTable(list);
+ }
+#elseif($table.tree)
+ public AjaxResult list(${ClassName} ${className})
+ {
+ List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
+ return success(list);
+ }
+#end
+
+ /**
+ * 瀵煎嚭${functionName}鍒楄〃
+ */
+ @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')")
+ @Log(title = "${functionName}", businessType = BusinessType.EXPORT)
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, ${ClassName} ${className})
+ {
+ List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
+ ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class);
+ util.exportExcel(response, list, "${functionName}鏁版嵁");
+ }
+
+ /**
+ * 鑾峰彇${functionName}璇︾粏淇℃伅
+ */
+ @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')")
+ @GetMapping(value = "/{${pkColumn.javaField}}")
+ public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField})
+ {
+ return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}));
+ }
+
+ /**
+ * 鏂板${functionName}
+ */
+ @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')")
+ @Log(title = "${functionName}", businessType = BusinessType.INSERT)
+ @PostMapping
+ public AjaxResult add(@RequestBody ${ClassName} ${className})
+ {
+ return toAjax(${className}Service.insert${ClassName}(${className}));
+ }
+
+ /**
+ * 淇敼${functionName}
+ */
+ @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')")
+ @Log(title = "${functionName}", businessType = BusinessType.UPDATE)
+ @PutMapping
+ public AjaxResult edit(@RequestBody ${ClassName} ${className})
+ {
+ return toAjax(${className}Service.update${ClassName}(${className}));
+ }
+
+ /**
+ * 鍒犻櫎${functionName}
+ */
+ @PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')")
+ @Log(title = "${functionName}", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{${pkColumn.javaField}s}")
+ public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s)
+ {
+ return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s));
+ }
+}
diff --git a/ycl-generator/src/main/resources/vm/java/domain.java.vm b/ycl-generator/src/main/resources/vm/java/domain.java.vm
new file mode 100644
index 0000000..748d7e6
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/java/domain.java.vm
@@ -0,0 +1,103 @@
+package ${packageName}.domain;
+
+#foreach ($import in $importList)
+import ${import};
+#end
+import com.ycl.common.annotation.Excel;
+#if($table.crud || $table.sub)
+import com.ycl.common.core.domain.BaseEntity;
+#elseif($table.tree)
+import com.ycl.common.core.domain.TreeEntity;
+#end
+
+/**
+ * ${functionName}瀵硅薄 ${tableName}
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+#if($table.crud || $table.sub)
+#set($Entity="BaseEntity")
+#elseif($table.tree)
+#set($Entity="TreeEntity")
+#end
+public class ${ClassName} extends ${Entity}
+{
+ private static final long serialVersionUID = 1L;
+
+#foreach ($column in $columns)
+#if(!$table.isSuperColumn($column.javaField))
+ /** $column.columnComment */
+#if($column.list)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($parentheseIndex != -1)
+ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+#elseif($column.javaType == 'Date')
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
+#else
+ @Excel(name = "${comment}")
+#end
+#end
+ private $column.javaType $column.javaField;
+
+#end
+#end
+#if($table.sub)
+ /** $table.subTable.functionName淇℃伅 */
+ private List<${subClassName}> ${subclassName}List;
+
+#end
+#foreach ($column in $columns)
+#if(!$table.isSuperColumn($column.javaField))
+#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
+#set($AttrName=$column.javaField)
+#else
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#end
+ public void set${AttrName}($column.javaType $column.javaField)
+ {
+ this.$column.javaField = $column.javaField;
+ }
+
+ public $column.javaType get${AttrName}()
+ {
+ return $column.javaField;
+ }
+#end
+#end
+
+#if($table.sub)
+ public List<${subClassName}> get${subClassName}List()
+ {
+ return ${subclassName}List;
+ }
+
+ public void set${subClassName}List(List<${subClassName}> ${subclassName}List)
+ {
+ this.${subclassName}List = ${subclassName}List;
+ }
+
+#end
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+#foreach ($column in $columns)
+#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
+#set($AttrName=$column.javaField)
+#else
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#end
+ .append("${column.javaField}", get${AttrName}())
+#end
+#if($table.sub)
+ .append("${subclassName}List", get${subClassName}List())
+#end
+ .toString();
+ }
+}
diff --git a/ycl-generator/src/main/resources/vm/java/mapper.java.vm b/ycl-generator/src/main/resources/vm/java/mapper.java.vm
new file mode 100644
index 0000000..7e7d7c2
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/java/mapper.java.vm
@@ -0,0 +1,91 @@
+package ${packageName}.mapper;
+
+import java.util.List;
+import ${packageName}.domain.${ClassName};
+#if($table.sub)
+import ${packageName}.domain.${subClassName};
+#end
+
+/**
+ * ${functionName}Mapper鎺ュ彛
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+public interface ${ClassName}Mapper
+{
+ /**
+ * 鏌ヨ${functionName}
+ *
+ * @param ${pkColumn.javaField} ${functionName}涓婚敭
+ * @return ${functionName}
+ */
+ public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
+
+ /**
+ * 鏌ヨ${functionName}鍒楄〃
+ *
+ * @param ${className} ${functionName}
+ * @return ${functionName}闆嗗悎
+ */
+ public List<${ClassName}> select${ClassName}List(${ClassName} ${className});
+
+ /**
+ * 鏂板${functionName}
+ *
+ * @param ${className} ${functionName}
+ * @return 缁撴灉
+ */
+ public int insert${ClassName}(${ClassName} ${className});
+
+ /**
+ * 淇敼${functionName}
+ *
+ * @param ${className} ${functionName}
+ * @return 缁撴灉
+ */
+ public int update${ClassName}(${ClassName} ${className});
+
+ /**
+ * 鍒犻櫎${functionName}
+ *
+ * @param ${pkColumn.javaField} ${functionName}涓婚敭
+ * @return 缁撴灉
+ */
+ public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
+
+ /**
+ * 鎵归噺鍒犻櫎${functionName}
+ *
+ * @param ${pkColumn.javaField}s 闇�瑕佸垹闄ょ殑鏁版嵁涓婚敭闆嗗悎
+ * @return 缁撴灉
+ */
+ public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);
+#if($table.sub)
+
+ /**
+ * 鎵归噺鍒犻櫎${subTable.functionName}
+ *
+ * @param ${pkColumn.javaField}s 闇�瑕佸垹闄ょ殑鏁版嵁涓婚敭闆嗗悎
+ * @return 缁撴灉
+ */
+ public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);
+
+ /**
+ * 鎵归噺鏂板${subTable.functionName}
+ *
+ * @param ${subclassName}List ${subTable.functionName}鍒楄〃
+ * @return 缁撴灉
+ */
+ public int batch${subClassName}(List<${subClassName}> ${subclassName}List);
+
+
+ /**
+ * 閫氳繃${functionName}涓婚敭鍒犻櫎${subTable.functionName}淇℃伅
+ *
+ * @param ${pkColumn.javaField} ${functionName}ID
+ * @return 缁撴灉
+ */
+ public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField});
+#end
+}
diff --git a/ycl-generator/src/main/resources/vm/java/service.java.vm b/ycl-generator/src/main/resources/vm/java/service.java.vm
new file mode 100644
index 0000000..264882b
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/java/service.java.vm
@@ -0,0 +1,61 @@
+package ${packageName}.service;
+
+import java.util.List;
+import ${packageName}.domain.${ClassName};
+
+/**
+ * ${functionName}Service鎺ュ彛
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+public interface I${ClassName}Service
+{
+ /**
+ * 鏌ヨ${functionName}
+ *
+ * @param ${pkColumn.javaField} ${functionName}涓婚敭
+ * @return ${functionName}
+ */
+ public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
+
+ /**
+ * 鏌ヨ${functionName}鍒楄〃
+ *
+ * @param ${className} ${functionName}
+ * @return ${functionName}闆嗗悎
+ */
+ public List<${ClassName}> select${ClassName}List(${ClassName} ${className});
+
+ /**
+ * 鏂板${functionName}
+ *
+ * @param ${className} ${functionName}
+ * @return 缁撴灉
+ */
+ public int insert${ClassName}(${ClassName} ${className});
+
+ /**
+ * 淇敼${functionName}
+ *
+ * @param ${className} ${functionName}
+ * @return 缁撴灉
+ */
+ public int update${ClassName}(${ClassName} ${className});
+
+ /**
+ * 鎵归噺鍒犻櫎${functionName}
+ *
+ * @param ${pkColumn.javaField}s 闇�瑕佸垹闄ょ殑${functionName}涓婚敭闆嗗悎
+ * @return 缁撴灉
+ */
+ public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);
+
+ /**
+ * 鍒犻櫎${functionName}淇℃伅
+ *
+ * @param ${pkColumn.javaField} ${functionName}涓婚敭
+ * @return 缁撴灉
+ */
+ public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
+}
diff --git a/ycl-generator/src/main/resources/vm/java/serviceImpl.java.vm b/ycl-generator/src/main/resources/vm/java/serviceImpl.java.vm
new file mode 100644
index 0000000..3cb525a
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/java/serviceImpl.java.vm
@@ -0,0 +1,169 @@
+package ${packageName}.service.impl;
+
+import java.util.List;
+#foreach ($column in $columns)
+#if($column.javaField == 'createTime' || $column.javaField == 'updateTime')
+import com.ycl.common.utils.DateUtils;
+#break
+#end
+#end
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+#if($table.sub)
+import java.util.ArrayList;
+import com.ycl.common.utils.StringUtils;
+import org.springframework.transaction.annotation.Transactional;
+import ${packageName}.domain.${subClassName};
+#end
+import ${packageName}.mapper.${ClassName}Mapper;
+import ${packageName}.domain.${ClassName};
+import ${packageName}.service.I${ClassName}Service;
+
+/**
+ * ${functionName}Service涓氬姟灞傚鐞�
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+@Service
+public class ${ClassName}ServiceImpl implements I${ClassName}Service
+{
+ @Autowired
+ private ${ClassName}Mapper ${className}Mapper;
+
+ /**
+ * 鏌ヨ${functionName}
+ *
+ * @param ${pkColumn.javaField} ${functionName}涓婚敭
+ * @return ${functionName}
+ */
+ @Override
+ public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
+ {
+ return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField});
+ }
+
+ /**
+ * 鏌ヨ${functionName}鍒楄〃
+ *
+ * @param ${className} ${functionName}
+ * @return ${functionName}
+ */
+ @Override
+ public List<${ClassName}> select${ClassName}List(${ClassName} ${className})
+ {
+ return ${className}Mapper.select${ClassName}List(${className});
+ }
+
+ /**
+ * 鏂板${functionName}
+ *
+ * @param ${className} ${functionName}
+ * @return 缁撴灉
+ */
+#if($table.sub)
+ @Transactional
+#end
+ @Override
+ public int insert${ClassName}(${ClassName} ${className})
+ {
+#foreach ($column in $columns)
+#if($column.javaField == 'createTime')
+ ${className}.setCreateTime(DateUtils.getNowDate());
+#end
+#end
+#if($table.sub)
+ int rows = ${className}Mapper.insert${ClassName}(${className});
+ insert${subClassName}(${className});
+ return rows;
+#else
+ return ${className}Mapper.insert${ClassName}(${className});
+#end
+ }
+
+ /**
+ * 淇敼${functionName}
+ *
+ * @param ${className} ${functionName}
+ * @return 缁撴灉
+ */
+#if($table.sub)
+ @Transactional
+#end
+ @Override
+ public int update${ClassName}(${ClassName} ${className})
+ {
+#foreach ($column in $columns)
+#if($column.javaField == 'updateTime')
+ ${className}.setUpdateTime(DateUtils.getNowDate());
+#end
+#end
+#if($table.sub)
+ ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}());
+ insert${subClassName}(${className});
+#end
+ return ${className}Mapper.update${ClassName}(${className});
+ }
+
+ /**
+ * 鎵归噺鍒犻櫎${functionName}
+ *
+ * @param ${pkColumn.javaField}s 闇�瑕佸垹闄ょ殑${functionName}涓婚敭
+ * @return 缁撴灉
+ */
+#if($table.sub)
+ @Transactional
+#end
+ @Override
+ public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s)
+ {
+#if($table.sub)
+ ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s);
+#end
+ return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s);
+ }
+
+ /**
+ * 鍒犻櫎${functionName}淇℃伅
+ *
+ * @param ${pkColumn.javaField} ${functionName}涓婚敭
+ * @return 缁撴灉
+ */
+#if($table.sub)
+ @Transactional
+#end
+ @Override
+ public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
+ {
+#if($table.sub)
+ ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField});
+#end
+ return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField});
+ }
+#if($table.sub)
+
+ /**
+ * 鏂板${subTable.functionName}淇℃伅
+ *
+ * @param ${className} ${functionName}瀵硅薄
+ */
+ public void insert${subClassName}(${ClassName} ${className})
+ {
+ List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List();
+ ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}();
+ if (StringUtils.isNotNull(${subclassName}List))
+ {
+ List<${subClassName}> list = new ArrayList<${subClassName}>();
+ for (${subClassName} ${subclassName} : ${subclassName}List)
+ {
+ ${subclassName}.set${subTableFkClassName}(${pkColumn.javaField});
+ list.add(${subclassName});
+ }
+ if (list.size() > 0)
+ {
+ ${className}Mapper.batch${subClassName}(list);
+ }
+ }
+ }
+#end
+}
diff --git a/ycl-generator/src/main/resources/vm/java/sub-domain.java.vm b/ycl-generator/src/main/resources/vm/java/sub-domain.java.vm
new file mode 100644
index 0000000..2170974
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/java/sub-domain.java.vm
@@ -0,0 +1,74 @@
+package ${packageName}.domain;
+
+#foreach ($import in $subImportList)
+import ${import};
+#end
+import com.ycl.common.annotation.Excel;
+import com.ycl.common.core.domain.BaseEntity;
+
+/**
+ * ${subTable.functionName}瀵硅薄 ${subTableName}
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+public class ${subClassName} extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+#foreach ($column in $subTable.columns)
+#if(!$table.isSuperColumn($column.javaField))
+ /** $column.columnComment */
+#if($column.list)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($parentheseIndex != -1)
+ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+#elseif($column.javaType == 'Date')
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
+#else
+ @Excel(name = "${comment}")
+#end
+#end
+ private $column.javaType $column.javaField;
+
+#end
+#end
+#foreach ($column in $subTable.columns)
+#if(!$table.isSuperColumn($column.javaField))
+#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
+#set($AttrName=$column.javaField)
+#else
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#end
+ public void set${AttrName}($column.javaType $column.javaField)
+ {
+ this.$column.javaField = $column.javaField;
+ }
+
+ public $column.javaType get${AttrName}()
+ {
+ return $column.javaField;
+ }
+#end
+#end
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+#foreach ($column in $subTable.columns)
+#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
+#set($AttrName=$column.javaField)
+#else
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#end
+ .append("${column.javaField}", get${AttrName}())
+#end
+ .toString();
+ }
+}
diff --git a/ycl-generator/src/main/resources/vm/js/api.js.vm b/ycl-generator/src/main/resources/vm/js/api.js.vm
new file mode 100644
index 0000000..9295524
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/js/api.js.vm
@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 鏌ヨ${functionName}鍒楄〃
+export function list${BusinessName}(query) {
+ return request({
+ url: '/${moduleName}/${businessName}/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 鏌ヨ${functionName}璇︾粏
+export function get${BusinessName}(${pkColumn.javaField}) {
+ return request({
+ url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField},
+ method: 'get'
+ })
+}
+
+// 鏂板${functionName}
+export function add${BusinessName}(data) {
+ return request({
+ url: '/${moduleName}/${businessName}',
+ method: 'post',
+ data: data
+ })
+}
+
+// 淇敼${functionName}
+export function update${BusinessName}(data) {
+ return request({
+ url: '/${moduleName}/${businessName}',
+ method: 'put',
+ data: data
+ })
+}
+
+// 鍒犻櫎${functionName}
+export function del${BusinessName}(${pkColumn.javaField}) {
+ return request({
+ url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField},
+ method: 'delete'
+ })
+}
diff --git a/ycl-generator/src/main/resources/vm/sql/sql.vm b/ycl-generator/src/main/resources/vm/sql/sql.vm
new file mode 100644
index 0000000..0575583
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/sql/sql.vm
@@ -0,0 +1,22 @@
+-- 鑿滃崟 SQL
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', sysdate(), '', null, '${functionName}鑿滃崟');
+
+-- 鎸夐挳鐖惰彍鍗旾D
+SELECT @parentId := LAST_INSERT_ID();
+
+-- 鎸夐挳 SQL
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('${functionName}鏌ヨ', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', sysdate(), '', null, '');
+
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('${functionName}鏂板', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', sysdate(), '', null, '');
+
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('${functionName}淇敼', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', sysdate(), '', null, '');
+
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('${functionName}鍒犻櫎', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', sysdate(), '', null, '');
+
+insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values('${functionName}瀵煎嚭', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', sysdate(), '', null, '');
\ No newline at end of file
diff --git a/ycl-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ycl-generator/src/main/resources/vm/vue/index-tree.vue.vm
new file mode 100644
index 0000000..a4c64a0
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/vue/index-tree.vue.vm
@@ -0,0 +1,505 @@
+<template>
+ <div class="app-container">
+ <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+#foreach($column in $columns)
+#if($column.query)
+#set($dictType=$column.dictType)
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.htmlType == "input")
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-input
+ v-model="queryParams.${column.javaField}"
+ placeholder="璇疯緭鍏�${comment}"
+ clearable
+ @keyup.enter.native="handleQuery"
+ />
+ </el-form-item>
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable>
+ <el-option
+ v-for="dict in dict.type.${dictType}"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ />
+ </el-select>
+ </el-form-item>
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable>
+ <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-date-picker clearable
+ v-model="queryParams.${column.javaField}"
+ type="date"
+ value-format="yyyy-MM-dd"
+ placeholder="閫夋嫨${comment}">
+ </el-date-picker>
+ </el-form-item>
+#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+ <el-form-item label="${comment}">
+ <el-date-picker
+ v-model="daterange${AttrName}"
+ style="width: 240px"
+ value-format="yyyy-MM-dd"
+ type="daterange"
+ range-separator="-"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ ></el-date-picker>
+ </el-form-item>
+#end
+#end
+#end
+ <el-form-item>
+ <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button>
+ <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+
+ <el-row :gutter="10" class="mb8">
+ <el-col :span="1.5">
+ <el-button
+ type="primary"
+ plain
+ icon="el-icon-plus"
+ size="mini"
+ @click="handleAdd"
+ v-hasPermi="['${moduleName}:${businessName}:add']"
+ >鏂板</el-button>
+ </el-col>
+ <el-col :span="1.5">
+ <el-button
+ type="info"
+ plain
+ icon="el-icon-sort"
+ size="mini"
+ @click="toggleExpandAll"
+ >灞曞紑/鎶樺彔</el-button>
+ </el-col>
+ <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+ </el-row>
+
+ <el-table
+ v-if="refreshTable"
+ v-loading="loading"
+ :data="${businessName}List"
+ row-key="${treeCode}"
+ :default-expand-all="isExpandAll"
+ :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
+ >
+#foreach($column in $columns)
+#set($javaField=$column.javaField)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.pk)
+#elseif($column.list && $column.htmlType == "datetime")
+ <el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
+ <template slot-scope="scope">
+ <span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span>
+ </template>
+ </el-table-column>
+#elseif($column.list && $column.htmlType == "imageUpload")
+ <el-table-column label="${comment}" align="center" prop="${javaField}" width="100">
+ <template slot-scope="scope">
+ <image-preview :src="scope.row.${javaField}" :width="50" :height="50"/>
+ </template>
+ </el-table-column>
+#elseif($column.list && "" != $column.dictType)
+ <el-table-column label="${comment}" align="center" prop="${javaField}">
+ <template slot-scope="scope">
+#if($column.htmlType == "checkbox")
+ <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/>
+#else
+ <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField}"/>
+#end
+ </template>
+ </el-table-column>
+#elseif($column.list && "" != $javaField)
+#if(${foreach.index} == 1)
+ <el-table-column label="${comment}" prop="${javaField}" />
+#else
+ <el-table-column label="${comment}" align="center" prop="${javaField}" />
+#end
+#end
+#end
+ <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+ <template slot-scope="scope">
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-edit"
+ @click="handleUpdate(scope.row)"
+ v-hasPermi="['${moduleName}:${businessName}:edit']"
+ >淇敼</el-button>
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-plus"
+ @click="handleAdd(scope.row)"
+ v-hasPermi="['${moduleName}:${businessName}:add']"
+ >鏂板</el-button>
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-delete"
+ @click="handleDelete(scope.row)"
+ v-hasPermi="['${moduleName}:${businessName}:remove']"
+ >鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <!-- 娣诲姞鎴栦慨鏀�${functionName}瀵硅瘽妗� -->
+ <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+ <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+#foreach($column in $columns)
+#set($field=$column.javaField)
+#if($column.insert && !$column.pk)
+#if(($column.usableColumn) || (!$column.superColumn))
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#set($dictType=$column.dictType)
+#if("" != $treeParentCode && $column.javaField == $treeParentCode)
+ <el-form-item label="${comment}" prop="${treeParentCode}">
+ <treeselect v-model="form.${treeParentCode}" :options="${businessName}Options" :normalizer="normalizer" placeholder="璇烽�夋嫨${comment}" />
+ </el-form-item>
+#elseif($column.htmlType == "input")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-input v-model="form.${field}" placeholder="璇疯緭鍏�${comment}" />
+ </el-form-item>
+#elseif($column.htmlType == "imageUpload")
+ <el-form-item label="${comment}" prop="${field}">
+ <image-upload v-model="form.${field}"/>
+ </el-form-item>
+#elseif($column.htmlType == "fileUpload")
+ <el-form-item label="${comment}" prop="${field}">
+ <file-upload v-model="form.${field}"/>
+ </el-form-item>
+#elseif($column.htmlType == "editor")
+ <el-form-item label="${comment}">
+ <editor v-model="form.${field}" :min-height="192"/>
+ </el-form-item>
+#elseif($column.htmlType == "select" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
+ <el-option
+ v-for="dict in dict.type.${dictType}"
+ :key="dict.value"
+ :label="dict.label"
+#if($column.javaType == "Integer" || $column.javaType == "Long")
+ :value="parseInt(dict.value)"
+#else
+ :value="dict.value"
+#end
+ ></el-option>
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "select" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
+ <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "checkbox" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-checkbox-group v-model="form.${field}">
+ <el-checkbox
+ v-for="dict in dict.type.${dictType}"
+ :key="dict.value"
+ :label="dict.value">
+ {{dict.label}}
+ </el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+#elseif($column.htmlType == "checkbox" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-checkbox-group v-model="form.${field}">
+ <el-checkbox>璇烽�夋嫨瀛楀吀鐢熸垚</el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+#elseif($column.htmlType == "radio" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-radio-group v-model="form.${field}">
+ <el-radio
+ v-for="dict in dict.type.${dictType}"
+ :key="dict.value"
+#if($column.javaType == "Integer" || $column.javaType == "Long")
+ :label="parseInt(dict.value)"
+#else
+ :label="dict.value"
+#end
+ >{{dict.label}}</el-radio>
+ </el-radio-group>
+ </el-form-item>
+#elseif($column.htmlType == "radio" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-radio-group v-model="form.${field}">
+ <el-radio label="1">璇烽�夋嫨瀛楀吀鐢熸垚</el-radio>
+ </el-radio-group>
+ </el-form-item>
+#elseif($column.htmlType == "datetime")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-date-picker clearable
+ v-model="form.${field}"
+ type="date"
+ value-format="yyyy-MM-dd"
+ placeholder="閫夋嫨${comment}">
+ </el-date-picker>
+ </el-form-item>
+#elseif($column.htmlType == "textarea")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-input v-model="form.${field}" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
+ </el-form-item>
+#end
+#end
+#end
+#end
+ </el-form>
+ <div slot="footer" class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+ <el-button @click="cancel">鍙� 娑�</el-button>
+ </div>
+ </el-dialog>
+ </div>
+</template>
+
+<script>
+import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+
+export default {
+ name: "${BusinessName}",
+#if(${dicts} != '')
+ dicts: [${dicts}],
+#end
+ components: {
+ Treeselect
+ },
+ data() {
+ return {
+ // 閬僵灞�
+ loading: true,
+ // 鏄剧ず鎼滅储鏉′欢
+ showSearch: true,
+ // ${functionName}琛ㄦ牸鏁版嵁
+ ${businessName}List: [],
+ // ${functionName}鏍戦�夐」
+ ${businessName}Options: [],
+ // 寮瑰嚭灞傛爣棰�
+ title: "",
+ // 鏄惁鏄剧ず寮瑰嚭灞�
+ open: false,
+ // 鏄惁灞曞紑锛岄粯璁ゅ叏閮ㄥ睍寮�
+ isExpandAll: true,
+ // 閲嶆柊娓叉煋琛ㄦ牸鐘舵��
+ refreshTable: true,
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ // $comment鏃堕棿鑼冨洿
+ daterange${AttrName}: [],
+#end
+#end
+ // 鏌ヨ鍙傛暟
+ queryParams: {
+#foreach ($column in $columns)
+#if($column.query)
+ $column.javaField: null#if($foreach.count != $columns.size()),#end
+#end
+#end
+ },
+ // 琛ㄥ崟鍙傛暟
+ form: {},
+ // 琛ㄥ崟鏍¢獙
+ rules: {
+#foreach ($column in $columns)
+#if($column.required)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+ $column.javaField: [
+ { required: true, message: "$comment涓嶈兘涓虹┖", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
+ ]#if($foreach.count != $columns.size()),#end
+#end
+#end
+ }
+ };
+ },
+ created() {
+ this.getList();
+ },
+ methods: {
+ /** 鏌ヨ${functionName}鍒楄〃 */
+ getList() {
+ this.loading = true;
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+ this.queryParams.params = {};
+#break
+#end
+#end
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ if (null != this.daterange${AttrName} && '' != this.daterange${AttrName}) {
+ this.queryParams.params["begin${AttrName}"] = this.daterange${AttrName}[0];
+ this.queryParams.params["end${AttrName}"] = this.daterange${AttrName}[1];
+ }
+#end
+#end
+ list${BusinessName}(this.queryParams).then(response => {
+ this.${businessName}List = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
+ this.loading = false;
+ });
+ },
+ /** 杞崲${functionName}鏁版嵁缁撴瀯 */
+ normalizer(node) {
+ if (node.children && !node.children.length) {
+ delete node.children;
+ }
+ return {
+ id: node.${treeCode},
+ label: node.${treeName},
+ children: node.children
+ };
+ },
+ /** 鏌ヨ${functionName}涓嬫媺鏍戠粨鏋� */
+ getTreeselect() {
+ list${BusinessName}().then(response => {
+ this.${businessName}Options = [];
+ const data = { ${treeCode}: 0, ${treeName}: '椤剁骇鑺傜偣', children: [] };
+ data.children = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
+ this.${businessName}Options.push(data);
+ });
+ },
+ // 鍙栨秷鎸夐挳
+ cancel() {
+ this.open = false;
+ this.reset();
+ },
+ // 琛ㄥ崟閲嶇疆
+ reset() {
+ this.form = {
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ $column.javaField: []#if($foreach.count != $columns.size()),#end
+#else
+ $column.javaField: null#if($foreach.count != $columns.size()),#end
+#end
+#end
+ };
+ this.resetForm("form");
+ },
+ /** 鎼滅储鎸夐挳鎿嶄綔 */
+ handleQuery() {
+ this.getList();
+ },
+ /** 閲嶇疆鎸夐挳鎿嶄綔 */
+ resetQuery() {
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ this.daterange${AttrName} = [];
+#end
+#end
+ this.resetForm("queryForm");
+ this.handleQuery();
+ },
+ /** 鏂板鎸夐挳鎿嶄綔 */
+ handleAdd(row) {
+ this.reset();
+ this.getTreeselect();
+ if (row != null && row.${treeCode}) {
+ this.form.${treeParentCode} = row.${treeCode};
+ } else {
+ this.form.${treeParentCode} = 0;
+ }
+ this.open = true;
+ this.title = "娣诲姞${functionName}";
+ },
+ /** 灞曞紑/鎶樺彔鎿嶄綔 */
+ toggleExpandAll() {
+ this.refreshTable = false;
+ this.isExpandAll = !this.isExpandAll;
+ this.$nextTick(() => {
+ this.refreshTable = true;
+ });
+ },
+ /** 淇敼鎸夐挳鎿嶄綔 */
+ handleUpdate(row) {
+ this.reset();
+ this.getTreeselect();
+ if (row != null) {
+ this.form.${treeParentCode} = row.${treeCode};
+ }
+ get${BusinessName}(row.${pkColumn.javaField}).then(response => {
+ this.form = response.data;
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ this.form.$column.javaField = this.form.${column.javaField}.split(",");
+#end
+#end
+ this.open = true;
+ this.title = "淇敼${functionName}";
+ });
+ },
+ /** 鎻愪氦鎸夐挳 */
+ submitForm() {
+ this.#[[$]]#refs["form"].validate(valid => {
+ if (valid) {
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ this.form.$column.javaField = this.form.${column.javaField}.join(",");
+#end
+#end
+ if (this.form.${pkColumn.javaField} != null) {
+ update${BusinessName}(this.form).then(response => {
+ this.#[[$modal]]#.msgSuccess("淇敼鎴愬姛");
+ this.open = false;
+ this.getList();
+ });
+ } else {
+ add${BusinessName}(this.form).then(response => {
+ this.#[[$modal]]#.msgSuccess("鏂板鎴愬姛");
+ this.open = false;
+ this.getList();
+ });
+ }
+ }
+ });
+ },
+ /** 鍒犻櫎鎸夐挳鎿嶄綔 */
+ handleDelete(row) {
+ this.#[[$modal]]#.confirm('鏄惁纭鍒犻櫎${functionName}缂栧彿涓�"' + row.${pkColumn.javaField} + '"鐨勬暟鎹」锛�').then(function() {
+ return del${BusinessName}(row.${pkColumn.javaField});
+ }).then(() => {
+ this.getList();
+ this.#[[$modal]]#.msgSuccess("鍒犻櫎鎴愬姛");
+ }).catch(() => {});
+ }
+ }
+};
+</script>
diff --git a/ycl-generator/src/main/resources/vm/vue/index.vue.vm b/ycl-generator/src/main/resources/vm/vue/index.vue.vm
new file mode 100644
index 0000000..6296014
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/vue/index.vue.vm
@@ -0,0 +1,602 @@
+<template>
+ <div class="app-container">
+ <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+#foreach($column in $columns)
+#if($column.query)
+#set($dictType=$column.dictType)
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.htmlType == "input")
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-input
+ v-model="queryParams.${column.javaField}"
+ placeholder="璇疯緭鍏�${comment}"
+ clearable
+ @keyup.enter.native="handleQuery"
+ />
+ </el-form-item>
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable>
+ <el-option
+ v-for="dict in dict.type.${dictType}"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ />
+ </el-select>
+ </el-form-item>
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable>
+ <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-date-picker clearable
+ v-model="queryParams.${column.javaField}"
+ type="date"
+ value-format="yyyy-MM-dd"
+ placeholder="璇烽�夋嫨${comment}">
+ </el-date-picker>
+ </el-form-item>
+#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+ <el-form-item label="${comment}">
+ <el-date-picker
+ v-model="daterange${AttrName}"
+ style="width: 240px"
+ value-format="yyyy-MM-dd"
+ type="daterange"
+ range-separator="-"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ ></el-date-picker>
+ </el-form-item>
+#end
+#end
+#end
+ <el-form-item>
+ <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button>
+ <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+
+ <el-row :gutter="10" class="mb8">
+ <el-col :span="1.5">
+ <el-button
+ type="primary"
+ plain
+ icon="el-icon-plus"
+ size="mini"
+ @click="handleAdd"
+ v-hasPermi="['${moduleName}:${businessName}:add']"
+ >鏂板</el-button>
+ </el-col>
+ <el-col :span="1.5">
+ <el-button
+ type="success"
+ plain
+ icon="el-icon-edit"
+ size="mini"
+ :disabled="single"
+ @click="handleUpdate"
+ v-hasPermi="['${moduleName}:${businessName}:edit']"
+ >淇敼</el-button>
+ </el-col>
+ <el-col :span="1.5">
+ <el-button
+ type="danger"
+ plain
+ icon="el-icon-delete"
+ size="mini"
+ :disabled="multiple"
+ @click="handleDelete"
+ v-hasPermi="['${moduleName}:${businessName}:remove']"
+ >鍒犻櫎</el-button>
+ </el-col>
+ <el-col :span="1.5">
+ <el-button
+ type="warning"
+ plain
+ icon="el-icon-download"
+ size="mini"
+ @click="handleExport"
+ v-hasPermi="['${moduleName}:${businessName}:export']"
+ >瀵煎嚭</el-button>
+ </el-col>
+ <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+ </el-row>
+
+ <el-table v-loading="loading" :data="${businessName}List" @selection-change="handleSelectionChange">
+ <el-table-column type="selection" width="55" align="center" />
+#foreach($column in $columns)
+#set($javaField=$column.javaField)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.pk)
+ <el-table-column label="${comment}" align="center" prop="${javaField}" />
+#elseif($column.list && $column.htmlType == "datetime")
+ <el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
+ <template slot-scope="scope">
+ <span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span>
+ </template>
+ </el-table-column>
+#elseif($column.list && $column.htmlType == "imageUpload")
+ <el-table-column label="${comment}" align="center" prop="${javaField}" width="100">
+ <template slot-scope="scope">
+ <image-preview :src="scope.row.${javaField}" :width="50" :height="50"/>
+ </template>
+ </el-table-column>
+#elseif($column.list && "" != $column.dictType)
+ <el-table-column label="${comment}" align="center" prop="${javaField}">
+ <template slot-scope="scope">
+#if($column.htmlType == "checkbox")
+ <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/>
+#else
+ <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField}"/>
+#end
+ </template>
+ </el-table-column>
+#elseif($column.list && "" != $javaField)
+ <el-table-column label="${comment}" align="center" prop="${javaField}" />
+#end
+#end
+ <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+ <template slot-scope="scope">
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-edit"
+ @click="handleUpdate(scope.row)"
+ v-hasPermi="['${moduleName}:${businessName}:edit']"
+ >淇敼</el-button>
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-delete"
+ @click="handleDelete(scope.row)"
+ v-hasPermi="['${moduleName}:${businessName}:remove']"
+ >鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <pagination
+ v-show="total>0"
+ :total="total"
+ :page.sync="queryParams.pageNum"
+ :limit.sync="queryParams.pageSize"
+ @pagination="getList"
+ />
+
+ <!-- 娣诲姞鎴栦慨鏀�${functionName}瀵硅瘽妗� -->
+ <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+ <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+#foreach($column in $columns)
+#set($field=$column.javaField)
+#if($column.insert && !$column.pk)
+#if(($column.usableColumn) || (!$column.superColumn))
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#set($dictType=$column.dictType)
+#if($column.htmlType == "input")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-input v-model="form.${field}" placeholder="璇疯緭鍏�${comment}" />
+ </el-form-item>
+#elseif($column.htmlType == "imageUpload")
+ <el-form-item label="${comment}" prop="${field}">
+ <image-upload v-model="form.${field}"/>
+ </el-form-item>
+#elseif($column.htmlType == "fileUpload")
+ <el-form-item label="${comment}" prop="${field}">
+ <file-upload v-model="form.${field}"/>
+ </el-form-item>
+#elseif($column.htmlType == "editor")
+ <el-form-item label="${comment}">
+ <editor v-model="form.${field}" :min-height="192"/>
+ </el-form-item>
+#elseif($column.htmlType == "select" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
+ <el-option
+ v-for="dict in dict.type.${dictType}"
+ :key="dict.value"
+ :label="dict.label"
+#if($column.javaType == "Integer" || $column.javaType == "Long")
+ :value="parseInt(dict.value)"
+#else
+ :value="dict.value"
+#end
+ ></el-option>
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "select" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
+ <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "checkbox" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-checkbox-group v-model="form.${field}">
+ <el-checkbox
+ v-for="dict in dict.type.${dictType}"
+ :key="dict.value"
+ :label="dict.value">
+ {{dict.label}}
+ </el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+#elseif($column.htmlType == "checkbox" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-checkbox-group v-model="form.${field}">
+ <el-checkbox>璇烽�夋嫨瀛楀吀鐢熸垚</el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+#elseif($column.htmlType == "radio" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-radio-group v-model="form.${field}">
+ <el-radio
+ v-for="dict in dict.type.${dictType}"
+ :key="dict.value"
+#if($column.javaType == "Integer" || $column.javaType == "Long")
+ :label="parseInt(dict.value)"
+#else
+ :label="dict.value"
+#end
+ >{{dict.label}}</el-radio>
+ </el-radio-group>
+ </el-form-item>
+#elseif($column.htmlType == "radio" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-radio-group v-model="form.${field}">
+ <el-radio label="1">璇烽�夋嫨瀛楀吀鐢熸垚</el-radio>
+ </el-radio-group>
+ </el-form-item>
+#elseif($column.htmlType == "datetime")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-date-picker clearable
+ v-model="form.${field}"
+ type="date"
+ value-format="yyyy-MM-dd"
+ placeholder="璇烽�夋嫨${comment}">
+ </el-date-picker>
+ </el-form-item>
+#elseif($column.htmlType == "textarea")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-input v-model="form.${field}" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
+ </el-form-item>
+#end
+#end
+#end
+#end
+#if($table.sub)
+ <el-divider content-position="center">${subTable.functionName}淇℃伅</el-divider>
+ <el-row :gutter="10" class="mb8">
+ <el-col :span="1.5">
+ <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd${subClassName}">娣诲姞</el-button>
+ </el-col>
+ <el-col :span="1.5">
+ <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDelete${subClassName}">鍒犻櫎</el-button>
+ </el-col>
+ </el-row>
+ <el-table :data="${subclassName}List" :row-class-name="row${subClassName}Index" @selection-change="handle${subClassName}SelectionChange" ref="${subclassName}">
+ <el-table-column type="selection" width="50" align="center" />
+ <el-table-column label="搴忓彿" align="center" prop="index" width="50"/>
+#foreach($column in $subTable.columns)
+#set($javaField=$column.javaField)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.pk || $javaField == ${subTableFkclassName})
+#elseif($column.list && $column.htmlType == "input")
+ <el-table-column label="$comment" prop="${javaField}" width="150">
+ <template slot-scope="scope">
+ <el-input v-model="scope.row.$javaField" placeholder="璇疯緭鍏�$comment" />
+ </template>
+ </el-table-column>
+#elseif($column.list && $column.htmlType == "datetime")
+ <el-table-column label="$comment" prop="${javaField}" width="240">
+ <template slot-scope="scope">
+ <el-date-picker clearable v-model="scope.row.$javaField" type="date" value-format="yyyy-MM-dd" placeholder="璇烽�夋嫨$comment" />
+ </template>
+ </el-table-column>
+#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" != $column.dictType)
+ <el-table-column label="$comment" prop="${javaField}" width="150">
+ <template slot-scope="scope">
+ <el-select v-model="scope.row.$javaField" placeholder="璇烽�夋嫨$comment">
+ <el-option
+ v-for="dict in dict.type.$column.dictType"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ ></el-option>
+ </el-select>
+ </template>
+ </el-table-column>
+#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" == $column.dictType)
+ <el-table-column label="$comment" prop="${javaField}" width="150">
+ <template slot-scope="scope">
+ <el-select v-model="scope.row.$javaField" placeholder="璇烽�夋嫨$comment">
+ <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+ </el-select>
+ </template>
+ </el-table-column>
+#end
+#end
+ </el-table>
+#end
+ </el-form>
+ <div slot="footer" class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+ <el-button @click="cancel">鍙� 娑�</el-button>
+ </div>
+ </el-dialog>
+ </div>
+</template>
+
+<script>
+import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}";
+
+export default {
+ name: "${BusinessName}",
+#if(${dicts} != '')
+ dicts: [${dicts}],
+#end
+ data() {
+ return {
+ // 閬僵灞�
+ loading: true,
+ // 閫変腑鏁扮粍
+ ids: [],
+#if($table.sub)
+ // 瀛愯〃閫変腑鏁版嵁
+ checked${subClassName}: [],
+#end
+ // 闈炲崟涓鐢�
+ single: true,
+ // 闈炲涓鐢�
+ multiple: true,
+ // 鏄剧ず鎼滅储鏉′欢
+ showSearch: true,
+ // 鎬绘潯鏁�
+ total: 0,
+ // ${functionName}琛ㄦ牸鏁版嵁
+ ${businessName}List: [],
+#if($table.sub)
+ // ${subTable.functionName}琛ㄦ牸鏁版嵁
+ ${subclassName}List: [],
+#end
+ // 寮瑰嚭灞傛爣棰�
+ title: "",
+ // 鏄惁鏄剧ず寮瑰嚭灞�
+ open: false,
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ // $comment鏃堕棿鑼冨洿
+ daterange${AttrName}: [],
+#end
+#end
+ // 鏌ヨ鍙傛暟
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+#foreach ($column in $columns)
+#if($column.query)
+ $column.javaField: null#if($foreach.count != $columns.size()),#end
+#end
+#end
+ },
+ // 琛ㄥ崟鍙傛暟
+ form: {},
+ // 琛ㄥ崟鏍¢獙
+ rules: {
+#foreach ($column in $columns)
+#if($column.required)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+ $column.javaField: [
+ { required: true, message: "$comment涓嶈兘涓虹┖", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
+ ]#if($foreach.count != $columns.size()),#end
+#end
+#end
+ }
+ };
+ },
+ created() {
+ this.getList();
+ },
+ methods: {
+ /** 鏌ヨ${functionName}鍒楄〃 */
+ getList() {
+ this.loading = true;
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+ this.queryParams.params = {};
+#break
+#end
+#end
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ if (null != this.daterange${AttrName} && '' != this.daterange${AttrName}) {
+ this.queryParams.params["begin${AttrName}"] = this.daterange${AttrName}[0];
+ this.queryParams.params["end${AttrName}"] = this.daterange${AttrName}[1];
+ }
+#end
+#end
+ list${BusinessName}(this.queryParams).then(response => {
+ this.${businessName}List = response.rows;
+ this.total = response.total;
+ this.loading = false;
+ });
+ },
+ // 鍙栨秷鎸夐挳
+ cancel() {
+ this.open = false;
+ this.reset();
+ },
+ // 琛ㄥ崟閲嶇疆
+ reset() {
+ this.form = {
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ $column.javaField: []#if($foreach.count != $columns.size()),#end
+#else
+ $column.javaField: null#if($foreach.count != $columns.size()),#end
+#end
+#end
+ };
+#if($table.sub)
+ this.${subclassName}List = [];
+#end
+ this.resetForm("form");
+ },
+ /** 鎼滅储鎸夐挳鎿嶄綔 */
+ handleQuery() {
+ this.queryParams.pageNum = 1;
+ this.getList();
+ },
+ /** 閲嶇疆鎸夐挳鎿嶄綔 */
+ resetQuery() {
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ this.daterange${AttrName} = [];
+#end
+#end
+ this.resetForm("queryForm");
+ this.handleQuery();
+ },
+ // 澶氶�夋閫変腑鏁版嵁
+ handleSelectionChange(selection) {
+ this.ids = selection.map(item => item.${pkColumn.javaField})
+ this.single = selection.length!==1
+ this.multiple = !selection.length
+ },
+ /** 鏂板鎸夐挳鎿嶄綔 */
+ handleAdd() {
+ this.reset();
+ this.open = true;
+ this.title = "娣诲姞${functionName}";
+ },
+ /** 淇敼鎸夐挳鎿嶄綔 */
+ handleUpdate(row) {
+ this.reset();
+ const ${pkColumn.javaField} = row.${pkColumn.javaField} || this.ids
+ get${BusinessName}(${pkColumn.javaField}).then(response => {
+ this.form = response.data;
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ this.form.$column.javaField = this.form.${column.javaField}.split(",");
+#end
+#end
+#if($table.sub)
+ this.${subclassName}List = response.data.${subclassName}List;
+#end
+ this.open = true;
+ this.title = "淇敼${functionName}";
+ });
+ },
+ /** 鎻愪氦鎸夐挳 */
+ submitForm() {
+ this.#[[$]]#refs["form"].validate(valid => {
+ if (valid) {
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ this.form.$column.javaField = this.form.${column.javaField}.join(",");
+#end
+#end
+#if($table.sub)
+ this.form.${subclassName}List = this.${subclassName}List;
+#end
+ if (this.form.${pkColumn.javaField} != null) {
+ update${BusinessName}(this.form).then(response => {
+ this.#[[$modal]]#.msgSuccess("淇敼鎴愬姛");
+ this.open = false;
+ this.getList();
+ });
+ } else {
+ add${BusinessName}(this.form).then(response => {
+ this.#[[$modal]]#.msgSuccess("鏂板鎴愬姛");
+ this.open = false;
+ this.getList();
+ });
+ }
+ }
+ });
+ },
+ /** 鍒犻櫎鎸夐挳鎿嶄綔 */
+ handleDelete(row) {
+ const ${pkColumn.javaField}s = row.${pkColumn.javaField} || this.ids;
+ this.#[[$modal]]#.confirm('鏄惁纭鍒犻櫎${functionName}缂栧彿涓�"' + ${pkColumn.javaField}s + '"鐨勬暟鎹」锛�').then(function() {
+ return del${BusinessName}(${pkColumn.javaField}s);
+ }).then(() => {
+ this.getList();
+ this.#[[$modal]]#.msgSuccess("鍒犻櫎鎴愬姛");
+ }).catch(() => {});
+ },
+#if($table.sub)
+ /** ${subTable.functionName}搴忓彿 */
+ row${subClassName}Index({ row, rowIndex }) {
+ row.index = rowIndex + 1;
+ },
+ /** ${subTable.functionName}娣诲姞鎸夐挳鎿嶄綔 */
+ handleAdd${subClassName}() {
+ let obj = {};
+#foreach($column in $subTable.columns)
+#if($column.pk || $column.javaField == ${subTableFkclassName})
+#elseif($column.list && "" != $javaField)
+ obj.$column.javaField = "";
+#end
+#end
+ this.${subclassName}List.push(obj);
+ },
+ /** ${subTable.functionName}鍒犻櫎鎸夐挳鎿嶄綔 */
+ handleDelete${subClassName}() {
+ if (this.checked${subClassName}.length == 0) {
+ this.#[[$modal]]#.msgError("璇峰厛閫夋嫨瑕佸垹闄ょ殑${subTable.functionName}鏁版嵁");
+ } else {
+ const ${subclassName}List = this.${subclassName}List;
+ const checked${subClassName} = this.checked${subClassName};
+ this.${subclassName}List = ${subclassName}List.filter(function(item) {
+ return checked${subClassName}.indexOf(item.index) == -1
+ });
+ }
+ },
+ /** 澶嶉�夋閫変腑鏁版嵁 */
+ handle${subClassName}SelectionChange(selection) {
+ this.checked${subClassName} = selection.map(item => item.index)
+ },
+#end
+ /** 瀵煎嚭鎸夐挳鎿嶄綔 */
+ handleExport() {
+ this.download('${moduleName}/${businessName}/export', {
+ ...this.queryParams
+ }, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
+ }
+ }
+};
+</script>
diff --git a/ycl-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm b/ycl-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm
new file mode 100644
index 0000000..7bbd2fc
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/vue/v3/index-tree.vue.vm
@@ -0,0 +1,474 @@
+<template>
+ <div class="app-container">
+ <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+#foreach($column in $columns)
+#if($column.query)
+#set($dictType=$column.dictType)
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.htmlType == "input")
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-input
+ v-model="queryParams.${column.javaField}"
+ placeholder="璇疯緭鍏�${comment}"
+ clearable
+ @keyup.enter="handleQuery"
+ />
+ </el-form-item>
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable>
+ <el-option
+ v-for="dict in ${dictType}"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ />
+ </el-select>
+ </el-form-item>
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable>
+ <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-date-picker clearable
+ v-model="queryParams.${column.javaField}"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="閫夋嫨${comment}">
+ </el-date-picker>
+ </el-form-item>
+#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+ <el-form-item label="${comment}" style="width: 308px">
+ <el-date-picker
+ v-model="daterange${AttrName}"
+ value-format="YYYY-MM-DD"
+ type="daterange"
+ range-separator="-"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ ></el-date-picker>
+ </el-form-item>
+#end
+#end
+#end
+ <el-form-item>
+ <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+ <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+
+ <el-row :gutter="10" class="mb8">
+ <el-col :span="1.5">
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="handleAdd"
+ v-hasPermi="['${moduleName}:${businessName}:add']"
+ >鏂板</el-button>
+ </el-col>
+ <el-col :span="1.5">
+ <el-button
+ type="info"
+ plain
+ icon="Sort"
+ @click="toggleExpandAll"
+ >灞曞紑/鎶樺彔</el-button>
+ </el-col>
+ <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+ </el-row>
+
+ <el-table
+ v-if="refreshTable"
+ v-loading="loading"
+ :data="${businessName}List"
+ row-key="${treeCode}"
+ :default-expand-all="isExpandAll"
+ :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
+ >
+#foreach($column in $columns)
+#set($javaField=$column.javaField)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.pk)
+#elseif($column.list && $column.htmlType == "datetime")
+ <el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
+ <template #default="scope">
+ <span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span>
+ </template>
+ </el-table-column>
+#elseif($column.list && $column.htmlType == "imageUpload")
+ <el-table-column label="${comment}" align="center" prop="${javaField}" width="100">
+ <template #default="scope">
+ <image-preview :src="scope.row.${javaField}" :width="50" :height="50"/>
+ </template>
+ </el-table-column>
+#elseif($column.list && "" != $column.dictType)
+ <el-table-column label="${comment}" align="center" prop="${javaField}">
+ <template #default="scope">
+#if($column.htmlType == "checkbox")
+ <dict-tag :options="${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/>
+#else
+ <dict-tag :options="${column.dictType}" :value="scope.row.${javaField}"/>
+#end
+ </template>
+ </el-table-column>
+#elseif($column.list && "" != $javaField)
+#if(${foreach.index} == 1)
+ <el-table-column label="${comment}" prop="${javaField}" />
+#else
+ <el-table-column label="${comment}" align="center" prop="${javaField}" />
+#end
+#end
+#end
+ <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+ <template #default="scope">
+ <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']">淇敼</el-button>
+ <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['${moduleName}:${businessName}:add']">鏂板</el-button>
+ <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <!-- 娣诲姞鎴栦慨鏀�${functionName}瀵硅瘽妗� -->
+ <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+ <el-form ref="${businessName}Ref" :model="form" :rules="rules" label-width="80px">
+#foreach($column in $columns)
+#set($field=$column.javaField)
+#if($column.insert && !$column.pk)
+#if(($column.usableColumn) || (!$column.superColumn))
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#set($dictType=$column.dictType)
+#if("" != $treeParentCode && $column.javaField == $treeParentCode)
+ <el-form-item label="${comment}" prop="${treeParentCode}">
+ <el-tree-select
+ v-model="form.${treeParentCode}"
+ :data="${businessName}Options"
+ :props="{ value: '${treeCode}', label: '${treeName}', children: 'children' }"
+ value-key="${treeCode}"
+ placeholder="璇烽�夋嫨${comment}"
+ check-strictly
+ />
+ </el-form-item>
+#elseif($column.htmlType == "input")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-input v-model="form.${field}" placeholder="璇疯緭鍏�${comment}" />
+ </el-form-item>
+#elseif($column.htmlType == "imageUpload")
+ <el-form-item label="${comment}" prop="${field}">
+ <image-upload v-model="form.${field}"/>
+ </el-form-item>
+#elseif($column.htmlType == "fileUpload")
+ <el-form-item label="${comment}" prop="${field}">
+ <file-upload v-model="form.${field}"/>
+ </el-form-item>
+#elseif($column.htmlType == "editor")
+ <el-form-item label="${comment}">
+ <editor v-model="form.${field}" :min-height="192"/>
+ </el-form-item>
+#elseif($column.htmlType == "select" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
+ <el-option
+ v-for="dict in ${dictType}"
+ :key="dict.value"
+ :label="dict.label"
+#if($column.javaType == "Integer" || $column.javaType == "Long")
+ :value="parseInt(dict.value)"
+#else
+ :value="dict.value"
+#end
+ ></el-option>
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "select" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
+ <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "checkbox" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-checkbox-group v-model="form.${field}">
+ <el-checkbox
+ v-for="dict in ${dictType}"
+ :key="dict.value"
+ :label="dict.value">
+ {{dict.label}}
+ </el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+#elseif($column.htmlType == "checkbox" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-checkbox-group v-model="form.${field}">
+ <el-checkbox>璇烽�夋嫨瀛楀吀鐢熸垚</el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+#elseif($column.htmlType == "radio" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-radio-group v-model="form.${field}">
+ <el-radio
+ v-for="dict in ${dictType}"
+ :key="dict.value"
+#if($column.javaType == "Integer" || $column.javaType == "Long")
+ :label="parseInt(dict.value)"
+#else
+ :label="dict.value"
+#end
+ >{{dict.label}}</el-radio>
+ </el-radio-group>
+ </el-form-item>
+#elseif($column.htmlType == "radio" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-radio-group v-model="form.${field}">
+ <el-radio label="1">璇烽�夋嫨瀛楀吀鐢熸垚</el-radio>
+ </el-radio-group>
+ </el-form-item>
+#elseif($column.htmlType == "datetime")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-date-picker clearable
+ v-model="form.${field}"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="閫夋嫨${comment}">
+ </el-date-picker>
+ </el-form-item>
+#elseif($column.htmlType == "textarea")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-input v-model="form.${field}" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
+ </el-form-item>
+#end
+#end
+#end
+#end
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+ <el-button @click="cancel">鍙� 娑�</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup name="${BusinessName}">
+import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}";
+
+const { proxy } = getCurrentInstance();
+#if(${dicts} != '')
+#set($dictsNoSymbol=$dicts.replace("'", ""))
+const { ${dictsNoSymbol} } = proxy.useDict(${dicts});
+#end
+
+const ${businessName}List = ref([]);
+const ${businessName}Options = ref([]);
+const open = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const title = ref("");
+const isExpandAll = ref(true);
+const refreshTable = ref(true);
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+const daterange${AttrName} = ref([]);
+#end
+#end
+
+const data = reactive({
+ form: {},
+ queryParams: {
+ #foreach ($column in $columns)
+#if($column.query)
+ $column.javaField: null#if($foreach.count != $columns.size()),#end
+#end
+#end
+ },
+ rules: {
+ #foreach ($column in $columns)
+#if($column.required)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+ $column.javaField: [
+ { required: true, message: "$comment涓嶈兘涓虹┖", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
+ ]#if($foreach.count != $columns.size()),#end
+#end
+#end
+ }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 鏌ヨ${functionName}鍒楄〃 */
+function getList() {
+ loading.value = true;
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+ queryParams.value.params = {};
+#break
+#end
+#end
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ if (null != daterange${AttrName} && '' != daterange${AttrName}) {
+ queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0];
+ queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1];
+ }
+#end
+#end
+ list${BusinessName}(queryParams.value).then(response => {
+ ${businessName}List.value = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}");
+ loading.value = false;
+ });
+}
+
+/** 鏌ヨ${functionName}涓嬫媺鏍戠粨鏋� */
+function getTreeselect() {
+ list${BusinessName}().then(response => {
+ ${businessName}Options.value = [];
+ const data = { ${treeCode}: 0, ${treeName}: '椤剁骇鑺傜偣', children: [] };
+ data.children = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}");
+ ${businessName}Options.value.push(data);
+ });
+}
+
+// 鍙栨秷鎸夐挳
+function cancel() {
+ open.value = false;
+ reset();
+}
+
+// 琛ㄥ崟閲嶇疆
+function reset() {
+ form.value = {
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ $column.javaField: []#if($foreach.count != $columns.size()),#end
+#else
+ $column.javaField: null#if($foreach.count != $columns.size()),#end
+#end
+#end
+ };
+ proxy.resetForm("${businessName}Ref");
+}
+
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+function handleQuery() {
+ getList();
+}
+
+/** 閲嶇疆鎸夐挳鎿嶄綔 */
+function resetQuery() {
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ daterange${AttrName}.value = [];
+#end
+#end
+ proxy.resetForm("queryRef");
+ handleQuery();
+}
+
+/** 鏂板鎸夐挳鎿嶄綔 */
+function handleAdd(row) {
+ reset();
+ getTreeselect();
+ if (row != null && row.${treeCode}) {
+ form.value.${treeParentCode} = row.${treeCode};
+ } else {
+ form.value.${treeParentCode} = 0;
+ }
+ open.value = true;
+ title.value = "娣诲姞${functionName}";
+}
+
+/** 灞曞紑/鎶樺彔鎿嶄綔 */
+function toggleExpandAll() {
+ refreshTable.value = false;
+ isExpandAll.value = !isExpandAll.value;
+ nextTick(() => {
+ refreshTable.value = true;
+ });
+}
+
+/** 淇敼鎸夐挳鎿嶄綔 */
+async function handleUpdate(row) {
+ reset();
+ await getTreeselect();
+ if (row != null) {
+ form.value.${treeParentCode} = row.${treeCode};
+ }
+ get${BusinessName}(row.${pkColumn.javaField}).then(response => {
+ form.value = response.data;
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ form.value.$column.javaField = form.value.${column.javaField}.split(",");
+#end
+#end
+ open.value = true;
+ title.value = "淇敼${functionName}";
+ });
+}
+
+/** 鎻愪氦鎸夐挳 */
+function submitForm() {
+ proxy.#[[$]]#refs["${businessName}Ref"].validate(valid => {
+ if (valid) {
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ form.value.$column.javaField = form.value.${column.javaField}.join(",");
+#end
+#end
+ if (form.value.${pkColumn.javaField} != null) {
+ update${BusinessName}(form.value).then(response => {
+ proxy.#[[$modal]]#.msgSuccess("淇敼鎴愬姛");
+ open.value = false;
+ getList();
+ });
+ } else {
+ add${BusinessName}(form.value).then(response => {
+ proxy.#[[$modal]]#.msgSuccess("鏂板鎴愬姛");
+ open.value = false;
+ getList();
+ });
+ }
+ }
+ });
+}
+
+/** 鍒犻櫎鎸夐挳鎿嶄綔 */
+function handleDelete(row) {
+ proxy.#[[$modal]]#.confirm('鏄惁纭鍒犻櫎${functionName}缂栧彿涓�"' + row.${pkColumn.javaField} + '"鐨勬暟鎹」锛�').then(function() {
+ return del${BusinessName}(row.${pkColumn.javaField});
+ }).then(() => {
+ getList();
+ proxy.#[[$modal]]#.msgSuccess("鍒犻櫎鎴愬姛");
+ }).catch(() => {});
+}
+
+getList();
+</script>
diff --git a/ycl-generator/src/main/resources/vm/vue/v3/index.vue.vm b/ycl-generator/src/main/resources/vm/vue/v3/index.vue.vm
new file mode 100644
index 0000000..8b25665
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/vue/v3/index.vue.vm
@@ -0,0 +1,590 @@
+<template>
+ <div class="app-container">
+ <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+#foreach($column in $columns)
+#if($column.query)
+#set($dictType=$column.dictType)
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.htmlType == "input")
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-input
+ v-model="queryParams.${column.javaField}"
+ placeholder="璇疯緭鍏�${comment}"
+ clearable
+ @keyup.enter="handleQuery"
+ />
+ </el-form-item>
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable>
+ <el-option
+ v-for="dict in ${dictType}"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ />
+ </el-select>
+ </el-form-item>
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable>
+ <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
+ <el-form-item label="${comment}" prop="${column.javaField}">
+ <el-date-picker clearable
+ v-model="queryParams.${column.javaField}"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="璇烽�夋嫨${comment}">
+ </el-date-picker>
+ </el-form-item>
+#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+ <el-form-item label="${comment}" style="width: 308px">
+ <el-date-picker
+ v-model="daterange${AttrName}"
+ value-format="YYYY-MM-DD"
+ type="daterange"
+ range-separator="-"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ ></el-date-picker>
+ </el-form-item>
+#end
+#end
+#end
+ <el-form-item>
+ <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+ <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+
+ <el-row :gutter="10" class="mb8">
+ <el-col :span="1.5">
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="handleAdd"
+ v-hasPermi="['${moduleName}:${businessName}:add']"
+ >鏂板</el-button>
+ </el-col>
+ <el-col :span="1.5">
+ <el-button
+ type="success"
+ plain
+ icon="Edit"
+ :disabled="single"
+ @click="handleUpdate"
+ v-hasPermi="['${moduleName}:${businessName}:edit']"
+ >淇敼</el-button>
+ </el-col>
+ <el-col :span="1.5">
+ <el-button
+ type="danger"
+ plain
+ icon="Delete"
+ :disabled="multiple"
+ @click="handleDelete"
+ v-hasPermi="['${moduleName}:${businessName}:remove']"
+ >鍒犻櫎</el-button>
+ </el-col>
+ <el-col :span="1.5">
+ <el-button
+ type="warning"
+ plain
+ icon="Download"
+ @click="handleExport"
+ v-hasPermi="['${moduleName}:${businessName}:export']"
+ >瀵煎嚭</el-button>
+ </el-col>
+ <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+ </el-row>
+
+ <el-table v-loading="loading" :data="${businessName}List" @selection-change="handleSelectionChange">
+ <el-table-column type="selection" width="55" align="center" />
+#foreach($column in $columns)
+#set($javaField=$column.javaField)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.pk)
+ <el-table-column label="${comment}" align="center" prop="${javaField}" />
+#elseif($column.list && $column.htmlType == "datetime")
+ <el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
+ <template #default="scope">
+ <span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span>
+ </template>
+ </el-table-column>
+#elseif($column.list && $column.htmlType == "imageUpload")
+ <el-table-column label="${comment}" align="center" prop="${javaField}" width="100">
+ <template #default="scope">
+ <image-preview :src="scope.row.${javaField}" :width="50" :height="50"/>
+ </template>
+ </el-table-column>
+#elseif($column.list && "" != $column.dictType)
+ <el-table-column label="${comment}" align="center" prop="${javaField}">
+ <template #default="scope">
+#if($column.htmlType == "checkbox")
+ <dict-tag :options="${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/>
+#else
+ <dict-tag :options="${column.dictType}" :value="scope.row.${javaField}"/>
+#end
+ </template>
+ </el-table-column>
+#elseif($column.list && "" != $javaField)
+ <el-table-column label="${comment}" align="center" prop="${javaField}" />
+#end
+#end
+ <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+ <template #default="scope">
+ <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']">淇敼</el-button>
+ <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <pagination
+ v-show="total>0"
+ :total="total"
+ v-model:page="queryParams.pageNum"
+ v-model:limit="queryParams.pageSize"
+ @pagination="getList"
+ />
+
+ <!-- 娣诲姞鎴栦慨鏀�${functionName}瀵硅瘽妗� -->
+ <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+ <el-form ref="${businessName}Ref" :model="form" :rules="rules" label-width="80px">
+#foreach($column in $columns)
+#set($field=$column.javaField)
+#if($column.insert && !$column.pk)
+#if(($column.usableColumn) || (!$column.superColumn))
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#set($dictType=$column.dictType)
+#if($column.htmlType == "input")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-input v-model="form.${field}" placeholder="璇疯緭鍏�${comment}" />
+ </el-form-item>
+#elseif($column.htmlType == "imageUpload")
+ <el-form-item label="${comment}" prop="${field}">
+ <image-upload v-model="form.${field}"/>
+ </el-form-item>
+#elseif($column.htmlType == "fileUpload")
+ <el-form-item label="${comment}" prop="${field}">
+ <file-upload v-model="form.${field}"/>
+ </el-form-item>
+#elseif($column.htmlType == "editor")
+ <el-form-item label="${comment}">
+ <editor v-model="form.${field}" :min-height="192"/>
+ </el-form-item>
+#elseif($column.htmlType == "select" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
+ <el-option
+ v-for="dict in ${dictType}"
+ :key="dict.value"
+ :label="dict.label"
+#if($column.javaType == "Integer" || $column.javaType == "Long")
+ :value="parseInt(dict.value)"
+#else
+ :value="dict.value"
+#end
+ ></el-option>
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "select" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
+ <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+ </el-select>
+ </el-form-item>
+#elseif($column.htmlType == "checkbox" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-checkbox-group v-model="form.${field}">
+ <el-checkbox
+ v-for="dict in ${dictType}"
+ :key="dict.value"
+ :label="dict.value">
+ {{dict.label}}
+ </el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+#elseif($column.htmlType == "checkbox" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-checkbox-group v-model="form.${field}">
+ <el-checkbox>璇烽�夋嫨瀛楀吀鐢熸垚</el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+#elseif($column.htmlType == "radio" && "" != $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-radio-group v-model="form.${field}">
+ <el-radio
+ v-for="dict in ${dictType}"
+ :key="dict.value"
+#if($column.javaType == "Integer" || $column.javaType == "Long")
+ :label="parseInt(dict.value)"
+#else
+ :label="dict.value"
+#end
+ >{{dict.label}}</el-radio>
+ </el-radio-group>
+ </el-form-item>
+#elseif($column.htmlType == "radio" && $dictType)
+ <el-form-item label="${comment}" prop="${field}">
+ <el-radio-group v-model="form.${field}">
+ <el-radio label="1">璇烽�夋嫨瀛楀吀鐢熸垚</el-radio>
+ </el-radio-group>
+ </el-form-item>
+#elseif($column.htmlType == "datetime")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-date-picker clearable
+ v-model="form.${field}"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="璇烽�夋嫨${comment}">
+ </el-date-picker>
+ </el-form-item>
+#elseif($column.htmlType == "textarea")
+ <el-form-item label="${comment}" prop="${field}">
+ <el-input v-model="form.${field}" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
+ </el-form-item>
+#end
+#end
+#end
+#end
+#if($table.sub)
+ <el-divider content-position="center">${subTable.functionName}淇℃伅</el-divider>
+ <el-row :gutter="10" class="mb8">
+ <el-col :span="1.5">
+ <el-button type="primary" icon="Plus" @click="handleAdd${subClassName}">娣诲姞</el-button>
+ </el-col>
+ <el-col :span="1.5">
+ <el-button type="danger" icon="Delete" @click="handleDelete${subClassName}">鍒犻櫎</el-button>
+ </el-col>
+ </el-row>
+ <el-table :data="${subclassName}List" :row-class-name="row${subClassName}Index" @selection-change="handle${subClassName}SelectionChange" ref="${subclassName}">
+ <el-table-column type="selection" width="50" align="center" />
+ <el-table-column label="搴忓彿" align="center" prop="index" width="50"/>
+#foreach($column in $subTable.columns)
+#set($javaField=$column.javaField)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.pk || $javaField == ${subTableFkclassName})
+#elseif($column.list && $column.htmlType == "input")
+ <el-table-column label="$comment" prop="${javaField}" width="150">
+ <template #default="scope">
+ <el-input v-model="scope.row.$javaField" placeholder="璇疯緭鍏�$comment" />
+ </template>
+ </el-table-column>
+#elseif($column.list && $column.htmlType == "datetime")
+ <el-table-column label="$comment" prop="${javaField}" width="240">
+ <template #default="scope">
+ <el-date-picker clearable
+ v-model="scope.row.$javaField"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="璇烽�夋嫨$comment">
+ </el-date-picker>
+ </template>
+ </el-table-column>
+#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" != $column.dictType)
+ <el-table-column label="$comment" prop="${javaField}" width="150">
+ <template #default="scope">
+ <el-select v-model="scope.row.$javaField" placeholder="璇烽�夋嫨$comment">
+ <el-option
+ v-for="dict in $column.dictType"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ ></el-option>
+ </el-select>
+ </template>
+ </el-table-column>
+#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" == $column.dictType)
+ <el-table-column label="$comment" prop="${javaField}" width="150">
+ <template #default="scope">
+ <el-select v-model="scope.row.$javaField" placeholder="璇烽�夋嫨$comment">
+ <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+ </el-select>
+ </template>
+ </el-table-column>
+#end
+#end
+ </el-table>
+#end
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+ <el-button @click="cancel">鍙� 娑�</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup name="${BusinessName}">
+import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}";
+
+const { proxy } = getCurrentInstance();
+#if(${dicts} != '')
+#set($dictsNoSymbol=$dicts.replace("'", ""))
+const { ${dictsNoSymbol} } = proxy.useDict(${dicts});
+#end
+
+const ${businessName}List = ref([]);
+#if($table.sub)
+const ${subclassName}List = ref([]);
+#end
+const open = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+#if($table.sub)
+const checked${subClassName} = ref([]);
+#end
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const title = ref("");
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+const daterange${AttrName} = ref([]);
+#end
+#end
+
+const data = reactive({
+ form: {},
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ #foreach ($column in $columns)
+#if($column.query)
+ $column.javaField: null#if($foreach.count != $columns.size()),#end
+#end
+#end
+ },
+ rules: {
+ #foreach ($column in $columns)
+#if($column.required)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+ $column.javaField: [
+ { required: true, message: "$comment涓嶈兘涓虹┖", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
+ ]#if($foreach.count != $columns.size()),#end
+#end
+#end
+ }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 鏌ヨ${functionName}鍒楄〃 */
+function getList() {
+ loading.value = true;
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+ queryParams.value.params = {};
+#break
+#end
+#end
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ if (null != daterange${AttrName} && '' != daterange${AttrName}) {
+ queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0];
+ queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1];
+ }
+#end
+#end
+ list${BusinessName}(queryParams.value).then(response => {
+ ${businessName}List.value = response.rows;
+ total.value = response.total;
+ loading.value = false;
+ });
+}
+
+// 鍙栨秷鎸夐挳
+function cancel() {
+ open.value = false;
+ reset();
+}
+
+// 琛ㄥ崟閲嶇疆
+function reset() {
+ form.value = {
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ $column.javaField: []#if($foreach.count != $columns.size()),#end
+#else
+ $column.javaField: null#if($foreach.count != $columns.size()),#end
+#end
+#end
+ };
+#if($table.sub)
+ ${subclassName}List.value = [];
+#end
+ proxy.resetForm("${businessName}Ref");
+}
+
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+function handleQuery() {
+ queryParams.value.pageNum = 1;
+ getList();
+}
+
+/** 閲嶇疆鎸夐挳鎿嶄綔 */
+function resetQuery() {
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+ daterange${AttrName}.value = [];
+#end
+#end
+ proxy.resetForm("queryRef");
+ handleQuery();
+}
+
+// 澶氶�夋閫変腑鏁版嵁
+function handleSelectionChange(selection) {
+ ids.value = selection.map(item => item.${pkColumn.javaField});
+ single.value = selection.length != 1;
+ multiple.value = !selection.length;
+}
+
+/** 鏂板鎸夐挳鎿嶄綔 */
+function handleAdd() {
+ reset();
+ open.value = true;
+ title.value = "娣诲姞${functionName}";
+}
+
+/** 淇敼鎸夐挳鎿嶄綔 */
+function handleUpdate(row) {
+ reset();
+ const _${pkColumn.javaField} = row.${pkColumn.javaField} || ids.value
+ get${BusinessName}(_${pkColumn.javaField}).then(response => {
+ form.value = response.data;
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ form.value.$column.javaField = form.value.${column.javaField}.split(",");
+#end
+#end
+#if($table.sub)
+ ${subclassName}List.value = response.data.${subclassName}List;
+#end
+ open.value = true;
+ title.value = "淇敼${functionName}";
+ });
+}
+
+/** 鎻愪氦鎸夐挳 */
+function submitForm() {
+ proxy.#[[$]]#refs["${businessName}Ref"].validate(valid => {
+ if (valid) {
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+ form.value.$column.javaField = form.value.${column.javaField}.join(",");
+#end
+#end
+#if($table.sub)
+ form.value.${subclassName}List = ${subclassName}List.value;
+#end
+ if (form.value.${pkColumn.javaField} != null) {
+ update${BusinessName}(form.value).then(response => {
+ proxy.#[[$modal]]#.msgSuccess("淇敼鎴愬姛");
+ open.value = false;
+ getList();
+ });
+ } else {
+ add${BusinessName}(form.value).then(response => {
+ proxy.#[[$modal]]#.msgSuccess("鏂板鎴愬姛");
+ open.value = false;
+ getList();
+ });
+ }
+ }
+ });
+}
+
+/** 鍒犻櫎鎸夐挳鎿嶄綔 */
+function handleDelete(row) {
+ const _${pkColumn.javaField}s = row.${pkColumn.javaField} || ids.value;
+ proxy.#[[$modal]]#.confirm('鏄惁纭鍒犻櫎${functionName}缂栧彿涓�"' + _${pkColumn.javaField}s + '"鐨勬暟鎹」锛�').then(function() {
+ return del${BusinessName}(_${pkColumn.javaField}s);
+ }).then(() => {
+ getList();
+ proxy.#[[$modal]]#.msgSuccess("鍒犻櫎鎴愬姛");
+ }).catch(() => {});
+}
+
+#if($table.sub)
+/** ${subTable.functionName}搴忓彿 */
+function row${subClassName}Index({ row, rowIndex }) {
+ row.index = rowIndex + 1;
+}
+
+/** ${subTable.functionName}娣诲姞鎸夐挳鎿嶄綔 */
+function handleAdd${subClassName}() {
+ let obj = {};
+#foreach($column in $subTable.columns)
+#if($column.pk || $column.javaField == ${subTableFkclassName})
+#elseif($column.list && "" != $javaField)
+ obj.$column.javaField = "";
+#end
+#end
+ ${subclassName}List.value.push(obj);
+}
+
+/** ${subTable.functionName}鍒犻櫎鎸夐挳鎿嶄綔 */
+function handleDelete${subClassName}() {
+ if (checked${subClassName}.value.length == 0) {
+ proxy.#[[$modal]]#.msgError("璇峰厛閫夋嫨瑕佸垹闄ょ殑${subTable.functionName}鏁版嵁");
+ } else {
+ const ${subclassName}s = ${subclassName}List.value;
+ const checked${subClassName}s = checked${subClassName}.value;
+ ${subclassName}List.value = ${subclassName}s.filter(function(item) {
+ return checked${subClassName}s.indexOf(item.index) == -1
+ });
+ }
+}
+
+/** 澶嶉�夋閫変腑鏁版嵁 */
+function handle${subClassName}SelectionChange(selection) {
+ checked${subClassName}.value = selection.map(item => item.index)
+}
+
+#end
+/** 瀵煎嚭鎸夐挳鎿嶄綔 */
+function handleExport() {
+ proxy.download('${moduleName}/${businessName}/export', {
+ ...queryParams.value
+ }, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
+}
+
+getList();
+</script>
diff --git a/ycl-generator/src/main/resources/vm/vue/v3/readme.txt b/ycl-generator/src/main/resources/vm/vue/v3/readme.txt
new file mode 100644
index 0000000..99239bb
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/vue/v3/readme.txt
@@ -0,0 +1 @@
+如果使用的是RuoYi-Vue3前端,那么需要覆盖一下此目录的模板index.vue.vm、index-tree.vue.vm文件到上级vue目录。
\ No newline at end of file
diff --git a/ycl-generator/src/main/resources/vm/xml/mapper.xml.vm b/ycl-generator/src/main/resources/vm/xml/mapper.xml.vm
new file mode 100644
index 0000000..0ceb3d8
--- /dev/null
+++ b/ycl-generator/src/main/resources/vm/xml/mapper.xml.vm
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="${packageName}.mapper.${ClassName}Mapper">
+
+ <resultMap type="${ClassName}" id="${ClassName}Result">
+#foreach ($column in $columns)
+ <result property="${column.javaField}" column="${column.columnName}" />
+#end
+ </resultMap>
+#if($table.sub)
+
+ <resultMap id="${ClassName}${subClassName}Result" type="${ClassName}" extends="${ClassName}Result">
+ <collection property="${subclassName}List" notNullColumn="sub_${subTable.pkColumn.columnName}" javaType="java.util.List" resultMap="${subClassName}Result" />
+ </resultMap>
+
+ <resultMap type="${subClassName}" id="${subClassName}Result">
+#foreach ($column in $subTable.columns)
+ <result property="${column.javaField}" column="sub_${column.columnName}" />
+#end
+ </resultMap>
+#end
+
+ <sql id="select${ClassName}Vo">
+ select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName}
+ </sql>
+
+ <select id="select${ClassName}List" parameterType="${ClassName}" resultMap="${ClassName}Result">
+ <include refid="select${ClassName}Vo"/>
+ <where>
+#foreach($column in $columns)
+#set($queryType=$column.queryType)
+#set($javaField=$column.javaField)
+#set($javaType=$column.javaType)
+#set($columnName=$column.columnName)
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#if($column.query)
+#if($column.queryType == "EQ")
+ <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName = #{$javaField}</if>
+#elseif($queryType == "NE")
+ <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName != #{$javaField}</if>
+#elseif($queryType == "GT")
+ <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName > #{$javaField}</if>
+#elseif($queryType == "GTE")
+ <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName >= #{$javaField}</if>
+#elseif($queryType == "LT")
+ <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName < #{$javaField}</if>
+#elseif($queryType == "LTE")
+ <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName <= #{$javaField}</if>
+#elseif($queryType == "LIKE")
+ <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName like concat('%', #{$javaField}, '%')</if>
+#elseif($queryType == "BETWEEN")
+ <if test="params.begin$AttrName != null and params.begin$AttrName != '' and params.end$AttrName != null and params.end$AttrName != ''"> and $columnName between #{params.begin$AttrName} and #{params.end$AttrName}</if>
+#end
+#end
+#end
+ </where>
+ </select>
+
+ <select id="select${ClassName}By${pkColumn.capJavaField}" parameterType="${pkColumn.javaType}" resultMap="#if($table.sub)${ClassName}${subClassName}Result#else${ClassName}Result#end">
+#if($table.crud || $table.tree)
+ <include refid="select${ClassName}Vo"/>
+ where ${pkColumn.columnName} = #{${pkColumn.javaField}}
+#elseif($table.sub)
+ select#foreach($column in $columns) a.$column.columnName#if($foreach.count != $columns.size()),#end#end,
+ #foreach($column in $subTable.columns) b.$column.columnName as sub_$column.columnName#if($foreach.count != $subTable.columns.size()),#end#end
+
+ from ${tableName} a
+ left join ${subTableName} b on b.${subTableFkName} = a.${pkColumn.columnName}
+ where a.${pkColumn.columnName} = #{${pkColumn.javaField}}
+#end
+ </select>
+
+ <insert id="insert${ClassName}" parameterType="${ClassName}"#if($pkColumn.increment) useGeneratedKeys="true" keyProperty="$pkColumn.javaField"#end>
+ insert into ${tableName}
+ <trim prefix="(" suffix=")" suffixOverrides=",">
+#foreach($column in $columns)
+#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment)
+ <if test="$column.javaField != null#if($column.javaType == 'String' && $column.required) and $column.javaField != ''#end">$column.columnName,</if>
+#end
+#end
+ </trim>
+ <trim prefix="values (" suffix=")" suffixOverrides=",">
+#foreach($column in $columns)
+#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment)
+ <if test="$column.javaField != null#if($column.javaType == 'String' && $column.required) and $column.javaField != ''#end">#{$column.javaField},</if>
+#end
+#end
+ </trim>
+ </insert>
+
+ <update id="update${ClassName}" parameterType="${ClassName}">
+ update ${tableName}
+ <trim prefix="SET" suffixOverrides=",">
+#foreach($column in $columns)
+#if($column.columnName != $pkColumn.columnName)
+ <if test="$column.javaField != null#if($column.javaType == 'String' && $column.required) and $column.javaField != ''#end">$column.columnName = #{$column.javaField},</if>
+#end
+#end
+ </trim>
+ where ${pkColumn.columnName} = #{${pkColumn.javaField}}
+ </update>
+
+ <delete id="delete${ClassName}By${pkColumn.capJavaField}" parameterType="${pkColumn.javaType}">
+ delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}}
+ </delete>
+
+ <delete id="delete${ClassName}By${pkColumn.capJavaField}s" parameterType="String">
+ delete from ${tableName} where ${pkColumn.columnName} in
+ <foreach item="${pkColumn.javaField}" collection="array" open="(" separator="," close=")">
+ #{${pkColumn.javaField}}
+ </foreach>
+ </delete>
+#if($table.sub)
+
+ <delete id="delete${subClassName}By${subTableFkClassName}s" parameterType="String">
+ delete from ${subTableName} where ${subTableFkName} in
+ <foreach item="${subTableFkclassName}" collection="array" open="(" separator="," close=")">
+ #{${subTableFkclassName}}
+ </foreach>
+ </delete>
+
+ <delete id="delete${subClassName}By${subTableFkClassName}" parameterType="${pkColumn.javaType}">
+ delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}}
+ </delete>
+
+ <insert id="batch${subClassName}">
+ insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values
+ <foreach item="item" index="index" collection="list" separator=",">
+ (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end)
+ </foreach>
+ </insert>
+#end
+</mapper>
\ No newline at end of file
diff --git a/ycl-pojo/pom.xml b/ycl-pojo/pom.xml
index 539b465..7eba8e3 100644
--- a/ycl-pojo/pom.xml
+++ b/ycl-pojo/pom.xml
@@ -17,6 +17,11 @@
</properties>
<dependencies>
+ <!-- 鑾峰彇绯荤粺淇℃伅 -->
+ <dependency>
+ <groupId>com.github.oshi</groupId>
+ <artifactId>oshi-core</artifactId>
+ </dependency>
<dependency>
<groupId>com.ycl</groupId>
<artifactId>ycl-common</artifactId>
diff --git a/ycl-pojo/src/main/java/com/ycl/system/Server.java b/ycl-pojo/src/main/java/com/ycl/system/Server.java
new file mode 100644
index 0000000..9ba10f7
--- /dev/null
+++ b/ycl-pojo/src/main/java/com/ycl/system/Server.java
@@ -0,0 +1,237 @@
+package com.ycl.system;
+
+import com.ycl.system.server.*;
+import oshi.SystemInfo;
+import oshi.hardware.CentralProcessor;
+import oshi.hardware.CentralProcessor.TickType;
+import oshi.hardware.GlobalMemory;
+import oshi.hardware.HardwareAbstractionLayer;
+import oshi.software.os.FileSystem;
+import oshi.software.os.OSFileStore;
+import oshi.software.os.OperatingSystem;
+import oshi.util.Util;
+import utils.Arith;
+import utils.ip.IpUtils;
+
+import java.net.UnknownHostException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * 鏈嶅姟鍣ㄧ浉鍏充俊鎭�
+ *
+ * @author ruoyi
+ */
+public class Server
+{
+ private static final int OSHI_WAIT_SECOND = 1000;
+
+ /**
+ * CPU鐩稿叧淇℃伅
+ */
+ private Cpu cpu = new Cpu();
+
+ /**
+ * 鍏у瓨鐩稿叧淇℃伅
+ */
+ private Mem mem = new Mem();
+
+ /**
+ * JVM鐩稿叧淇℃伅
+ */
+ private Jvm jvm = new Jvm();
+
+ /**
+ * 鏈嶅姟鍣ㄧ浉鍏充俊鎭�
+ */
+ private Sys sys = new Sys();
+
+ /**
+ * 纾佺洏鐩稿叧淇℃伅
+ */
+ private List<SysFile> sysFiles = new LinkedList<SysFile>();
+
+ public Cpu getCpu()
+ {
+ return cpu;
+ }
+
+ public void setCpu(Cpu cpu)
+ {
+ this.cpu = cpu;
+ }
+
+ public Mem getMem()
+ {
+ return mem;
+ }
+
+ public void setMem(Mem mem)
+ {
+ this.mem = mem;
+ }
+
+ public Jvm getJvm()
+ {
+ return jvm;
+ }
+
+ public void setJvm(Jvm jvm)
+ {
+ this.jvm = jvm;
+ }
+
+ public Sys getSys()
+ {
+ return sys;
+ }
+
+ public void setSys(Sys sys)
+ {
+ this.sys = sys;
+ }
+
+ public List<SysFile> getSysFiles()
+ {
+ return sysFiles;
+ }
+
+ public void setSysFiles(List<SysFile> sysFiles)
+ {
+ this.sysFiles = sysFiles;
+ }
+
+ public void copyTo() throws Exception
+ {
+ SystemInfo si = new SystemInfo();
+ HardwareAbstractionLayer hal = si.getHardware();
+
+ setCpuInfo(hal.getProcessor());
+
+ setMemInfo(hal.getMemory());
+
+ setSysInfo();
+
+ setJvmInfo();
+
+ setSysFiles(si.getOperatingSystem());
+ }
+
+ /**
+ * 璁剧疆CPU淇℃伅
+ */
+ private void setCpuInfo(CentralProcessor processor)
+ {
+ // CPU淇℃伅
+ long[] prevTicks = processor.getSystemCpuLoadTicks();
+ Util.sleep(OSHI_WAIT_SECOND);
+ long[] ticks = processor.getSystemCpuLoadTicks();
+ long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
+ long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
+ long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
+ long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
+ long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
+ long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
+ long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
+ long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
+ long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
+ cpu.setCpuNum(processor.getLogicalProcessorCount());
+ cpu.setTotal(totalCpu);
+ cpu.setSys(cSys);
+ cpu.setUsed(user);
+ cpu.setWait(iowait);
+ cpu.setFree(idle);
+ }
+
+ /**
+ * 璁剧疆鍐呭瓨淇℃伅
+ */
+ private void setMemInfo(GlobalMemory memory)
+ {
+ mem.setTotal(memory.getTotal());
+ mem.setUsed(memory.getTotal() - memory.getAvailable());
+ mem.setFree(memory.getAvailable());
+ }
+
+ /**
+ * 璁剧疆鏈嶅姟鍣ㄤ俊鎭�
+ */
+ private void setSysInfo()
+ {
+ Properties props = System.getProperties();
+ sys.setComputerName(IpUtils.getHostName());
+ sys.setComputerIp(IpUtils.getHostIp());
+ sys.setOsName(props.getProperty("os.name"));
+ sys.setOsArch(props.getProperty("os.arch"));
+ sys.setUserDir(props.getProperty("user.dir"));
+ }
+
+ /**
+ * 璁剧疆Java铏氭嫙鏈�
+ */
+ private void setJvmInfo() throws UnknownHostException
+ {
+ Properties props = System.getProperties();
+ jvm.setTotal(Runtime.getRuntime().totalMemory());
+ jvm.setMax(Runtime.getRuntime().maxMemory());
+ jvm.setFree(Runtime.getRuntime().freeMemory());
+ jvm.setVersion(props.getProperty("java.version"));
+ jvm.setHome(props.getProperty("java.home"));
+ }
+
+ /**
+ * 璁剧疆纾佺洏淇℃伅
+ */
+ private void setSysFiles(OperatingSystem os)
+ {
+ FileSystem fileSystem = os.getFileSystem();
+ List<OSFileStore> fsArray = fileSystem.getFileStores();
+ for (OSFileStore fs : fsArray)
+ {
+ long free = fs.getUsableSpace();
+ long total = fs.getTotalSpace();
+ long used = total - free;
+ SysFile sysFile = new SysFile();
+ sysFile.setDirName(fs.getMount());
+ sysFile.setSysTypeName(fs.getType());
+ sysFile.setTypeName(fs.getName());
+ sysFile.setTotal(convertFileSize(total));
+ sysFile.setFree(convertFileSize(free));
+ sysFile.setUsed(convertFileSize(used));
+ sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100));
+ sysFiles.add(sysFile);
+ }
+ }
+
+ /**
+ * 瀛楄妭杞崲
+ *
+ * @param size 瀛楄妭澶у皬
+ * @return 杞崲鍚庡��
+ */
+ public String convertFileSize(long size)
+ {
+ long kb = 1024;
+ long mb = kb * 1024;
+ long gb = mb * 1024;
+ if (size >= gb)
+ {
+ return String.format("%.1f GB", (float) size / gb);
+ }
+ else if (size >= mb)
+ {
+ float f = (float) size / mb;
+ return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
+ }
+ else if (size >= kb)
+ {
+ float f = (float) size / kb;
+ return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
+ }
+ else
+ {
+ return String.format("%d B", size);
+ }
+ }
+}
diff --git a/ycl-pojo/src/main/java/com/ycl/system/server/Cpu.java b/ycl-pojo/src/main/java/com/ycl/system/server/Cpu.java
new file mode 100644
index 0000000..5b594f8
--- /dev/null
+++ b/ycl-pojo/src/main/java/com/ycl/system/server/Cpu.java
@@ -0,0 +1,101 @@
+package com.ycl.system.server;
+
+import utils.Arith;
+
+/**
+ * CPU鐩稿叧淇℃伅
+ *
+ * @author ruoyi
+ */
+public class Cpu
+{
+ /**
+ * 鏍稿績鏁�
+ */
+ private int cpuNum;
+
+ /**
+ * CPU鎬荤殑浣跨敤鐜�
+ */
+ private double total;
+
+ /**
+ * CPU绯荤粺浣跨敤鐜�
+ */
+ private double sys;
+
+ /**
+ * CPU鐢ㄦ埛浣跨敤鐜�
+ */
+ private double used;
+
+ /**
+ * CPU褰撳墠绛夊緟鐜�
+ */
+ private double wait;
+
+ /**
+ * CPU褰撳墠绌洪棽鐜�
+ */
+ private double free;
+
+ public int getCpuNum()
+ {
+ return cpuNum;
+ }
+
+ public void setCpuNum(int cpuNum)
+ {
+ this.cpuNum = cpuNum;
+ }
+
+ public double getTotal()
+ {
+ return Arith.round(Arith.mul(total, 100), 2);
+ }
+
+ public void setTotal(double total)
+ {
+ this.total = total;
+ }
+
+ public double getSys()
+ {
+ return Arith.round(Arith.mul(sys / total, 100), 2);
+ }
+
+ public void setSys(double sys)
+ {
+ this.sys = sys;
+ }
+
+ public double getUsed()
+ {
+ return Arith.round(Arith.mul(used / total, 100), 2);
+ }
+
+ public void setUsed(double used)
+ {
+ this.used = used;
+ }
+
+ public double getWait()
+ {
+ return Arith.round(Arith.mul(wait / total, 100), 2);
+ }
+
+ public void setWait(double wait)
+ {
+ this.wait = wait;
+ }
+
+ public double getFree()
+ {
+ return Arith.round(Arith.mul(free / total, 100), 2);
+ }
+
+ public void setFree(double free)
+ {
+ this.free = free;
+ }
+}
diff --git a/ycl-pojo/src/main/java/com/ycl/system/server/Jvm.java b/ycl-pojo/src/main/java/com/ycl/system/server/Jvm.java
new file mode 100644
index 0000000..91d334e
--- /dev/null
+++ b/ycl-pojo/src/main/java/com/ycl/system/server/Jvm.java
@@ -0,0 +1,131 @@
+package com.ycl.system.server;
+
+import utils.Arith;
+import utils.DateUtils;
+
+import java.lang.management.ManagementFactory;
+
+/**
+ * JVM鐩稿叧淇℃伅
+ *
+ * @author ruoyi
+ */
+public class Jvm
+{
+ /**
+ * 褰撳墠JVM鍗犵敤鐨勫唴瀛樻�绘暟(M)
+ */
+ private double total;
+
+ /**
+ * JVM鏈�澶у彲鐢ㄥ唴瀛樻�绘暟(M)
+ */
+ private double max;
+
+ /**
+ * JVM绌洪棽鍐呭瓨(M)
+ */
+ private double free;
+
+ /**
+ * JDK鐗堟湰
+ */
+ private String version;
+
+ /**
+ * JDK璺緞
+ */
+ private String home;
+
+ public double getTotal()
+ {
+ return Arith.div(total, (1024 * 1024), 2);
+ }
+
+ public void setTotal(double total)
+ {
+ this.total = total;
+ }
+
+ public double getMax()
+ {
+ return Arith.div(max, (1024 * 1024), 2);
+ }
+
+ public void setMax(double max)
+ {
+ this.max = max;
+ }
+
+ public double getFree()
+ {
+ return Arith.div(free, (1024 * 1024), 2);
+ }
+
+ public void setFree(double free)
+ {
+ this.free = free;
+ }
+
+ public double getUsed()
+ {
+ return Arith.div(total - free, (1024 * 1024), 2);
+ }
+
+ public double getUsage()
+ {
+ return Arith.mul(Arith.div(total - free, total, 4), 100);
+ }
+
+ /**
+ * 鑾峰彇JDK鍚嶇О
+ */
+ public String getName()
+ {
+ return ManagementFactory.getRuntimeMXBean().getVmName();
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion(String version)
+ {
+ this.version = version;
+ }
+
+ public String getHome()
+ {
+ return home;
+ }
+
+ public void setHome(String home)
+ {
+ this.home = home;
+ }
+
+ /**
+ * JDK鍚姩鏃堕棿
+ */
+ public String getStartTime()
+ {
+ return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate());
+ }
+
+ /**
+ * JDK杩愯鏃堕棿
+ */
+ public String getRunTime()
+ {
+ return DateUtils.timeDistance(DateUtils.getNowDate(), DateUtils.getServerStartDate());
+ }
+
+ /**
+ * 杩愯鍙傛暟
+ */
+ public String getInputArgs()
+ {
+ return ManagementFactory.getRuntimeMXBean().getInputArguments().toString();
+ }
+}
diff --git a/ycl-pojo/src/main/java/com/ycl/system/server/Mem.java b/ycl-pojo/src/main/java/com/ycl/system/server/Mem.java
new file mode 100644
index 0000000..e62a9a1
--- /dev/null
+++ b/ycl-pojo/src/main/java/com/ycl/system/server/Mem.java
@@ -0,0 +1,61 @@
+package com.ycl.system.server;
+
+import utils.Arith;
+
+/**
+ * 鍏у瓨鐩稿叧淇℃伅
+ *
+ * @author ruoyi
+ */
+public class Mem
+{
+ /**
+ * 鍐呭瓨鎬婚噺
+ */
+ private double total;
+
+ /**
+ * 宸茬敤鍐呭瓨
+ */
+ private double used;
+
+ /**
+ * 鍓╀綑鍐呭瓨
+ */
+ private double free;
+
+ public double getTotal()
+ {
+ return Arith.div(total, (1024 * 1024 * 1024), 2);
+ }
+
+ public void setTotal(long total)
+ {
+ this.total = total;
+ }
+
+ public double getUsed()
+ {
+ return Arith.div(used, (1024 * 1024 * 1024), 2);
+ }
+
+ public void setUsed(long used)
+ {
+ this.used = used;
+ }
+
+ public double getFree()
+ {
+ return Arith.div(free, (1024 * 1024 * 1024), 2);
+ }
+
+ public void setFree(long free)
+ {
+ this.free = free;
+ }
+
+ public double getUsage()
+ {
+ return Arith.mul(Arith.div(used, total, 4), 100);
+ }
+}
diff --git a/ycl-pojo/src/main/java/com/ycl/system/server/Sys.java b/ycl-pojo/src/main/java/com/ycl/system/server/Sys.java
new file mode 100644
index 0000000..4801d15
--- /dev/null
+++ b/ycl-pojo/src/main/java/com/ycl/system/server/Sys.java
@@ -0,0 +1,84 @@
+package com.ycl.system.server;
+
+/**
+ * 绯荤粺鐩稿叧淇℃伅
+ *
+ * @author ruoyi
+ */
+public class Sys
+{
+ /**
+ * 鏈嶅姟鍣ㄥ悕绉�
+ */
+ private String computerName;
+
+ /**
+ * 鏈嶅姟鍣↖p
+ */
+ private String computerIp;
+
+ /**
+ * 椤圭洰璺緞
+ */
+ private String userDir;
+
+ /**
+ * 鎿嶄綔绯荤粺
+ */
+ private String osName;
+
+ /**
+ * 绯荤粺鏋舵瀯
+ */
+ private String osArch;
+
+ public String getComputerName()
+ {
+ return computerName;
+ }
+
+ public void setComputerName(String computerName)
+ {
+ this.computerName = computerName;
+ }
+
+ public String getComputerIp()
+ {
+ return computerIp;
+ }
+
+ public void setComputerIp(String computerIp)
+ {
+ this.computerIp = computerIp;
+ }
+
+ public String getUserDir()
+ {
+ return userDir;
+ }
+
+ public void setUserDir(String userDir)
+ {
+ this.userDir = userDir;
+ }
+
+ public String getOsName()
+ {
+ return osName;
+ }
+
+ public void setOsName(String osName)
+ {
+ this.osName = osName;
+ }
+
+ public String getOsArch()
+ {
+ return osArch;
+ }
+
+ public void setOsArch(String osArch)
+ {
+ this.osArch = osArch;
+ }
+}
diff --git a/ycl-pojo/src/main/java/com/ycl/system/server/SysFile.java b/ycl-pojo/src/main/java/com/ycl/system/server/SysFile.java
new file mode 100644
index 0000000..5606356
--- /dev/null
+++ b/ycl-pojo/src/main/java/com/ycl/system/server/SysFile.java
@@ -0,0 +1,114 @@
+package com.ycl.system.server;
+
+/**
+ * 绯荤粺鏂囦欢鐩稿叧淇℃伅
+ *
+ * @author ruoyi
+ */
+public class SysFile
+{
+ /**
+ * 鐩樼璺緞
+ */
+ private String dirName;
+
+ /**
+ * 鐩樼绫诲瀷
+ */
+ private String sysTypeName;
+
+ /**
+ * 鏂囦欢绫诲瀷
+ */
+ private String typeName;
+
+ /**
+ * 鎬诲ぇ灏�
+ */
+ private String total;
+
+ /**
+ * 鍓╀綑澶у皬
+ */
+ private String free;
+
+ /**
+ * 宸茬粡浣跨敤閲�
+ */
+ private String used;
+
+ /**
+ * 璧勬簮鐨勪娇鐢ㄧ巼
+ */
+ private double usage;
+
+ public String getDirName()
+ {
+ return dirName;
+ }
+
+ public void setDirName(String dirName)
+ {
+ this.dirName = dirName;
+ }
+
+ public String getSysTypeName()
+ {
+ return sysTypeName;
+ }
+
+ public void setSysTypeName(String sysTypeName)
+ {
+ this.sysTypeName = sysTypeName;
+ }
+
+ public String getTypeName()
+ {
+ return typeName;
+ }
+
+ public void setTypeName(String typeName)
+ {
+ this.typeName = typeName;
+ }
+
+ public String getTotal()
+ {
+ return total;
+ }
+
+ public void setTotal(String total)
+ {
+ this.total = total;
+ }
+
+ public String getFree()
+ {
+ return free;
+ }
+
+ public void setFree(String free)
+ {
+ this.free = free;
+ }
+
+ public String getUsed()
+ {
+ return used;
+ }
+
+ public void setUsed(String used)
+ {
+ this.used = used;
+ }
+
+ public double getUsage()
+ {
+ return usage;
+ }
+
+ public void setUsage(double usage)
+ {
+ this.usage = usage;
+ }
+}
diff --git a/ycl-server/pom.xml b/ycl-server/pom.xml
index 1e5d560..55b6025 100644
--- a/ycl-server/pom.xml
+++ b/ycl-server/pom.xml
@@ -17,7 +17,12 @@
</properties>
<dependencies>
-
+ <!-- 浠g爜鐢熸垚-->
+ <dependency>
+ <groupId>com.ycl</groupId>
+ <artifactId>ycl-generator</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>com.ycl</groupId>
<artifactId>ycl-pojo</artifactId>
diff --git a/ycl-server/src/main/java/com/ycl/aop/DataScopeAspect.java b/ycl-server/src/main/java/com/ycl/aop/DataScopeAspect.java
new file mode 100644
index 0000000..f10ed83
--- /dev/null
+++ b/ycl-server/src/main/java/com/ycl/aop/DataScopeAspect.java
@@ -0,0 +1,175 @@
+package com.ycl.aop;
+
+import annotation.DataScope;
+import com.ycl.context.PermissionContextHolder;
+import com.ycl.system.entity.BaseEntity;
+import com.ycl.system.entity.SysRole;
+import com.ycl.system.entity.SysUser;
+import com.ycl.system.model.LoginUser;
+import com.ycl.utils.SecurityUtils;
+import com.ycl.utils.StringUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.springframework.stereotype.Component;
+import utils.text.Convert;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鏁版嵁杩囨护澶勭悊
+ *
+ * @author ruoyi
+ */
+@Aspect
+@Component
+public class DataScopeAspect
+{
+ /**
+ * 鍏ㄩ儴鏁版嵁鏉冮檺
+ */
+ public static final String DATA_SCOPE_ALL = "1";
+
+ /**
+ * 鑷畾鏁版嵁鏉冮檺
+ */
+ public static final String DATA_SCOPE_CUSTOM = "2";
+
+ /**
+ * 閮ㄩ棬鏁版嵁鏉冮檺
+ */
+ public static final String DATA_SCOPE_DEPT = "3";
+
+ /**
+ * 閮ㄩ棬鍙婁互涓嬫暟鎹潈闄�
+ */
+ public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
+
+ /**
+ * 浠呮湰浜烘暟鎹潈闄�
+ */
+ public static final String DATA_SCOPE_SELF = "5";
+
+ /**
+ * 鏁版嵁鏉冮檺杩囨护鍏抽敭瀛�
+ */
+ public static final String DATA_SCOPE = "dataScope";
+
+ @Before("@annotation(controllerDataScope)")
+ public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable
+ {
+ clearDataScope(point);
+ handleDataScope(point, controllerDataScope);
+ }
+
+ protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope)
+ {
+ // 鑾峰彇褰撳墠鐨勭敤鎴�
+ LoginUser loginUser = SecurityUtils.getLoginUser();
+ if (StringUtils.isNotNull(loginUser))
+ {
+ SysUser currentUser = loginUser.getUser();
+ // 濡傛灉鏄秴绾х鐞嗗憳锛屽垯涓嶈繃婊ゆ暟鎹�
+ if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
+ {
+ String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext());
+ dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
+ controllerDataScope.userAlias(), permission);
+ }
+ }
+ }
+
+ /**
+ * 鏁版嵁鑼冨洿杩囨护
+ *
+ * @param joinPoint 鍒囩偣
+ * @param user 鐢ㄦ埛
+ * @param deptAlias 閮ㄩ棬鍒悕
+ * @param userAlias 鐢ㄦ埛鍒悕
+ * @param permission 鏉冮檺瀛楃
+ */
+ public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission)
+ {
+ StringBuilder sqlString = new StringBuilder();
+ List<String> conditions = new ArrayList<String>();
+
+ for (SysRole role : user.getRoles())
+ {
+ String dataScope = role.getDataScope();
+ if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope))
+ {
+ continue;
+ }
+ if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions())
+ && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
+ {
+ continue;
+ }
+ if (DATA_SCOPE_ALL.equals(dataScope))
+ {
+ sqlString = new StringBuilder();
+ conditions.add(dataScope);
+ break;
+ }
+ else if (DATA_SCOPE_CUSTOM.equals(dataScope))
+ {
+ sqlString.append(StringUtils.format(
+ " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
+ role.getRoleId()));
+ }
+ else if (DATA_SCOPE_DEPT.equals(dataScope))
+ {
+ sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
+ }
+ else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
+ {
+ sqlString.append(StringUtils.format(
+ " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
+ deptAlias, user.getDeptId(), user.getDeptId()));
+ }
+ else if (DATA_SCOPE_SELF.equals(dataScope))
+ {
+ if (StringUtils.isNotBlank(userAlias))
+ {
+ sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
+ }
+ else
+ {
+ // 鏁版嵁鏉冮檺涓轰粎鏈汉涓旀病鏈塽serAlias鍒悕涓嶆煡璇换浣曟暟鎹�
+ sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
+ }
+ }
+ conditions.add(dataScope);
+ }
+
+ // 澶氳鑹叉儏鍐典笅锛屾墍鏈夎鑹查兘涓嶅寘鍚紶閫掕繃鏉ョ殑鏉冮檺瀛楃锛岃繖涓椂鍊檚qlString涔熶細涓虹┖锛屾墍浠ヨ闄愬埗涓�涓�,涓嶆煡璇换浣曟暟鎹�
+ if (StringUtils.isEmpty(conditions))
+ {
+ sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
+ }
+
+ if (StringUtils.isNotBlank(sqlString.toString()))
+ {
+ Object params = joinPoint.getArgs()[0];
+ if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
+ {
+ BaseEntity baseEntity = (BaseEntity) params;
+ baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
+ }
+ }
+ }
+
+ /**
+ * 鎷兼帴鏉冮檺sql鍓嶅厛娓呯┖params.dataScope鍙傛暟闃叉娉ㄥ叆
+ */
+ private void clearDataScope(final JoinPoint joinPoint)
+ {
+ Object params = joinPoint.getArgs()[0];
+ if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
+ {
+ BaseEntity baseEntity = (BaseEntity) params;
+ baseEntity.getParams().put(DATA_SCOPE, "");
+ }
+ }
+}
diff --git a/ycl-server/src/main/java/com/ycl/config/FastJson2JsonRedisSerializer.java b/ycl-server/src/main/java/com/ycl/config/FastJson2JsonRedisSerializer.java
new file mode 100644
index 0000000..44131e8
--- /dev/null
+++ b/ycl-server/src/main/java/com/ycl/config/FastJson2JsonRedisSerializer.java
@@ -0,0 +1,49 @@
+package com.ycl.config;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.JSONWriter;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.SerializationException;
+
+import java.nio.charset.Charset;
+
+/**
+ * Redis浣跨敤FastJson搴忓垪鍖�
+ *
+ * @author ruoyi
+ */
+public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
+{
+ public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
+
+ private Class<T> clazz;
+
+ public FastJson2JsonRedisSerializer(Class<T> clazz)
+ {
+ super();
+ this.clazz = clazz;
+ }
+
+ @Override
+ public byte[] serialize(T t) throws SerializationException
+ {
+ if (t == null)
+ {
+ return new byte[0];
+ }
+ return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
+ }
+
+ @Override
+ public T deserialize(byte[] bytes) throws SerializationException
+ {
+ if (bytes == null || bytes.length <= 0)
+ {
+ return null;
+ }
+ String str = new String(bytes, DEFAULT_CHARSET);
+
+ return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
+ }
+}
diff --git a/ycl-server/src/main/java/com/ycl/config/RedisConfig.java b/ycl-server/src/main/java/com/ycl/config/RedisConfig.java
new file mode 100644
index 0000000..86babf0
--- /dev/null
+++ b/ycl-server/src/main/java/com/ycl/config/RedisConfig.java
@@ -0,0 +1,69 @@
+package com.ycl.config;
+
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * redis閰嶇疆
+ *
+ * @author ruoyi
+ */
+@Configuration
+@EnableCaching
+public class RedisConfig extends CachingConfigurerSupport
+{
+ @Bean
+ @SuppressWarnings(value = { "unchecked", "rawtypes" })
+ public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
+ {
+ RedisTemplate<Object, Object> template = new RedisTemplate<>();
+ template.setConnectionFactory(connectionFactory);
+
+ FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
+
+ // 浣跨敤StringRedisSerializer鏉ュ簭鍒楀寲鍜屽弽搴忓垪鍖杛edis鐨刱ey鍊�
+ template.setKeySerializer(new StringRedisSerializer());
+ template.setValueSerializer(serializer);
+
+ // Hash鐨刱ey涔熼噰鐢⊿tringRedisSerializer鐨勫簭鍒楀寲鏂瑰紡
+ template.setHashKeySerializer(new StringRedisSerializer());
+ template.setHashValueSerializer(serializer);
+
+ template.afterPropertiesSet();
+ return template;
+ }
+
+ @Bean
+ public DefaultRedisScript<Long> limitScript()
+ {
+ DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
+ redisScript.setScriptText(limitScriptText());
+ redisScript.setResultType(Long.class);
+ return redisScript;
+ }
+
+ /**
+ * 闄愭祦鑴氭湰
+ */
+ private String limitScriptText()
+ {
+ return "local key = KEYS[1]\n" +
+ "local count = tonumber(ARGV[1])\n" +
+ "local time = tonumber(ARGV[2])\n" +
+ "local current = redis.call('get', key);\n" +
+ "if current and tonumber(current) > count then\n" +
+ " return tonumber(current);\n" +
+ "end\n" +
+ "current = redis.call('incr', key)\n" +
+ "if tonumber(current) == 1 then\n" +
+ " redis.call('expire', key, time)\n" +
+ "end\n" +
+ "return tonumber(current);";
+ }
+}
diff --git a/ycl-server/src/main/java/com/ycl/config/SecurityConfig.java b/ycl-server/src/main/java/com/ycl/config/SecurityConfig.java
index 7005cfa..de57a5f 100644
--- a/ycl-server/src/main/java/com/ycl/config/SecurityConfig.java
+++ b/ycl-server/src/main/java/com/ycl/config/SecurityConfig.java
@@ -24,8 +24,6 @@
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
@@ -71,7 +69,7 @@
/**
* 鍏佽鍖垮悕璁块棶鐨勫湴鍧�
*/
- @Autowired
+ @Resource
private PermitAllUrlProperties permitAllUrl;
@Bean
diff --git a/ycl-server/src/main/java/com/ycl/handler/GlobalExceptionHandler.java b/ycl-server/src/main/java/com/ycl/handler/GlobalExceptionHandler.java
new file mode 100644
index 0000000..bcaade1
--- /dev/null
+++ b/ycl-server/src/main/java/com/ycl/handler/GlobalExceptionHandler.java
@@ -0,0 +1,114 @@
+package com.ycl.handler;
+
+import com.ycl.exception.DemoModeException;
+import com.ycl.exception.ServiceException;
+import com.ycl.system.AjaxResult;
+import com.ycl.utils.StringUtils;
+import constant.HttpStatus;
+import jakarta.servlet.http.HttpServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.validation.BindException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+/**
+ * 鍏ㄥ眬寮傚父澶勭悊鍣�
+ *
+ * @author ruoyi
+ */
+@RestControllerAdvice
+public class GlobalExceptionHandler
+{
+ private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
+
+ /**
+ * 鏉冮檺鏍¢獙寮傚父
+ */
+ @ExceptionHandler(AccessDeniedException.class)
+ public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request)
+ {
+ String requestURI = request.getRequestURI();
+ log.error("璇锋眰鍦板潃'{}',鏉冮檺鏍¢獙澶辫触'{}'", requestURI, e.getMessage());
+ return AjaxResult.error(HttpStatus.FORBIDDEN, "娌℃湁鏉冮檺锛岃鑱旂郴绠$悊鍛樻巿鏉�");
+ }
+
+ /**
+ * 璇锋眰鏂瑰紡涓嶆敮鎸�
+ */
+ @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
+ public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
+ HttpServletRequest request)
+ {
+ String requestURI = request.getRequestURI();
+ log.error("璇锋眰鍦板潃'{}',涓嶆敮鎸�'{}'璇锋眰", requestURI, e.getMethod());
+ return AjaxResult.error(e.getMessage());
+ }
+
+ /**
+ * 涓氬姟寮傚父
+ */
+ @ExceptionHandler(ServiceException.class)
+ public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
+ {
+ log.error(e.getMessage(), e);
+ Integer code = e.getCode();
+ return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
+ }
+
+ /**
+ * 鎷︽埅鏈煡鐨勮繍琛屾椂寮傚父
+ */
+ @ExceptionHandler(RuntimeException.class)
+ public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
+ {
+ String requestURI = request.getRequestURI();
+ log.error("璇锋眰鍦板潃'{}',鍙戠敓鏈煡寮傚父.", requestURI, e);
+ return AjaxResult.error(e.getMessage());
+ }
+
+ /**
+ * 绯荤粺寮傚父
+ */
+ @ExceptionHandler(Exception.class)
+ public AjaxResult handleException(Exception e, HttpServletRequest request)
+ {
+ String requestURI = request.getRequestURI();
+ log.error("璇锋眰鍦板潃'{}',鍙戠敓绯荤粺寮傚父.", requestURI, e);
+ return AjaxResult.error(e.getMessage());
+ }
+
+ /**
+ * 鑷畾涔夐獙璇佸紓甯�
+ */
+ @ExceptionHandler(BindException.class)
+ public AjaxResult handleBindException(BindException e)
+ {
+ log.error(e.getMessage(), e);
+ String message = e.getAllErrors().get(0).getDefaultMessage();
+ return AjaxResult.error(message);
+ }
+
+ /**
+ * 鑷畾涔夐獙璇佸紓甯�
+ */
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
+ {
+ log.error(e.getMessage(), e);
+ String message = e.getBindingResult().getFieldError().getDefaultMessage();
+ return AjaxResult.error(message);
+ }
+
+ /**
+ * 婕旂ず妯″紡寮傚父
+ */
+ @ExceptionHandler(DemoModeException.class)
+ public AjaxResult handleDemoModeException(DemoModeException e)
+ {
+ return AjaxResult.error("婕旂ず妯″紡锛屼笉鍏佽鎿嶄綔");
+ }
+}
diff --git a/ycl-server/src/main/java/com/ycl/properties/PermitAllUrlProperties.java b/ycl-server/src/main/java/com/ycl/properties/PermitAllUrlProperties.java
index a924f8d..f876a8f 100644
--- a/ycl-server/src/main/java/com/ycl/properties/PermitAllUrlProperties.java
+++ b/ycl-server/src/main/java/com/ycl/properties/PermitAllUrlProperties.java
@@ -34,7 +34,7 @@
@Override
public void afterPropertiesSet()
{
- RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
+ RequestMappingHandlerMapping mapping = applicationContext.getBean("requestMappingHandlerMapping",RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
map.keySet().forEach(info -> {
diff --git a/ycl-server/src/main/java/com/ycl/system/controller/SysLogininforController.java b/ycl-server/src/main/java/com/ycl/system/controller/SysLogininforController.java
new file mode 100644
index 0000000..2871824
--- /dev/null
+++ b/ycl-server/src/main/java/com/ycl/system/controller/SysLogininforController.java
@@ -0,0 +1,77 @@
+package com.ycl.system.controller;
+
+import annotation.Log;
+import com.ycl.system.AjaxResult;
+import com.ycl.system.domain.SysLogininfor;
+import com.ycl.system.page.TableDataInfo;
+import com.ycl.system.service.ISysLogininforService;
+import com.ycl.system.service.SysPasswordService;
+import com.ycl.utils.poi.ExcelUtil;
+import enumeration.BusinessType;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 绯荤粺璁块棶璁板綍
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/logininfor")
+public class SysLogininforController extends BaseController
+{
+ @Autowired
+ private ISysLogininforService logininforService;
+
+ @Autowired
+ private SysPasswordService passwordService;
+
+ @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
+ @GetMapping("/list")
+ public TableDataInfo list(SysLogininfor logininfor)
+ {
+ startPage();
+ List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
+ return getDataTable(list);
+ }
+
+ @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.EXPORT)
+ @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, SysLogininfor logininfor)
+ {
+ List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
+ ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
+ util.exportExcel(response, list, "鐧诲綍鏃ュ織");
+ }
+
+ @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
+ @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{infoIds}")
+ public AjaxResult remove(@PathVariable Long[] infoIds)
+ {
+ return toAjax(logininforService.deleteLogininforByIds(infoIds));
+ }
+
+ @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
+ @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.CLEAN)
+ @DeleteMapping("/clean")
+ public AjaxResult clean()
+ {
+ logininforService.cleanLogininfor();
+ return success();
+ }
+
+ @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
+ @Log(title = "璐︽埛瑙i攣", businessType = BusinessType.OTHER)
+ @GetMapping("/unlock/{userName}")
+ public AjaxResult unlock(@PathVariable("userName") String userName)
+ {
+ passwordService.clearLoginRecordCache(userName);
+ return success();
+ }
+}
diff --git a/ycl-server/src/main/java/com/ycl/system/controller/SysOperlogController.java b/ycl-server/src/main/java/com/ycl/system/controller/SysOperlogController.java
new file mode 100644
index 0000000..cc0c16d
--- /dev/null
+++ b/ycl-server/src/main/java/com/ycl/system/controller/SysOperlogController.java
@@ -0,0 +1,64 @@
+package com.ycl.system.controller;
+
+import annotation.Log;
+import com.ycl.system.AjaxResult;
+import com.ycl.system.domain.SysOperLog;
+import com.ycl.system.page.TableDataInfo;
+import com.ycl.system.service.ISysOperLogService;
+import com.ycl.utils.poi.ExcelUtil;
+import enumeration.BusinessType;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 鎿嶄綔鏃ュ織璁板綍
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/operlog")
+public class SysOperlogController extends BaseController
+{
+ @Autowired
+ private ISysOperLogService operLogService;
+
+ @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
+ @GetMapping("/list")
+ public TableDataInfo list(SysOperLog operLog)
+ {
+ startPage();
+ List<SysOperLog> list = operLogService.selectOperLogList(operLog);
+ return getDataTable(list);
+ }
+
+ @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.EXPORT)
+ @PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, SysOperLog operLog)
+ {
+ List<SysOperLog> list = operLogService.selectOperLogList(operLog);
+ ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
+ util.exportExcel(response, list, "鎿嶄綔鏃ュ織");
+ }
+
+ @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.DELETE)
+ @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
+ @DeleteMapping("/{operIds}")
+ public AjaxResult remove(@PathVariable Long[] operIds)
+ {
+ return toAjax(operLogService.deleteOperLogByIds(operIds));
+ }
+
+ @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.CLEAN)
+ @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
+ @DeleteMapping("/clean")
+ public AjaxResult clean()
+ {
+ operLogService.cleanOperLog();
+ return success();
+ }
+}
diff --git a/ycl-server/src/main/java/com/ycl/system/monitor/CacheController.java b/ycl-server/src/main/java/com/ycl/system/monitor/CacheController.java
new file mode 100644
index 0000000..0b6e57c
--- /dev/null
+++ b/ycl-server/src/main/java/com/ycl/system/monitor/CacheController.java
@@ -0,0 +1,111 @@
+package com.ycl.system.monitor;
+
+import com.ycl.system.AjaxResult;
+import com.ycl.system.domain.SysCache;
+import constant.CacheConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+import utils.StringUtils;
+
+import java.util.*;
+
+/**
+ * 缂撳瓨鐩戞帶
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/cache")
+public class CacheController
+{
+ @Autowired
+ private RedisTemplate<String, String> redisTemplate;
+
+ private final static List<SysCache> caches = new ArrayList<SysCache>();
+ {
+ caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "鐢ㄦ埛淇℃伅"));
+ caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "閰嶇疆淇℃伅"));
+ caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "鏁版嵁瀛楀吀"));
+ caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "楠岃瘉鐮�"));
+ caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "闃查噸鎻愪氦"));
+ caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "闄愭祦澶勭悊"));
+ caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "瀵嗙爜閿欒娆℃暟"));
+ }
+
+ @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+ @GetMapping()
+ public AjaxResult getInfo() throws Exception
+ {
+ Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
+ Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
+ Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
+
+ Map<String, Object> result = new HashMap<>(3);
+ result.put("info", info);
+ result.put("dbSize", dbSize);
+
+ List<Map<String, String>> pieList = new ArrayList<>();
+ commandStats.stringPropertyNames().forEach(key -> {
+ Map<String, String> data = new HashMap<>(2);
+ String property = commandStats.getProperty(key);
+ data.put("name", StringUtils.removeStart(key, "cmdstat_"));
+ data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
+ pieList.add(data);
+ });
+ result.put("commandStats", pieList);
+ return AjaxResult.success(result);
+ }
+
+ @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+ @GetMapping("/getNames")
+ public AjaxResult cache()
+ {
+ return AjaxResult.success(caches);
+ }
+
+ @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+ @GetMapping("/getKeys/{cacheName}")
+ public AjaxResult getCacheKeys(@PathVariable String cacheName)
+ {
+ Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
+ return AjaxResult.success(cacheKeys);
+ }
+
+ @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+ @GetMapping("/getValue/{cacheName}/{cacheKey}")
+ public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey)
+ {
+ String cacheValue = redisTemplate.opsForValue().get(cacheKey);
+ SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue);
+ return AjaxResult.success(sysCache);
+ }
+
+ @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+ @DeleteMapping("/clearCacheName/{cacheName}")
+ public AjaxResult clearCacheName(@PathVariable String cacheName)
+ {
+ Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
+ redisTemplate.delete(cacheKeys);
+ return AjaxResult.success();
+ }
+
+ @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+ @DeleteMapping("/clearCacheKey/{cacheKey}")
+ public AjaxResult clearCacheKey(@PathVariable String cacheKey)
+ {
+ redisTemplate.delete(cacheKey);
+ return AjaxResult.success();
+ }
+
+ @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+ @DeleteMapping("/clearCacheAll")
+ public AjaxResult clearCacheAll()
+ {
+ Collection<String> cacheKeys = redisTemplate.keys("*");
+ redisTemplate.delete(cacheKeys);
+ return AjaxResult.success();
+ }
+}
diff --git a/ycl-server/src/main/java/com/ycl/system/monitor/ServerController.java b/ycl-server/src/main/java/com/ycl/system/monitor/ServerController.java
new file mode 100644
index 0000000..42a1575
--- /dev/null
+++ b/ycl-server/src/main/java/com/ycl/system/monitor/ServerController.java
@@ -0,0 +1,27 @@
+package com.ycl.system.monitor;
+
+import com.ycl.system.AjaxResult;
+import com.ycl.system.Server;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 鏈嶅姟鍣ㄧ洃鎺�
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/server")
+public class ServerController
+{
+ @PreAuthorize("@ss.hasPermi('monitor:server:list')")
+ @GetMapping()
+ public AjaxResult getInfo() throws Exception
+ {
+ Server server = new Server();
+ server.copyTo();
+ return AjaxResult.success(server);
+ }
+}
diff --git a/ycl-server/src/main/java/com/ycl/system/monitor/SysUserOnlineController.java b/ycl-server/src/main/java/com/ycl/system/monitor/SysUserOnlineController.java
new file mode 100644
index 0000000..3a16283
--- /dev/null
+++ b/ycl-server/src/main/java/com/ycl/system/monitor/SysUserOnlineController.java
@@ -0,0 +1,80 @@
+package com.ycl.system.monitor;
+
+import annotation.Log;
+import com.ycl.system.AjaxResult;
+import com.ycl.system.controller.BaseController;
+import com.ycl.system.domain.SysUserOnline;
+import com.ycl.system.model.LoginUser;
+import com.ycl.system.page.TableDataInfo;
+import com.ycl.system.service.ISysUserOnlineService;
+import com.ycl.utils.redis.RedisCache;
+import constant.CacheConstants;
+import enumeration.BusinessType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+import utils.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 鍦ㄧ嚎鐢ㄦ埛鐩戞帶
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/online")
+public class SysUserOnlineController extends BaseController
+{
+ @Autowired
+ private ISysUserOnlineService userOnlineService;
+
+ @Autowired
+ private RedisCache redisCache;
+
+ @PreAuthorize("@ss.hasPermi('monitor:online:list')")
+ @GetMapping("/list")
+ public TableDataInfo list(String ipaddr, String userName)
+ {
+ Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
+ List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
+ for (String key : keys)
+ {
+ LoginUser user = redisCache.getCacheObject(key);
+ if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
+ {
+ userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
+ }
+ else if (StringUtils.isNotEmpty(ipaddr))
+ {
+ userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
+ }
+ else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
+ {
+ userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
+ }
+ else
+ {
+ userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
+ }
+ }
+ Collections.reverse(userOnlineList);
+ userOnlineList.removeAll(Collections.singleton(null));
+ return getDataTable(userOnlineList);
+ }
+
+ /**
+ * 寮洪��鐢ㄦ埛
+ */
+ @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
+ @Log(title = "鍦ㄧ嚎鐢ㄦ埛", businessType = BusinessType.FORCE)
+ @DeleteMapping("/{tokenId}")
+ public AjaxResult forceLogout(@PathVariable String tokenId)
+ {
+ redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
+ return success();
+ }
+}
diff --git a/ycl-server/src/main/resources/application.yml b/ycl-server/src/main/resources/application.yml
index 1f21e84..6cb55a0 100644
--- a/ycl-server/src/main/resources/application.yml
+++ b/ycl-server/src/main/resources/application.yml
@@ -52,7 +52,7 @@
# 浠ょ墝瀵嗛挜
secret: 1212121hsodhsdhasdhsaldhsalhdlsahdlsad1212121hsodhsdhasdhsaldhsalhdlsahdlsad1212121hsodhsdhasdhsaldhsalhdlsahdlsad1212121hsodhsdhasdhsaldhsalhdlsahdlsad1212121hsodhsdhasdhsaldhsalhdlsahdlsad1212121hsodhsdhasdhsaldhsalhdlsahdlsadlsadhsaldhsalhdlsahdlsadlsad
# 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
- expireTime: 30
+ expireTime: 300
#MP閰嶇疆
mybatis-plus:
--
Gitblit v1.8.0