From 13b31b2ca2a5f8600002a042b536c9d5529842e3 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期一, 09 三月 2026 19:21:18 +0800
Subject: [PATCH] #

---
 src/main/java/com/core/generators/CoolGenerator.java |  853 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 853 insertions(+), 0 deletions(-)

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..6e4ebfd
--- /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.cj.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.annotation.TableId;");
+            imports.add("import com.baomidou.mybatisplus.annotation.IdType;");
+        }
+        if (hasTableLogic) {
+            imports.add("import com.baomidou.mybatisplus.annotation.TableLogic;");
+        }
+        if (hasTableField) {
+            imports.add("import com.baomidou.mybatisplus.annotation.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.getById(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;
+        }
+    }
+}

--
Gitblit v1.9.1