From 536e17a446c170a8b214aaf188b98817ee6258c1 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期一, 09 三月 2026 15:23:23 +0800
Subject: [PATCH] #

---
 src/main/java/com/core/common/Cools.java                      |  318 +++++
 src/main/java/com/core/annotations/AppAuth.java               |   20 
 src/main/java/com/core/common/BaseRes.java                    |   13 
 src/main/resources/templates/Service.txt                      |    8 
 src/main/java/com/core/common/AesUtils.java                   |   50 
 src/main/java/com/core/annotations/CoolTranslate.java         |   13 
 src/main/java/com/core/generators/constant/SqlOsType.java     |    6 
 pom.xml                                                       |    8 
 src/main/java/com/core/common/RadixTools.java                 |  131 ++
 src/main/java/com/core/exception/ApplicationException.java    |   14 
 src/main/java/com/core/generators/domain/Column.java          |  265 ++++
 src/main/resources/templates/Entity.txt                       |   16 
 src/main/resources/templates/Js.txt                           |  244 ++++
 src/main/java/com/core/utils/SignUtils.java                   |   30 
 src/main/java/com/core/common/DateUtils.java                  |  161 ++
 src/main/java/com/core/controller/AbstractBaseController.java |   74 +
 src/main/java/com/core/common/Arith.java                      |   77 +
 src/main/java/com/core/common/SpringUtils.java                |   35 
 src/main/java/com/core/common/SnowflakeIdWorker.java          |   78 +
 src/main/java/com/core/domain/QueryField.java                 |   17 
 src/main/java/com/core/config/CoolBaseConfig.java             |   26 
 src/main/resources/templates/Xml.txt                          |   10 
 src/main/java/com/core/annotations/ManagerAuth.java           |   20 
 src/main/resources/templates/Controller.txt                   |  139 ++
 src/main/java/com/core/common/Cache.java                      |   61 +
 src/main/java/com/core/common/R.java                          |   58 +
 src/main/java/com/core/domain/QueryType.java                  |   20 
 src/main/java/com/core/utils/Algorithm.java                   |   10 
 src/main/resources/templates/Mapper.txt                       |   12 
 src/main/resources/templates/ServiceImpl.txt                  |   12 
 /dev/null                                                     |    1 
 src/main/java/com/core/generators/CoolGenerator.java          |  853 +++++++++++++++
 src/main/resources/META-INF/spring.factories                  |    1 
 src/main/resources/templates/Html.txt                         |   70 +
 src/main/java/com/core/generators/utils/GeneratorUtils.java   |  134 ++
 src/main/java/com/core/domain/KeyValueVo.java                 |   32 
 src/main/resources/templates/Sql.txt                          |   18 
 src/main/resources/templates/HtmlDetail.txt                   |   48 
 src/main/java/com/core/common/Protocol.java                   |   80 +
 src/main/java/com/core/exception/CoolException.java           |   12 
 40 files changed, 3,186 insertions(+), 9 deletions(-)

diff --git a/pom.xml b/pom.xml
index 6497e70..ee6148a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,7 +15,6 @@
 
     <properties>
         <java.version>1.8</java.version>
-        <cool.version>3.4.0</cool.version>
         <mysql-driver.version>5.1.47</mysql-driver.version>
         <mybatis-plus.version>2.3.2</mybatis-plus.version>
         <fastjson.version>1.2.83</fastjson.version>
@@ -36,13 +35,6 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>cn.cool</groupId>
-            <artifactId>framework</artifactId>
-            <version>3.4.0</version>
-            <scope>system</scope>
-            <systemPath>${project.basedir}/version/lib/framework-3.4.0.jar</systemPath>
         </dependency>
         <dependency>
             <groupId>mysql</groupId>
diff --git a/src/main/java/com/core/annotations/AppAuth.java b/src/main/java/com/core/annotations/AppAuth.java
new file mode 100644
index 0000000..a73cd4f
--- /dev/null
+++ b/src/main/java/com/core/annotations/AppAuth.java
@@ -0,0 +1,20 @@
+package com.core.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AppAuth {
+
+    Auth value() default Auth.CHECK;
+
+    String memo() default "";
+
+    enum Auth {
+        CHECK,
+        NONE
+    }
+}
diff --git a/src/main/java/com/core/annotations/CoolTranslate.java b/src/main/java/com/core/annotations/CoolTranslate.java
new file mode 100644
index 0000000..98d32f6
--- /dev/null
+++ b/src/main/java/com/core/annotations/CoolTranslate.java
@@ -0,0 +1,13 @@
+package com.core.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface CoolTranslate {
+
+    String value() default "";
+}
diff --git a/src/main/java/com/core/annotations/ManagerAuth.java b/src/main/java/com/core/annotations/ManagerAuth.java
new file mode 100644
index 0000000..08d7546
--- /dev/null
+++ b/src/main/java/com/core/annotations/ManagerAuth.java
@@ -0,0 +1,20 @@
+package com.core.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ManagerAuth {
+
+    Auth value() default Auth.CHECK;
+
+    String memo() default "";
+
+    enum Auth {
+        CHECK,
+        NONE
+    }
+}
diff --git a/src/main/java/com/core/common/AesUtils.java b/src/main/java/com/core/common/AesUtils.java
new file mode 100644
index 0000000..1cd8964
--- /dev/null
+++ b/src/main/java/com/core/common/AesUtils.java
@@ -0,0 +1,50 @@
+package com.core.common;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+
+public class AesUtils {
+
+    private static final String DEFAULT_CHARSET = "utf-8";
+    private static final int DEFAULT_KEY_LENGTH = 16;
+
+    public static String encrypt(String data, String key) {
+        try {
+            if (key == null || "".equals(key) || key.length() != DEFAULT_KEY_LENGTH) {
+                return null;
+            }
+            byte[] raw = key.getBytes(StandardCharsets.UTF_8);
+            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
+            byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
+            return RadixTools.bytesToHexStr(encrypted);
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    public static String decrypt(String data, String key) {
+        try {
+            if (key == null || "".equals(key) || key.length() != DEFAULT_KEY_LENGTH) {
+                return null;
+            }
+            byte[] raw = key.getBytes(StandardCharsets.UTF_8);
+            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
+            byte[] original = cipher.doFinal(RadixTools.hexStringToBytes(data));
+            return new String(original, StandardCharsets.UTF_8);
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+        String key = "123456";
+        String data = "15988786205&timestamp=" + (System.currentTimeMillis() + 5000000L);
+        System.out.println(System.currentTimeMillis() + 5000000L);
+        System.out.println(encrypt(data, key));
+    }
+}
diff --git a/src/main/java/com/core/common/Arith.java b/src/main/java/com/core/common/Arith.java
new file mode 100644
index 0000000..a5d56d0
--- /dev/null
+++ b/src/main/java/com/core/common/Arith.java
@@ -0,0 +1,77 @@
+package com.core.common;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+public class Arith {
+
+    private enum ArithType {
+        ADD(0),
+        DIVIDE(1),
+        SUBTRACT(2),
+        MULTIPLY(3);
+
+        private final int value;
+
+        ArithType(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+    }
+
+    public static double add(int scale, Number... nums) {
+        return getAirth(scale, ArithType.ADD.getValue(), nums);
+    }
+
+    public static double subtract(int scale, Number... nums) {
+        return getAirth(scale, ArithType.SUBTRACT.getValue(), nums);
+    }
+
+    public static double multiplys(int scale, Number... nums) {
+        return getAirth(scale, ArithType.MULTIPLY.getValue(), nums);
+    }
+
+    public static double divides(int scale, Number... nums) {
+        return getAirth(scale, ArithType.DIVIDE.getValue(), nums);
+    }
+
+    public static int percentage(Number... nums) {
+        return (int) (divides(2, nums) * 100);
+    }
+
+    public static double remainder(Number... nums) {
+        return new BigDecimal(nums[0].toString())
+                .remainder(new BigDecimal(String.valueOf(nums[1])))
+                .doubleValue();
+    }
+
+    private static double getAirth(int scale, int type, Number... nums) {
+        if (nums == null || nums.length == 0) {
+            return 0D;
+        }
+        BigDecimal result = new BigDecimal(nums[0].toString());
+        for (int i = 1; i < nums.length; i++) {
+            BigDecimal current = new BigDecimal(String.valueOf(nums[i]));
+            switch (type) {
+                case 0:
+                    result = result.add(current);
+                    break;
+                case 1:
+                    result = result.divide(current, scale, RoundingMode.HALF_UP);
+                    break;
+                case 2:
+                    result = result.subtract(current);
+                    break;
+                case 3:
+                    result = result.multiply(current);
+                    break;
+                default:
+                    return 0D;
+            }
+        }
+        return result.setScale(scale, RoundingMode.HALF_UP).doubleValue();
+    }
+}
diff --git a/src/main/java/com/core/common/BaseRes.java b/src/main/java/com/core/common/BaseRes.java
new file mode 100644
index 0000000..5f909ca
--- /dev/null
+++ b/src/main/java/com/core/common/BaseRes.java
@@ -0,0 +1,13 @@
+package com.core.common;
+
+public interface BaseRes {
+
+    String OK = "200-鎿嶄綔鎴愬姛";
+    String EMPTY = "201-鏆傛棤鏁版嵁";
+    String LIMIT = "202-鏃犳潈闄�";
+    String PARAM = "401-鍙傛暟涓虹┖";
+    String DENIED = "403-璇烽噸鏂扮櫥褰�";
+    String REPEAT = "407-宸插瓨鍦�";
+    String NO_ACTIVATION = "409-璇峰厛婵�娲荤郴缁�";
+    String ERROR = "500-鏈嶅姟鍣ㄩ敊璇�";
+}
diff --git a/src/main/java/com/core/common/Cache.java b/src/main/java/com/core/common/Cache.java
new file mode 100644
index 0000000..2fef707
--- /dev/null
+++ b/src/main/java/com/core/common/Cache.java
@@ -0,0 +1,61 @@
+package com.core.common;
+
+import com.core.exception.ApplicationException;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Supplier;
+
+public class Cache {
+
+    private Map<String, Object> caches = new ConcurrentHashMap<>();
+
+    public <T> T get(Class<T> clazz) {
+        return (T) get(clazz.getName());
+    }
+
+    public Object get(String key) {
+        return get(key, true);
+    }
+
+    public <T> T get(String key, Supplier<T> supplier) {
+        if (!hasKey(key)) {
+            put(key, supplier.get());
+        }
+        return (T) get(key);
+    }
+
+    public Object get(String key, boolean require) {
+        if (require && !hasKey(key)) {
+            throw new ApplicationException(this + "-鎵句笉鍒扮紦瀛樺璞�:" + key);
+        }
+        return caches.get(key);
+    }
+
+    public Cache put(Object value) {
+        String key = value.getClass().getName();
+        put(key, value);
+        return this;
+    }
+
+    public Cache put(String key, Object value) {
+        put(key, value, true);
+        return this;
+    }
+
+    public Cache put(String key, Object value, boolean requireNotExists) {
+        if (requireNotExists && hasKey(key)) {
+            throw new ApplicationException(this + "-缂撳瓨" + key + "宸插瓨鍦�");
+        }
+        caches.put(key, value);
+        return this;
+    }
+
+    public boolean hasKey(Class<?> clazz) {
+        return hasKey(clazz.getName());
+    }
+
+    public boolean hasKey(String key) {
+        return caches.containsKey(key);
+    }
+}
diff --git a/src/main/java/com/core/common/Cools.java b/src/main/java/com/core/common/Cools.java
new file mode 100644
index 0000000..e100bf2
--- /dev/null
+++ b/src/main/java/com/core/common/Cools.java
@@ -0,0 +1,318 @@
+package com.core.common;
+
+import com.core.annotations.CoolTranslate;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class Cools {
+
+    private static final char[] HEX_DIGITS = {
+            '0', '1', '2', '3', '4', '5', '6', '7',
+            '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+    };
+
+    public static boolean isEmpty(Object... objects) {
+        for (Object object : objects) {
+            if (isEmpty(object)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean isEmpty(Object object) {
+        if (object == null) {
+            return true;
+        }
+        if (object instanceof String) {
+            return "".equals(object.toString().trim());
+        }
+        if (object instanceof List) {
+            return ((List<?>) object).size() == 0;
+        }
+        if (object instanceof Map) {
+            return ((Map<?, ?>) object).size() == 0;
+        }
+        if (object instanceof Set) {
+            return ((Set<?>) object).size() == 0;
+        }
+        if (object instanceof Object[]) {
+            return ((Object[]) object).length == 0;
+        }
+        if (object instanceof int[]) {
+            return ((int[]) object).length == 0;
+        }
+        if (object instanceof long[]) {
+            return ((long[]) object).length == 0;
+        }
+        return false;
+    }
+
+    public static int sqlLimitIndex(Integer curr, Integer limit) {
+        return (curr.intValue() - 1) * limit.intValue();
+    }
+
+    public static String enToken(String data, String key) {
+        return AesUtils.encrypt(data, zerofill(key, Integer.valueOf(16)));
+    }
+
+    public static String deTokn(String data, String key) {
+        return AesUtils.decrypt(data, zerofill(key, Integer.valueOf(16)));
+    }
+
+    public static String zerofill(String str, Integer length) {
+        if (str.length() == length.intValue()) {
+            return str;
+        }
+        if (str.length() > length.intValue()) {
+            return str.substring(0, 16);
+        }
+        StringBuilder builder = new StringBuilder(str);
+        for (int i = 0; i < length.intValue() - str.length(); i++) {
+            builder.append("0");
+        }
+        return builder.toString();
+    }
+
+    public static String deleteChar(String str, boolean end) {
+        if (isEmpty(str)) {
+            return "";
+        }
+        if (end) {
+            return str.substring(0, str.length() - 1);
+        }
+        return str.substring(1);
+    }
+
+    public static String deleteChar(String str) {
+        return deleteChar(str, true);
+    }
+
+    public static <T> T conver(Map<? extends String, ?> map, Class<T> clazz) {
+        T target = null;
+        try {
+            Constructor<T> constructor = clazz.getDeclaredConstructor();
+            boolean accessible = constructor.isAccessible();
+            constructor.setAccessible(true);
+            target = constructor.newInstance();
+            constructor.setAccessible(accessible);
+        } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
+            e.printStackTrace();
+        }
+        Class<?> current = clazz;
+        while (current != null && !Object.class.equals(current)) {
+            for (Field field : current.getDeclaredFields()) {
+                if (Modifier.isFinal(field.getModifiers())
+                        || Modifier.isStatic(field.getModifiers())
+                        || Modifier.isTransient(field.getModifiers())) {
+                    continue;
+                }
+                String fieldName = field.getName();
+                Object val = map.containsKey(fieldName) ? map.get(fieldName) : null;
+                if (val == null) {
+                    continue;
+                }
+                boolean accessible = field.isAccessible();
+                field.setAccessible(true);
+                Class<?> fieldType = field.getType();
+                try {
+                    field.set(target, convertFieldValue(fieldType, val));
+                } catch (Exception ex) {
+                    System.err.println("convert error ===> Class[" + current + "],Field:[" + fieldName
+                            + "],Type:[" + fieldType + "],Value:[" + val + "]");
+                }
+                field.setAccessible(accessible);
+            }
+            current = current.getSuperclass();
+        }
+        return target;
+    }
+
+    private static Object convertFieldValue(Class<?> fieldType, Object val)
+            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
+        if (fieldType.isInstance(val)) {
+            return val;
+        }
+        if (fieldType == String.class) {
+            return String.valueOf(val);
+        }
+        if (fieldType == Integer.class || fieldType == int.class) {
+            return Integer.valueOf(String.valueOf(val));
+        }
+        if (fieldType == Long.class || fieldType == long.class) {
+            return Long.valueOf(String.valueOf(val));
+        }
+        if (fieldType == Short.class || fieldType == short.class) {
+            return Short.valueOf(String.valueOf(val));
+        }
+        if (fieldType == Double.class || fieldType == double.class) {
+            return Double.valueOf(String.valueOf(val));
+        }
+        if (fieldType == Float.class || fieldType == float.class) {
+            return Float.valueOf(String.valueOf(val));
+        }
+        if (fieldType == Boolean.class || fieldType == boolean.class) {
+            return Boolean.valueOf(String.valueOf(val));
+        }
+        if (fieldType == Byte.class || fieldType == byte.class) {
+            return Byte.valueOf(String.valueOf(val));
+        }
+        if (fieldType.isEnum()) {
+            return Enum.valueOf((Class<? extends Enum>) fieldType, String.valueOf(val));
+        }
+        Constructor<?> constructor = fieldType.getDeclaredConstructor(String.class);
+        boolean constructorAccessible = constructor.isAccessible();
+        constructor.setAccessible(true);
+        Object result = constructor.newInstance(String.valueOf(val));
+        constructor.setAccessible(constructorAccessible);
+        return result;
+    }
+
+    public static Map<String, Object> conver(Object object) {
+        Field[] fields = getAllFields(object.getClass());
+        Map<String, Object> result = new HashMap<>();
+        for (Field field : fields) {
+            String fieldName = field.getName();
+            boolean accessible = field.isAccessible();
+            field.setAccessible(true);
+            Object val = null;
+            try {
+                val = field.get(object);
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+            field.setAccessible(accessible);
+            if (val != null) {
+                result.put(fieldName, val);
+            }
+        }
+        return result;
+    }
+
+    public static Field[] getAllFields(Class<?> clazz) {
+        return getAllFields(clazz, null);
+    }
+
+    private static Field[] getAllFields(Class<?> clazz, Field[] fields) {
+        Field[] allFields = fields == null ? clazz.getDeclaredFields() : fields;
+        Class<?> superClass = clazz.getSuperclass();
+        if (superClass == null || superClass == Object.class) {
+            return allFields;
+        }
+        Field[] superFields = superClass.getDeclaredFields();
+        allFields = addAll(allFields, superFields);
+        return getAllFields(superClass, allFields);
+    }
+
+    public static <T> T[] addAll(T[] array1, T... array2) {
+        if (array1 == null) {
+            return clone(array2);
+        }
+        if (array2 == null) {
+            return clone(array1);
+        }
+        Class<?> type1 = array1.getClass().getComponentType();
+        T[] joined = (T[]) Array.newInstance(type1, array1.length + array2.length);
+        System.arraycopy(array1, 0, joined, 0, array1.length);
+        try {
+            System.arraycopy(array2, 0, joined, array1.length, array2.length);
+            return joined;
+        } catch (ArrayStoreException ex) {
+            Class<?> type2 = array2.getClass().getComponentType();
+            if (!type1.isAssignableFrom(type2)) {
+                throw new RuntimeException("Cannot store" + type2.getName() + " in an array of" + type1.getName(), ex);
+            }
+            throw ex;
+        }
+    }
+
+    private static <T> T[] clone(T[] array) {
+        return array == null ? null : (T[]) array.clone();
+    }
+
+    public static CoolMap add(String key, Object value) {
+        CoolMap map = new CoolMap();
+        map.put(key, value);
+        return map;
+    }
+
+    public static String md5(String str) {
+        try {
+            MessageDigest digest = MessageDigest.getInstance("MD5");
+            byte[] bytes = digest.digest(str.getBytes(StandardCharsets.UTF_8));
+            char[] chars = new char[bytes.length * 2];
+            for (int i = 0; i < bytes.length; i++) {
+                int val = bytes[i];
+                chars[i * 2] = HEX_DIGITS[(val & 0xF0) >> 4];
+                chars[i * 2 + 1] = HEX_DIGITS[val & 0x0F];
+            }
+            return new String(chars).toLowerCase();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("md5鍔犲瘑澶辫触,str=".concat(str));
+        }
+    }
+
+    public static Map<String, Object> translate(Object object) {
+        Field[] fields = getAllFields(object.getClass());
+        Map<String, Object> result = new HashMap<>();
+        for (Field field : fields) {
+            String fieldName = field.getName();
+            if (field.isAnnotationPresent(CoolTranslate.class)) {
+                CoolTranslate translate = field.getAnnotation(CoolTranslate.class);
+                if (!isEmpty(translate.value())) {
+                    fieldName = translate.value();
+                }
+            }
+            boolean accessible = field.isAccessible();
+            field.setAccessible(true);
+            Object val = null;
+            try {
+                val = field.get(object);
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+            field.setAccessible(accessible);
+            if (val != null) {
+                result.put(fieldName, val);
+            }
+        }
+        return result;
+    }
+
+    public static boolean eq(String left, String right) {
+        if (isEmpty(left) && isEmpty(right)) {
+            return true;
+        }
+        if (isEmpty(left) && !isEmpty(right)) {
+            return false;
+        }
+        if (isEmpty(right) && !isEmpty(left)) {
+            return false;
+        }
+        return left.equals(right);
+    }
+
+    public static class CoolMap extends HashMap<String, Object> {
+
+        public CoolMap add(String key, Object value) {
+            put(key, value);
+            return this;
+        }
+
+        public CoolMap $(String key, Object value) {
+            put(key, value);
+            return this;
+        }
+    }
+}
diff --git a/src/main/java/com/core/common/DateUtils.java b/src/main/java/com/core/common/DateUtils.java
new file mode 100644
index 0000000..f8e9c20
--- /dev/null
+++ b/src/main/java/com/core/common/DateUtils.java
@@ -0,0 +1,161 @@
+package com.core.common;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+public class DateUtils {
+
+    public static final String yyyyMMdd_C = "yyyy骞碝M鏈坉d鏃�";
+    public static final String yyyyMM_F = "yyyy-MM";
+    public static final String yyyyMMdd_F = "yyyy-MM-dd";
+    public static final String yyyyMMddHHmmss_F = "yyyy-MM-dd HH:mm:ss";
+    public static final String yyyyMMddHHmmsssss_F = "yyyy-MM-dd HH:mm:ss:SSS";
+    public static final String yyyy = "yyyy";
+    public static final String yyyyMM = "yyyyMM";
+    public static final String yyyyMMdd = "yyyyMMdd";
+    public static final String yyyyMMddHH = "yyyyMMddHH";
+    public static final String yyyyMMddHHmmss = "yyyyMMddHHmmss";
+    public static final String YYMMDDHHMMSS = "yyMMddHHmmss";
+    public static final String yyyyMMddHHmmsssss = "yyyyMMddHHmmssSSS";
+
+    public static String convert(Date date, String format) {
+        return new SimpleDateFormat(format).format(date);
+    }
+
+    public static String convert(Date date) {
+        return convert(date, yyyyMMddHHmmss_F);
+    }
+
+    public static Date convert(String text, String format) {
+        if (text.length() < format.length()) {
+            throw new RuntimeException("鏃堕棿瑙f瀽澶辫触 ==>>" + text);
+        }
+        if (text.length() > format.length()) {
+            text = text.substring(0, format.length());
+        }
+        try {
+            return new SimpleDateFormat(format).parse(text);
+        } catch (ParseException e) {
+            throw new RuntimeException("鏃堕棿瑙f瀽澶辫触 ==>>" + text);
+        }
+    }
+
+    public static Date convert(String text) {
+        return convert(text, yyyyMMddHHmmss_F);
+    }
+
+    public static int diff(Date start, Date end) {
+        return getDaysByTimestamp(Math.abs(end.getTime() - start.getTime()));
+    }
+
+    public static long diffToMinute(Date start, Date end) {
+        return Math.abs(end.getTime() - start.getTime()) / 1000L / 60L;
+    }
+
+    public static long diffToSeconds(Date start, Date end) {
+        return Math.abs(end.getTime() - start.getTime()) / 1000L;
+    }
+
+    private static int getDaysByTimestamp(long timestamp) {
+        double days = Arith.divides(2, timestamp, 86400000);
+        int value = (int) days;
+        if (days > value) {
+            return value + 1;
+        }
+        return value;
+    }
+
+    public static int diffToNow(Date date) {
+        long val = new Date().getTime() - date.getTime();
+        return (int) (Math.abs(val) / 1000L);
+    }
+
+    public static String createTimeStamp() {
+        return Long.toString(System.currentTimeMillis() / 1000L);
+    }
+
+    public static Date calculate(Date date, Long amount, TimeUnit unit, boolean before) {
+        if (Objects.isNull(date) || Objects.isNull(amount) || Objects.isNull(unit)) {
+            return null;
+        }
+        return new Date(before ? date.getTime() - unit.toMillis(amount) : date.getTime() + unit.toMillis(amount));
+    }
+
+    public static Date calculate(Date date, Long amount, TimeUnit unit) {
+        return calculate(date, amount, unit, false);
+    }
+
+    public static DateEntity getDateEntity(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        DateEntity entity = new DateEntity();
+        entity.setYear(calendar.get(Calendar.YEAR));
+        entity.setMonth(calendar.get(Calendar.MONTH));
+        entity.setDay(calendar.get(Calendar.DAY_OF_MONTH));
+        entity.setHour(calendar.get(Calendar.HOUR_OF_DAY));
+        entity.setMinute(calendar.get(Calendar.MINUTE));
+        entity.setSecond(calendar.get(Calendar.SECOND));
+        return entity;
+    }
+
+    public static class DateEntity {
+        private int year;
+        private int month;
+        private int day;
+        private int hour;
+        private int minute;
+        private int second;
+
+        public int getYear() {
+            return year;
+        }
+
+        public void setYear(int year) {
+            this.year = year;
+        }
+
+        public int getMonth() {
+            return month;
+        }
+
+        public void setMonth(int month) {
+            this.month = month;
+        }
+
+        public int getDay() {
+            return day;
+        }
+
+        public void setDay(int day) {
+            this.day = day;
+        }
+
+        public int getHour() {
+            return hour;
+        }
+
+        public void setHour(int hour) {
+            this.hour = hour;
+        }
+
+        public int getMinute() {
+            return minute;
+        }
+
+        public void setMinute(int minute) {
+            this.minute = minute;
+        }
+
+        public int getSecond() {
+            return second;
+        }
+
+        public void setSecond(int second) {
+            this.second = second;
+        }
+    }
+}
diff --git a/src/main/java/com/core/common/Protocol.java b/src/main/java/com/core/common/Protocol.java
new file mode 100644
index 0000000..8bd0995
--- /dev/null
+++ b/src/main/java/com/core/common/Protocol.java
@@ -0,0 +1,80 @@
+package com.core.common;
+
+import java.io.Serializable;
+
+public class Protocol<T> implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private int code;
+    private String msg;
+    private T data;
+
+    public Protocol() {
+    }
+
+    public Protocol(int code, String msg, T data) {
+        setCode(code);
+        setMsg(msg);
+        setData(data);
+    }
+
+    public Protocol(int code, String msg) {
+        this(code, msg, null);
+    }
+
+    public static <T> Protocol<T> ok() {
+        return parse(BaseRes.OK);
+    }
+
+    public static <T> Protocol<T> ok(T data) {
+        Protocol<T> protocol = parse(BaseRes.OK);
+        protocol.setData(data);
+        return protocol;
+    }
+
+    public static <T> Protocol<T> error() {
+        return parse(BaseRes.ERROR);
+    }
+
+    public static <T> Protocol<T> error(String msg) {
+        Protocol<T> protocol = parse(BaseRes.ERROR);
+        protocol.setMsg(msg);
+        return protocol;
+    }
+
+    public static <T> Protocol<T> parse(String baseRes) {
+        if (Cools.isEmpty(baseRes)) {
+            return parse(BaseRes.ERROR);
+        }
+        String[] arr = baseRes.split("-");
+        if (arr.length == 2) {
+            return new Protocol<>(Integer.parseInt(arr[0]), arr[1]);
+        }
+        return parse("500-".concat(baseRes));
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}
diff --git a/src/main/java/com/core/common/R.java b/src/main/java/com/core/common/R.java
new file mode 100644
index 0000000..72d9bd0
--- /dev/null
+++ b/src/main/java/com/core/common/R.java
@@ -0,0 +1,58 @@
+package com.core.common;
+
+import java.util.HashMap;
+
+public class R extends HashMap<String, Object> {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String CODE = "code";
+    private static final String MSG = "msg";
+    private static final String DATA = "data";
+
+    public R(Integer code, String msg) {
+        super();
+        put(CODE, code);
+        put(MSG, msg);
+    }
+
+    public static R ok() {
+        return parse(BaseRes.OK);
+    }
+
+    public static R ok(String msg) {
+        R r = ok();
+        r.put(MSG, msg);
+        return r;
+    }
+
+    public static R ok(Object data) {
+        return parse(BaseRes.OK).add(data);
+    }
+
+    public static R error() {
+        return parse(BaseRes.ERROR);
+    }
+
+    public static R error(String msg) {
+        R r = error();
+        r.put(MSG, msg);
+        return r;
+    }
+
+    public R add(Object data) {
+        put(DATA, data);
+        return this;
+    }
+
+    public static R parse(String baseRes) {
+        if (Cools.isEmpty(baseRes)) {
+            return parse(BaseRes.ERROR);
+        }
+        String[] arr = baseRes.split("-");
+        if (arr.length == 2) {
+            return new R(Integer.parseInt(arr[0]), arr[1]);
+        }
+        return parse("500-".concat(baseRes));
+    }
+}
diff --git a/src/main/java/com/core/common/RadixTools.java b/src/main/java/com/core/common/RadixTools.java
new file mode 100644
index 0000000..a0ad5a5
--- /dev/null
+++ b/src/main/java/com/core/common/RadixTools.java
@@ -0,0 +1,131 @@
+package com.core.common;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+
+public class RadixTools {
+
+    public static void main(String[] args) {
+        String val = toBinaryString((byte) 1);
+        System.out.println(val);
+        for (int i = val.length() - 1; i >= 0; i--) {
+            char c = val.charAt(i);
+            if (i == 7 && c == '1') {
+                System.out.println("===");
+            }
+        }
+    }
+
+    public static String toBinaryString(byte b) {
+        return Long.toBinaryString((b & 0xFF) + 0x100L).substring(1);
+    }
+
+    public static String toBinaryString(byte[] bytes) {
+        StringBuilder builder = new StringBuilder();
+        for (byte b : bytes) {
+            builder.append(Long.toBinaryString((b & 0xFF) + 0x100L).substring(1));
+        }
+        return builder.toString();
+    }
+
+    public static byte[] hexStringToBytes(String hexString) {
+        if (hexString == null || "".equals(hexString)) {
+            return null;
+        }
+        String upper = hexString.toUpperCase();
+        int length = upper.length() / 2;
+        char[] chars = upper.toCharArray();
+        byte[] result = new byte[length];
+        for (int i = 0; i < length; i++) {
+            int pos = i * 2;
+            result[i] = (byte) ((charToByte(chars[pos]) << 4) | charToByte(chars[pos + 1]));
+        }
+        return result;
+    }
+
+    public static String bytesToHexStr(byte[] bytes) {
+        StringBuilder builder = new StringBuilder(bytes.length * 2);
+        for (byte b : bytes) {
+            builder.append(String.format("%02x", b & 0xFF));
+        }
+        return builder.toString();
+    }
+
+    private static byte charToByte(char c) {
+        return (byte) "0123456789ABCDEF".indexOf(c);
+    }
+
+    public static String bytesToStr(byte[] bytes) {
+        return bytesToStr(bytes, Charset.forName("gbk"));
+    }
+
+    public static String bytesToStr(byte[] bytes, Charset charset) {
+        return new String(bytes, charset).trim().toUpperCase();
+    }
+
+    public static byte[] strToBytes(String str) throws UnsupportedEncodingException {
+        return str.getBytes("gbk");
+    }
+
+    public static byte[] longToBytes(long value) {
+        long tmp = value;
+        byte[] bytes = new byte[8];
+        for (int i = 0; i < bytes.length; i++) {
+            bytes[i] = Long.valueOf(tmp & 0xFF).byteValue();
+            tmp = tmp >> 8;
+        }
+        return bytes;
+    }
+
+    public static long bytesToLong(byte[] bytes) {
+        long result = 0L;
+        long b0 = bytes[0] & 0xFFL;
+        long b1 = (bytes[1] & 0xFFL) << 8;
+        long b2 = (bytes[2] & 0xFFL) << 16;
+        long b3 = (bytes[3] & 0xFFL) << 24;
+        long b4 = (bytes[4] & 0xFFL) << 32;
+        long b5 = (bytes[5] & 0xFFL) << 40;
+        long b6 = (bytes[6] & 0xFFL) << 48;
+        long b7 = (bytes[7] & 0xFFL) << 56;
+        result = b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7;
+        return result;
+    }
+
+    public static byte[] intToBytes(int value) {
+        int tmp = value;
+        byte[] bytes = new byte[4];
+        for (int i = 0; i < bytes.length; i++) {
+            bytes[i] = Integer.valueOf(tmp & 0xFF).byteValue();
+            tmp = tmp >> 8;
+        }
+        return bytes;
+    }
+
+    public static int bytesToInt(byte[] bytes) {
+        int result;
+        int b0 = bytes[0] & 0xFF;
+        int b1 = (bytes[1] & 0xFF) << 8;
+        int b2 = (bytes[2] & 0xFF) << 16;
+        int b3 = (bytes[3] & 0xFF) << 24;
+        result = b0 | b1 | b2 | b3;
+        return result;
+    }
+
+    public static short byteToShort(byte[] bytes) {
+        short result;
+        short b0 = (short) (bytes[0] & 0xFF);
+        short b1 = (short) ((bytes[1] & 0xFF) << 8);
+        result = (short) (b0 | b1);
+        return result;
+    }
+
+    public static byte[] shortToByte(short value) {
+        int tmp = value;
+        byte[] bytes = new byte[2];
+        for (int i = 0; i < bytes.length; i++) {
+            bytes[i] = Integer.valueOf(tmp & 0xFF).byteValue();
+            tmp = tmp >> 8;
+        }
+        return bytes;
+    }
+}
diff --git a/src/main/java/com/core/common/SnowflakeIdWorker.java b/src/main/java/com/core/common/SnowflakeIdWorker.java
new file mode 100644
index 0000000..7dd3d7b
--- /dev/null
+++ b/src/main/java/com/core/common/SnowflakeIdWorker.java
@@ -0,0 +1,78 @@
+package com.core.common;
+
+public class SnowflakeIdWorker {
+
+    private final long twepoch = 1420041600000L;
+    private final long sequenceBits = 12L;
+    private final long workerIdBits = 5L;
+    private final long datacenterIdBits = 5L;
+    private final long workerIdLeftShift = 12L;
+    private final long datacenterIdLeftShift = 17L;
+    private final long timestampLeftShift = 22L;
+    private final long maxWorkerId = 31L;
+    private final long maxDatacenterId = 31L;
+    private final long sequenceMask = 4095L;
+
+    private long workerId;
+    private long datacenterId;
+    private long sequence = 0L;
+    private long lastTimestamp = -1L;
+
+    public SnowflakeIdWorker(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    public SnowflakeIdWorker() {
+        this(0L, 0L);
+    }
+
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(String.format(
+                    "Clock moved backwards.  Refusing to generate id for %d milliseconds",
+                    lastTimestamp - timestamp));
+        }
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            if (sequence == 0) {
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        } else {
+            sequence = 0L;
+        }
+        lastTimestamp = timestamp;
+        return ((timestamp - twepoch) << timestampLeftShift)
+                | (datacenterId << datacenterIdLeftShift)
+                | (workerId << workerIdLeftShift)
+                | sequence;
+    }
+
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+
+    public static void main(String[] args) {
+        SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0L, 0L);
+        for (int i = 0; i < 1000; i++) {
+            long id = idWorker.nextId();
+            System.out.println(Long.toBinaryString(id));
+            System.out.println(id);
+        }
+    }
+}
diff --git a/src/main/java/com/core/common/SpringUtils.java b/src/main/java/com/core/common/SpringUtils.java
new file mode 100644
index 0000000..eab0cd2
--- /dev/null
+++ b/src/main/java/com/core/common/SpringUtils.java
@@ -0,0 +1,35 @@
+package com.core.common;
+
+import com.core.exception.CoolException;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public class SpringUtils implements ApplicationContextAware {
+
+    private static ApplicationContext application;
+
+    public static void init(ApplicationContext applicationContext) {
+        application = applicationContext;
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        application = applicationContext;
+    }
+
+    private static ApplicationContext getApplicationContext() {
+        if (application == null) {
+            throw new CoolException(BaseRes.ERROR);
+        }
+        return application;
+    }
+
+    public static <T> T getBean(Class<T> clazz) {
+        return getApplicationContext().getBean(clazz);
+    }
+
+    public static Object getBean(String name) {
+        return getApplicationContext().getBean(name);
+    }
+}
diff --git a/src/main/java/com/core/config/CoolBaseConfig.java b/src/main/java/com/core/config/CoolBaseConfig.java
new file mode 100644
index 0000000..c6af983
--- /dev/null
+++ b/src/main/java/com/core/config/CoolBaseConfig.java
@@ -0,0 +1,26 @@
+package com.core.config;
+
+import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
+import com.core.common.SnowflakeIdWorker;
+import com.core.common.SpringUtils;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class CoolBaseConfig {
+
+    @Bean
+    public PaginationInterceptor paginationInterceptor() {
+        return new PaginationInterceptor();
+    }
+
+    @Bean
+    public SpringUtils getSpringUtils() {
+        return new SpringUtils();
+    }
+
+    @Bean
+    public SnowflakeIdWorker snowflakeIdWorker() {
+        return new SnowflakeIdWorker();
+    }
+}
diff --git a/src/main/java/com/core/controller/AbstractBaseController.java b/src/main/java/com/core/controller/AbstractBaseController.java
new file mode 100644
index 0000000..6780538
--- /dev/null
+++ b/src/main/java/com/core/controller/AbstractBaseController.java
@@ -0,0 +1,74 @@
+package com.core.controller;
+
+import com.core.common.BaseRes;
+import com.core.common.Cools;
+import com.core.exception.CoolException;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public abstract class AbstractBaseController {
+
+    public <T> List exportSupport(List<T> list, List<String> fields) {
+        if (Cools.isEmpty(list)) {
+            throw new CoolException(BaseRes.EMPTY);
+        }
+        try {
+            List<Object> result = new ArrayList<>();
+            Method[] methods = list.get(0).getClass().getMethods();
+            for (T item : list) {
+                List<Object> row = new ArrayList<>();
+                for (String field : fields) {
+                    for (Method method : methods) {
+                        if (("get" + field).toLowerCase().equals(method.getName().toLowerCase())) {
+                            Object value = method.invoke(item);
+                            row.add(value);
+                            break;
+                        }
+                    }
+                }
+                result.add(row);
+            }
+            return result;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static Map<String, Object> excludeTrash(Map<String, Object> map) {
+        if (Cools.isEmpty(map)) {
+            return new HashMap<>();
+        }
+        Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<String, Object> entry = iterator.next();
+            String key = entry.getKey();
+            if ("curr".equals(key)
+                    || "limit".equals(key)
+                    || "orderByField".equals(key)
+                    || "orderByType".equals(key)
+                    || "condition".equals(key)
+                    || Cools.isEmpty(entry.getValue())) {
+                iterator.remove();
+            }
+        }
+        return map;
+    }
+
+    public static String humpToLine(String str) {
+        Pattern pattern = Pattern.compile("[A-Z]");
+        Matcher matcher = pattern.matcher(str);
+        StringBuffer buffer = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(buffer, "_" + matcher.group(0).toLowerCase());
+        }
+        matcher.appendTail(buffer);
+        return buffer.toString();
+    }
+}
diff --git a/src/main/java/com/core/domain/KeyValueVo.java b/src/main/java/com/core/domain/KeyValueVo.java
new file mode 100644
index 0000000..d769832
--- /dev/null
+++ b/src/main/java/com/core/domain/KeyValueVo.java
@@ -0,0 +1,32 @@
+package com.core.domain;
+
+public class KeyValueVo {
+
+    private String name;
+
+    private Object value;
+
+    public KeyValueVo() {
+    }
+
+    public KeyValueVo(String name, Object value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(Object value) {
+        this.value = value;
+    }
+}
diff --git a/src/main/java/com/core/domain/QueryField.java b/src/main/java/com/core/domain/QueryField.java
new file mode 100644
index 0000000..7a06356
--- /dev/null
+++ b/src/main/java/com/core/domain/QueryField.java
@@ -0,0 +1,17 @@
+package com.core.domain;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
+public @interface QueryField {
+
+    String value() default "";
+
+    QueryType type() default QueryType.LIKE;
+}
diff --git a/src/main/java/com/core/domain/QueryType.java b/src/main/java/com/core/domain/QueryType.java
new file mode 100644
index 0000000..4e0e774
--- /dev/null
+++ b/src/main/java/com/core/domain/QueryType.java
@@ -0,0 +1,20 @@
+package com.core.domain;
+
+public enum QueryType {
+    EQ,
+    NE,
+    GT,
+    GE,
+    LT,
+    LE,
+    LIKE,
+    NOT_LIKE,
+    LIKE_LEFT,
+    LIKE_RIGHT,
+    IS_NULL,
+    IS_NOT_NULL,
+    IN,
+    NOT_IN,
+    IN_STR,
+    NOT_IN_STR
+}
diff --git a/src/main/java/com/core/exception/ApplicationException.java b/src/main/java/com/core/exception/ApplicationException.java
new file mode 100644
index 0000000..5b55120
--- /dev/null
+++ b/src/main/java/com/core/exception/ApplicationException.java
@@ -0,0 +1,14 @@
+package com.core.exception;
+
+public class ApplicationException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    public ApplicationException(Throwable cause) {
+        super(cause);
+    }
+
+    public ApplicationException(String message) {
+        super(message);
+    }
+}
diff --git a/src/main/java/com/core/exception/CoolException.java b/src/main/java/com/core/exception/CoolException.java
new file mode 100644
index 0000000..3fbf21e
--- /dev/null
+++ b/src/main/java/com/core/exception/CoolException.java
@@ -0,0 +1,12 @@
+package com.core.exception;
+
+public class CoolException extends RuntimeException {
+
+    public CoolException(Throwable cause) {
+        super(cause);
+    }
+
+    public CoolException(String message) {
+        super(message);
+    }
+}
diff --git a/src/main/java/com/core/generators/CoolGenerator.java b/src/main/java/com/core/generators/CoolGenerator.java
new file mode 100644
index 0000000..8bf9fec
--- /dev/null
+++ b/src/main/java/com/core/generators/CoolGenerator.java
@@ -0,0 +1,853 @@
+package com.core.generators;
+
+import com.core.common.Cools;
+import com.core.generators.constant.SqlOsType;
+import com.core.generators.domain.Column;
+import com.core.generators.utils.GeneratorUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class CoolGenerator {
+
+    private static final String[] ALL_TEMPLATES = {
+            "Controller", "Service", "ServiceImpl", "Mapper", "Entity",
+            "Xml", "Html", "HtmlDetail", "Js", "Sql"
+    };
+    private static final Set<String> SYSTEM_MODEL = new LinkedHashSet<>(Arrays.asList("User", "Host"));
+
+    public String url;
+    public String username;
+    public String password;
+    public String table;
+    public String packagePath;
+    public boolean controller = true;
+    public boolean service = true;
+    public boolean mapper = true;
+    public boolean entity = true;
+    public boolean xml = true;
+    public boolean html = true;
+    public boolean htmlDetail = false;
+    public boolean js = true;
+    public boolean sql = true;
+    public SqlOsType sqlOsType;
+    public String backendPrefixPath = "";
+    public String frontendPrefixPath = "";
+
+    private List<Column> columns = new ArrayList<>();
+    private String fullEntityName;
+    private String simpleEntityName;
+    private String entityImport;
+    private String entityContent;
+    private String xmlContent;
+    private String htmlSearchContent;
+    private String htmlDialogContent;
+    private String htmlDetailContent;
+    private String jsTableContent;
+    private String jsDateContent;
+    private String primaryKeyColumn;
+    private String primaryKeyType;
+    private String majorColumn;
+    private String systemPackage;
+
+    public void build() throws Exception {
+        init();
+        System.out.println("寮�濮嬬敓鎴愯〃[" + table + "]瀵瑰簲浠g爜锛屽疄浣撳悕[" + fullEntityName + "]");
+        for (String templateName : ALL_TEMPLATES) {
+            boolean enabled = false;
+            String fileDir = "";
+            String fileName = "";
+            String routeSegment = templateName.toLowerCase();
+            if (routeSegment.contains("impl")) {
+                routeSegment = routeSegment.substring(0, routeSegment.length() - 4) + "/" + routeSegment.substring(routeSegment.length() - 4);
+            }
+            switch (templateName) {
+                case "Controller":
+                    enabled = controller;
+                    fileDir = backendPrefixPath + "src/main/java/" + packagePath.replace(".", "/") + "/" + routeSegment + "/";
+                    fileName = fullEntityName + "Controller.java";
+                    break;
+                case "Service":
+                    enabled = service;
+                    fileDir = backendPrefixPath + "src/main/java/" + packagePath.replace(".", "/") + "/" + routeSegment + "/";
+                    fileName = fullEntityName + "Service.java";
+                    break;
+                case "ServiceImpl":
+                    enabled = service;
+                    fileDir = backendPrefixPath + "src/main/java/" + packagePath.replace(".", "/") + "/" + routeSegment + "/";
+                    fileName = fullEntityName + "ServiceImpl.java";
+                    break;
+                case "Mapper":
+                    enabled = mapper;
+                    fileDir = backendPrefixPath + "src/main/java/" + packagePath.replace(".", "/") + "/" + routeSegment + "/";
+                    fileName = fullEntityName + "Mapper.java";
+                    break;
+                case "Entity":
+                    enabled = entity;
+                    fileDir = backendPrefixPath + "src/main/java/" + packagePath.replace(".", "/") + "/" + routeSegment + "/";
+                    fileName = fullEntityName + ".java";
+                    break;
+                case "Xml":
+                    enabled = xml;
+                    fileDir = backendPrefixPath + "src/main/resources/mapper/";
+                    fileName = fullEntityName + "Mapper.xml";
+                    break;
+                case "Html":
+                    enabled = html;
+                    fileDir = frontendPrefixPath + "src/main/webapp//views/" + simpleEntityName + "/";
+                    fileName = simpleEntityName + ".html";
+                    break;
+                case "HtmlDetail":
+                    enabled = htmlDetail;
+                    fileDir = frontendPrefixPath + "src/main/webapp//views/" + simpleEntityName + "/";
+                    fileName = simpleEntityName + "_detail.html";
+                    break;
+                case "Js":
+                    enabled = js;
+                    fileDir = frontendPrefixPath + "src/main/webapp/static/js/" + simpleEntityName + "/";
+                    fileName = simpleEntityName + ".js";
+                    break;
+                case "Sql":
+                    enabled = sql;
+                    fileDir = backendPrefixPath + "version/sql/";
+                    fileName = simpleEntityName + ".sql";
+                    break;
+                default:
+                    break;
+            }
+            if (!enabled) {
+                continue;
+            }
+            try {
+                String template = loadTemplate(templateName + ".txt");
+                String content = renderTemplate(template);
+                writeFile(fileDir, fileName, content, templateName);
+            } catch (Exception e) {
+                System.out.println(fullEntityName + templateName + " 婧愭枃浠跺垱寤哄け璐ワ細" + e.getMessage());
+                throw e;
+            }
+        }
+        System.out.println("琛╗" + table + "]浠g爜鐢熸垚缁撴潫");
+    }
+
+    private void init() throws Exception {
+        validate();
+        systemPackage = resolveSystemPackage();
+        fullEntityName = GeneratorUtils.getNameSpace(table);
+        simpleEntityName = GeneratorUtils.firstCharConvert(fullEntityName);
+        System.out.println("寮�濮嬭鍙栬〃缁撴瀯锛�" + table);
+        Connection connection = createConnection();
+        try {
+            switch (sqlOsType) {
+                case MYSQL:
+                    columns = getMysqlColumns(connection, table, true, sqlOsType);
+                    break;
+                case SQL_SERVER:
+                    columns = getSqlServerColumns(connection, table, true, sqlOsType);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unsupported sql type: " + sqlOsType);
+            }
+        } finally {
+            connection.close();
+        }
+        if (Cools.isEmpty(columns)) {
+            throw new IllegalStateException("table has no columns: " + table);
+        }
+        System.out.println("琛ㄧ粨鏋勮鍙栧畬鎴愶紝鍏� " + columns.size() + " 涓瓧娈�");
+        primaryKeyColumn = resolvePrimaryKeyColumn();
+        primaryKeyType = resolvePrimaryKeyType();
+        majorColumn = resolveMajorColumn();
+        entityImport = buildEntityImports();
+        entityContent = buildEntityContent();
+        xmlContent = buildXmlContent();
+        htmlSearchContent = buildHtmlSearchContent();
+        htmlDialogContent = buildHtmlDialogContent();
+        htmlDetailContent = buildHtmlDetailContent();
+        jsTableContent = buildJsTableContent();
+        jsDateContent = buildJsDateContent();
+    }
+
+    private void validate() {
+        if (Cools.isEmpty(url, username, password, table, packagePath) || sqlOsType == null) {
+            throw new IllegalArgumentException("url/username/password/table/packagePath/sqlOsType are required");
+        }
+    }
+
+    private String resolveSystemPackage() {
+        String[] arr = packagePath.split("\\.");
+        if (arr.length <= 2) {
+            return packagePath;
+        }
+        return arr[0] + "." + arr[1];
+    }
+
+    private Connection createConnection() throws Exception {
+        String jdbcUrl = url;
+        switch (sqlOsType) {
+            case MYSQL:
+                Class.forName("com.mysql.jdbc.Driver");
+                if (!jdbcUrl.startsWith("jdbc:mysql://")) {
+                    jdbcUrl = "jdbc:mysql://" + jdbcUrl;
+                }
+                if (!jdbcUrl.contains("?")) {
+                    jdbcUrl = jdbcUrl + "?useUnicode=true&characterEncoding=utf-8&useSSL=false&remarksReporting=true";
+                } else if (!jdbcUrl.contains("remarksReporting=")) {
+                    jdbcUrl = jdbcUrl + "&remarksReporting=true";
+                }
+                return DriverManager.getConnection(jdbcUrl, username, password);
+            case SQL_SERVER:
+                Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
+                if (!jdbcUrl.startsWith("jdbc:sqlserver://")) {
+                    jdbcUrl = "jdbc:sqlserver://" + jdbcUrl;
+                }
+                return DriverManager.getConnection(jdbcUrl, username, password);
+            default:
+                throw new IllegalArgumentException("Unsupported sql type: " + sqlOsType);
+        }
+    }
+
+    public static List<Column> getMysqlColumns(Connection connection, String table, boolean withForeignKey, SqlOsType sqlOsType) throws Exception {
+        return getColumns(connection, table, withForeignKey, sqlOsType);
+    }
+
+    public static List<Column> getSqlServerColumns(Connection connection, String table, boolean withForeignKey, SqlOsType sqlOsType) throws Exception {
+        return getColumns(connection, table, withForeignKey, sqlOsType);
+    }
+
+    private static List<Column> getColumns(Connection connection, String table, boolean withForeignKey, SqlOsType sqlOsType) throws Exception {
+        List<Column> columns = new ArrayList<>();
+        DatabaseMetaData metaData = connection.getMetaData();
+        TableRef tableRef = parseTableRef(table);
+        Set<String> primaryKeys = new LinkedHashSet<>();
+        ResultSet pkRs = metaData.getPrimaryKeys(tableRef.catalog, tableRef.schema, tableRef.table);
+        try {
+            while (pkRs.next()) {
+                primaryKeys.add(pkRs.getString("COLUMN_NAME"));
+            }
+        } finally {
+            pkRs.close();
+        }
+
+        ResultSet columnRs = metaData.getColumns(tableRef.catalog, tableRef.schema, tableRef.table, null);
+        try {
+            while (columnRs.next()) {
+                String columnName = columnRs.getString("COLUMN_NAME");
+                int sqlType = columnRs.getInt("DATA_TYPE");
+                String type = GeneratorUtils.getType(sqlType);
+                if (Cools.isEmpty(type)) {
+                    type = "String";
+                }
+                String remarks = columnRs.getString("REMARKS");
+                boolean primaryKey = primaryKeys.contains(columnName);
+                boolean mainKey = primaryKey && isAutoIncrement(columnRs);
+                boolean notNull = columnRs.getInt("NULLABLE") == DatabaseMetaData.columnNoNulls;
+                Integer length = GeneratorUtils.getColumnLength(columnRs.getString("TYPE_NAME"));
+                columns.add(new Column(connection, columnName, type, remarks, primaryKey, mainKey, notNull, length,
+                        withForeignKey, sqlOsType));
+            }
+        } finally {
+            columnRs.close();
+        }
+        for (Column column : columns) {
+            System.out.println(column.toString());
+        }
+        return columns;
+    }
+
+    private static boolean isAutoIncrement(ResultSet columnRs) {
+        try {
+            return "YES".equalsIgnoreCase(columnRs.getString("IS_AUTOINCREMENT"));
+        } catch (SQLException e) {
+            return false;
+        }
+    }
+
+    private static TableRef parseTableRef(String table) {
+        if (table != null && table.contains(".")) {
+            String[] arr = table.split("\\.");
+            return new TableRef(null, arr[0], arr[arr.length - 1]);
+        }
+        return new TableRef(null, null, table);
+    }
+
+    private String resolvePrimaryKeyColumn() {
+        for (Column column : columns) {
+            if (column.isPrimaryKey()) {
+                return column.getHumpName();
+            }
+        }
+        return columns.get(0).getHumpName();
+    }
+
+    private String resolvePrimaryKeyType() {
+        for (Column column : columns) {
+            if (column.isPrimaryKey()) {
+                return column.getType();
+            }
+        }
+        return columns.get(0).getType();
+    }
+
+    private String resolveMajorColumn() {
+        for (Column column : columns) {
+            if (column.isMajor()) {
+                return column.getHumpName();
+            }
+        }
+        for (Column column : columns) {
+            if (!column.isPrimaryKey()) {
+                return column.getHumpName();
+            }
+        }
+        return primaryKeyColumn;
+    }
+
+    private String buildEntityImports() {
+        Set<String> imports = new LinkedHashSet<>();
+        boolean hasTableId = false;
+        boolean hasTableField = false;
+        boolean hasDate = false;
+        boolean needCools = false;
+        boolean hasSpringUtils = false;
+        boolean hasTableLogic = false;
+        for (Column column : columns) {
+            if (column.isPrimaryKey()) {
+                hasTableId = true;
+            } else if (!column.getName().equals(column.getHumpName())) {
+                hasTableField = true;
+            }
+            if ("deleted".equals(column.getName())) {
+                hasTableLogic = true;
+            }
+            if ("Date".equals(column.getType())) {
+                hasDate = true;
+                needCools = true;
+            }
+            if (!Cools.isEmpty(column.getEnums()) || !Cools.isEmpty(column.getForeignKey())) {
+                needCools = true;
+            }
+            if (!Cools.isEmpty(column.getForeignKey())) {
+                hasSpringUtils = true;
+                imports.add("import " + getForeignBasePackage(column.getForeignKey()) + ".service." + column.getForeignKey() + "Service;");
+                imports.add("import " + getForeignBasePackage(column.getForeignKey()) + ".entity." + column.getForeignKey() + ";");
+            }
+        }
+        if (needCools) {
+            imports.add("import com.core.common.Cools;");
+        }
+        if (hasSpringUtils) {
+            imports.add("import com.core.common.SpringUtils;");
+        }
+        if (hasTableId) {
+            imports.add("import com.baomidou.mybatisplus.annotations.TableId;");
+            imports.add("import com.baomidou.mybatisplus.enums.IdType;");
+        }
+        if (hasTableLogic) {
+            imports.add("import com.baomidou.mybatisplus.annotations.TableLogic;");
+        }
+        if (hasTableField) {
+            imports.add("import com.baomidou.mybatisplus.annotations.TableField;");
+        }
+        if (hasDate) {
+            imports.add("import java.text.SimpleDateFormat;");
+            imports.add("import java.util.Date;");
+            imports.add("import org.springframework.format.annotation.DateTimeFormat;");
+        }
+        if (imports.isEmpty()) {
+            return "";
+        }
+        StringBuilder builder = new StringBuilder();
+        for (String item : imports) {
+            builder.append(item).append("\n");
+        }
+        return builder.toString();
+    }
+
+    private String buildEntityContent() {
+        StringBuilder builder = new StringBuilder();
+        for (Column column : columns) {
+            builder.append("    /**\n");
+            builder.append("     * ").append(column.getWholeComment()).append("\n");
+            builder.append("     */\n");
+            builder.append("    @ApiModelProperty(value= \"").append(escapeJava(column.getWholeComment())).append("\")\n");
+            if (column.isPrimaryKey()) {
+                builder.append("    @TableId(value = \"").append(column.getName()).append("\", type = IdType.")
+                        .append(column.isMainKey() ? "AUTO" : "INPUT").append(")\n");
+            } else if (!column.getName().equals(column.getHumpName())) {
+                builder.append("    @TableField(\"").append(column.getName()).append("\")\n");
+            }
+            if ("deleted".equals(column.getName())) {
+                builder.append("    @TableLogic\n");
+            }
+            if ("Date".equals(column.getType())) {
+                builder.append("    @DateTimeFormat(pattern=\"yyyy-MM-dd HH:mm:ss\")\n");
+            }
+            builder.append("    private ").append(column.getType()).append(" ").append(column.getHumpName()).append(";\n\n");
+        }
+        List<Column> constructorColumns = getNonPrimaryColumns();
+        builder.append("    public ").append(fullEntityName).append("() {}\n\n");
+        if (!constructorColumns.isEmpty()) {
+            builder.append("    public ").append(fullEntityName).append("(");
+            for (Column column : constructorColumns) {
+                builder.append(column.getType()).append(" ").append(column.getHumpName()).append(",");
+            }
+            builder.deleteCharAt(builder.length() - 1);
+            builder.append(") {\n");
+            for (Column column : constructorColumns) {
+                builder.append("        this.").append(column.getHumpName()).append(" = ").append(column.getHumpName()).append(";\n");
+            }
+            builder.append("    }\n\n");
+
+            builder.append("//    ").append(fullEntityName).append(" ").append(simpleEntityName)
+                    .append(" = new ").append(fullEntityName).append("(\n");
+            for (int i = 0; i < constructorColumns.size(); i++) {
+                Column column = constructorColumns.get(i);
+                builder.append("//            null");
+                if (i < constructorColumns.size() - 1) {
+                    builder.append(",");
+                }
+                builder.append("    // ").append(column.getComment());
+                if (column.isNotNull()) {
+                    builder.append("[闈炵┖]");
+                }
+                if (i < constructorColumns.size() - 1) {
+                    builder.append("\n");
+                }
+            }
+            builder.append("\n//    );\n\n");
+        }
+        List<String> displayGetters = buildDisplayGetters();
+        for (String getter : displayGetters) {
+            builder.append(getter).append("\n\n");
+        }
+        return trimTrailingBlankLines(builder.toString());
+    }
+
+    private List<String> buildDisplayGetters() {
+        List<String> getters = new ArrayList<>();
+        for (Column column : columns) {
+            String field = column.getHumpName();
+            String methodName = GeneratorUtils.firstCharConvert(field, false);
+            if ("Date".equals(column.getType())) {
+                StringBuilder builder = new StringBuilder();
+                builder.append("    public String get").append(methodName).append("$(){\n");
+                builder.append("        if (Cools.isEmpty(this.").append(field).append(")){\n");
+                builder.append("            return \"\";\n");
+                builder.append("        }\n");
+                builder.append("        return new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\").format(this.").append(field).append(");\n");
+                builder.append("    }");
+                getters.add(builder.toString());
+                continue;
+            }
+            if (!Cools.isEmpty(column.getEnums())) {
+                StringBuilder builder = new StringBuilder();
+                builder.append("    public String get").append(methodName).append("$(){\n");
+                builder.append("        if (null == this.").append(field).append("){ return null; }\n");
+                builder.append("        switch (String.valueOf(this.").append(field).append(")){\n");
+                for (Map<String, Object> map : column.getEnums()) {
+                    for (Map.Entry<String, Object> entry : map.entrySet()) {
+                        builder.append("            case \"").append(escapeJava(entry.getKey())).append("\":\n");
+                        builder.append("                return \"").append(escapeJava(String.valueOf(entry.getValue()))).append("\";\n");
+                    }
+                }
+                builder.append("            default:\n");
+                builder.append("                return String.valueOf(this.").append(field).append(");\n");
+                builder.append("        }\n");
+                builder.append("    }");
+                getters.add(builder.toString());
+                continue;
+            }
+            if (!Cools.isEmpty(column.getForeignKeyMajor())) {
+                StringBuilder builder = new StringBuilder();
+                builder.append("    public String get").append(methodName).append("$(){\n");
+                builder.append("        ").append(column.getForeignKey()).append("Service service = SpringUtils.getBean(")
+                        .append(column.getForeignKey()).append("Service.class);\n");
+                builder.append("        ").append(column.getForeignKey()).append(" ")
+                        .append(GeneratorUtils.firstCharConvert(column.getForeignKey())).append(" = service.selectById(this.")
+                        .append(field).append(");\n");
+                builder.append("        if (!Cools.isEmpty(").append(GeneratorUtils.firstCharConvert(column.getForeignKey()))
+                        .append(")){\n");
+                builder.append("            return String.valueOf(").append(GeneratorUtils.firstCharConvert(column.getForeignKey()))
+                        .append(".get").append(column.getForeignKeyMajor()).append("());\n");
+                builder.append("        }\n");
+                builder.append("        return null;\n");
+                builder.append("    }");
+                getters.add(builder.toString());
+            }
+        }
+        return getters;
+    }
+
+    private String buildXmlContent() {
+        StringBuilder builder = new StringBuilder();
+        for (Column column : columns) {
+            if (column.isPrimaryKey()) {
+                builder.append("        <id column=\"").append(column.getName()).append("\" property=\"")
+                        .append(column.getHumpName()).append("\" />\n");
+            } else {
+                builder.append("        <result column=\"").append(column.getName()).append("\" property=\"")
+                        .append(column.getHumpName()).append("\" />\n");
+            }
+        }
+        return trimTrailingBlankLines(builder.toString());
+    }
+
+    private String buildHtmlSearchContent() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("                    <div class=\"layui-inline\">\n");
+        builder.append("                        <div class=\"layui-input-inline\">\n");
+        builder.append("                            <input class=\"layui-input\" type=\"text\" name=\"condition\" placeholder=\"璇疯緭鍏" autocomplete=\"off\">\n");
+        builder.append("                        </div>\n");
+        builder.append("                    </div>\n");
+        Column rangeColumn = resolveRangeSearchColumn();
+        if (rangeColumn != null) {
+            builder.append("                    <div class=\"layui-inline\" style=\"width: 300px\">\n");
+            builder.append("                        <div class=\"layui-input-inline\">\n");
+            builder.append("                            <input class=\"layui-input layui-laydate-range\" name=\"")
+                    .append(rangeColumn.getName()).append("\" type=\"text\" placeholder=\"")
+                    .append(GeneratorUtils.supportHtmlName(rangeColumn.getComment()))
+                    .append("鑼冨洿\" autocomplete=\"off\" style=\"width: 300px\">\n");
+            builder.append("                        </div>\n");
+            builder.append("                    </div>\n");
+        }
+        return trimTrailingBlankLines(builder.toString());
+    }
+
+    private String buildHtmlDialogContent() {
+        StringBuilder builder = new StringBuilder();
+        for (Column column : columns) {
+            String field = column.getHumpName();
+            if (column.isPrimaryKey()) {
+                builder.append("                <input name=\"").append(field).append("\" type=\"hidden\">\n");
+                continue;
+            }
+            builder.append("                <div class=\"layui-form-item\">\n");
+            builder.append("                    <label class=\"layui-form-label");
+            if (column.isNotNull()) {
+                builder.append(" layui-form-required");
+            }
+            builder.append("\">").append(column.getComment()).append(": </label>\n");
+            builder.append("                    <div class=\"layui-input-block");
+            if (!Cools.isEmpty(column.getForeignKeyMajor())) {
+                builder.append(" cool-auto-complete");
+            }
+            builder.append("\">\n");
+            appendFormField(builder, column, "                        ");
+            builder.append("                    </div>\n");
+            builder.append("                </div>\n");
+        }
+        return trimTrailingBlankLines(builder.toString());
+    }
+
+    private String buildHtmlDetailContent() {
+        StringBuilder builder = new StringBuilder();
+        for (Column column : columns) {
+            String field = column.getHumpName();
+            String label = GeneratorUtils.supportHtmlName(column.getComment());
+            if (column.isPrimaryKey()) {
+                builder.append("        <div class=\"layui-inline\" style=\"display: none\">\n");
+                builder.append("            <label class=\"layui-form-label\">").append(label).append("锛�</label>\n");
+                builder.append("            <div class=\"layui-input-inline\">\n");
+                builder.append("                <input id=\"").append(field).append("\" class=\"layui-input\" type=\"text\" placeholder=\"")
+                        .append(column.getComment()).append("\">\n");
+                builder.append("            </div>\n");
+                builder.append("        </div>\n");
+                continue;
+            }
+            builder.append("        <div class=\"layui-inline\">\n");
+            builder.append("            <label class=\"layui-form-label\">");
+            if (column.isNotNull()) {
+                builder.append("<span class=\"not-null\">*</span>");
+            }
+            builder.append(label).append("锛�</label>\n");
+            builder.append("            <div class=\"layui-input-inline");
+            if (!Cools.isEmpty(column.getForeignKeyMajor())) {
+                builder.append(" cool-auto-complete");
+            }
+            builder.append("\">\n");
+            appendDetailFormField(builder, column, "                ");
+            builder.append("            </div>\n");
+            builder.append("        </div>\n");
+        }
+        return trimTrailingBlankLines(builder.toString());
+    }
+
+    private String buildJsTableContent() {
+        StringBuilder builder = new StringBuilder();
+        for (Column column : columns) {
+            String field = resolveDisplayField(column);
+            builder.append("            ,{field: '").append(field).append("', align: 'center',title: '")
+                    .append(escapeJs(column.getComment())).append("'");
+            if (column.isCheckBox()) {
+                builder.append(", templet:function(row){\n")
+                        .append("                    var html = \"<input value='").append(column.getHumpName())
+                        .append("' type='checkbox' lay-skin='primary' lay-filter='tableCheckbox' table-index='\"+row.LAY_TABLE_INDEX+\"'\";\n")
+                        .append("                    if(row.").append(column.getHumpName()).append(" === 'Y'){html += \" checked \";}\n")
+                        .append("                    html += \">\";\n")
+                        .append("                    return html;\n")
+                        .append("                }");
+            }
+            if (column.isPrimaryKey()) {
+                builder.append(", sort: true");
+            }
+            builder.append("}\n");
+        }
+        return trimTrailingBlankLines(builder.toString());
+    }
+
+    private String buildJsDateContent() {
+        StringBuilder builder = new StringBuilder();
+        for (Column column : columns) {
+            if (column.isPrimaryKey()) {
+                continue;
+            }
+            if (!"Date".equals(column.getType())) {
+                continue;
+            }
+            builder.append("            layDate.render({\n");
+            builder.append("                elem: '#").append(column.getHumpName()).append("$',\n");
+            builder.append("                type: 'datetime',\n");
+            builder.append("                value: data!==undefined?data['").append(column.getHumpName()).append("$']:null\n");
+            builder.append("            });\n");
+        }
+        return trimTrailingBlankLines(builder.toString());
+    }
+
+    private String resolveDisplayField(Column column) {
+        if ("Date".equals(column.getType()) || !Cools.isEmpty(column.getEnums()) || !Cools.isEmpty(column.getForeignKeyMajor())) {
+            return column.getHumpName() + "$";
+        }
+        return column.getHumpName();
+    }
+
+    private List<Column> getNonPrimaryColumns() {
+        List<Column> result = new ArrayList<>();
+        for (Column column : columns) {
+            if (!column.isPrimaryKey()) {
+                result.add(column);
+            }
+        }
+        return result;
+    }
+
+    private Column resolveRangeSearchColumn() {
+        for (Column column : columns) {
+            if ("Date".equals(column.getType()) && ("create_time".equals(column.getName()) || "createTime".equals(column.getHumpName()))) {
+                return column;
+            }
+        }
+        for (Column column : columns) {
+            if ("Date".equals(column.getType())) {
+                return column;
+            }
+        }
+        return null;
+    }
+
+    private String getForeignBasePackage(String foreignKey) {
+        if (SYSTEM_MODEL.contains(foreignKey)) {
+            return systemPackage + ".system";
+        }
+        return packagePath;
+    }
+
+    private void appendFormField(StringBuilder builder, Column column, String inputIndent) {
+        String field = column.getHumpName();
+        if (Cools.isEmpty(column.getEnums())) {
+            builder.append(inputIndent).append("<input class=\"layui-input\" name=\"").append(field);
+            if ("Date".equals(column.getType())) {
+                builder.append("\" id=\"").append(field).append("$");
+            }
+            builder.append("\" placeholder=\"璇疯緭鍏�").append(column.getComment()).append("\"");
+            if (column.isNotNull()) {
+                builder.append(" lay-vertype=\"tips\" lay-verify=\"required\"");
+            }
+            if (!Cools.isEmpty(column.getForeignKeyMajor())) {
+                builder.append(" style=\"display: none\"");
+            }
+            builder.append(" autocomplete=\"off\">\n");
+            if (!Cools.isEmpty(column.getForeignKeyMajor())) {
+                String queryKey = GeneratorUtils.firstCharConvert(column.getForeignKey()) + "QueryBy" + field;
+                builder.append(inputIndent).append("<input id=\"").append(field).append("$\" name=\"").append(field)
+                        .append("$\" class=\"layui-input cool-auto-complete-div\" onclick=\"autoShow(this.id)\" type=\"text\" placeholder=\"璇疯緭鍏�")
+                        .append(column.getComment()).append("\" onfocus=this.blur() autocomplete=\"off\">\n");
+                builder.append(inputIndent).append("<div class=\"cool-auto-complete-window\">\n");
+                builder.append(inputIndent).append("    <input class=\"cool-auto-complete-window-input\" data-key=\"")
+                        .append(queryKey).append("\" onkeyup=\"autoLoad(this.getAttribute('data-key'))\">\n");
+                builder.append(inputIndent).append("    <select class=\"cool-auto-complete-window-select\" data-key=\"")
+                        .append(queryKey).append("Select\" onchange=\"confirmed(this.getAttribute('data-key'))\" multiple=\"multiple\">\n");
+                builder.append(inputIndent).append("    </select>\n");
+                builder.append(inputIndent).append("</div>\n");
+            }
+            return;
+        }
+        builder.append(inputIndent).append("<select name=\"").append(field).append("\"");
+        if (column.isNotNull()) {
+            builder.append(" lay-vertype=\"tips\" lay-verify=\"required\"");
+        }
+        builder.append(">\n");
+        builder.append(inputIndent).append("    <option value=\"\">璇烽�夋嫨").append(column.getComment()).append("</option>\n");
+        for (Map<String, Object> map : column.getEnums()) {
+            for (Map.Entry<String, Object> entry : map.entrySet()) {
+                builder.append(inputIndent).append("    <option value=\"").append(entry.getKey()).append("\">")
+                        .append(entry.getValue()).append("</option>\n");
+            }
+        }
+        builder.append(inputIndent).append("</select>\n");
+    }
+
+    private void appendDetailFormField(StringBuilder builder, Column column, String inputIndent) {
+        String field = column.getHumpName();
+        if (Cools.isEmpty(column.getEnums())) {
+            if (!Cools.isEmpty(column.getForeignKeyMajor())) {
+                String queryKey = GeneratorUtils.firstCharConvert(column.getForeignKey()) + "QueryBy" + field;
+                builder.append(inputIndent).append("<input id=\"").append(field)
+                        .append("\" class=\"layui-input\" type=\"text\" style=\"display: none\">\n");
+                builder.append(inputIndent).append("<input id=\"").append(field).append("$\" class=\"layui-input cool-auto-complete-div\" onclick=\"autoShow(this.id)\" type=\"text\" placeholder=\"璇疯緭鍏�")
+                        .append(column.getComment()).append("\" onfocus=this.blur() autocomplete=\"off\">\n");
+                builder.append(inputIndent).append("<div class=\"cool-auto-complete-window\">\n");
+                builder.append(inputIndent).append("    <input class=\"cool-auto-complete-window-input\" data-key=\"")
+                        .append(queryKey).append("\" onkeyup=\"autoLoad(this.getAttribute('data-key'))\">\n");
+                builder.append(inputIndent).append("    <select class=\"cool-auto-complete-window-select\" data-key=\"")
+                        .append(queryKey).append("Select\" onchange=\"confirmed(this.getAttribute('data-key'))\" multiple=\"multiple\">\n");
+                builder.append(inputIndent).append("    </select>\n");
+                builder.append(inputIndent).append("</div>\n");
+                return;
+            }
+            builder.append(inputIndent).append("<input id=\"").append(field);
+            if ("Date".equals(column.getType())) {
+                builder.append("$");
+            }
+            builder.append("\" class=\"layui-input\" type=\"text\" placeholder=\"").append(column.getComment())
+                    .append("\" autocomplete=\"off\"");
+            if (column.isNotNull()) {
+                builder.append(" lay-verify=\"required\"");
+            }
+            builder.append(">\n");
+            return;
+        }
+        builder.append(inputIndent).append("<select id=\"").append(field).append("\"");
+        if (column.isNotNull()) {
+            builder.append(" lay-verify=\"required\"");
+        }
+        builder.append(">\n");
+        builder.append(inputIndent).append("    <option value=\"\">璇烽�夋嫨").append(column.getComment()).append("</option>\n");
+        for (Map<String, Object> map : column.getEnums()) {
+            for (Map.Entry<String, Object> entry : map.entrySet()) {
+                builder.append(inputIndent).append("    <option value=\"").append(entry.getKey()).append("\">")
+                        .append(entry.getValue()).append("</option>\n");
+            }
+        }
+        builder.append(inputIndent).append("</select>\n");
+    }
+
+    private String renderTemplate(String template) {
+        Map<String, String> values = new LinkedHashMap<>();
+        values.put("COMPANYNAME", packagePath);
+        values.put("SYSTEMPACKAGE", systemPackage);
+        values.put("ENTITYNAME", fullEntityName);
+        values.put("SIMPLEENTITYNAME", simpleEntityName);
+        values.put("TABLENAME", table);
+        values.put("ENTITYIMPORT", entityImport);
+        values.put("ENTITYCONTENT", entityContent);
+        values.put("XMLCONTENT", xmlContent);
+        values.put("HTMLSEARCHCONTENT", htmlSearchContent);
+        values.put("HTMLDIALOGCONTENT", htmlDialogContent);
+        values.put("HTMLDETAILCONTENT", htmlDetailContent);
+        values.put("JSTABLECONTENT", jsTableContent);
+        values.put("JSDATECONTENT", jsDateContent);
+        values.put("PRIMARYKEYCOLUMN", GeneratorUtils.firstCharConvert(primaryKeyColumn, false));
+        values.put("PRIMARYKEYCOLUMN0", primaryKeyColumn);
+        values.put("PRIMARYKEYTYPE", primaryKeyType);
+        values.put("MAJORCOLUMN", GeneratorUtils.humpToLine(majorColumn));
+        values.put("UPCASEMARJORCOLUMN", GeneratorUtils.firstCharConvert(majorColumn, false));
+        String content = template;
+        for (Map.Entry<String, String> entry : values.entrySet()) {
+            content = content.replace("@{" + entry.getKey() + "}", entry.getValue() == null ? "" : entry.getValue());
+        }
+        return content;
+    }
+
+    private void writeFile(String dir, String fileName, String content, String templateName) throws IOException {
+        Path directory = Paths.get(dir);
+        Files.createDirectories(directory);
+        Path file = directory.resolve(fileName);
+        if (Files.exists(file)) {
+            System.out.println(fullEntityName + templateName + " 婧愭枃浠跺凡缁忓瓨鍦ㄥ垱寤哄け璐ワ紒");
+            return;
+        }
+        try {
+            Files.write(file, content.getBytes(StandardCharsets.UTF_8),
+                    StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
+            System.out.println(fullEntityName + templateName + " 婧愭枃浠跺垱寤烘垚鍔燂紒");
+        } catch (FileAlreadyExistsException e) {
+            System.out.println(fullEntityName + templateName + " 婧愭枃浠跺凡缁忓瓨鍦ㄥ垱寤哄け璐ワ紒");
+        }
+    }
+
+    private String loadTemplate(String name) throws IOException {
+        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("templates/" + name);
+        if (inputStream == null) {
+            throw new IOException("template not found: " + name);
+        }
+        try {
+            ByteArrayOutputStream output = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int len;
+            while ((len = inputStream.read(buffer)) != -1) {
+                output.write(buffer, 0, len);
+            }
+            return new String(output.toByteArray(), StandardCharsets.UTF_8);
+        } finally {
+            inputStream.close();
+        }
+    }
+
+    private String trimTrailingBlankLines(String text) {
+        String trimmed = text;
+        while (trimmed.endsWith("\n\n")) {
+            trimmed = trimmed.substring(0, trimmed.length() - 1);
+        }
+        return trimmed;
+    }
+
+    private String escapeJava(String text) {
+        return text == null ? "" : text.replace("\\", "\\\\").replace("\"", "\\\"");
+    }
+
+    private String escapeJs(String text) {
+        return escapeJava(text).replace("'", "\\'");
+    }
+
+    private static class TableRef {
+        private final String catalog;
+        private final String schema;
+        private final String table;
+
+        private TableRef(String catalog, String schema, String table) {
+            this.catalog = catalog;
+            this.schema = schema;
+            this.table = table;
+        }
+    }
+}
diff --git a/src/main/java/com/core/generators/constant/SqlOsType.java b/src/main/java/com/core/generators/constant/SqlOsType.java
new file mode 100644
index 0000000..5bdb4fe
--- /dev/null
+++ b/src/main/java/com/core/generators/constant/SqlOsType.java
@@ -0,0 +1,6 @@
+package com.core.generators.constant;
+
+public enum SqlOsType {
+    MYSQL,
+    SQL_SERVER
+}
diff --git a/src/main/java/com/core/generators/domain/Column.java b/src/main/java/com/core/generators/domain/Column.java
new file mode 100644
index 0000000..cd4314e
--- /dev/null
+++ b/src/main/java/com/core/generators/domain/Column.java
@@ -0,0 +1,265 @@
+package com.core.generators.domain;
+
+import com.core.common.Cools;
+import com.core.generators.CoolGenerator;
+import com.core.generators.constant.SqlOsType;
+import com.core.generators.utils.GeneratorUtils;
+
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Column {
+
+    private String name;
+    private String type;
+    private String comment;
+    private String humpName;
+    private boolean primaryKey;
+    private boolean mainKey;
+    private boolean notNull;
+    private boolean major;
+    private boolean image;
+    private boolean checkBox;
+    private String foreignKey;
+    private String foreignKeyMajor;
+    private List<Map<String, Object>> enums;
+    private Integer length;
+
+    public Column(Connection connection, String name, String type, String comment, boolean primaryKey,
+                  boolean mainKey, boolean notNull, Integer length, boolean withForeignKey, SqlOsType sqlOsType) {
+        this.name = name;
+        this.type = type;
+        this.comment = "";
+        if (!Cools.isEmpty(comment)) {
+            Pattern enumTitlePattern = Pattern.compile("(.+?)(?=\\{)");
+            Matcher enumTitleMatcher = enumTitlePattern.matcher(comment);
+            Pattern foreignTitlePattern = Pattern.compile("(.+?)(?=\\[)");
+            Matcher foreignTitleMatcher = foreignTitlePattern.matcher(comment);
+            if (enumTitleMatcher.find()) {
+                this.comment = enumTitleMatcher.group();
+                Pattern enumPattern = Pattern.compile("(?<=\\{)(.+?)(?=})");
+                Matcher enumMatcher = enumPattern.matcher(comment);
+                if (enumMatcher.find()) {
+                    String enumText = enumMatcher.group();
+                    if (!Cools.isEmpty(enumText)) {
+                        String[] enumArr = enumText.split(",");
+                        this.enums = new ArrayList<>();
+                        for (String item : enumArr) {
+                            Map<String, Object> map = new HashMap<>();
+                            String[] pair = item.split(":");
+                            if (pair.length >= 2) {
+                                map.put(pair[0], pair[1]);
+                                this.enums.add(map);
+                            }
+                        }
+                    }
+                }
+            } else if (foreignTitleMatcher.find()) {
+                this.comment = foreignTitleMatcher.group();
+                Pattern foreignPattern = Pattern.compile("(?<=\\[)(.+?)(?=])");
+                Matcher foreignMatcher = foreignPattern.matcher(comment);
+                if (foreignMatcher.find()) {
+                    String foreignTable = foreignMatcher.group();
+                    if (!Cools.isEmpty(foreignTable)) {
+                        this.foreignKey = GeneratorUtils.getNameSpace(foreignTable);
+                        List<Column> foreignColumns = new ArrayList<>();
+                        if (withForeignKey) {
+                            try {
+                                switch (sqlOsType) {
+                                    case MYSQL:
+                                        foreignColumns = CoolGenerator.getMysqlColumns(connection, foreignTable, false, sqlOsType);
+                                        break;
+                                    case SQL_SERVER:
+                                        foreignColumns = CoolGenerator.getSqlServerColumns(connection, foreignTable, false, sqlOsType);
+                                        break;
+                                    default:
+                                        break;
+                                }
+                            } catch (Exception ex) {
+                                ex.printStackTrace();
+                            }
+                        }
+                        if (!Cools.isEmpty(foreignColumns)) {
+                            for (Column column : foreignColumns) {
+                                if (column.isMajor()) {
+                                    this.foreignKeyMajor = GeneratorUtils.firstCharConvert(column.getHumpName(), false);
+                                }
+                            }
+                            if (Cools.isEmpty(this.foreignKeyMajor)) {
+                                this.foreignKeyMajor = "Id";
+                            }
+                        }
+                    }
+                }
+            } else {
+                this.comment = comment;
+            }
+            if (comment.endsWith("(*)")) {
+                this.comment = comment.substring(0, comment.length() - 3);
+                this.major = true;
+            }
+            if (comment.endsWith("(img)")) {
+                this.comment = comment.substring(0, comment.length() - 5);
+                this.image = true;
+            }
+            if (comment.endsWith("(checkbox)")) {
+                this.comment = comment.substring(0, comment.length() - 10);
+                this.checkBox = true;
+            }
+        }
+        this.primaryKey = primaryKey;
+        this.mainKey = mainKey;
+        this.notNull = notNull;
+        this.length = length;
+        this.humpName = GeneratorUtils._convert(name);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public String getWholeComment() {
+        if (!Cools.isEmpty(this.enums)) {
+            StringBuilder builder = new StringBuilder("");
+            for (Map<String, Object> map : this.enums) {
+                for (Map.Entry<String, Object> entry : map.entrySet()) {
+                    builder.append(entry.getKey()).append(":").append(entry.getValue()).append("  ");
+                }
+            }
+            return new StringBuilder().append(this.comment).append(builder.toString()).toString();
+        }
+        return this.comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    public String getHumpName() {
+        return humpName;
+    }
+
+    public boolean isPrimaryKey() {
+        return primaryKey;
+    }
+
+    public boolean isOnly() {
+        return primaryKey;
+    }
+
+    public void setPrimaryKey(boolean primaryKey) {
+        this.primaryKey = primaryKey;
+    }
+
+    public boolean isNotNull() {
+        return notNull;
+    }
+
+    public void setNotNull(boolean notNull) {
+        this.notNull = notNull;
+    }
+
+    public String getForeignKey() {
+        return foreignKey;
+    }
+
+    public void setForeignKey(String foreignKey) {
+        this.foreignKey = foreignKey;
+    }
+
+    public String getForeignKeyMajor() {
+        return foreignKeyMajor;
+    }
+
+    public void setForeignKeyMajor(String foreignKeyMajor) {
+        this.foreignKeyMajor = foreignKeyMajor;
+    }
+
+    public List<Map<String, Object>> getEnums() {
+        return enums;
+    }
+
+    public void setEnums(List<Map<String, Object>> enums) {
+        this.enums = enums;
+    }
+
+    public Integer getLength() {
+        return length;
+    }
+
+    public void setLength(Integer length) {
+        this.length = length;
+    }
+
+    public boolean isMajor() {
+        return major;
+    }
+
+    public void setMajor(boolean major) {
+        this.major = major;
+    }
+
+    public boolean isImage() {
+        return image;
+    }
+
+    public void setImage(boolean image) {
+        this.image = image;
+    }
+
+    public boolean isCheckBox() {
+        return checkBox;
+    }
+
+    public void setCheckBox(boolean checkBox) {
+        this.checkBox = checkBox;
+    }
+
+    public boolean isMainKey() {
+        return mainKey;
+    }
+
+    public void setMainKey(boolean mainKey) {
+        this.mainKey = mainKey;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder()
+                .append("Column{name='").append(name).append('\'')
+                .append(", type='").append(type).append('\'')
+                .append(", comment='").append(comment).append('\'')
+                .append(", humpName='").append(humpName).append('\'')
+                .append(", primaryKey=").append(primaryKey)
+                .append(", notNull=").append(notNull)
+                .append(", major=").append(major)
+                .append(", image=").append(image)
+                .append(", foreignKey='").append(foreignKey).append('\'')
+                .append(", foreignKeyMajor='").append(foreignKeyMajor).append('\'')
+                .append(", enums=").append(enums)
+                .append(", length=").append(length)
+                .append('}')
+                .toString();
+    }
+}
diff --git a/src/main/java/com/core/generators/utils/GeneratorUtils.java b/src/main/java/com/core/generators/utils/GeneratorUtils.java
new file mode 100644
index 0000000..cb6767f
--- /dev/null
+++ b/src/main/java/com/core/generators/utils/GeneratorUtils.java
@@ -0,0 +1,134 @@
+package com.core.generators.utils;
+
+import com.core.common.Cools;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class GeneratorUtils {
+
+    public static String _convert(String text, boolean keepFirst) {
+        String[] arr = text.split("_");
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < arr.length; i++) {
+            if (i == 0 && keepFirst) {
+                builder.append(arr[i]);
+            } else {
+                builder.append(arr[i].substring(0, 1).toUpperCase()).append(arr[i].substring(1));
+            }
+        }
+        return builder.toString();
+    }
+
+    public static String _convert(String text) {
+        return _convert(text, true);
+    }
+
+    public static String getType(int sqlType) {
+        switch (sqlType) {
+            case -7:
+                return "Boolean";
+            case -6:
+            case 5:
+                return "Short";
+            case 4:
+                return "Integer";
+            case -5:
+                return "Long";
+            case 8:
+            case 3:
+                return "Double";
+            case -15:
+            case -9:
+            case 1:
+            case 12:
+            case 2004:
+            case -1:
+                return "String";
+            case 91:
+            case 93:
+                return "Date";
+            default:
+                return null;
+        }
+    }
+
+    public static String getNameSpace(String tableName) {
+        String[] arr = tableName.split("_");
+        StringBuilder builder = new StringBuilder();
+        for (int i = 1; i < arr.length; i++) {
+            if (i != 1) {
+                builder.append("_");
+            }
+            builder.append(arr[i]);
+        }
+        return _convert(builder.toString(), false);
+    }
+
+    public static String supportHtmlName(String name) {
+        if (Cools.isEmpty(name)) {
+            return "";
+        }
+        if (name.length() == 2) {
+            return new StringBuilder()
+                    .append(name.charAt(0))
+                    .append("銆�銆�")
+                    .append(name.charAt(1))
+                    .toString();
+        }
+        if (name.length() == 3) {
+            return new StringBuilder()
+                    .append(name.charAt(0))
+                    .append(" ")
+                    .append(name.charAt(1))
+                    .append(" ")
+                    .append(name.charAt(2))
+                    .toString();
+        }
+        return name;
+    }
+
+    public static Integer getColumnLength(String typeText) {
+        if (Cools.isEmpty(typeText)) {
+            return null;
+        }
+        Pattern pattern = Pattern.compile("(?<=\\()(.+?)(?=\\))");
+        Matcher matcher = pattern.matcher(typeText);
+        if (matcher.find()) {
+            String value = matcher.group();
+            if (value.contains(",")) {
+                value = value.split(",")[0];
+            }
+            return Integer.valueOf(Integer.parseInt(value));
+        }
+        return null;
+    }
+
+    public static String firstCharConvert(String text, boolean lower) {
+        if (Cools.isEmpty(text)) {
+            return "";
+        }
+        String first = text.substring(0, 1);
+        if (lower) {
+            first = first.toLowerCase();
+        } else {
+            first = first.toUpperCase();
+        }
+        return new StringBuilder().append(first).append(text.substring(1)).toString();
+    }
+
+    public static String firstCharConvert(String text) {
+        return firstCharConvert(text, true);
+    }
+
+    public static String humpToLine(String text) {
+        Pattern pattern = Pattern.compile("[A-Z]");
+        Matcher matcher = pattern.matcher(text);
+        StringBuffer buffer = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(buffer, "_" + matcher.group(0).toLowerCase());
+        }
+        matcher.appendTail(buffer);
+        return buffer.toString();
+    }
+}
diff --git a/src/main/java/com/core/utils/Algorithm.java b/src/main/java/com/core/utils/Algorithm.java
new file mode 100644
index 0000000..7e5c560
--- /dev/null
+++ b/src/main/java/com/core/utils/Algorithm.java
@@ -0,0 +1,10 @@
+package com.core.utils;
+
+/**
+ * 绠楁硶
+ */
+public class Algorithm {
+
+    private Algorithm() {
+    }
+}
diff --git a/src/main/java/com/core/utils/SignUtils.java b/src/main/java/com/core/utils/SignUtils.java
new file mode 100644
index 0000000..cbb46b6
--- /dev/null
+++ b/src/main/java/com/core/utils/SignUtils.java
@@ -0,0 +1,30 @@
+package com.core.utils;
+
+import com.core.common.Cools;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class SignUtils {
+
+    public static String sign(Map<String, Object> param, String key) {
+        List<String> list = new ArrayList<>();
+        for (String mapKey : param.keySet()) {
+            Object value = param.get(mapKey);
+            if ("sign".equals(mapKey) || value == null) {
+                continue;
+            }
+            list.add(mapKey + "=" + value + "&");
+        }
+        String[] arr = list.toArray(new String[0]);
+        Arrays.sort(arr, String.CASE_INSENSITIVE_ORDER);
+        StringBuilder builder = new StringBuilder();
+        for (String item : arr) {
+            builder.append(item);
+        }
+        String text = builder.toString() + "key=" + key;
+        return Cools.md5(text).toUpperCase();
+    }
+}
diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..da631fc
--- /dev/null
+++ b/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.core.config.CoolBaseConfig
diff --git a/src/main/resources/templates/Controller.txt b/src/main/resources/templates/Controller.txt
new file mode 100644
index 0000000..682fcbc
--- /dev/null
+++ b/src/main/resources/templates/Controller.txt
@@ -0,0 +1,139 @@
+package @{COMPANYNAME}.controller;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
+import com.baomidou.mybatisplus.plugins.Page;
+import com.core.common.DateUtils;
+import com.core.domain.KeyValueVo;
+import @{COMPANYNAME}.entity.@{ENTITYNAME};
+import @{COMPANYNAME}.service.@{ENTITYNAME}Service;
+import com.core.annotations.ManagerAuth;
+import com.core.common.BaseRes;
+import com.core.common.Cools;
+import com.core.common.R;
+import @{SYSTEMPACKAGE}.common.web.BaseController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+@RestController
+public class @{ENTITYNAME}Controller extends BaseController {
+
+    @Autowired
+    private @{ENTITYNAME}Service @{SIMPLEENTITYNAME}Service;
+
+    @RequestMapping(value = "/@{SIMPLEENTITYNAME}/{id}/auth")
+    @ManagerAuth
+    public R get(@PathVariable("id") String id) {
+        return R.ok(@{SIMPLEENTITYNAME}Service.selectById(String.valueOf(id)));
+    }
+
+    @RequestMapping(value = "/@{SIMPLEENTITYNAME}/list/auth")
+    @ManagerAuth
+    public R list(@RequestParam(defaultValue = "1")Integer curr,
+                  @RequestParam(defaultValue = "10")Integer limit,
+                  @RequestParam(required = false)String orderByField,
+                  @RequestParam(required = false)String orderByType,
+                  @RequestParam(required = false)String condition,
+                  @RequestParam Map<String, Object> param){
+        EntityWrapper<@{ENTITYNAME}> wrapper = new EntityWrapper<>();
+        excludeTrash(param);
+        convert(param, wrapper);
+        allLike(@{ENTITYNAME}.class, param.keySet(), wrapper, condition);
+        if (!Cools.isEmpty(orderByField)){wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));}
+        return R.ok(@{SIMPLEENTITYNAME}Service.selectPage(new Page<>(curr, limit), wrapper));
+    }
+
+    private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper){
+        for (Map.Entry<String, Object> entry : map.entrySet()){
+            String val = String.valueOf(entry.getValue());
+            if (val.contains(RANGE_TIME_LINK)){
+                String[] dates = val.split(RANGE_TIME_LINK);
+                wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
+                wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
+            } else {
+                wrapper.like(entry.getKey(), val);
+            }
+        }
+    }
+
+    @RequestMapping(value = "/@{SIMPLEENTITYNAME}/add/auth")
+    @ManagerAuth
+    public R add(@{ENTITYNAME} @{SIMPLEENTITYNAME}) {
+        @{SIMPLEENTITYNAME}Service.insert(@{SIMPLEENTITYNAME});
+        return R.ok();
+    }
+
+	@RequestMapping(value = "/@{SIMPLEENTITYNAME}/update/auth")
+	@ManagerAuth
+    public R update(@{ENTITYNAME} @{SIMPLEENTITYNAME}){
+        if (Cools.isEmpty(@{SIMPLEENTITYNAME}) || null==@{SIMPLEENTITYNAME}.get@{PRIMARYKEYCOLUMN}()){
+            return R.error();
+        }
+        @{SIMPLEENTITYNAME}Service.updateById(@{SIMPLEENTITYNAME});
+        return R.ok();
+    }
+
+    @RequestMapping(value = "/@{SIMPLEENTITYNAME}/delete/auth")
+    @ManagerAuth
+    public R delete(@RequestParam(value="ids[]") @{PRIMARYKEYTYPE}[] ids){
+         for (@{PRIMARYKEYTYPE} id : ids){
+            @{SIMPLEENTITYNAME}Service.deleteById(id);
+        }
+        return R.ok();
+    }
+
+    @RequestMapping(value = "/@{SIMPLEENTITYNAME}/export/auth")
+    @ManagerAuth
+    public R export(@RequestBody JSONObject param){
+        EntityWrapper<@{ENTITYNAME}> wrapper = new EntityWrapper<>();
+        List<String> fields = JSONObject.parseArray(param.getJSONArray("fields").toJSONString(), String.class);
+        Map<String, Object> map = excludeTrash(param.getJSONObject("@{SIMPLEENTITYNAME}"));
+        convert(map, wrapper);
+        List<@{ENTITYNAME}> list = @{SIMPLEENTITYNAME}Service.selectList(wrapper);
+        return R.ok(exportSupport(list, fields));
+    }
+
+    @RequestMapping(value = "/@{SIMPLEENTITYNAME}Query/auth")
+    @ManagerAuth
+    public R query(String condition) {
+        EntityWrapper<@{ENTITYNAME}> wrapper = new EntityWrapper<>();
+        wrapper.like("@{MAJORCOLUMN}", condition);
+        Page<@{ENTITYNAME}> page = @{SIMPLEENTITYNAME}Service.selectPage(new Page<>(0, 10), wrapper);
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (@{ENTITYNAME} @{SIMPLEENTITYNAME} : page.getRecords()){
+            Map<String, Object> map = new HashMap<>();
+            map.put("id", @{SIMPLEENTITYNAME}.get@{PRIMARYKEYCOLUMN}());
+            map.put("value", @{SIMPLEENTITYNAME}.get@{UPCASEMARJORCOLUMN}());
+            result.add(map);
+        }
+        return R.ok(result);
+    }
+
+    @RequestMapping("/@{SIMPLEENTITYNAME}/all/get/kv")
+    @ManagerAuth
+    public R getDataKV(@RequestParam(required = false) String condition) {
+        List<KeyValueVo> vos = new ArrayList<>();
+        EntityWrapper<@{ENTITYNAME}> wrapper = new EntityWrapper<>();
+        if (!Cools.isEmpty(condition)) {
+            wrapper.like("@{MAJORCOLUMN}", condition);
+        }
+        @{SIMPLEENTITYNAME}Service.selectPage(new Page<>(1, 30), wrapper).getRecords()
+                .forEach(item -> vos.add(new KeyValueVo(String.valueOf(item.get@{UPCASEMARJORCOLUMN}()), item.get@{PRIMARYKEYCOLUMN}())));
+        return R.ok().add(vos);
+    }
+
+    @RequestMapping(value = "/@{SIMPLEENTITYNAME}/check/column/auth")
+    @ManagerAuth
+    public R query(@RequestBody JSONObject param) {
+        Wrapper<@{ENTITYNAME}> wrapper = new EntityWrapper<@{ENTITYNAME}>().eq(humpToLine(String.valueOf(param.get("key"))), param.get("val"));
+        if (null != @{SIMPLEENTITYNAME}Service.selectOne(wrapper)){
+            return R.parse(BaseRes.REPEAT).add(getComment(@{ENTITYNAME}.class, String.valueOf(param.get("key"))));
+        }
+        return R.ok();
+    }
+
+}
diff --git a/src/main/resources/templates/Entity.txt b/src/main/resources/templates/Entity.txt
new file mode 100644
index 0000000..69d0b41
--- /dev/null
+++ b/src/main/resources/templates/Entity.txt
@@ -0,0 +1,16 @@
+package @{COMPANYNAME}.entity;
+
+@{ENTITYIMPORT}
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import com.baomidou.mybatisplus.annotations.TableName;
+import java.io.Serializable;
+
+@Data
+@TableName("@{TABLENAME}")
+public class @{ENTITYNAME} implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+@{ENTITYCONTENT}
+}
diff --git a/src/main/resources/templates/Html.txt b/src/main/resources/templates/Html.txt
new file mode 100644
index 0000000..e804af2
--- /dev/null
+++ b/src/main/resources/templates/Html.txt
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title></title>
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+    <link rel="stylesheet" href="../../static/layui/css/layui.css" media="all">
+    <link rel="stylesheet" href="../../static/css/admin.css?v=318" media="all">
+    <link rel="stylesheet" href="../../static/css/cool.css" media="all">
+</head>
+<body>
+
+<div class="layui-fluid">
+    <div class="layui-card">
+        <div class="layui-card-body">
+            <div class="layui-form toolbar" id="search-box">
+                <div class="layui-form-item">
+@{HTMLSEARCHCONTENT}
+                    <div class="layui-inline">&emsp;
+                        <button class="layui-btn icon-btn" lay-filter="search" lay-submit>
+                            <i class="layui-icon">&#xe615;</i>鎼滅储
+                        </button>
+                        <button class="layui-btn icon-btn" lay-filter="reset" lay-submit>
+                            <i class="layui-icon">&#xe666;</i>閲嶇疆
+                        </button>
+                    </div>
+                </div>
+            </div>
+            <table class="layui-hide" id="@{SIMPLEENTITYNAME}" lay-filter="@{SIMPLEENTITYNAME}"></table>
+        </div>
+    </div>
+</div>
+
+<script type="text/html" id="toolbar">
+    <div class="layui-btn-container">
+        <button class="layui-btn layui-btn-sm" id="btn-add" lay-event="addData">鏂板</button>
+        <button class="layui-btn layui-btn-sm layui-btn-danger" id="btn-delete" lay-event="deleteData">鍒犻櫎</button>
+        <button class="layui-btn layui-btn-primary layui-btn-sm" id="btn-export" lay-event="exportData" style="float: right">瀵煎嚭</button>
+    </div>
+</script>
+
+<script type="text/html" id="operate">
+    <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="edit">淇敼</a>
+    <a class="layui-btn layui-btn-danger layui-btn-xs btn-edit" lay-event="del">鍒犻櫎</a>
+</script>
+
+<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
+<script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
+<script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
+<script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script>
+<script type="text/javascript" src="../../static/js/@{SIMPLEENTITYNAME}/@{SIMPLEENTITYNAME}.js" charset="utf-8"></script>
+</body>
+<!-- 琛ㄥ崟寮圭獥 -->
+<script type="text/html" id="editDialog">
+    <form id="detail" lay-filter="detail" class="layui-form admin-form model-form">
+        <div class="layui-row">
+            <div class="layui-col-md12">
+@{HTMLDIALOGCONTENT}
+             </div>
+        </div>
+        <hr class="layui-bg-gray">
+        <div class="layui-form-item text-right">
+            <button class="layui-btn" lay-filter="editSubmit" lay-submit="">淇濆瓨</button>
+            <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">鍙栨秷</button>
+        </div>
+    </form>
+</script>
+</html>
diff --git a/src/main/resources/templates/HtmlDetail.txt b/src/main/resources/templates/HtmlDetail.txt
new file mode 100644
index 0000000..8df1c33
--- /dev/null
+++ b/src/main/resources/templates/HtmlDetail.txt
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title></title>
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+    <link rel="stylesheet" href="../../static/layui/css/layui.css" media="all">
+    <link rel="stylesheet" href="../../static/css/cool.css" media="all">
+    <link rel="stylesheet" href="../../static/css/common.css" media="all">
+</head>
+<body>
+
+<!-- 璇︽儏 -->
+<div id="data-detail" class="layer_self_wrap">
+    <form id="detail" class="layui-form">
+    <!--
+        <div class="layui-inline"  style="display: none">
+            <label class="layui-form-label"><span class="not-null">*</span>缂栥��銆�鍙凤細</label>
+            <div class="layui-input-inline">
+                <input id="id" class="layui-input" type="text" placeholder="缂栧彿">
+            </div>
+        </div>
+    -->
+@{HTMLDETAILCONTENT}
+
+        <hr class="layui-bg-gray">
+
+        <div id="data-detail-btn" class="layui-btn-container layui-form-item">
+            <div id="data-detail-submit-save" type="button" class="layui-btn layui-btn-normal" lay-submit lay-filter="save">淇濆瓨</div>
+            <div id="data-detail-submit-edit" type="button" class="layui-btn layui-btn-normal" lay-submit lay-filter="edit">淇敼</div>
+            <div id="data-detail-close" type="button" class="layui-btn" lay-submit lay-filter="close">鍏抽棴</div>
+        </div>
+
+        <div id="prompt">
+            娓╅Θ鎻愮ず锛氳浠旂粏濉啓鐩稿叧淇℃伅锛�<span class="extrude"><span class="not-null">*</span> 涓哄繀濉�夐」銆�</span>
+        </div>
+    </form>
+</div>
+</body>
+<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
+<script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
+<script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
+<script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script>
+<script type="text/javascript" src="../../static/js/@{SIMPLEENTITYNAME}/@{SIMPLEENTITYNAME}.js" charset="utf-8"></script>
+</html>
+
diff --git a/src/main/resources/templates/Js.txt b/src/main/resources/templates/Js.txt
new file mode 100644
index 0000000..77ec15d
--- /dev/null
+++ b/src/main/resources/templates/Js.txt
@@ -0,0 +1,244 @@
+var pageCurr;
+layui.config({
+    base: baseUrl + "/static/layui/lay/modules/"
+}).use(['table','laydate', 'form', 'admin'], function(){
+    var table = layui.table;
+    var $ = layui.jquery;
+    var layer = layui.layer;
+    var layDate = layui.laydate;
+    var form = layui.form;
+    var admin = layui.admin;
+
+    // 鏁版嵁娓叉煋
+    tableIns = table.render({
+        elem: '#@{SIMPLEENTITYNAME}',
+        headers: {token: localStorage.getItem('token')},
+        url: baseUrl+'/@{SIMPLEENTITYNAME}/list/auth',
+        page: true,
+        limit: 15,
+        limits: [15, 30, 50, 100, 200, 500],
+        toolbar: '#toolbar',
+        cellMinWidth: 50,
+        height: 'full-120',
+        cols: [[
+            {type: 'checkbox'}
+@{JSTABLECONTENT}
+            ,{fixed: 'right', title:'鎿嶄綔', align: 'center', toolbar: '#operate', width:120}
+        ]],
+        request: {
+            pageName: 'curr',
+            pageSize: 'limit'
+        },
+        parseData: function (res) {
+            return {
+                'code': res.code,
+                'msg': res.msg,
+                'count': res.data.total,
+                'data': res.data.records
+            }
+        },
+        response: {
+            statusCode: 200
+        },
+        done: function(res, curr, count) {
+            if (res.code === 403) {
+                top.location.href = baseUrl+"/";
+            }
+            pageCurr=curr;
+            limit();
+        }
+    });
+
+    // 鐩戝惉鎺掑簭浜嬩欢
+    table.on('sort(@{SIMPLEENTITYNAME})', function (obj) {
+        var searchData = {};
+        $.each($('#search-box [name]').serializeArray(), function() {
+            searchData[this.name] = this.value;
+        });
+        searchData['orderByField'] = obj.field;
+        searchData['orderByType'] = obj.type;
+        tableIns.reload({
+            where: searchData,
+            page: {curr: 1}
+        });
+    });
+
+    // 鐩戝惉澶村伐鍏锋爮浜嬩欢
+    table.on('toolbar(@{SIMPLEENTITYNAME})', function (obj) {
+        var checkStatus = table.checkStatus(obj.config.id).data;
+        switch(obj.event) {
+            case 'addData':
+                showEditModel();
+                break;
+            case 'deleteData':
+               if (checkStatus.length === 0) {
+                   layer.msg('璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁', {icon: 2});
+                   return;
+               }
+               del(checkStatus.map(function (d) {
+                   return d.@{PRIMARYKEYCOLUMN0};
+               }));
+               break;
+            case 'exportData':
+                admin.confirm('纭畾瀵煎嚭Excel鍚�', {shadeClose: true}, function(){
+                    var titles=[];
+                    var fields=[];
+                    obj.config.cols[0].map(function (col) {
+                        if (col.type === 'normal' && col.hide === false && col.toolbar == null) {
+                            titles.push(col.title);
+                            fields.push(col.field);
+                        }
+                    });
+                    var exportData = {};
+                    $.each($('#search-box [name]').serializeArray(), function() {
+                        exportData[this.name] = this.value;
+                    });
+                    var param = {
+                        '@{SIMPLEENTITYNAME}': exportData,
+                        'fields': fields
+                    };
+                    $.ajax({
+                        url: baseUrl+"/@{SIMPLEENTITYNAME}/export/auth",
+                        headers: {'token': localStorage.getItem('token')},
+                        data: JSON.stringify(param),
+                        dataType:'json',
+                        contentType:'application/json;charset=UTF-8',
+                        method: 'POST',
+                        success: function (res) {
+                            layer.closeAll();
+                            if (res.code === 200) {
+                                table.exportFile(titles,res.data,'xls');
+                            } else if (res.code === 403) {
+                                top.location.href = baseUrl+"/";
+                            } else {
+                                layer.msg(res.msg, {icon: 2})
+                            }
+                        }
+                    });
+                });
+                break;
+        }
+    });
+
+    // 鐩戝惉琛屽伐鍏蜂簨浠�
+    table.on('tool(@{SIMPLEENTITYNAME})', function(obj){
+        var data = obj.data;
+        switch (obj.event) {
+            case 'edit':
+                showEditModel(data);
+                break;
+            case "del":
+                del([data.@{PRIMARYKEYCOLUMN0}]);
+                break;
+        }
+    });
+
+    /* 寮圭獥 - 鏂板銆佷慨鏀� */
+    function showEditModel(mData) {
+        admin.open({
+            type: 1,
+            area: '600px',
+            title: (mData ? '淇敼' : '娣诲姞') + '',
+            content: $('#editDialog').html(),
+            success: function (layero, dIndex) {
+                form.val('detail', mData);
+                layDateRender(mData);
+                form.on('submit(editSubmit)', function (data) {
+                    var loadIndex = layer.load(2);
+                    $.ajax({
+                        url: baseUrl+"/@{SIMPLEENTITYNAME}/"+(mData?'update':'add')+"/auth",
+                        headers: {'token': localStorage.getItem('token')},
+                        data: data.field,
+                        method: 'POST',
+                        success: function (res) {
+                            layer.close(loadIndex);
+                            if (res.code === 200){
+                                layer.close(dIndex);
+                                layer.msg(res.msg, {icon: 1});
+                                tableReload();
+                            } else if (res.code === 403){
+                                top.location.href = baseUrl+"/";
+                            }else {
+                                layer.msg(res.msg, {icon: 2});
+                            }
+                        }
+                    })
+                    return false;
+                });
+                $(layero).children('.layui-layer-content').css('overflow', 'visible');
+                layui.form.render('select');
+            }
+        });
+    }
+
+    /* 鍒犻櫎 */
+    function del(ids) {
+        layer.confirm('纭畾瑕佸垹闄ら�変腑鏁版嵁鍚楋紵', {
+            skin: 'layui-layer-admin',
+            shade: .1
+        }, function (i) {
+            layer.close(i);
+            var loadIndex = layer.load(2);
+            $.ajax({
+                url: baseUrl+"/@{SIMPLEENTITYNAME}/delete/auth",
+                headers: {'token': localStorage.getItem('token')},
+                data: {ids: ids},
+                method: 'POST',
+                success: function (res) {
+                    layer.close(loadIndex);
+                    if (res.code === 200){
+                        layer.msg(res.msg, {icon: 1});
+                        tableReload();
+                    } else if (res.code === 403){
+                        top.location.href = baseUrl+"/";
+                    } else {
+                        layer.msg(res.msg, {icon: 2});
+                    }
+                }
+            })
+        });
+    }
+
+    // 鎼滅储
+    form.on('submit(search)', function (data) {
+        pageCurr = 1;
+        tableReload(false);
+    });
+
+    // 閲嶇疆
+    form.on('submit(reset)', function (data) {
+        pageCurr = 1;
+        clearFormVal($('#search-box'));
+        tableReload(false);
+    });
+
+    // 鏃堕棿閫夋嫨鍣�
+    function layDateRender(data) {
+        setTimeout(function () {
+            layDate.render({
+                elem: '.layui-laydate-range'
+                ,type: 'datetime'
+                ,range: true
+            });
+@{JSDATECONTENT}
+        }, 300);
+    }
+    layDateRender();
+
+});
+
+// 鍏抽棴鍔ㄤ綔
+$(document).on('click','#data-detail-close', function () {
+    parent.layer.closeAll();
+});
+
+function tableReload(child) {
+    var searchData = {};
+    $.each($('#search-box [name]').serializeArray(), function() {
+        searchData[this.name] = this.value;
+    });
+    tableIns.reload({
+        where: searchData,
+        page: {curr: pageCurr}
+     });
+}
diff --git a/src/main/resources/templates/Mapper.txt b/src/main/resources/templates/Mapper.txt
new file mode 100644
index 0000000..97e6e38
--- /dev/null
+++ b/src/main/resources/templates/Mapper.txt
@@ -0,0 +1,12 @@
+package @{COMPANYNAME}.mapper;
+
+import @{COMPANYNAME}.entity.@{ENTITYNAME};
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface @{ENTITYNAME}Mapper extends BaseMapper<@{ENTITYNAME}> {
+
+}
diff --git a/src/main/resources/templates/Service.txt b/src/main/resources/templates/Service.txt
new file mode 100644
index 0000000..28f8cc4
--- /dev/null
+++ b/src/main/resources/templates/Service.txt
@@ -0,0 +1,8 @@
+package @{COMPANYNAME}.service;
+
+import @{COMPANYNAME}.entity.@{ENTITYNAME};
+import com.baomidou.mybatisplus.service.IService;
+
+public interface @{ENTITYNAME}Service extends IService<@{ENTITYNAME}> {
+
+}
diff --git a/src/main/resources/templates/ServiceImpl.txt b/src/main/resources/templates/ServiceImpl.txt
new file mode 100644
index 0000000..04256bd
--- /dev/null
+++ b/src/main/resources/templates/ServiceImpl.txt
@@ -0,0 +1,12 @@
+package @{COMPANYNAME}.service.impl;
+
+import @{COMPANYNAME}.mapper.@{ENTITYNAME}Mapper;
+import @{COMPANYNAME}.entity.@{ENTITYNAME};
+import @{COMPANYNAME}.service.@{ENTITYNAME}Service;
+import com.baomidou.mybatisplus.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service("@{SIMPLEENTITYNAME}Service")
+public class @{ENTITYNAME}ServiceImpl extends ServiceImpl<@{ENTITYNAME}Mapper, @{ENTITYNAME}> implements @{ENTITYNAME}Service {
+
+}
diff --git a/src/main/resources/templates/Sql.txt b/src/main/resources/templates/Sql.txt
new file mode 100644
index 0000000..c11d64d
--- /dev/null
+++ b/src/main/resources/templates/Sql.txt
@@ -0,0 +1,18 @@
+-- save @{SIMPLEENTITYNAME} record
+-- mysql
+insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( '@{SIMPLEENTITYNAME}/@{SIMPLEENTITYNAME}.html', '@{SIMPLEENTITYNAME}绠$悊', null , '2', null , '1');
+
+insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( '@{SIMPLEENTITYNAME}#view', '鏌ヨ', '', '3', '0', '1');
+insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( '@{SIMPLEENTITYNAME}#btn-add', '鏂板', '', '3', '1', '1');
+insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( '@{SIMPLEENTITYNAME}#btn-edit', '缂栬緫', '', '3', '2', '1');
+insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( '@{SIMPLEENTITYNAME}#btn-delete', '鍒犻櫎', '', '3', '3', '1');
+insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( '@{SIMPLEENTITYNAME}#btn-export', '瀵煎嚭', '', '3', '4', '1');
+
+-- sqlserver
+insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'@{SIMPLEENTITYNAME}/@{SIMPLEENTITYNAME}.html', N'@{SIMPLEENTITYNAME}绠$悊', null, '2', null, '1');
+
+insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'@{SIMPLEENTITYNAME}#view', N'鏌ヨ', '', '3', '0', '1');
+insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'@{SIMPLEENTITYNAME}#btn-add', N'鏂板', '', '3', '1', '1');
+insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'@{SIMPLEENTITYNAME}#btn-edit', N'缂栬緫', '', '3', '2', '1');
+insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'@{SIMPLEENTITYNAME}#btn-delete', N'鍒犻櫎', '', '3', '3', '1');
+insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'@{SIMPLEENTITYNAME}#btn-export', N'瀵煎嚭', '', '3', '4', '1');
diff --git a/src/main/resources/templates/Xml.txt b/src/main/resources/templates/Xml.txt
new file mode 100644
index 0000000..aceeed2
--- /dev/null
+++ b/src/main/resources/templates/Xml.txt
@@ -0,0 +1,10 @@
+<?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="@{COMPANYNAME}.mapper.@{ENTITYNAME}Mapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="@{COMPANYNAME}.entity.@{ENTITYNAME}">
+@{XMLCONTENT}
+    </resultMap>
+
+</mapper>
diff --git a/version/lib/cool-framework-install.txt b/version/lib/cool-framework-install.txt
deleted file mode 100644
index 0f282e0..0000000
--- a/version/lib/cool-framework-install.txt
+++ /dev/null
@@ -1 +0,0 @@
-mvn install:install-file -Dfile=framework-3.4.0.jar -DgroupId=cn.cool -DartifactId=framework -Dversion=3.4.0 -Dpackaging=jar -DgeneratePom=true

--
Gitblit v1.9.1