Browse Source

add 新增 代码生成器适配 多数据库可切换生成代码

疯狂的狮子li 3 years ago
parent
commit
db5d448623

+ 1 - 1
ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTable.java

@@ -202,7 +202,7 @@ public class GenTable extends BaseEntity {
     public static boolean isSuperColumn(String tplCategory, String javaField) {
         if (isTree(tplCategory)) {
             return StringUtils.equalsAnyIgnoreCase(javaField,
-                ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY));
+                    ArrayUtils.addAll(GenConstants.TREE_ENTITY, GenConstants.BASE_ENTITY));
         }
         return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY);
     }

+ 4 - 4
ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/domain/GenTableColumn.java

@@ -189,10 +189,10 @@ public class GenTableColumn extends BaseEntity {
 
     public static boolean isSuperColumn(String javaField) {
         return StringUtils.equalsAnyIgnoreCase(javaField,
-            // BaseEntity
-            "createBy", "createTime", "updateBy", "updateTime",
-            // TreeEntity
-            "parentName", "parentId");
+                // BaseEntity
+                "createBy", "createTime", "updateBy", "updateTime",
+                // TreeEntity
+                "parentName", "parentId");
     }
 
     public boolean isUsableColumn() {

+ 1 - 10
ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/mapper/GenTableMapper.java

@@ -18,16 +18,7 @@ import java.util.List;
 @InterceptorIgnore(dataPermission = "true")
 public interface GenTableMapper extends BaseMapperPlus<GenTableMapper, GenTable, GenTable> {
 
-    Page<GenTable> selectPageDbTableList(@Param("page") Page<GenTable> page, @Param(Constants.WRAPPER) Wrapper<Object> queryWrapper);
-
-    /**
-     * 查询据库列表
-     *
-     * @param queryWrapper 查询条件
-     * @return 数据库表集合
-     */
-    List<GenTable> selectDbTableList(@Param(Constants.WRAPPER) Wrapper<Object> queryWrapper);
-
+    Page<GenTable> selectPageDbTableList(@Param("page") Page<GenTable> page, @Param("genTable") GenTable genTable);
 
     /**
      * 查询据库列表

+ 3 - 39
ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableServiceImpl.java

@@ -6,7 +6,7 @@ import cn.hutool.core.lang.Dict;
 import cn.hutool.core.lang.Snowflake;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.dynamic.datasource.annotation.DS;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -50,6 +50,7 @@ import java.util.zip.ZipOutputStream;
  *
  * @author ruoyi
  */
+@DS("#header.datasource")
 @Slf4j
 @RequiredArgsConstructor
 @Service
@@ -90,17 +91,6 @@ public class GenTableServiceImpl implements IGenTableService {
         return TableDataInfo.build(page);
     }
 
-    /**
-     * 查询业务列表
-     *
-     * @param genTable 业务信息
-     * @return 业务集合
-     */
-    @Override
-    public List<GenTable> selectGenTableList(GenTable genTable) {
-        return baseMapper.selectList(this.buildGenTableQueryWrapper(genTable));
-    }
-
     private QueryWrapper<GenTable> buildGenTableQueryWrapper(GenTable genTable) {
         Map<String, Object> params = genTable.getParams();
         QueryWrapper<GenTable> wrapper = Wrappers.query();
@@ -114,36 +104,10 @@ public class GenTableServiceImpl implements IGenTableService {
 
     @Override
     public TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery) {
-        Page<GenTable> page = baseMapper.selectPageDbTableList(pageQuery.build(), this.buildDbTableQueryWrapper(genTable));
+        Page<GenTable> page = baseMapper.selectPageDbTableList(pageQuery.build(), genTable);
         return TableDataInfo.build(page);
     }
 
-    /**
-     * 查询据库列表
-     *
-     * @param genTable 业务信息
-     * @return 数据库表集合
-     */
-    @Override
-    public List<GenTable> selectDbTableList(GenTable genTable) {
-        return baseMapper.selectDbTableList(this.buildDbTableQueryWrapper(genTable));
-    }
-
-    private Wrapper<Object> buildDbTableQueryWrapper(GenTable genTable) {
-        Map<String, Object> params = genTable.getParams();
-        QueryWrapper<Object> wrapper = Wrappers.query();
-        wrapper.apply("table_schema = (select database())")
-            .notLike("table_name", "xxl_job_")
-            .notLike("table_name", "gen_")
-            .notInSql("table_name", "select table_name from gen_table")
-            .like(StringUtils.isNotBlank(genTable.getTableName()), "lower(table_name)", StringUtils.lowerCase(genTable.getTableName()))
-            .like(StringUtils.isNotBlank(genTable.getTableComment()), "lower(table_comment)", StringUtils.lowerCase(genTable.getTableComment()))
-            .between(params.get("beginTime") != null && params.get("endTime") != null,
-                "create_time", params.get("beginTime"), params.get("endTime"))
-            .orderByDesc("create_time");
-        return wrapper;
-    }
-
     /**
      * 查询据库列表
      *

+ 0 - 16
ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/IGenTableService.java

@@ -27,22 +27,6 @@ public interface IGenTableService {
 
     TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery);
 
-    /**
-     * 查询业务列表
-     *
-     * @param genTable 业务信息
-     * @return 业务集合
-     */
-    List<GenTable> selectGenTableList(GenTable genTable);
-
-    /**
-     * 查询据库列表
-     *
-     * @param genTable 业务信息
-     * @return 数据库表集合
-     */
-    List<GenTable> selectDbTableList(GenTable genTable);
-
     /**
      * 查询据库列表
      *

+ 5 - 8
ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/GenUtils.java

@@ -92,11 +92,6 @@ public class GenUtils {
             column.setIsQuery(GenConstants.REQUIRE);
         }
 
-        // 查询字段
-        if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) {
-            column.setIsQuery(GenConstants.REQUIRE);
-        }
-
         // 查询字段类型
         if (StringUtils.endsWithIgnoreCase(columnName, "name")) {
             column.setQueryType(GenConstants.QUERY_LIKE);
@@ -107,7 +102,7 @@ public class GenUtils {
         }
         // 类型&性别字段设置下拉框
         else if (StringUtils.endsWithIgnoreCase(columnName, "type")
-            || StringUtils.endsWithIgnoreCase(columnName, "sex")) {
+                || StringUtils.endsWithIgnoreCase(columnName, "sex")) {
             column.setHtmlType(GenConstants.HTML_SELECT);
         }
         // 图片字段设置图片上传控件
@@ -154,9 +149,11 @@ public class GenUtils {
      * @return 业务名
      */
     public static String getBusinessName(String tableName) {
-        int lastIndex = tableName.lastIndexOf("_");
+        int firstIndex = tableName.indexOf("_");
         int nameLength = tableName.length();
-        return StringUtils.substring(tableName, lastIndex + 1, nameLength);
+        String businessName = StringUtils.substring(tableName, firstIndex + 1, nameLength);
+        businessName = StringUtils.toCamelCase(businessName);
+        return businessName;
     }
 
     /**

+ 11 - 4
ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/util/VelocityUtils.java

@@ -8,6 +8,7 @@ import com.ruoyi.common.core.constant.GenConstants;
 import com.ruoyi.common.core.utils.DateUtils;
 import com.ruoyi.common.core.utils.JsonUtils;
 import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.mybatis.helper.DataBaseHelper;
 import com.ruoyi.gen.domain.GenTable;
 import com.ruoyi.gen.domain.GenTableColumn;
 import lombok.AccessLevel;
@@ -138,7 +139,13 @@ public class VelocityUtils {
         templates.add("vm/java/serviceImpl.java.vm");
         templates.add("vm/java/controller.java.vm");
         templates.add("vm/xml/mapper.xml.vm");
-        templates.add("vm/sql/sql.vm");
+        if (DataBaseHelper.isOracle()) {
+            templates.add("vm/sql/oracle/sql.vm");
+        } else if (DataBaseHelper.isPostgerSql()) {
+            templates.add("vm/sql/postgres/sql.vm");
+        } else {
+            templates.add("vm/sql/sql.vm");
+        }
         templates.add("vm/js/api.js.vm");
         if (GenConstants.TPL_CRUD.equals(tplCategory)) {
             templates.add("vm/vue/index.vue.vm");
@@ -263,8 +270,8 @@ public class VelocityUtils {
     public static void addDicts(Set<String> dicts, List<GenTableColumn> columns) {
         for (GenTableColumn column : columns) {
             if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
-                column.getHtmlType(),
-                new String[]{GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX})) {
+                    column.getHtmlType(),
+                    new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) {
                 dicts.add("'" + column.getDictType() + "'");
             }
         }
@@ -289,7 +296,7 @@ public class VelocityUtils {
      */
     public static String getParentMenuId(Dict paramsObj) {
         if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID)
-            && StringUtils.isNotEmpty(paramsObj.getStr(GenConstants.PARENT_MENU_ID))) {
+                && StringUtils.isNotEmpty(paramsObj.getStr(GenConstants.PARENT_MENU_ID))) {
             return paramsObj.getStr(GenConstants.PARENT_MENU_ID);
         }
         return DEFAULT_PARENT_MENU_ID;

+ 64 - 3
ruoyi-modules/ruoyi-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml

@@ -30,9 +30,70 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
-		select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type
-		from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
-		order by ordinal_position
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
+            select column_name,
+            (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required,
+            (case when column_key = 'PRI' then '1' else '0' end) as is_pk,
+            ordinal_position as sort,
+            column_comment,
+            (case when extra = 'auto_increment' then '1' else '0' end) as is_increment,
+            column_type
+            from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
+            order by ordinal_position
+        </if>
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
+            select lower(temp.column_name) as column_name,
+            (case when (temp.nullable = 'N'  and  temp.constraint_type != 'P') then '1' else null end) as is_required,
+            (case when temp.constraint_type = 'P' then '1' else '0' end) as is_pk,
+            temp.column_id as sort,
+            temp.comments as column_comment,
+            (case when temp.constraint_type = 'P' then '1' else '0' end) as is_increment,
+            lower(temp.data_type) as column_type
+            from (
+            select col.column_id, col.column_name,col.nullable, col.data_type, colc.comments, uc.constraint_type, row_number()
+            over (partition by col.column_name order by uc.constraint_type desc) as row_flg
+            from user_tab_columns col
+            left join user_col_comments colc on colc.table_name = col.table_name and colc.column_name = col.column_name
+            left join user_cons_columns ucc on ucc.table_name = col.table_name and ucc.column_name = col.column_name
+            left join user_constraints uc on uc.constraint_name = ucc.constraint_name
+            where col.table_name = upper(#{tableName})
+            ) temp
+            WHERE temp.row_flg = 1
+            ORDER BY temp.column_id
+        </if>
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
+            SELECT column_name, is_required, is_pk, sort, column_comment, is_increment, column_type
+            FROM (
+            SELECT c.relname AS table_name,
+            a.attname AS column_name,
+            d.description AS column_comment,
+            CASE WHEN a.attnotnull AND con.conname IS NULL THEN 1 ELSE 0
+            END AS is_required,
+            CASE WHEN con.conname IS NOT NULL THEN 1 ELSE 0
+            END AS is_pk,
+            a.attnum AS sort,
+            CASE WHEN "position"(pg_get_expr(ad.adbin, ad.adrelid),
+            ((c.relname::text || '_'::text) || a.attname::text) || '_seq'::text) > 0 THEN 1 ELSE 0
+            END AS is_increment,
+            btrim(
+            CASE WHEN t.typelem <![CDATA[ <> ]]> 0::oid AND t.typlen = '-1'::integer THEN 'ARRAY'::text ELSE
+            CASE WHEN t.typtype = 'd'::"char" THEN format_type(t.typbasetype, NULL::integer)
+            ELSE format_type(a.atttypid, NULL::integer) END
+            END, '"'::text
+            ) AS column_type
+            FROM pg_attribute a
+            JOIN (pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid) ON a.attrelid = c.oid
+            LEFT JOIN pg_description d ON d.objoid = c.oid AND a.attnum = d.objsubid
+            LEFT JOIN pg_constraint con ON con.conrelid = c.oid AND (a.attnum = ANY (con.conkey))
+            LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
+            LEFT JOIN pg_type t ON a.atttypid = t.oid
+            WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"]))
+            AND a.attnum > 0
+            AND n.nspname = 'public'::name
+            ORDER BY c.relname, a.attnum
+            ) temp
+            WHERE table_name = (#{tableName})
+        </if>
 	</select>
 
 </mapper>

+ 127 - 18
ruoyi-modules/ruoyi-gen/src/main/resources/mapper/generator/GenTableMapper.xml

@@ -54,30 +54,139 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <select id="selectPageDbTableList" resultMap="GenTableResult">
-        select table_name, table_comment, create_time, update_time
-        from information_schema.tables
-        ${ew.getCustomSqlSegment}
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
+            select table_name, table_comment, create_time, update_time
+            from information_schema.tables
+            where table_schema = (select database())
+            AND table_name NOT LIKE 'xxl_job_%' AND table_name NOT LIKE 'gen_%'
+            AND table_name NOT IN (select table_name from gen_table)
+            <if test="genTable.tableName != null and genTable.tableName != ''">
+                AND lower(table_name) like lower(concat('%', #{genTable.tableName}, '%'))
+            </if>
+            <if test="genTable.tableComment != null and genTable.tableComment != ''">
+                AND lower(table_comment) like lower(concat('%', #{genTable.tableComment}, '%'))
+            </if>
+            order by create_time desc
+        </if>
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
+            select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time
+            from user_tables dt, user_tab_comments dtc, user_objects uo
+            where dt.table_name = dtc.table_name
+            and dt.table_name = uo.object_name
+            and uo.object_type = 'TABLE'
+            AND dt.table_name NOT LIKE 'XXL_JOB_%' AND dt.table_name NOT LIKE 'GEN_%'
+            AND lower(dt.table_name) NOT IN (select table_name from gen_table)
+            <if test="genTable.tableName != null and genTable.tableName != ''">
+                AND lower(dt.table_name) like lower(concat(concat('%', #{genTable.tableName}), '%'))
+            </if>
+            <if test="genTable.tableComment != null and genTable.tableComment != ''">
+                AND lower(dtc.comments) like lower(concat(concat('%', #{genTable.tableComment}), '%'))
+            </if>
+            order by create_time desc
+        </if>
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
+            select table_name, table_comment, create_time, update_time
+            from (
+                SELECT c.relname AS table_name,
+                        obj_description(c.oid) AS table_comment,
+                        CURRENT_TIMESTAMP AS create_time,
+                        CURRENT_TIMESTAMP AS update_time
+                FROM pg_class c
+                    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+                WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"]))
+                    AND c.relname != 'spatial_%'::text
+                    AND n.nspname = 'public'::name
+                    AND n.nspname <![CDATA[ <> ]]> ''::name
+            ) list_table
+            where table_name NOT LIKE 'xxl_job_%' AND table_name NOT LIKE 'gen_%'
+            AND table_name NOT IN (select table_name from gen_table)
+            <if test="genTable.tableName != null and genTable.tableName != ''">
+                AND lower(table_name) like lower(concat('%', #{genTable.tableName}, '%'))
+            </if>
+            <if test="genTable.tableComment != null and genTable.tableComment != ''">
+                AND lower(table_comment) like lower(concat('%', #{genTable.tableComment}, '%'))
+            </if>
+            order by create_time desc
+        </if>
     </select>
 
-	<select id="selectDbTableList" resultMap="GenTableResult">
-        select table_name, table_comment, create_time, update_time
-        from information_schema.tables
-        ${ew.getCustomSqlSegment}
-	</select>
-
 	<select id="selectDbTableListByNames" resultMap="GenTableResult">
-		select table_name, table_comment, create_time, update_time from information_schema.tables
-		where table_name NOT LIKE 'qrtz_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database())
-		and table_name in
-	    <foreach collection="array" item="name" open="(" separator="," close=")">
- 			#{name}
-        </foreach>
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
+            select table_name, table_comment, create_time, update_time from information_schema.tables
+            where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database())
+            and table_name in
+            <foreach collection="array" item="name" open="(" separator="," close=")">
+                #{name}
+            </foreach>
+        </if>
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
+            select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time
+            from user_tables dt, user_tab_comments dtc, user_objects uo
+            where dt.table_name = dtc.table_name
+            and dt.table_name = uo.object_name
+            and uo.object_type = 'TABLE'
+            AND dt.table_name NOT LIKE 'XXL_JOB_%' AND dt.table_name NOT LIKE 'GEN_%'
+            AND dt.table_name NOT IN (select table_name from gen_table)
+            and lower(dt.table_name) in
+            <foreach collection="array" item="name" open="(" separator="," close=")">
+                #{name}
+            </foreach>
+        </if>
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
+            select table_name, table_comment, create_time, update_time
+            from (
+                SELECT c.relname AS table_name,
+                       obj_description(c.oid) AS table_comment,
+                       CURRENT_TIMESTAMP AS create_time,
+                       CURRENT_TIMESTAMP AS update_time
+                FROM pg_class c
+                    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+                WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"]))
+                    AND c.relname != 'spatial_%'::text
+                    AND n.nspname = 'public'::name
+                    AND n.nspname <![CDATA[ <> ]]> ''::name
+            ) list_table
+            where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%'
+            and table_name in
+            <foreach collection="array" item="name" open="(" separator="," close=")">
+                #{name}
+            </foreach>
+        </if>
 	</select>
 
 	<select id="selectTableByName" parameterType="String" resultMap="GenTableResult">
-		select table_name, table_comment, create_time, update_time from information_schema.tables
-		where table_comment <![CDATA[ <> ]]> '' and table_schema = (select database())
-		and table_name = #{tableName}
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
+            select table_name, table_comment, create_time, update_time from information_schema.tables
+            where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database())
+            and table_name = #{tableName}
+        </if>
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
+            select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time
+            from user_tables dt, user_tab_comments dtc, user_objects uo
+            where dt.table_name = dtc.table_name
+            and dt.table_name = uo.object_name
+            and uo.object_type = 'TABLE'
+            AND dt.table_name NOT LIKE 'XXL_JOB_%' AND dt.table_name NOT LIKE 'GEN_%'
+            AND dt.table_name NOT IN (select table_name from gen_table)
+            and lower(dt.table_name) = #{tableName}
+        </if>
+        <if test="@com.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
+            select table_name, table_comment, create_time, update_time
+            from (
+                SELECT c.relname AS table_name,
+                       obj_description(c.oid) AS table_comment,
+                       CURRENT_TIMESTAMP AS create_time,
+                       CURRENT_TIMESTAMP AS update_time
+                FROM pg_class c
+                    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+                WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"]))
+                    AND c.relname != 'spatial_%'::text
+                    AND n.nspname = 'public'::name
+                    AND n.nspname <![CDATA[ <> ]]> ''::name
+            ) list_table
+            where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%'
+            and table_name = #{tableName}
+        </if>
 	</select>
 
 	<select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult">

+ 19 - 0
ruoyi-modules/ruoyi-gen/src/main/resources/vm/sql/oracle/sql.vm

@@ -0,0 +1,19 @@
+-- 菜单 SQL
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[0]}, '${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', sysdate, '', null, '${functionName}菜单');
+
+-- 按钮 SQL
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[1]}, '${functionName}查询', ${table.menuIds[0]}, '1',  '#', '', 1,  0, 'F', '0', '0', '${permissionPrefix}:query',        '#', 'admin', sysdate, '', null, '');
+
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[2]}, '${functionName}新增', ${table.menuIds[0]}, '2',  '#', '', 1,  0, 'F', '0', '0', '${permissionPrefix}:add',          '#', 'admin', sysdate, '', null, '');
+
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[3]}, '${functionName}修改', ${table.menuIds[0]}, '3',  '#', '', 1,  0, 'F', '0', '0', '${permissionPrefix}:edit',         '#', 'admin', sysdate, '', null, '');
+
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[4]}, '${functionName}删除', ${table.menuIds[0]}, '4',  '#', '', 1,  0, 'F', '0', '0', '${permissionPrefix}:remove',       '#', 'admin', sysdate, '', null, '');
+
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[5]}, '${functionName}导出', ${table.menuIds[0]}, '5',  '#', '', 1,  0, 'F', '0', '0', '${permissionPrefix}:export',       '#', 'admin', sysdate, '', null, '');

+ 20 - 0
ruoyi-modules/ruoyi-gen/src/main/resources/vm/sql/postgres/sql.vm

@@ -0,0 +1,20 @@
+-- 菜单 SQL
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[0]}, '${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', now(), '', null, '${functionName}菜单');
+
+-- 按钮 SQL
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[1]}, '${functionName}查询', ${table.menuIds[0]}, '1',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query',        '#', 'admin', now(), '', null, '');
+
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[2]}, '${functionName}新增', ${table.menuIds[0]}, '2',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add',          '#', 'admin', now(), '', null, '');
+
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[3]}, '${functionName}修改', ${table.menuIds[0]}, '3',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit',         '#', 'admin', now(), '', null, '');
+
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[4]}, '${functionName}删除', ${table.menuIds[0]}, '4',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove',       '#', 'admin', now(), '', null, '');
+
+insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
+values(${table.menuIds[5]}, '${functionName}导出', ${table.menuIds[0]}, '5',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export',       '#', 'admin', now(), '', null, '');
+

+ 85 - 76
ruoyi-ui/src/api/tool/gen.js

@@ -1,76 +1,85 @@
-import request from '@/utils/request'
-
-// 查询生成表数据
-export function listTable(query) {
-  return request({
-    url: '/code/gen/list',
-    method: 'get',
-    params: query
-  })
-}
-// 查询db数据库列表
-export function listDbTable(query) {
-  return request({
-    url: '/code/gen/db/list',
-    method: 'get',
-    params: query
-  })
-}
-
-// 查询表详细信息
-export function getGenTable(tableId) {
-  return request({
-    url: '/code/gen/' + tableId,
-    method: 'get'
-  })
-}
-
-// 修改代码生成信息
-export function updateGenTable(data) {
-  return request({
-    url: '/code/gen',
-    method: 'put',
-    data: data
-  })
-}
-
-// 导入表
-export function importTable(data) {
-  return request({
-    url: '/code/gen/importTable',
-    method: 'post',
-    params: data
-  })
-}
-
-// 预览生成代码
-export function previewTable(tableId) {
-  return request({
-    url: '/code/gen/preview/' + tableId,
-    method: 'get'
-  })
-}
-
-// 删除表数据
-export function delTable(tableId) {
-  return request({
-    url: '/code/gen/' + tableId,
-    method: 'delete'
-  })
-}
-
-// 生成代码(自定义路径)
-export function genCode(tableName) {
-  return request({
-    url: '/code/gen/genCode/' + tableName,
-    method: 'get'
-  })
-}
-
-// 同步数据库
-export function synchDb(tableName) {
-  return request({
-    url: '/code/gen/synchDb/' + tableName,
-    method: 'get'
-  })
-}
+import request from '@/utils/request'
+
+// 查询生成表数据
+export function listTable(query) {
+  return request({
+    headers: { 'datasource': localStorage.getItem("dataName") },
+    url: '/code/gen/list',
+    method: 'get',
+    params: query
+  })
+}
+// 查询db数据库列表
+export function listDbTable(query) {
+  return request({
+    headers: { 'datasource': localStorage.getItem("dataName") },
+    url: '/code/gen/db/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询表详细信息
+export function getGenTable(tableId) {
+  return request({
+    headers: { 'datasource': localStorage.getItem("dataName") },
+    url: '/code/gen/' + tableId,
+    method: 'get'
+  })
+}
+
+// 修改代码生成信息
+export function updateGenTable(data) {
+  return request({
+    headers: { 'datasource': localStorage.getItem("dataName") },
+    url: '/code/gen',
+    method: 'put',
+    data: data
+  })
+}
+
+// 导入表
+export function importTable(data) {
+  return request({
+    headers: { 'datasource': localStorage.getItem("dataName") },
+    url: '/code/gen/importTable',
+    method: 'post',
+    params: data
+  })
+}
+
+// 预览生成代码
+export function previewTable(tableId) {
+  return request({
+    headers: { 'datasource': localStorage.getItem("dataName") },
+    url: '/code/gen/preview/' + tableId,
+    method: 'get'
+  })
+}
+
+// 删除表数据
+export function delTable(tableId) {
+  return request({
+    headers: { 'datasource': localStorage.getItem("dataName") },
+    url: '/code/gen/' + tableId,
+    method: 'delete'
+  })
+}
+
+// 生成代码(自定义路径)
+export function genCode(tableName) {
+  return request({
+    headers: { 'datasource': localStorage.getItem("dataName") },
+    url: '/code/gen/genCode/' + tableName,
+    method: 'get'
+  })
+}
+
+// 同步数据库
+export function synchDb(tableName) {
+  return request({
+    headers: { 'datasource': localStorage.getItem("dataName") },
+    url: '/code/gen/synchDb/' + tableName,
+    method: 'get'
+  })
+}

+ 4 - 1
ruoyi-ui/src/plugins/download.js

@@ -38,7 +38,10 @@ export default {
       method: 'get',
       url: url,
       responseType: 'blob',
-      headers: { 'Authorization': 'Bearer ' + getToken() }
+      headers: {
+        'Authorization': 'Bearer ' + getToken(),
+        'datasource': localStorage.getItem("dataName")
+      }
     }).then(async (res) => {
       const isLogin = await blobValidate(res.data);
       if (isLogin) {

+ 299 - 299
ruoyi-ui/src/views/tool/gen/genInfoForm.vue

@@ -1,299 +1,299 @@
-<template>
-  <el-form ref="genInfoForm" :model="info" :rules="rules" label-width="150px">
-    <el-row>
-      <el-col :span="12">
-        <el-form-item prop="tplCategory">
-          <span slot="label">生成模板</span>
-          <el-select v-model="info.tplCategory" @change="tplSelectChange">
-            <el-option label="单表(增删改查)" value="crud" />
-            <el-option label="树表(增删改查)" value="tree" />
-            <el-option label="主子表(增删改查)" value="sub" />
-          </el-select>
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item prop="packageName">
-          <span slot="label">
-            生成包路径
-            <el-tooltip content="生成在哪个java包下,例如 com.ruoyi.system" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-input v-model="info.packageName" />
-        </el-form-item>
-      </el-col>
-
-      <el-col :span="12">
-        <el-form-item prop="moduleName">
-          <span slot="label">
-            生成模块名
-            <el-tooltip content="可理解为子系统名,例如 system" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-input v-model="info.moduleName" />
-        </el-form-item>
-      </el-col>
-
-      <el-col :span="12">
-        <el-form-item prop="businessName">
-          <span slot="label">
-            生成业务名
-            <el-tooltip content="可理解为功能英文名,例如 user" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-input v-model="info.businessName" />
-        </el-form-item>
-      </el-col>
-
-      <el-col :span="12">
-        <el-form-item prop="functionName">
-          <span slot="label">
-            生成功能名
-            <el-tooltip content="用作类描述,例如 用户" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-input v-model="info.functionName" />
-        </el-form-item>
-      </el-col>
-
-      <el-col :span="12">
-        <el-form-item>
-          <span slot="label">
-            上级菜单
-            <el-tooltip content="分配到指定菜单下,例如 系统管理" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <treeselect
-            :append-to-body="true"
-            v-model="info.parentMenuId"
-            :options="menus"
-            :normalizer="normalizer"
-            :show-count="true"
-            placeholder="请选择系统菜单"
-          />
-        </el-form-item>
-      </el-col>
-
-      <el-col :span="12">
-        <el-form-item prop="genType">
-          <span slot="label">
-            生成代码方式
-            <el-tooltip content="默认为zip压缩包下载,也可以自定义生成路径" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-radio v-model="info.genType" label="0">zip压缩包</el-radio>
-          <el-radio v-model="info.genType" label="1">自定义路径</el-radio>
-        </el-form-item>
-      </el-col>
-
-      <el-col :span="24" v-if="info.genType == '1'">
-        <el-form-item prop="genPath">
-          <span slot="label">
-            自定义路径
-            <el-tooltip content="填写磁盘绝对路径,若不填写,则生成到当前Web项目下" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-input v-model="info.genPath">
-            <el-dropdown slot="append">
-              <el-button type="primary">
-                最近路径快速选择
-                <i class="el-icon-arrow-down el-icon--right"></i>
-              </el-button>
-              <el-dropdown-menu slot="dropdown">
-                <el-dropdown-item @click.native="info.genPath = '/'">恢复默认的生成基础路径</el-dropdown-item>
-              </el-dropdown-menu>
-            </el-dropdown>
-          </el-input>
-        </el-form-item>
-      </el-col>
-    </el-row>
-
-    <el-row v-show="info.tplCategory == 'tree'">
-      <h4 class="form-header">其他信息</h4>
-      <el-col :span="12">
-        <el-form-item>
-          <span slot="label">
-            树编码字段
-            <el-tooltip content="树显示的编码字段名, 如:dept_id" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-select v-model="info.treeCode" placeholder="请选择">
-            <el-option
-              v-for="(column, index) in info.columns"
-              :key="index"
-              :label="column.columnName + ':' + column.columnComment"
-              :value="column.columnName"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item>
-          <span slot="label">
-            树父编码字段
-            <el-tooltip content="树显示的父编码字段名, 如:parent_Id" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-select v-model="info.treeParentCode" placeholder="请选择">
-            <el-option
-              v-for="(column, index) in info.columns"
-              :key="index"
-              :label="column.columnName + ':' + column.columnComment"
-              :value="column.columnName"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item>
-          <span slot="label">
-            树名称字段
-            <el-tooltip content="树节点的显示名称字段名, 如:dept_name" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-select v-model="info.treeName" placeholder="请选择">
-            <el-option
-              v-for="(column, index) in info.columns"
-              :key="index"
-              :label="column.columnName + ':' + column.columnComment"
-              :value="column.columnName"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-    </el-row>
-    <el-row v-show="info.tplCategory == 'sub'">
-      <h4 class="form-header">关联信息</h4>
-      <el-col :span="12">
-        <el-form-item>
-          <span slot="label">
-            关联子表的表名
-            <el-tooltip content="关联子表的表名, 如:sys_user" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-select v-model="info.subTableName" placeholder="请选择" @change="subSelectChange">
-            <el-option
-              v-for="(table, index) in tables"
-              :key="index"
-              :label="table.tableName + ':' + table.tableComment"
-              :value="table.tableName"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item>
-          <span slot="label">
-            子表关联的外键名
-            <el-tooltip content="子表关联的外键名, 如:user_id" placement="top">
-              <i class="el-icon-question"></i>
-            </el-tooltip>
-          </span>
-          <el-select v-model="info.subTableFkName" placeholder="请选择">
-            <el-option
-              v-for="(column, index) in subColumns"
-              :key="index"
-              :label="column.columnName + ':' + column.columnComment"
-              :value="column.columnName"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
-    </el-row>
-  </el-form>
-</template>
-
-<script>
-import Treeselect from "@riophae/vue-treeselect";
-import "@riophae/vue-treeselect/dist/vue-treeselect.css";
-
-export default {
-  components: { Treeselect },
-  props: {
-    info: {
-      type: Object,
-      default: null
-    },
-    tables: {
-      type: Array,
-      default: null
-    },
-    menus: {
-      type: Array,
-      default: []
-    },
-  },
-  data() {
-    return {
-      subColumns: [],
-      rules: {
-        tplCategory: [
-          { required: true, message: "请选择生成模板", trigger: "blur" }
-        ],
-        packageName: [
-          { required: true, message: "请输入生成包路径", trigger: "blur" }
-        ],
-        moduleName: [
-          { required: true, message: "请输入生成模块名", trigger: "blur" }
-        ],
-        businessName: [
-          { required: true, message: "请输入生成业务名", trigger: "blur" }
-        ],
-        functionName: [
-          { required: true, message: "请输入生成功能名", trigger: "blur" }
-        ],
-      }
-    };
-  },
-  created() {},
-  watch: {
-    'info.subTableName': function(val) {
-      this.setSubTableColumns(val);
-    }
-  },
-  methods: {
-    /** 转换菜单数据结构 */
-    normalizer(node) {
-      if (node.children && !node.children.length) {
-        delete node.children;
-      }
-      return {
-        id: node.menuId,
-        label: node.menuName,
-        children: node.children
-      };
-    },
-    /** 选择子表名触发 */
-    subSelectChange(value) {
-      this.info.subTableFkName = '';
-    },
-    /** 选择生成模板触发 */
-    tplSelectChange(value) {
-      if(value !== 'sub') {
-        this.info.subTableName = '';
-        this.info.subTableFkName = '';
-      }
-    },
-    /** 设置关联外键 */
-    setSubTableColumns(value) {
-      for (var item in this.tables) {
-        const name = this.tables[item].tableName;
-        if (value === name) {
-          this.subColumns = this.tables[item].columns;
-          break;
-        }
-      }
-    }
-  }
-};
-</script>
+<template>
+  <el-form ref="genInfoForm" :model="info" :rules="rules" label-width="150px">
+    <el-row>
+      <el-col :span="12">
+        <el-form-item prop="tplCategory">
+          <span slot="label">生成模板</span>
+          <el-select v-model="info.tplCategory" @change="tplSelectChange">
+            <el-option label="单表(增删改查)" value="crud" />
+            <el-option label="树表(增删改查)" value="tree" />
+<!--            <el-option label="主子表(增删改查)" value="sub" />-->
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item prop="packageName">
+          <span slot="label">
+            生成包路径
+            <el-tooltip content="生成在哪个java包下,例如 com.ruoyi.system" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-input v-model="info.packageName" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12">
+        <el-form-item prop="moduleName">
+          <span slot="label">
+            生成模块名
+            <el-tooltip content="可理解为子系统名,例如 system" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-input v-model="info.moduleName" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12">
+        <el-form-item prop="businessName">
+          <span slot="label">
+            生成业务名
+            <el-tooltip content="可理解为功能英文名,例如 user" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-input v-model="info.businessName" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12">
+        <el-form-item prop="functionName">
+          <span slot="label">
+            生成功能名
+            <el-tooltip content="用作类描述,例如 用户" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-input v-model="info.functionName" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12">
+        <el-form-item>
+          <span slot="label">
+            上级菜单
+            <el-tooltip content="分配到指定菜单下,例如 系统管理" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <treeselect
+            :append-to-body="true"
+            v-model="info.parentMenuId"
+            :options="menus"
+            :normalizer="normalizer"
+            :show-count="true"
+            placeholder="请选择系统菜单"
+          />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12">
+        <el-form-item prop="genType">
+          <span slot="label">
+            生成代码方式
+            <el-tooltip content="默认为zip压缩包下载,也可以自定义生成路径" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-radio v-model="info.genType" label="0">zip压缩包</el-radio>
+          <el-radio v-model="info.genType" label="1">自定义路径</el-radio>
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="24" v-if="info.genType == '1'">
+        <el-form-item prop="genPath">
+          <span slot="label">
+            自定义路径
+            <el-tooltip content="填写磁盘绝对路径,若不填写,则生成到当前Web项目下" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-input v-model="info.genPath">
+            <el-dropdown slot="append">
+              <el-button type="primary">
+                最近路径快速选择
+                <i class="el-icon-arrow-down el-icon--right"></i>
+              </el-button>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item @click.native="info.genPath = '/'">恢复默认的生成基础路径</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+          </el-input>
+        </el-form-item>
+      </el-col>
+    </el-row>
+
+    <el-row v-show="info.tplCategory == 'tree'">
+      <h4 class="form-header">其他信息</h4>
+      <el-col :span="12">
+        <el-form-item>
+          <span slot="label">
+            树编码字段
+            <el-tooltip content="树显示的编码字段名, 如:dept_id" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-select v-model="info.treeCode" placeholder="请选择">
+            <el-option
+              v-for="(column, index) in info.columns"
+              :key="index"
+              :label="column.columnName + ':' + column.columnComment"
+              :value="column.columnName"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item>
+          <span slot="label">
+            树父编码字段
+            <el-tooltip content="树显示的父编码字段名, 如:parent_Id" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-select v-model="info.treeParentCode" placeholder="请选择">
+            <el-option
+              v-for="(column, index) in info.columns"
+              :key="index"
+              :label="column.columnName + ':' + column.columnComment"
+              :value="column.columnName"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item>
+          <span slot="label">
+            树名称字段
+            <el-tooltip content="树节点的显示名称字段名, 如:dept_name" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-select v-model="info.treeName" placeholder="请选择">
+            <el-option
+              v-for="(column, index) in info.columns"
+              :key="index"
+              :label="column.columnName + ':' + column.columnComment"
+              :value="column.columnName"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+    </el-row>
+    <el-row v-show="info.tplCategory == 'sub'">
+      <h4 class="form-header">关联信息</h4>
+      <el-col :span="12">
+        <el-form-item>
+          <span slot="label">
+            关联子表的表名
+            <el-tooltip content="关联子表的表名, 如:sys_user" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-select v-model="info.subTableName" placeholder="请选择" @change="subSelectChange">
+            <el-option
+              v-for="(table, index) in tables"
+              :key="index"
+              :label="table.tableName + ':' + table.tableComment"
+              :value="table.tableName"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item>
+          <span slot="label">
+            子表关联的外键名
+            <el-tooltip content="子表关联的外键名, 如:user_id" placement="top">
+              <i class="el-icon-question"></i>
+            </el-tooltip>
+          </span>
+          <el-select v-model="info.subTableFkName" placeholder="请选择">
+            <el-option
+              v-for="(column, index) in subColumns"
+              :key="index"
+              :label="column.columnName + ':' + column.columnComment"
+              :value="column.columnName"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-col>
+    </el-row>
+  </el-form>
+</template>
+
+<script>
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+
+export default {
+  components: { Treeselect },
+  props: {
+    info: {
+      type: Object,
+      default: null
+    },
+    tables: {
+      type: Array,
+      default: null
+    },
+    menus: {
+      type: Array,
+      default: []
+    },
+  },
+  data() {
+    return {
+      subColumns: [],
+      rules: {
+        tplCategory: [
+          { required: true, message: "请选择生成模板", trigger: "blur" }
+        ],
+        packageName: [
+          { required: true, message: "请输入生成包路径", trigger: "blur" }
+        ],
+        moduleName: [
+          { required: true, message: "请输入生成模块名", trigger: "blur" }
+        ],
+        businessName: [
+          { required: true, message: "请输入生成业务名", trigger: "blur" }
+        ],
+        functionName: [
+          { required: true, message: "请输入生成功能名", trigger: "blur" }
+        ],
+      }
+    };
+  },
+  created() {},
+  watch: {
+    'info.subTableName': function(val) {
+      this.setSubTableColumns(val);
+    }
+  },
+  methods: {
+    /** 转换菜单数据结构 */
+    normalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.menuId,
+        label: node.menuName,
+        children: node.children
+      };
+    },
+    /** 选择子表名触发 */
+    subSelectChange(value) {
+      this.info.subTableFkName = '';
+    },
+    /** 选择生成模板触发 */
+    tplSelectChange(value) {
+      if(value !== 'sub') {
+        this.info.subTableName = '';
+        this.info.subTableFkName = '';
+      }
+    },
+    /** 设置关联外键 */
+    setSubTableColumns(value) {
+      for (var item in this.tables) {
+        const name = this.tables[item].tableName;
+        if (value === name) {
+          this.subColumns = this.tables[item].columns;
+          break;
+        }
+      }
+    }
+  }
+};
+</script>

+ 13 - 2
ruoyi-ui/src/views/tool/gen/index.vue

@@ -1,6 +1,14 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="数据源" prop="dataName">
+        <el-input
+          v-model="queryParams.dataName"
+          placeholder="请输入数据源名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
       <el-form-item label="表名称" prop="tableName">
         <el-input
           v-model="queryParams.tableName"
@@ -217,7 +225,8 @@ export default {
         pageNum: 1,
         pageSize: 10,
         tableName: undefined,
-        tableComment: undefined
+        tableComment: undefined,
+        dataName: "master"
       },
       // 预览参数
       preview: {
@@ -229,6 +238,7 @@ export default {
     };
   },
   created() {
+    localStorage.setItem("dataName", this.queryParams.dataName);
     this.getList();
   },
   activated() {
@@ -252,6 +262,7 @@ export default {
     },
     /** 搜索按钮操作 */
     handleQuery() {
+      localStorage.setItem("dataName", this.queryParams.dataName);
       this.queryParams.pageNum = 1;
       this.getList();
     },
@@ -305,7 +316,7 @@ export default {
       return result.value || '&nbsp;';
     },
     /** 复制代码成功 */
-    clipboardSuccess(){
+    clipboardSuccess() {
       this.$modal.msgSuccess("复制成功");
     },
     // 多选框选中数据