Jelajahi Sumber

Merge remote-tracking branch 'ruoyi-cloud/master'

# Conflicts:
#	ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
#	ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableServiceImpl.java
#	ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/controller/SysJobController.java
#	ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
#	sql/ry_config_20220114.sql
疯狂的狮子li 4 tahun lalu
induk
melakukan
c28d9c208e

+ 120 - 120
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java

@@ -1,120 +1,120 @@
-package com.ruoyi.common.core.constant;
-
-/**
- * 通用常量信息
- *
- * @author Lion Li
- */
-public interface Constants {
-    /**
-     * UTF-8 字符集
-     */
-    String UTF8 = "UTF-8";
-
-    /**
-     * GBK 字符集
-     */
-    String GBK = "GBK";
-
-    /**
-     * RMI 远程方法调用
-     */
-    String LOOKUP_RMI = "rmi:";
-
-    /**
-     * LDAP 远程方法调用
-     */
-    String LOOKUP_LDAP = "ldap:";
-
-    /**
-     * LDAPS 远程方法调用
-     */
-    String LOOKUP_LDAPS = "ldaps:";
-
-    /**
-     * http请求
-     */
-    String HTTP = "http://";
-
-    /**
-     * https请求
-     */
-    String HTTPS = "https://";
-
-    /**
-     * 成功标记
-     */
-    Integer SUCCESS = 200;
-
-    /**
-     * 失败标记
-     */
-    Integer FAIL = 500;
-
-    /**
-     * 登录成功
-     */
-    String LOGIN_SUCCESS = "Success";
-
-    /**
-     * 注销
-     */
-    String LOGOUT = "Logout";
-
-    /**
-     * 注册
-     */
-    String REGISTER = "Register";
-
-    /**
-     * 登录失败
-     */
-    String LOGIN_FAIL = "Error";
-
-    /**
-     * 当前记录起始索引
-     */
-    String PAGE_NUM = "pageNum";
-
-    /**
-     * 每页显示记录数
-     */
-    String PAGE_SIZE = "pageSize";
-
-    /**
-     * 排序列
-     */
-    String ORDER_BY_COLUMN = "orderByColumn";
-
-    /**
-     * 排序的方向 "desc" 或者 "asc".
-     */
-    String IS_ASC = "isAsc";
-
-    /**
-     * 验证码 redis key
-     */
-    String CAPTCHA_CODE_KEY = "captcha_codes:";
-
-    /**
-     * 验证码有效期(分钟)
-     */
-    long CAPTCHA_EXPIRATION = 2;
-
-
-    /**
-     * 参数管理 cache key
-     */
-    String SYS_CONFIG_KEY = "sys_config:";
-
-    /**
-     * 字典管理 cache key
-     */
-    String SYS_DICT_KEY = "sys_dict:";
-
-    /**
-     * 资源映射路径 前缀
-     */
-    String RESOURCE_PREFIX = "/profile";
-
-}
+package com.ruoyi.common.core.constant;
+
+/**
+ * 通用常量信息
+ *
+ * @author Lion Li
+ */
+public interface Constants {
+    /**
+     * UTF-8 字符集
+     */
+    String UTF8 = "UTF-8";
+
+    /**
+     * GBK 字符集
+     */
+    String GBK = "GBK";
+
+    /**
+     * RMI 远程方法调用
+     */
+    String LOOKUP_RMI = "rmi:";
+
+    /**
+     * LDAP 远程方法调用
+     */
+    String LOOKUP_LDAP = "ldap:";
+
+    /**
+     * LDAPS 远程方法调用
+     */
+    String LOOKUP_LDAPS = "ldaps:";
+
+    /**
+     * http请求
+     */
+    String HTTP = "http://";
+
+    /**
+     * https请求
+     */
+    String HTTPS = "https://";
+
+    /**
+     * 成功标记
+     */
+    Integer SUCCESS = 200;
+
+    /**
+     * 失败标记
+     */
+    Integer FAIL = 500;
+
+    /**
+     * 登录成功
+     */
+    String LOGIN_SUCCESS = "Success";
+
+    /**
+     * 注销
+     */
+    String LOGOUT = "Logout";
+
+    /**
+     * 注册
+     */
+    String REGISTER = "Register";
+
+    /**
+     * 登录失败
+     */
+    String LOGIN_FAIL = "Error";
+
+    /**
+     * 当前记录起始索引
+     */
+    String PAGE_NUM = "pageNum";
+
+    /**
+     * 每页显示记录数
+     */
+    String PAGE_SIZE = "pageSize";
+
+    /**
+     * 排序列
+     */
+    String ORDER_BY_COLUMN = "orderByColumn";
+
+    /**
+     * 排序的方向 "desc" 或者 "asc".
+     */
+    String IS_ASC = "isAsc";
+
+    /**
+     * 验证码 redis key
+     */
+    String CAPTCHA_CODE_KEY = "captcha_codes:";
+
+    /**
+     * 验证码有效期(分钟)
+     */
+    long CAPTCHA_EXPIRATION = 2;
+
+
+    /**
+     * 参数管理 cache key
+     */
+    String SYS_CONFIG_KEY = "sys_config:";
+
+    /**
+     * 字典管理 cache key
+     */
+    String SYS_DICT_KEY = "sys_dict:";
+
+    /**
+     * 资源映射路径 前缀
+     */
+    String RESOURCE_PREFIX = "/profile";
+
+}

+ 444 - 435
ruoyi-modules/ruoyi-gen/src/main/java/com/ruoyi/gen/service/GenTableServiceImpl.java

@@ -1,435 +1,444 @@
-package com.ruoyi.gen.service;
-
-import com.ruoyi.common.core.constant.Constants;
-import com.ruoyi.common.core.constant.GenConstants;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.JsonUtils;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.security.utils.SecurityUtils;
-import com.ruoyi.gen.domain.GenTable;
-import com.ruoyi.gen.domain.GenTableColumn;
-import com.ruoyi.gen.mapper.GenTableColumnMapper;
-import com.ruoyi.gen.mapper.GenTableMapper;
-import com.ruoyi.gen.util.GenUtils;
-import com.ruoyi.gen.util.VelocityInitializer;
-import com.ruoyi.gen.util.VelocityUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.velocity.Template;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.Velocity;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-/**
- * 业务 服务层实现
- *
- * @author ruoyi
- */
-@Slf4j
-@RequiredArgsConstructor(onConstructor_ = @Autowired)
-@Service
-public class GenTableServiceImpl implements IGenTableService {
-
-    private final GenTableMapper genTableMapper;
-    private final GenTableColumnMapper genTableColumnMapper;
-
-    /**
-     * 查询业务信息
-     *
-     * @param id 业务ID
-     * @return 业务信息
-     */
-    @Override
-    public GenTable selectGenTableById(Long id) {
-        GenTable genTable = genTableMapper.selectGenTableById(id);
-        setTableFromOptions(genTable);
-        return genTable;
-    }
-
-    /**
-     * 查询业务列表
-     *
-     * @param genTable 业务信息
-     * @return 业务集合
-     */
-    @Override
-    public List<GenTable> selectGenTableList(GenTable genTable) {
-        return genTableMapper.selectGenTableList(genTable);
-    }
-
-    /**
-     * 查询据库列表
-     *
-     * @param genTable 业务信息
-     * @return 数据库表集合
-     */
-    @Override
-    public List<GenTable> selectDbTableList(GenTable genTable) {
-        return genTableMapper.selectDbTableList(genTable);
-    }
-
-    /**
-     * 查询据库列表
-     *
-     * @param tableNames 表名称组
-     * @return 数据库表集合
-     */
-    @Override
-    public List<GenTable> selectDbTableListByNames(String[] tableNames) {
-        return genTableMapper.selectDbTableListByNames(tableNames);
-    }
-
-    /**
-     * 查询所有表信息
-     *
-     * @return 表信息集合
-     */
-    @Override
-    public List<GenTable> selectGenTableAll() {
-        return genTableMapper.selectGenTableAll();
-    }
-
-    /**
-     * 修改业务
-     *
-     * @param genTable 业务信息
-     * @return 结果
-     */
-    @Override
-    @Transactional
-    public void updateGenTable(GenTable genTable) {
-        String options = JsonUtils.toJsonString(genTable.getParams());
-        genTable.setOptions(options);
-        int row = genTableMapper.updateGenTable(genTable);
-        if (row > 0) {
-            for (GenTableColumn cenTableColumn : genTable.getColumns()) {
-                genTableColumnMapper.updateGenTableColumn(cenTableColumn);
-            }
-        }
-    }
-
-    /**
-     * 删除业务对象
-     *
-     * @param tableIds 需要删除的数据ID
-     * @return 结果
-     */
-    @Override
-    @Transactional
-    public void deleteGenTableByIds(Long[] tableIds) {
-        genTableMapper.deleteGenTableByIds(tableIds);
-        genTableColumnMapper.deleteGenTableColumnByIds(tableIds);
-    }
-
-    /**
-     * 导入表结构
-     *
-     * @param tableList 导入表列表
-     */
-    @Override
-    @Transactional
-    public void importGenTable(List<GenTable> tableList) {
-        String operName = SecurityUtils.getUsername();
-        try {
-            for (GenTable table : tableList) {
-                String tableName = table.getTableName();
-                GenUtils.initTable(table, operName);
-                int row = genTableMapper.insertGenTable(table);
-                if (row > 0) {
-                    // 保存列信息
-                    List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
-                    for (GenTableColumn column : genTableColumns) {
-                        GenUtils.initColumnField(column, table);
-                        genTableColumnMapper.insertGenTableColumn(column);
-                    }
-                }
-            }
-        } catch (Exception e) {
-            throw new ServiceException("导入失败:" + e.getMessage());
-        }
-    }
-
-    /**
-     * 预览代码
-     *
-     * @param tableId 表编号
-     * @return 预览数据列表
-     */
-    @Override
-    public Map<String, String> previewCode(Long tableId) {
-        Map<String, String> dataMap = new LinkedHashMap<>();
-        // 查询表信息
-        GenTable table = genTableMapper.selectGenTableById(tableId);
-        // 设置主子表信息
-        setSubTable(table);
-        // 设置主键列信息
-        setPkColumn(table);
-        VelocityInitializer.initVelocity();
-
-        VelocityContext context = VelocityUtils.prepareContext(table);
-
-        // 获取模板列表
-        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
-        for (String template : templates) {
-            // 渲染模板
-            StringWriter sw = new StringWriter();
-            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
-            tpl.merge(context, sw);
-            dataMap.put(template, sw.toString());
-        }
-        return dataMap;
-    }
-
-    /**
-     * 生成代码(下载方式)
-     *
-     * @param tableName 表名称
-     * @return 数据
-     */
-    @Override
-    public byte[] downloadCode(String tableName) {
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        ZipOutputStream zip = new ZipOutputStream(outputStream);
-        generatorCode(tableName, zip);
-        IOUtils.closeQuietly(zip);
-        return outputStream.toByteArray();
-    }
-
-    /**
-     * 生成代码(自定义路径)
-     *
-     * @param tableName 表名称
-     */
-    @Override
-    public void generatorCode(String tableName) {
-        // 查询表信息
-        GenTable table = genTableMapper.selectGenTableByName(tableName);
-        // 设置主子表信息
-        setSubTable(table);
-        // 设置主键列信息
-        setPkColumn(table);
-
-        VelocityInitializer.initVelocity();
-
-        VelocityContext context = VelocityUtils.prepareContext(table);
-
-        // 获取模板列表
-        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
-        for (String template : templates) {
-            if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) {
-                // 渲染模板
-                StringWriter sw = new StringWriter();
-                Template tpl = Velocity.getTemplate(template, Constants.UTF8);
-                tpl.merge(context, sw);
-                try {
-                    String path = getGenPath(table, template);
-                    FileUtils.writeStringToFile(new File(path), sw.toString(), StandardCharsets.UTF_8);
-                } catch (IOException e) {
-                    throw new ServiceException("渲染模板失败,表名:" + table.getTableName());
-                }
-            }
-        }
-    }
-
-    /**
-     * 同步数据库
-     *
-     * @param tableName 表名称
-     */
-    @Override
-    @Transactional
-    public void synchDb(String tableName) {
-        GenTable table = genTableMapper.selectGenTableByName(tableName);
-        List<GenTableColumn> tableColumns = table.getColumns();
-        List<String> tableColumnNames = tableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
-
-        List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
-        if (StringUtils.isEmpty(dbTableColumns)) {
-            throw new ServiceException("同步数据失败,原表结构不存在");
-        }
-        List<String> dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
-
-        dbTableColumns.forEach(column -> {
-            if (!tableColumnNames.contains(column.getColumnName())) {
-                GenUtils.initColumnField(column, table);
-                genTableColumnMapper.insertGenTableColumn(column);
-            }
-        });
-
-        List<GenTableColumn> delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList());
-        if (StringUtils.isNotEmpty(delColumns)) {
-            genTableColumnMapper.deleteGenTableColumns(delColumns);
-        }
-    }
-
-    /**
-     * 批量生成代码(下载方式)
-     *
-     * @param tableNames 表数组
-     * @return 数据
-     */
-    @Override
-    public byte[] downloadCode(String[] tableNames) {
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        ZipOutputStream zip = new ZipOutputStream(outputStream);
-        for (String tableName : tableNames) {
-            generatorCode(tableName, zip);
-        }
-        IOUtils.closeQuietly(zip);
-        return outputStream.toByteArray();
-    }
-
-    /**
-     * 查询表信息并生成代码
-     */
-    private void generatorCode(String tableName, ZipOutputStream zip) {
-        // 查询表信息
-        GenTable table = genTableMapper.selectGenTableByName(tableName);
-        // 设置主子表信息
-        setSubTable(table);
-        // 设置主键列信息
-        setPkColumn(table);
-
-        VelocityInitializer.initVelocity();
-
-        VelocityContext context = VelocityUtils.prepareContext(table);
-
-        // 获取模板列表
-        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
-        for (String template : templates) {
-            // 渲染模板
-            StringWriter sw = new StringWriter();
-            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
-            tpl.merge(context, sw);
-            try {
-                // 添加到zip
-                zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
-                IOUtils.write(sw.toString(), zip, Constants.UTF8);
-                IOUtils.closeQuietly(sw);
-                zip.flush();
-                zip.closeEntry();
-            } catch (IOException e) {
-                log.error("渲染模板失败,表名:" + table.getTableName(), e);
-            }
-        }
-    }
-
-    /**
-     * 修改保存参数校验
-     *
-     * @param genTable 业务信息
-     */
-    @Override
-    public void validateEdit(GenTable genTable) {
-        if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) {
-            String options = JsonUtils.toJsonString(genTable.getParams());
-            Map<String, String> paramsObj = JsonUtils.parseMap(options);
-            if (StringUtils.isEmpty(paramsObj.get(GenConstants.TREE_CODE))) {
-                throw new ServiceException("树编码字段不能为空");
-            } else if (StringUtils.isEmpty(paramsObj.get(GenConstants.TREE_PARENT_CODE))) {
-                throw new ServiceException("树父编码字段不能为空");
-            } else if (StringUtils.isEmpty(paramsObj.get(GenConstants.TREE_NAME))) {
-                throw new ServiceException("树名称字段不能为空");
-            } else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) {
-                if (StringUtils.isEmpty(genTable.getSubTableName())) {
-                    throw new ServiceException("关联子表的表名不能为空");
-                } else if (StringUtils.isEmpty(genTable.getSubTableFkName())) {
-                    throw new ServiceException("子表关联的外键名不能为空");
-                }
-            }
-        }
-    }
-
-    /**
-     * 设置主键列信息
-     *
-     * @param table 业务表信息
-     */
-    public void setPkColumn(GenTable table) {
-        for (GenTableColumn column : table.getColumns()) {
-            if (column.isPk()) {
-                table.setPkColumn(column);
-                break;
-            }
-        }
-        if (StringUtils.isNull(table.getPkColumn())) {
-            table.setPkColumn(table.getColumns().get(0));
-        }
-        if (GenConstants.TPL_SUB.equals(table.getTplCategory())) {
-            for (GenTableColumn column : table.getSubTable().getColumns()) {
-                if (column.isPk()) {
-                    table.getSubTable().setPkColumn(column);
-                    break;
-                }
-            }
-            if (StringUtils.isNull(table.getSubTable().getPkColumn())) {
-                table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0));
-            }
-        }
-    }
-
-    /**
-     * 设置主子表信息
-     *
-     * @param table 业务表信息
-     */
-    public void setSubTable(GenTable table) {
-        String subTableName = table.getSubTableName();
-        if (StringUtils.isNotEmpty(subTableName)) {
-            table.setSubTable(genTableMapper.selectGenTableByName(subTableName));
-        }
-    }
-
-    /**
-     * 设置代码生成其他选项值
-     *
-     * @param genTable 设置后的生成对象
-     */
-    public void setTableFromOptions(GenTable genTable) {
-        Map<String, String> paramsObj = JsonUtils.parseMap(genTable.getOptions());
-        if (StringUtils.isNotNull(paramsObj)) {
-            String treeCode = paramsObj.get(GenConstants.TREE_CODE);
-            String treeParentCode = paramsObj.get(GenConstants.TREE_PARENT_CODE);
-            String treeName = paramsObj.get(GenConstants.TREE_NAME);
-            String parentMenuId = paramsObj.get(GenConstants.PARENT_MENU_ID);
-            String parentMenuName = paramsObj.get(GenConstants.PARENT_MENU_NAME);
-
-            genTable.setTreeCode(treeCode);
-            genTable.setTreeParentCode(treeParentCode);
-            genTable.setTreeName(treeName);
-            genTable.setParentMenuId(parentMenuId);
-            genTable.setParentMenuName(parentMenuName);
-        }
-    }
-
-    /**
-     * 获取代码生成地址
-     *
-     * @param table    业务表信息
-     * @param template 模板文件路径
-     * @return 生成地址
-     */
-    public static String getGenPath(GenTable table, String template) {
-        String genPath = table.getGenPath();
-        if (StringUtils.equals(genPath, "/")) {
-            return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
-        }
-        return genPath + File.separator + VelocityUtils.getFileName(template, table);
-    }
-}
+package com.ruoyi.gen.service;
+
+import com.ruoyi.common.core.constant.Constants;
+import com.ruoyi.common.core.constant.GenConstants;
+import com.ruoyi.common.core.exception.ServiceException;
+import com.ruoyi.common.core.utils.JsonUtils;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.security.utils.SecurityUtils;
+import com.ruoyi.gen.domain.GenTable;
+import com.ruoyi.gen.domain.GenTableColumn;
+import com.ruoyi.gen.mapper.GenTableColumnMapper;
+import com.ruoyi.gen.mapper.GenTableMapper;
+import com.ruoyi.gen.util.GenUtils;
+import com.ruoyi.gen.util.VelocityInitializer;
+import com.ruoyi.gen.util.VelocityUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
+import java.util.function.Function;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * 业务 服务层实现
+ *
+ * @author ruoyi
+ */
+@Slf4j
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@Service
+public class GenTableServiceImpl implements IGenTableService {
+
+    private final GenTableMapper genTableMapper;
+    private final GenTableColumnMapper genTableColumnMapper;
+
+    /**
+     * 查询业务信息
+     *
+     * @param id 业务ID
+     * @return 业务信息
+     */
+    @Override
+    public GenTable selectGenTableById(Long id) {
+        GenTable genTable = genTableMapper.selectGenTableById(id);
+        setTableFromOptions(genTable);
+        return genTable;
+    }
+
+    /**
+     * 查询业务列表
+     *
+     * @param genTable 业务信息
+     * @return 业务集合
+     */
+    @Override
+    public List<GenTable> selectGenTableList(GenTable genTable) {
+        return genTableMapper.selectGenTableList(genTable);
+    }
+
+    /**
+     * 查询据库列表
+     *
+     * @param genTable 业务信息
+     * @return 数据库表集合
+     */
+    @Override
+    public List<GenTable> selectDbTableList(GenTable genTable) {
+        return genTableMapper.selectDbTableList(genTable);
+    }
+
+    /**
+     * 查询据库列表
+     *
+     * @param tableNames 表名称组
+     * @return 数据库表集合
+     */
+    @Override
+    public List<GenTable> selectDbTableListByNames(String[] tableNames) {
+        return genTableMapper.selectDbTableListByNames(tableNames);
+    }
+
+    /**
+     * 查询所有表信息
+     *
+     * @return 表信息集合
+     */
+    @Override
+    public List<GenTable> selectGenTableAll() {
+        return genTableMapper.selectGenTableAll();
+    }
+
+    /**
+     * 修改业务
+     *
+     * @param genTable 业务信息
+     * @return 结果
+     */
+    @Override
+    @Transactional
+    public void updateGenTable(GenTable genTable) {
+        String options = JsonUtils.toJsonString(genTable.getParams());
+        genTable.setOptions(options);
+        int row = genTableMapper.updateGenTable(genTable);
+        if (row > 0) {
+            for (GenTableColumn cenTableColumn : genTable.getColumns()) {
+                genTableColumnMapper.updateGenTableColumn(cenTableColumn);
+            }
+        }
+    }
+
+    /**
+     * 删除业务对象
+     *
+     * @param tableIds 需要删除的数据ID
+     * @return 结果
+     */
+    @Override
+    @Transactional
+    public void deleteGenTableByIds(Long[] tableIds) {
+        genTableMapper.deleteGenTableByIds(tableIds);
+        genTableColumnMapper.deleteGenTableColumnByIds(tableIds);
+    }
+
+    /**
+     * 导入表结构
+     *
+     * @param tableList 导入表列表
+     */
+    @Override
+    @Transactional
+    public void importGenTable(List<GenTable> tableList) {
+        String operName = SecurityUtils.getUsername();
+        try {
+            for (GenTable table : tableList) {
+                String tableName = table.getTableName();
+                GenUtils.initTable(table, operName);
+                int row = genTableMapper.insertGenTable(table);
+                if (row > 0) {
+                    // 保存列信息
+                    List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
+                    for (GenTableColumn column : genTableColumns) {
+                        GenUtils.initColumnField(column, table);
+                        genTableColumnMapper.insertGenTableColumn(column);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new ServiceException("导入失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 预览代码
+     *
+     * @param tableId 表编号
+     * @return 预览数据列表
+     */
+    @Override
+    public Map<String, String> previewCode(Long tableId) {
+        Map<String, String> dataMap = new LinkedHashMap<>();
+        // 查询表信息
+        GenTable table = genTableMapper.selectGenTableById(tableId);
+        // 设置主子表信息
+        setSubTable(table);
+        // 设置主键列信息
+        setPkColumn(table);
+        VelocityInitializer.initVelocity();
+
+        VelocityContext context = VelocityUtils.prepareContext(table);
+
+        // 获取模板列表
+        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
+        for (String template : templates) {
+            // 渲染模板
+            StringWriter sw = new StringWriter();
+            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
+            tpl.merge(context, sw);
+            dataMap.put(template, sw.toString());
+        }
+        return dataMap;
+    }
+
+    /**
+     * 生成代码(下载方式)
+     *
+     * @param tableName 表名称
+     * @return 数据
+     */
+    @Override
+    public byte[] downloadCode(String tableName) {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ZipOutputStream zip = new ZipOutputStream(outputStream);
+        generatorCode(tableName, zip);
+        IOUtils.closeQuietly(zip);
+        return outputStream.toByteArray();
+    }
+
+    /**
+     * 生成代码(自定义路径)
+     *
+     * @param tableName 表名称
+     */
+    @Override
+    public void generatorCode(String tableName) {
+        // 查询表信息
+        GenTable table = genTableMapper.selectGenTableByName(tableName);
+        // 设置主子表信息
+        setSubTable(table);
+        // 设置主键列信息
+        setPkColumn(table);
+
+        VelocityInitializer.initVelocity();
+
+        VelocityContext context = VelocityUtils.prepareContext(table);
+
+        // 获取模板列表
+        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
+        for (String template : templates) {
+            if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm")) {
+                // 渲染模板
+                StringWriter sw = new StringWriter();
+                Template tpl = Velocity.getTemplate(template, Constants.UTF8);
+                tpl.merge(context, sw);
+                try {
+                    String path = getGenPath(table, template);
+                    FileUtils.writeStringToFile(new File(path), sw.toString(), StandardCharsets.UTF_8);
+                } catch (IOException e) {
+                    throw new ServiceException("渲染模板失败,表名:" + table.getTableName());
+                }
+            }
+        }
+    }
+
+    /**
+     * 同步数据库
+     *
+     * @param tableName 表名称
+     */
+    @Override
+    @Transactional
+    public void synchDb(String tableName) {
+        GenTable table = genTableMapper.selectGenTableByName(tableName);
+        List<GenTableColumn> tableColumns = table.getColumns();
+        Map<String, GenTableColumn> tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity()));
+
+        List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
+        if (StringUtils.isEmpty(dbTableColumns)) {
+            throw new ServiceException("同步数据失败,原表结构不存在");
+        }
+        List<String> dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
+
+        dbTableColumns.forEach(column -> {
+            GenUtils.initColumnField(column, table);
+            if (tableColumnMap.containsKey(column.getColumnName())) {
+                GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName());
+                column.setColumnId(prevColumn.getColumnId());
+                if (column.isList()) {
+                    // 如果是列表,继续保留字典类型
+                    column.setDictType(prevColumn.getDictType());
+                }
+                genTableColumnMapper.updateGenTableColumn(column);
+            } else {
+                genTableColumnMapper.insertGenTableColumn(column);
+            }
+        });
+
+        List<GenTableColumn> delColumns = tableColumns.stream().filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList());
+        if (StringUtils.isNotEmpty(delColumns)) {
+            genTableColumnMapper.deleteGenTableColumns(delColumns);
+        }
+    }
+
+    /**
+     * 批量生成代码(下载方式)
+     *
+     * @param tableNames 表数组
+     * @return 数据
+     */
+    @Override
+    public byte[] downloadCode(String[] tableNames) {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ZipOutputStream zip = new ZipOutputStream(outputStream);
+        for (String tableName : tableNames) {
+            generatorCode(tableName, zip);
+        }
+        IOUtils.closeQuietly(zip);
+        return outputStream.toByteArray();
+    }
+
+    /**
+     * 查询表信息并生成代码
+     */
+    private void generatorCode(String tableName, ZipOutputStream zip) {
+        // 查询表信息
+        GenTable table = genTableMapper.selectGenTableByName(tableName);
+        // 设置主子表信息
+        setSubTable(table);
+        // 设置主键列信息
+        setPkColumn(table);
+
+        VelocityInitializer.initVelocity();
+
+        VelocityContext context = VelocityUtils.prepareContext(table);
+
+        // 获取模板列表
+        List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
+        for (String template : templates) {
+            // 渲染模板
+            StringWriter sw = new StringWriter();
+            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
+            tpl.merge(context, sw);
+            try {
+                // 添加到zip
+                zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
+                IOUtils.write(sw.toString(), zip, Constants.UTF8);
+                IOUtils.closeQuietly(sw);
+                zip.flush();
+                zip.closeEntry();
+            } catch (IOException e) {
+                log.error("渲染模板失败,表名:" + table.getTableName(), e);
+            }
+        }
+    }
+
+    /**
+     * 修改保存参数校验
+     *
+     * @param genTable 业务信息
+     */
+    @Override
+    public void validateEdit(GenTable genTable) {
+        if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) {
+            String options = JsonUtils.toJsonString(genTable.getParams());
+            Map<String, String> paramsObj = JsonUtils.parseMap(options);
+            if (StringUtils.isEmpty(paramsObj.get(GenConstants.TREE_CODE))) {
+                throw new ServiceException("树编码字段不能为空");
+            } else if (StringUtils.isEmpty(paramsObj.get(GenConstants.TREE_PARENT_CODE))) {
+                throw new ServiceException("树父编码字段不能为空");
+            } else if (StringUtils.isEmpty(paramsObj.get(GenConstants.TREE_NAME))) {
+                throw new ServiceException("树名称字段不能为空");
+            } else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) {
+                if (StringUtils.isEmpty(genTable.getSubTableName())) {
+                    throw new ServiceException("关联子表的表名不能为空");
+                } else if (StringUtils.isEmpty(genTable.getSubTableFkName())) {
+                    throw new ServiceException("子表关联的外键名不能为空");
+                }
+            }
+        }
+    }
+
+    /**
+     * 设置主键列信息
+     *
+     * @param table 业务表信息
+     */
+    public void setPkColumn(GenTable table) {
+        for (GenTableColumn column : table.getColumns()) {
+            if (column.isPk()) {
+                table.setPkColumn(column);
+                break;
+            }
+        }
+        if (StringUtils.isNull(table.getPkColumn())) {
+            table.setPkColumn(table.getColumns().get(0));
+        }
+        if (GenConstants.TPL_SUB.equals(table.getTplCategory())) {
+            for (GenTableColumn column : table.getSubTable().getColumns()) {
+                if (column.isPk()) {
+                    table.getSubTable().setPkColumn(column);
+                    break;
+                }
+            }
+            if (StringUtils.isNull(table.getSubTable().getPkColumn())) {
+                table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0));
+            }
+        }
+    }
+
+    /**
+     * 设置主子表信息
+     *
+     * @param table 业务表信息
+     */
+    public void setSubTable(GenTable table) {
+        String subTableName = table.getSubTableName();
+        if (StringUtils.isNotEmpty(subTableName)) {
+            table.setSubTable(genTableMapper.selectGenTableByName(subTableName));
+        }
+    }
+
+    /**
+     * 设置代码生成其他选项值
+     *
+     * @param genTable 设置后的生成对象
+     */
+    public void setTableFromOptions(GenTable genTable) {
+        Map<String, String> paramsObj = JsonUtils.parseMap(genTable.getOptions());
+        if (StringUtils.isNotNull(paramsObj)) {
+            String treeCode = paramsObj.get(GenConstants.TREE_CODE);
+            String treeParentCode = paramsObj.get(GenConstants.TREE_PARENT_CODE);
+            String treeName = paramsObj.get(GenConstants.TREE_NAME);
+            String parentMenuId = paramsObj.get(GenConstants.PARENT_MENU_ID);
+            String parentMenuName = paramsObj.get(GenConstants.PARENT_MENU_NAME);
+
+            genTable.setTreeCode(treeCode);
+            genTable.setTreeParentCode(treeParentCode);
+            genTable.setTreeName(treeName);
+            genTable.setParentMenuId(parentMenuId);
+            genTable.setParentMenuName(parentMenuName);
+        }
+    }
+
+    /**
+     * 获取代码生成地址
+     *
+     * @param table    业务表信息
+     * @param template 模板文件路径
+     * @return 生成地址
+     */
+    public static String getGenPath(GenTable table, String template) {
+        String genPath = table.getGenPath();
+        if (StringUtils.equals(genPath, "/")) {
+            return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
+        }
+        return genPath + File.separator + VelocityUtils.getFileName(template, table);
+    }
+}

+ 203 - 199
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java

@@ -1,199 +1,203 @@
-package com.ruoyi.system.service.impl;
-
-import com.ruoyi.common.core.constant.UserConstants;
-import com.ruoyi.common.core.exception.ServiceException;
-import com.ruoyi.common.core.utils.StringUtils;
-import com.ruoyi.common.dict.utils.DictUtils;
-import com.ruoyi.system.api.domain.SysDictData;
-import com.ruoyi.system.api.domain.SysDictType;
-import com.ruoyi.system.mapper.SysDictDataMapper;
-import com.ruoyi.system.mapper.SysDictTypeMapper;
-import com.ruoyi.system.service.ISysDictTypeService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.PostConstruct;
-import java.util.List;
-
-/**
- * 字典 业务层处理
- *
- * @author ruoyi
- */
-@RequiredArgsConstructor(onConstructor_ = @Autowired)
-@Service
-public class SysDictTypeServiceImpl implements ISysDictTypeService {
-
-    private final SysDictTypeMapper dictTypeMapper;
-    private final SysDictDataMapper dictDataMapper;
-
-    /**
-     * 项目启动时,初始化字典到缓存
-     */
-    @PostConstruct
-    public void init() {
-        loadingDictCache();
-    }
-
-    /**
-     * 根据条件分页查询字典类型
-     *
-     * @param dictType 字典类型信息
-     * @return 字典类型集合信息
-     */
-    @Override
-    public List<SysDictType> selectDictTypeList(SysDictType dictType) {
-        return dictTypeMapper.selectDictTypeList(dictType);
-    }
-
-    /**
-     * 根据所有字典类型
-     *
-     * @return 字典类型集合信息
-     */
-    @Override
-    public List<SysDictType> selectDictTypeAll() {
-        return dictTypeMapper.selectDictTypeAll();
-    }
-
-    /**
-     * 根据字典类型查询字典数据
-     *
-     * @param dictType 字典类型
-     * @return 字典数据集合信息
-     */
-    @Override
-    public List<SysDictData> selectDictDataByType(String dictType) {
-        List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
-        if (StringUtils.isNotEmpty(dictDatas)) {
-            return dictDatas;
-        }
-        dictDatas = dictDataMapper.selectDictDataByType(dictType);
-        if (StringUtils.isNotEmpty(dictDatas)) {
-            DictUtils.setDictCache(dictType, dictDatas);
-            return dictDatas;
-        }
-        return null;
-    }
-
-    /**
-     * 根据字典类型ID查询信息
-     *
-     * @param dictId 字典类型ID
-     * @return 字典类型
-     */
-    @Override
-    public SysDictType selectDictTypeById(Long dictId) {
-        return dictTypeMapper.selectDictTypeById(dictId);
-    }
-
-    /**
-     * 根据字典类型查询信息
-     *
-     * @param dictType 字典类型
-     * @return 字典类型
-     */
-    @Override
-    public SysDictType selectDictTypeByType(String dictType) {
-        return dictTypeMapper.selectDictTypeByType(dictType);
-    }
-
-    /**
-     * 批量删除字典类型信息
-     *
-     * @param dictIds 需要删除的字典ID
-     * @return 结果
-     */
-    @Override
-    public void deleteDictTypeByIds(Long[] dictIds) {
-        for (Long dictId : dictIds) {
-            SysDictType dictType = selectDictTypeById(dictId);
-            if (dictDataMapper.countDictDataByType(dictType.getDictType()) > 0) {
-                throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
-            }
-            dictTypeMapper.deleteDictTypeById(dictId);
-            DictUtils.removeDictCache(dictType.getDictType());
-        }
-    }
-
-    /**
-     * 加载字典缓存数据
-     */
-    @Override
-    public void loadingDictCache() {
-        List<SysDictType> dictTypeList = dictTypeMapper.selectDictTypeAll();
-        for (SysDictType dictType : dictTypeList) {
-            List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dictType.getDictType());
-            DictUtils.setDictCache(dictType.getDictType(), dictDatas);
-        }
-    }
-
-    /**
-     * 清空字典缓存数据
-     */
-    @Override
-    public void clearDictCache() {
-        DictUtils.clearDictCache();
-    }
-
-    /**
-     * 重置字典缓存数据
-     */
-    @Override
-    public void resetDictCache() {
-        clearDictCache();
-        loadingDictCache();
-    }
-
-    /**
-     * 新增保存字典类型信息
-     *
-     * @param dict 字典类型信息
-     * @return 结果
-     */
-    @Override
-    public int insertDictType(SysDictType dict) {
-        int row = dictTypeMapper.insertDictType(dict);
-        if (row > 0) {
-            DictUtils.setDictCache(dict.getDictType(), null);
-        }
-        return row;
-    }
-
-    /**
-     * 修改保存字典类型信息
-     *
-     * @param dict 字典类型信息
-     * @return 结果
-     */
-    @Override
-    @Transactional
-    public int updateDictType(SysDictType dict) {
-        SysDictType oldDict = dictTypeMapper.selectDictTypeById(dict.getDictId());
-        dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType());
-        int row = dictTypeMapper.updateDictType(dict);
-        if (row > 0) {
-            List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType());
-            DictUtils.setDictCache(dict.getDictType(), dictDatas);
-        }
-        return row;
-    }
-
-    /**
-     * 校验字典类型称是否唯一
-     *
-     * @param dict 字典类型
-     * @return 结果
-     */
-    @Override
-    public String checkDictTypeUnique(SysDictType dict) {
-        Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId();
-        SysDictType dictType = dictTypeMapper.checkDictTypeUnique(dict.getDictType());
-        if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) {
-            return UserConstants.NOT_UNIQUE;
-        }
-        return UserConstants.UNIQUE;
-    }
-}
+package com.ruoyi.system.service.impl;
+
+import com.ruoyi.common.core.constant.UserConstants;
+import com.ruoyi.common.core.exception.ServiceException;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.dict.utils.DictUtils;
+import com.ruoyi.system.api.domain.SysDictData;
+import com.ruoyi.system.api.domain.SysDictType;
+import com.ruoyi.system.mapper.SysDictDataMapper;
+import com.ruoyi.system.mapper.SysDictTypeMapper;
+import com.ruoyi.system.service.ISysDictTypeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 字典 业务层处理
+ *
+ * @author ruoyi
+ */
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@Service
+public class SysDictTypeServiceImpl implements ISysDictTypeService {
+
+    private final SysDictTypeMapper dictTypeMapper;
+    private final SysDictDataMapper dictDataMapper;
+
+    /**
+     * 项目启动时,初始化字典到缓存
+     */
+    @PostConstruct
+    public void init() {
+        loadingDictCache();
+    }
+
+    /**
+     * 根据条件分页查询字典类型
+     *
+     * @param dictType 字典类型信息
+     * @return 字典类型集合信息
+     */
+    @Override
+    public List<SysDictType> selectDictTypeList(SysDictType dictType) {
+        return dictTypeMapper.selectDictTypeList(dictType);
+    }
+
+    /**
+     * 根据所有字典类型
+     *
+     * @return 字典类型集合信息
+     */
+    @Override
+    public List<SysDictType> selectDictTypeAll() {
+        return dictTypeMapper.selectDictTypeAll();
+    }
+
+    /**
+     * 根据字典类型查询字典数据
+     *
+     * @param dictType 字典类型
+     * @return 字典数据集合信息
+     */
+    @Override
+    public List<SysDictData> selectDictDataByType(String dictType) {
+        List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
+        if (StringUtils.isNotEmpty(dictDatas)) {
+            return dictDatas;
+        }
+        dictDatas = dictDataMapper.selectDictDataByType(dictType);
+        if (StringUtils.isNotEmpty(dictDatas)) {
+            DictUtils.setDictCache(dictType, dictDatas);
+            return dictDatas;
+        }
+        return null;
+    }
+
+    /**
+     * 根据字典类型ID查询信息
+     *
+     * @param dictId 字典类型ID
+     * @return 字典类型
+     */
+    @Override
+    public SysDictType selectDictTypeById(Long dictId) {
+        return dictTypeMapper.selectDictTypeById(dictId);
+    }
+
+    /**
+     * 根据字典类型查询信息
+     *
+     * @param dictType 字典类型
+     * @return 字典类型
+     */
+    @Override
+    public SysDictType selectDictTypeByType(String dictType) {
+        return dictTypeMapper.selectDictTypeByType(dictType);
+    }
+
+    /**
+     * 批量删除字典类型信息
+     *
+     * @param dictIds 需要删除的字典ID
+     * @return 结果
+     */
+    @Override
+    public void deleteDictTypeByIds(Long[] dictIds) {
+        for (Long dictId : dictIds) {
+            SysDictType dictType = selectDictTypeById(dictId);
+            if (dictDataMapper.countDictDataByType(dictType.getDictType()) > 0) {
+                throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
+            }
+            dictTypeMapper.deleteDictTypeById(dictId);
+            DictUtils.removeDictCache(dictType.getDictType());
+        }
+    }
+
+    /**
+     * 加载字典缓存数据
+     */
+    @Override
+    public void loadingDictCache() {
+        SysDictData dictData = new SysDictData();
+        dictData.setStatus("0");
+        Map<String, List<SysDictData>> dictDataMap = dictDataMapper.selectDictDataList(dictData).stream().collect(Collectors.groupingBy(SysDictData::getDictType));
+        for (Map.Entry<String, List<SysDictData>> entry : dictDataMap.entrySet()) {
+            DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList()));
+        }
+    }
+
+    /**
+     * 清空字典缓存数据
+     */
+    @Override
+    public void clearDictCache() {
+        DictUtils.clearDictCache();
+    }
+
+    /**
+     * 重置字典缓存数据
+     */
+    @Override
+    public void resetDictCache() {
+        clearDictCache();
+        loadingDictCache();
+    }
+
+    /**
+     * 新增保存字典类型信息
+     *
+     * @param dict 字典类型信息
+     * @return 结果
+     */
+    @Override
+    public int insertDictType(SysDictType dict) {
+        int row = dictTypeMapper.insertDictType(dict);
+        if (row > 0) {
+            DictUtils.setDictCache(dict.getDictType(), null);
+        }
+        return row;
+    }
+
+    /**
+     * 修改保存字典类型信息
+     *
+     * @param dict 字典类型信息
+     * @return 结果
+     */
+    @Override
+    @Transactional
+    public int updateDictType(SysDictType dict) {
+        SysDictType oldDict = dictTypeMapper.selectDictTypeById(dict.getDictId());
+        dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType());
+        int row = dictTypeMapper.updateDictType(dict);
+        if (row > 0) {
+            List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType());
+            DictUtils.setDictCache(dict.getDictType(), dictDatas);
+        }
+        return row;
+    }
+
+    /**
+     * 校验字典类型称是否唯一
+     *
+     * @param dict 字典类型
+     * @return 结果
+     */
+    @Override
+    public String checkDictTypeUnique(SysDictType dict) {
+        Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId();
+        SysDictType dictType = dictTypeMapper.checkDictTypeUnique(dict.getDictType());
+        if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) {
+            return UserConstants.NOT_UNIQUE;
+        }
+        return UserConstants.UNIQUE;
+    }
+}

+ 1 - 1
ruoyi-ui/src/views/login.vue

@@ -56,7 +56,7 @@
     </el-form>
     <!--  底部  -->
     <div class="el-login-footer">
-      <span>Copyright © 2018-2021 ruoyi.vip All Rights Reserved.</span>
+      <span>Copyright © 2018-2022 ruoyi.vip All Rights Reserved.</span>
     </div>
   </div>
 </template>

+ 1 - 1
ruoyi-ui/src/views/register.vue

@@ -61,7 +61,7 @@
     </el-form>
     <!--  底部  -->
     <div class="el-register-footer">
-      <span>Copyright © 2018-2021 ruoyi.vip All Rights Reserved.</span>
+      <span>Copyright © 2018-2022 ruoyi.vip All Rights Reserved.</span>
     </div>
   </div>
 </template>