Merge remote-tracking branch 'origin/master' into master
# Conflicts: # ruoyi-admin/src/main/resources/application-dev.yml # ruoyi-admin/src/main/resources/application-prod.yml
This commit is contained in:
commit
57e016d0f1
@ -9,6 +9,10 @@
|
|||||||
* 查看ruoyi-framework模块的pom.xml文件,根据注释更改依赖
|
* 查看ruoyi-framework模块的pom.xml文件,根据注释更改依赖
|
||||||
* 查看ruoyi-admin模块中的application.yml文件,根据注释更改配置
|
* 查看ruoyi-admin模块中的application.yml文件,根据注释更改配置
|
||||||
|
|
||||||
|
关于如何创建新模块
|
||||||
|
* 参考ruoyi-demo模块
|
||||||
|
* 需要改动: 父pom 与 admin模块pom
|
||||||
|
|
||||||
## 修改RuoYi功能
|
## 修改RuoYi功能
|
||||||
|
|
||||||
* ORM框架 使用 Mybatis-Plus 简化CRUD
|
* ORM框架 使用 Mybatis-Plus 简化CRUD
|
||||||
@ -17,16 +21,19 @@
|
|||||||
* 代码生成模板 改为适配 Mybatis-Plus 的代码
|
* 代码生成模板 改为适配 Mybatis-Plus 的代码
|
||||||
* 项目修改为 maven多环境配置
|
* 项目修改为 maven多环境配置
|
||||||
* 重磅更新 升级MybatisPlus 3.4.1 重写配置文件详细注释 更新所有插件
|
* 重磅更新 升级MybatisPlus 3.4.1 重写配置文件详细注释 更新所有插件
|
||||||
|
* 增加demo模块示例(给不会增加模块的小伙伴做参考)
|
||||||
* 同步升级 3.3
|
* 同步升级 3.3
|
||||||
|
|
||||||
## 平台简介
|
## 平台简介
|
||||||
|
|
||||||
|
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
|
||||||
|
|
||||||
* 前端采用Vue、Element UI。
|
* 前端采用Vue、Element UI。
|
||||||
* 后端采用Spring Boot、Spring Security、Redis & Jwt。
|
* 后端采用Spring Boot、Spring Security、Redis & Jwt。
|
||||||
* 权限认证使用Jwt,支持多终端认证系统。
|
* 权限认证使用Jwt,支持多终端认证系统。
|
||||||
* 支持加载动态权限菜单,多方式轻松权限控制。
|
* 支持加载动态权限菜单,多方式轻松权限控制。
|
||||||
* 高效率开发,使用代码生成器可以一键生成前后端代码。
|
* 高效率开发,使用代码生成器可以一键生成前后端代码。
|
||||||
* 提供了一个Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
|
* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast),Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
|
||||||
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
|
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
|
||||||
|
|
||||||
## 内置功能
|
## 内置功能
|
||||||
|
10
pom.xml
10
pom.xml
@ -43,7 +43,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
<version>2.1.18.RELEASE</version>
|
<version>2.2.12.RELEASE</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
@ -224,6 +224,13 @@
|
|||||||
<version>${ruoyi.version}</version>
|
<version>${ruoyi.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- demo模块 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.ruoyi</groupId>
|
||||||
|
<artifactId>ruoyi-demo</artifactId>
|
||||||
|
<version>${ruoyi.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
@ -234,6 +241,7 @@
|
|||||||
<module>ruoyi-quartz</module>
|
<module>ruoyi-quartz</module>
|
||||||
<module>ruoyi-generator</module>
|
<module>ruoyi-generator</module>
|
||||||
<module>ruoyi-common</module>
|
<module>ruoyi-common</module>
|
||||||
|
<module>ruoyi-demo</module>
|
||||||
</modules>
|
</modules>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
@ -66,6 +66,12 @@
|
|||||||
<artifactId>ruoyi-generator</artifactId>
|
<artifactId>ruoyi-generator</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- demo模块 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.ruoyi</groupId>
|
||||||
|
<artifactId>ruoyi-demo</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -149,7 +149,7 @@ public @interface Excel
|
|||||||
|
|
||||||
public enum ColumnType
|
public enum ColumnType
|
||||||
{
|
{
|
||||||
NUMERIC(0), STRING(1);
|
NUMERIC(0), STRING(1), IMAGE(2);
|
||||||
private final int value;
|
private final int value;
|
||||||
|
|
||||||
ColumnType(int value)
|
ColumnType(int value)
|
||||||
|
@ -29,8 +29,10 @@ public class GenConstants
|
|||||||
public static final String PARENT_MENU_NAME = "parentMenuName";
|
public static final String PARENT_MENU_NAME = "parentMenuName";
|
||||||
|
|
||||||
/** 数据库字符串类型 */
|
/** 数据库字符串类型 */
|
||||||
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2", "tinytext", "text",
|
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
|
||||||
"mediumtext", "longtext" };
|
|
||||||
|
/** 数据库文本类型 */
|
||||||
|
public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
|
||||||
|
|
||||||
/** 数据库时间类型 */
|
/** 数据库时间类型 */
|
||||||
public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
|
public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
|
||||||
|
@ -29,8 +29,8 @@ public class RepeatableFilter implements Filter
|
|||||||
throws IOException, ServletException
|
throws IOException, ServletException
|
||||||
{
|
{
|
||||||
ServletRequest requestWrapper = null;
|
ServletRequest requestWrapper = null;
|
||||||
if (request instanceof HttpServletRequest && StringUtils.equalsAnyIgnoreCase(request.getContentType(),
|
if (request instanceof HttpServletRequest
|
||||||
MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE))
|
&& StringUtils.equalsAnyIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE))
|
||||||
{
|
{
|
||||||
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
|
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,6 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
|
|||||||
public boolean isJsonRequest()
|
public boolean isJsonRequest()
|
||||||
{
|
{
|
||||||
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
|
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
|
||||||
return MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(header)
|
return MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(header);
|
||||||
|| MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(header);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -44,4 +44,33 @@ public class FileTypeUtils
|
|||||||
}
|
}
|
||||||
return fileName.substring(separatorIndex + 1).toLowerCase();
|
return fileName.substring(separatorIndex + 1).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件类型
|
||||||
|
*
|
||||||
|
* @param photoByte 文件字节码
|
||||||
|
* @return 后缀(不含".")
|
||||||
|
*/
|
||||||
|
public static String getFileExtendName(byte[] photoByte)
|
||||||
|
{
|
||||||
|
String strFileExtendName = "JPG";
|
||||||
|
if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
|
||||||
|
&& ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
|
||||||
|
{
|
||||||
|
strFileExtendName = "GIF";
|
||||||
|
}
|
||||||
|
else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
|
||||||
|
{
|
||||||
|
strFileExtendName = "JPG";
|
||||||
|
}
|
||||||
|
else if ((photoByte[0] == 66) && (photoByte[1] == 77))
|
||||||
|
{
|
||||||
|
strFileExtendName = "BMP";
|
||||||
|
}
|
||||||
|
else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
|
||||||
|
{
|
||||||
|
strFileExtendName = "PNG";
|
||||||
|
}
|
||||||
|
return strFileExtendName;
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
package com.ruoyi.common.utils.file;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import org.apache.poi.util.IOUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import com.ruoyi.common.config.RuoYiConfig;
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片处理工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class ImageUtils
|
||||||
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);
|
||||||
|
|
||||||
|
public static byte[] getImage(String imagePath)
|
||||||
|
{
|
||||||
|
InputStream is = getFile(imagePath);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return IOUtils.toByteArray(is);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.error("图片加载异常 {}", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IOUtils.closeQuietly(is);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputStream getFile(String imagePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] result = readFile(imagePath);
|
||||||
|
result = Arrays.copyOf(result, result.length);
|
||||||
|
return new ByteArrayInputStream(result);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.error("获取图片异常 {}", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取文件为字节数据
|
||||||
|
*
|
||||||
|
* @param key 地址
|
||||||
|
* @return 字节数据
|
||||||
|
*/
|
||||||
|
public static byte[] readFile(String url)
|
||||||
|
{
|
||||||
|
InputStream in = null;
|
||||||
|
ByteArrayOutputStream baos = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (url.startsWith("http"))
|
||||||
|
{
|
||||||
|
// 网络地址
|
||||||
|
URL urlObj = new URL(url);
|
||||||
|
URLConnection urlConnection = urlObj.openConnection();
|
||||||
|
urlConnection.setConnectTimeout(30 * 1000);
|
||||||
|
urlConnection.setReadTimeout(60 * 1000);
|
||||||
|
urlConnection.setDoInput(true);
|
||||||
|
in = urlConnection.getInputStream();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 本机地址
|
||||||
|
String localPath = RuoYiConfig.getProfile();
|
||||||
|
String downloadPath = localPath + StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX);
|
||||||
|
in = new FileInputStream(downloadPath);
|
||||||
|
}
|
||||||
|
return IOUtils.toByteArray(in);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.error("获取文件路径异常 {}", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IOUtils.closeQuietly(baos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -22,10 +22,12 @@ import org.apache.poi.ss.usermodel.BorderStyle;
|
|||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.CellStyle;
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
import org.apache.poi.ss.usermodel.CellType;
|
import org.apache.poi.ss.usermodel.CellType;
|
||||||
|
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||||
import org.apache.poi.ss.usermodel.DataValidation;
|
import org.apache.poi.ss.usermodel.DataValidation;
|
||||||
import org.apache.poi.ss.usermodel.DataValidationConstraint;
|
import org.apache.poi.ss.usermodel.DataValidationConstraint;
|
||||||
import org.apache.poi.ss.usermodel.DataValidationHelper;
|
import org.apache.poi.ss.usermodel.DataValidationHelper;
|
||||||
import org.apache.poi.ss.usermodel.DateUtil;
|
import org.apache.poi.ss.usermodel.DateUtil;
|
||||||
|
import org.apache.poi.ss.usermodel.Drawing;
|
||||||
import org.apache.poi.ss.usermodel.FillPatternType;
|
import org.apache.poi.ss.usermodel.FillPatternType;
|
||||||
import org.apache.poi.ss.usermodel.Font;
|
import org.apache.poi.ss.usermodel.Font;
|
||||||
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||||
@ -37,6 +39,7 @@ import org.apache.poi.ss.usermodel.Workbook;
|
|||||||
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||||
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
|
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -51,6 +54,8 @@ import com.ruoyi.common.exception.CustomException;
|
|||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.DictUtils;
|
import com.ruoyi.common.utils.DictUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.common.utils.file.FileTypeUtils;
|
||||||
|
import com.ruoyi.common.utils.file.ImageUtils;
|
||||||
import com.ruoyi.common.utils.reflect.ReflectUtils;
|
import com.ruoyi.common.utils.reflect.ReflectUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,16 +107,21 @@ public class ExcelUtil<T>
|
|||||||
*/
|
*/
|
||||||
private List<Object[]> fields;
|
private List<Object[]> fields;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大高度
|
||||||
|
*/
|
||||||
|
private short maxHeight;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统计列表
|
* 统计列表
|
||||||
*/
|
*/
|
||||||
private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
|
private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数字格式
|
* 数字格式
|
||||||
*/
|
*/
|
||||||
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
|
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实体对象
|
* 实体对象
|
||||||
*/
|
*/
|
||||||
@ -239,7 +249,15 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val = Convert.toStr(val);
|
String dateFormat = field.getAnnotation(Excel.class).dateFormat();
|
||||||
|
if (StringUtils.isNotEmpty(dateFormat))
|
||||||
|
{
|
||||||
|
val = DateUtils.parseDateToStr(dateFormat, (Date) val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val = Convert.toStr(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val)))
|
else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val)))
|
||||||
@ -521,6 +539,47 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value));
|
cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value));
|
||||||
}
|
}
|
||||||
|
else if (ColumnType.IMAGE == attr.cellType())
|
||||||
|
{
|
||||||
|
ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1),
|
||||||
|
cell.getRow().getRowNum() + 1);
|
||||||
|
String imagePath = Convert.toStr(value);
|
||||||
|
if (StringUtils.isNotEmpty(imagePath))
|
||||||
|
{
|
||||||
|
byte[] data = ImageUtils.getImage(imagePath);
|
||||||
|
getDrawingPatriarch(cell.getSheet()).createPicture(anchor,
|
||||||
|
cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取画布
|
||||||
|
*/
|
||||||
|
public static Drawing<?> getDrawingPatriarch(Sheet sheet)
|
||||||
|
{
|
||||||
|
if (sheet.getDrawingPatriarch() == null)
|
||||||
|
{
|
||||||
|
sheet.createDrawingPatriarch();
|
||||||
|
}
|
||||||
|
return sheet.getDrawingPatriarch();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取图片类型,设置图片插入类型
|
||||||
|
*/
|
||||||
|
public int getImageType(byte[] value)
|
||||||
|
{
|
||||||
|
String type = FileTypeUtils.getFileExtendName(value);
|
||||||
|
if ("JPG".equalsIgnoreCase(type))
|
||||||
|
{
|
||||||
|
return Workbook.PICTURE_TYPE_JPEG;
|
||||||
|
}
|
||||||
|
else if ("PNG".equalsIgnoreCase(type))
|
||||||
|
{
|
||||||
|
return Workbook.PICTURE_TYPE_PNG;
|
||||||
|
}
|
||||||
|
return Workbook.PICTURE_TYPE_JPEG;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -536,7 +595,6 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
// 设置列宽
|
// 设置列宽
|
||||||
sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
|
sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
|
||||||
row.setHeight((short) (attr.height() * 20));
|
|
||||||
}
|
}
|
||||||
// 如果设置了提示信息则鼠标放上去提示.
|
// 如果设置了提示信息则鼠标放上去提示.
|
||||||
if (StringUtils.isNotEmpty(attr.prompt()))
|
if (StringUtils.isNotEmpty(attr.prompt()))
|
||||||
@ -561,7 +619,7 @@ public class ExcelUtil<T>
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 设置行高
|
// 设置行高
|
||||||
row.setHeight((short) (attr.height() * 20));
|
row.setHeight(maxHeight);
|
||||||
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
|
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
|
||||||
if (attr.isExport())
|
if (attr.isExport())
|
||||||
{
|
{
|
||||||
@ -737,7 +795,7 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
return StringUtils.stripEnd(propertyString.toString(), separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析字典值
|
* 解析字典值
|
||||||
*
|
*
|
||||||
@ -763,7 +821,7 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
return DictUtils.getDictValue(dictType, dictLabel, separator);
|
return DictUtils.getDictValue(dictType, dictLabel, separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 合计统计信息
|
* 合计统计信息
|
||||||
*/
|
*/
|
||||||
@ -800,7 +858,7 @@ public class ExcelUtil<T>
|
|||||||
cell = row.createCell(0);
|
cell = row.createCell(0);
|
||||||
cell.setCellStyle(styles.get("total"));
|
cell.setCellStyle(styles.get("total"));
|
||||||
cell.setCellValue("合计");
|
cell.setCellValue("合计");
|
||||||
|
|
||||||
for (Integer key : keys)
|
for (Integer key : keys)
|
||||||
{
|
{
|
||||||
cell = row.createCell(key);
|
cell = row.createCell(key);
|
||||||
@ -916,6 +974,21 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList());
|
this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList());
|
||||||
|
this.maxHeight = getRowHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据注解获取最大行高
|
||||||
|
*/
|
||||||
|
public short getRowHeight()
|
||||||
|
{
|
||||||
|
double maxHeight = 0;
|
||||||
|
for (Object[] os : this.fields)
|
||||||
|
{
|
||||||
|
Excel excel = (Excel) os[1];
|
||||||
|
maxHeight = maxHeight > excel.height() ? maxHeight : excel.height();
|
||||||
|
}
|
||||||
|
return (short) (maxHeight * 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
28
ruoyi-demo/pom.xml
Normal file
28
ruoyi-demo/pom.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>ruoyi</artifactId>
|
||||||
|
<groupId>com.ruoyi</groupId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>ruoyi-demo</artifactId>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
demo模块
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- 通用工具-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.ruoyi</groupId>
|
||||||
|
<artifactId>ruoyi-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1 @@
|
|||||||
|
package com.ruoyi.demo.controller;
|
@ -0,0 +1 @@
|
|||||||
|
package com.ruoyi.demo.domain;
|
@ -0,0 +1 @@
|
|||||||
|
package com.ruoyi.demo.mapper;
|
@ -0,0 +1 @@
|
|||||||
|
package com.ruoyi.demo.service.impl;
|
@ -0,0 +1 @@
|
|||||||
|
package com.ruoyi.demo.service;
|
@ -8,8 +8,10 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
|
|||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* redis配置
|
* redis配置
|
||||||
@ -31,7 +33,7 @@ public class RedisConfig extends CachingConfigurerSupport
|
|||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||||
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||||
serializer.setObjectMapper(mapper);
|
serializer.setObjectMapper(mapper);
|
||||||
|
|
||||||
template.setValueSerializer(serializer);
|
template.setValueSerializer(serializer);
|
||||||
|
@ -40,13 +40,14 @@ public class GenUtils
|
|||||||
column.setCreateBy(table.getCreateBy());
|
column.setCreateBy(table.getCreateBy());
|
||||||
// 设置java字段名
|
// 设置java字段名
|
||||||
column.setJavaField(StringUtils.toCamelCase(columnName));
|
column.setJavaField(StringUtils.toCamelCase(columnName));
|
||||||
|
// 设置默认类型
|
||||||
|
column.setJavaType(GenConstants.TYPE_STRING);
|
||||||
|
|
||||||
if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType))
|
if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType))
|
||||||
{
|
{
|
||||||
column.setJavaType(GenConstants.TYPE_STRING);
|
|
||||||
// 字符串长度超过500设置为文本域
|
// 字符串长度超过500设置为文本域
|
||||||
Integer columnLength = getColumnLength(column.getColumnType());
|
Integer columnLength = getColumnLength(column.getColumnType());
|
||||||
String htmlType = columnLength >= 500 ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
|
String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
|
||||||
column.setHtmlType(htmlType);
|
column.setHtmlType(htmlType);
|
||||||
}
|
}
|
||||||
else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType))
|
else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType))
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
package ${packageName}.controller;
|
package ${packageName}.controller;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -49,98 +45,14 @@ public class ${ClassName}Controller extends BaseController {
|
|||||||
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')")
|
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
#if($table.crud)
|
#if($table.crud)
|
||||||
public TableDataInfo list(${ClassName} ${className})
|
public TableDataInfo list(${ClassName} ${className}) {
|
||||||
{
|
|
||||||
startPage();
|
startPage();
|
||||||
LambdaQueryWrapper<${ClassName}> lqw = Wrappers.lambdaQuery(${className});
|
List<${ClassName}> list = i${ClassName}Service.queryList(${className});
|
||||||
#foreach($column in $columns)
|
|
||||||
#set($queryType=$column.queryType)
|
|
||||||
#set($javaField=$column.javaField)
|
|
||||||
#set($javaType=$column.javaType)
|
|
||||||
#set($columnName=$column.columnName)
|
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
|
||||||
#if($column.query)
|
|
||||||
#if($column.queryType == "EQ")
|
|
||||||
#if($javaType == 'String')
|
|
||||||
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
|
||||||
lqw.eq(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (${className}.get$AttrName() != null){
|
|
||||||
lqw.eq(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
#elseif($queryType == "NE")
|
|
||||||
#if($javaType == 'String')
|
|
||||||
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
|
||||||
lqw.ne(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (${className}.get$AttrName() != null){
|
|
||||||
lqw.ne(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
#elseif($queryType == "GT")
|
|
||||||
#if($javaType == 'String')
|
|
||||||
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
|
||||||
lqw.gt(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (${className}.get$AttrName() != null){
|
|
||||||
lqw.gt(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
#elseif($queryType == "GTE")
|
|
||||||
#if($javaType == 'String')
|
|
||||||
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
|
||||||
lqw.ge(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (${className}.get$AttrName() != null){
|
|
||||||
lqw.ge(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
#elseif($queryType == "LT")
|
|
||||||
#if($javaType == 'String')
|
|
||||||
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
|
||||||
lqw.lt(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (${className}.get$AttrName() != null){
|
|
||||||
lqw.lt(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
#elseif($queryType == "LTE")
|
|
||||||
#if($javaType == 'String')
|
|
||||||
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
|
||||||
lqw.le(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (${className}.get$AttrName() != null){
|
|
||||||
lqw.le(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
#elseif($queryType == "LIKE")
|
|
||||||
#if($javaType == 'String')
|
|
||||||
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
|
||||||
lqw.like(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (${className}.get$AttrName() != null){
|
|
||||||
lqw.like(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
#elseif($queryType == "BETWEEN")
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
List<${ClassName}> list = i${ClassName}Service.list(lqw);
|
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
#elseif($table.tree)
|
#elseif($table.tree)
|
||||||
public AjaxResult list(${ClassName} ${className}) {
|
public AjaxResult list(${ClassName} ${className}) {
|
||||||
LambdaQueryWrapper<${ClassName}> lqw = Wrappers.lambdaQuery(${className});
|
List<${ClassName}> list = i${ClassName}Service.queryList(${className});
|
||||||
List<${ClassName}> list = i${ClassName}Service.list(lqw);
|
|
||||||
return AjaxResult.success(list);
|
return AjaxResult.success(list);
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
@ -152,9 +64,8 @@ public class ${ClassName}Controller extends BaseController {
|
|||||||
@Log(title = "${functionName}" , businessType = BusinessType.EXPORT)
|
@Log(title = "${functionName}" , businessType = BusinessType.EXPORT)
|
||||||
@GetMapping("/export" )
|
@GetMapping("/export" )
|
||||||
public AjaxResult export(${ClassName} ${className}) {
|
public AjaxResult export(${ClassName} ${className}) {
|
||||||
LambdaQueryWrapper<${ClassName}> lqw = new LambdaQueryWrapper<${ClassName}>(${className});
|
List<${ClassName}> list = i${ClassName}Service.queryList(${className});
|
||||||
List<${ClassName}> list = i${ClassName}Service.list(lqw);
|
ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class);
|
||||||
ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}. class);
|
|
||||||
return util.exportExcel(list, "${businessName}" );
|
return util.exportExcel(list, "${businessName}" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,14 +10,12 @@ import com.ruoyi.common.annotation.Excel;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
#if($table.crud)
|
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
|
||||||
#elseif($table.tree)
|
|
||||||
import com.ruoyi.common.core.domain.TreeEntity;
|
|
||||||
#end
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ${functionName}对象 ${tableName}
|
* ${functionName}对象 ${tableName}
|
||||||
@ -25,11 +23,6 @@ import com.ruoyi.common.core.domain.TreeEntity;
|
|||||||
* @author ${author}
|
* @author ${author}
|
||||||
* @date ${datetime}
|
* @date ${datetime}
|
||||||
*/
|
*/
|
||||||
#if($table.crud)
|
|
||||||
#set($Entity="BaseEntity")
|
|
||||||
#elseif($table.tree)
|
|
||||||
#set($Entity="TreeEntity")
|
|
||||||
#end
|
|
||||||
@Data
|
@Data
|
||||||
@ToString
|
@ToString
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@ -66,4 +59,7 @@ private static final long serialVersionUID=1L;
|
|||||||
private $column.javaType $column.javaField;
|
private $column.javaType $column.javaField;
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Map<String, Object> params = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package ${packageName}.service;
|
|||||||
|
|
||||||
import ${packageName}.domain.${ClassName};
|
import ${packageName}.domain.${ClassName};
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ${functionName}Service接口
|
* ${functionName}Service接口
|
||||||
@ -11,4 +12,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||||||
*/
|
*/
|
||||||
public interface I${ClassName}Service extends IService<${ClassName}> {
|
public interface I${ClassName}Service extends IService<${ClassName}> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询列表
|
||||||
|
*/
|
||||||
|
List<${ClassName}> queryList(${ClassName} ${className});
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,16 @@ package ${packageName}.service.impl;
|
|||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import ${packageName}.mapper.${ClassName}Mapper;
|
import ${packageName}.mapper.${ClassName}Mapper;
|
||||||
import ${packageName}.domain.${ClassName};
|
import ${packageName}.domain.${ClassName};
|
||||||
import ${packageName}.service.I${ClassName}Service;
|
import ${packageName}.service.I${ClassName}Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ${functionName}Service业务层处理
|
* ${functionName}Service业务层处理
|
||||||
*
|
*
|
||||||
@ -15,4 +21,94 @@ import ${packageName}.service.I${ClassName}Service;
|
|||||||
@Service
|
@Service
|
||||||
public class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}> implements I${ClassName}Service {
|
public class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}> implements I${ClassName}Service {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<${ClassName}> queryList(${ClassName} ${className}) {
|
||||||
|
LambdaQueryWrapper<${ClassName}> lqw = Wrappers.lambdaQuery();
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#set($queryType=$column.queryType)
|
||||||
|
#set($javaField=$column.javaField)
|
||||||
|
#set($javaType=$column.javaType)
|
||||||
|
#set($columnName=$column.columnName)
|
||||||
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#if($column.query)
|
||||||
|
#if($column.queryType == "EQ")
|
||||||
|
#if($javaType == 'String')
|
||||||
|
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
||||||
|
lqw.eq(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (${className}.get$AttrName() != null){
|
||||||
|
lqw.eq(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#elseif($queryType == "NE")
|
||||||
|
#if($javaType == 'String')
|
||||||
|
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
||||||
|
lqw.ne(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (${className}.get$AttrName() != null){
|
||||||
|
lqw.ne(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#elseif($queryType == "GT")
|
||||||
|
#if($javaType == 'String')
|
||||||
|
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
||||||
|
lqw.gt(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (${className}.get$AttrName() != null){
|
||||||
|
lqw.gt(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#elseif($queryType == "GTE")
|
||||||
|
#if($javaType == 'String')
|
||||||
|
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
||||||
|
lqw.ge(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (${className}.get$AttrName() != null){
|
||||||
|
lqw.ge(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#elseif($queryType == "LT")
|
||||||
|
#if($javaType == 'String')
|
||||||
|
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
||||||
|
lqw.lt(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (${className}.get$AttrName() != null){
|
||||||
|
lqw.lt(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#elseif($queryType == "LTE")
|
||||||
|
#if($javaType == 'String')
|
||||||
|
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
||||||
|
lqw.le(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (${className}.get$AttrName() != null){
|
||||||
|
lqw.le(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#elseif($queryType == "LIKE")
|
||||||
|
#if($javaType == 'String')
|
||||||
|
if (StringUtils.isNotBlank(${className}.get$AttrName())){
|
||||||
|
lqw.like(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (${className}.get$AttrName() != null){
|
||||||
|
lqw.like(${ClassName}::get$AttrName ,${className}.get$AttrName());
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#elseif($queryType == "BETWEEN")
|
||||||
|
Map<String, Object> params = ${className}.getParams();
|
||||||
|
if (params.get("begin$AttrName") != null && params.get("end$AttrName") != null) {
|
||||||
|
lqw.between(${ClassName}::get$AttrName ,params.get("begin$AttrName"),params.get("end$AttrName"));
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
return this.list(lqw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,15 +38,28 @@
|
|||||||
<el-option label="请选择字典生成" value="" />
|
<el-option label="请选择字典生成" value="" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "datetime")
|
#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
|
||||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||||
<el-date-picker clearable size="small" style="width: 200px"
|
<el-date-picker clearable size="small"
|
||||||
v-model="queryParams.${column.javaField}"
|
v-model="queryParams.${column.javaField}"
|
||||||
type="date"
|
type="date"
|
||||||
value-format="yyyy-MM-dd"
|
value-format="yyyy-MM-dd"
|
||||||
placeholder="选择${comment}">
|
placeholder="选择${comment}">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="daterange${AttrName}"
|
||||||
|
size="small"
|
||||||
|
style="width: 240px"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
@ -201,7 +214,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "datetime")
|
#elseif($column.htmlType == "datetime")
|
||||||
<el-form-item label="${comment}" prop="${field}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-date-picker clearable size="small" style="width: 200px"
|
<el-date-picker clearable size="small"
|
||||||
v-model="form.${field}"
|
v-model="form.${field}"
|
||||||
type="date"
|
type="date"
|
||||||
value-format="yyyy-MM-dd"
|
value-format="yyyy-MM-dd"
|
||||||
@ -283,6 +296,10 @@ export default {
|
|||||||
#if(${column.dictType} != '')
|
#if(${column.dictType} != '')
|
||||||
// $comment字典
|
// $comment字典
|
||||||
${column.javaField}Options: [],
|
${column.javaField}Options: [],
|
||||||
|
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
// $comment时间范围
|
||||||
|
daterange${AttrName}: [],
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
// 查询参数
|
// 查询参数
|
||||||
@ -329,6 +346,21 @@ export default {
|
|||||||
/** 查询${functionName}列表 */
|
/** 查询${functionName}列表 */
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
|
this.queryParams.params = {};
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
if (null != this.daterange${AttrName} && '' != this.daterange${AttrName}) {
|
||||||
|
this.queryParams.params["begin${AttrName}"] = this.daterange${AttrName}[0];
|
||||||
|
this.queryParams.params["end${AttrName}"] = this.daterange${AttrName}[1];
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
list${BusinessName}(this.queryParams).then(response => {
|
list${BusinessName}(this.queryParams).then(response => {
|
||||||
this.${businessName}List = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
|
this.${businessName}List = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
@ -397,6 +429,12 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
this.daterange${AttrName} = [];
|
||||||
|
#end
|
||||||
|
#end
|
||||||
this.resetForm("queryForm");
|
this.resetForm("queryForm");
|
||||||
this.handleQuery();
|
this.handleQuery();
|
||||||
},
|
},
|
||||||
|
@ -38,15 +38,28 @@
|
|||||||
<el-option label="请选择字典生成" value="" />
|
<el-option label="请选择字典生成" value="" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "datetime")
|
#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
|
||||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||||
<el-date-picker clearable size="small" style="width: 200px"
|
<el-date-picker clearable size="small"
|
||||||
v-model="queryParams.${column.javaField}"
|
v-model="queryParams.${column.javaField}"
|
||||||
type="date"
|
type="date"
|
||||||
value-format="yyyy-MM-dd"
|
value-format="yyyy-MM-dd"
|
||||||
placeholder="选择${comment}">
|
placeholder="选择${comment}">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="daterange${AttrName}"
|
||||||
|
size="small"
|
||||||
|
style="width: 240px"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
@ -95,7 +108,7 @@
|
|||||||
v-hasPermi="['${moduleName}:${businessName}:export']"
|
v-hasPermi="['${moduleName}:${businessName}:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="${businessName}List" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="${businessName}List" @selection-change="handleSelectionChange">
|
||||||
@ -230,7 +243,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "datetime")
|
#elseif($column.htmlType == "datetime")
|
||||||
<el-form-item label="${comment}" prop="${field}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-date-picker clearable size="small" style="width: 200px"
|
<el-date-picker clearable size="small"
|
||||||
v-model="form.${field}"
|
v-model="form.${field}"
|
||||||
type="date"
|
type="date"
|
||||||
value-format="yyyy-MM-dd"
|
value-format="yyyy-MM-dd"
|
||||||
@ -315,6 +328,10 @@ export default {
|
|||||||
#if(${column.dictType} != '')
|
#if(${column.dictType} != '')
|
||||||
// $comment字典
|
// $comment字典
|
||||||
${column.javaField}Options: [],
|
${column.javaField}Options: [],
|
||||||
|
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
// $comment时间范围
|
||||||
|
daterange${AttrName}: [],
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
// 查询参数
|
// 查询参数
|
||||||
@ -363,6 +380,21 @@ export default {
|
|||||||
/** 查询${functionName}列表 */
|
/** 查询${functionName}列表 */
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
|
this.queryParams.params = {};
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
if (null != this.daterange${AttrName} && '' != this.daterange${AttrName}) {
|
||||||
|
this.queryParams.params["begin${AttrName}"] = this.daterange${AttrName}[0];
|
||||||
|
this.queryParams.params["end${AttrName}"] = this.daterange${AttrName}[1];
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
list${BusinessName}(this.queryParams).then(response => {
|
list${BusinessName}(this.queryParams).then(response => {
|
||||||
this.${businessName}List = response.rows;
|
this.${businessName}List = response.rows;
|
||||||
this.total = response.total;
|
this.total = response.total;
|
||||||
@ -413,6 +445,12 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
this.daterange${AttrName} = [];
|
||||||
|
#end
|
||||||
|
#end
|
||||||
this.resetForm("queryForm");
|
this.resetForm("queryForm");
|
||||||
this.handleQuery();
|
this.handleQuery();
|
||||||
},
|
},
|
||||||
|
@ -131,7 +131,7 @@
|
|||||||
<if test="parentId != null">parent_id = #{parentId},</if>
|
<if test="parentId != null">parent_id = #{parentId},</if>
|
||||||
<if test="orderNum != null and orderNum != ''">order_num = #{orderNum},</if>
|
<if test="orderNum != null and orderNum != ''">order_num = #{orderNum},</if>
|
||||||
<if test="path != null and path != ''">path = #{path},</if>
|
<if test="path != null and path != ''">path = #{path},</if>
|
||||||
<if test="component != null and component != ''">component = #{component},</if>
|
<if test="component != null">component = #{component},</if>
|
||||||
<if test="isFrame != null and isFrame != ''">is_frame = #{isFrame},</if>
|
<if test="isFrame != null and isFrame != ''">is_frame = #{isFrame},</if>
|
||||||
<if test="isCache != null and isCache != ''">is_cache = #{isCache},</if>
|
<if test="isCache != null and isCache != ''">is_cache = #{isCache},</if>
|
||||||
<if test="menuType != null and menuType != ''">menu_type = #{menuType},</if>
|
<if test="menuType != null and menuType != ''">menu_type = #{menuType},</if>
|
||||||
|
@ -141,8 +141,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="deptId != null and deptId != 0">dept_id = #{deptId},</if>
|
<if test="deptId != null and deptId != 0">dept_id = #{deptId},</if>
|
||||||
<if test="userName != null and userName != ''">user_name = #{userName},</if>
|
<if test="userName != null and userName != ''">user_name = #{userName},</if>
|
||||||
<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
|
<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
|
||||||
<if test="email != null and email != ''">email = #{email},</if>
|
<if test="email != null ">email = #{email},</if>
|
||||||
<if test="phonenumber != null and phonenumber != ''">phonenumber = #{phonenumber},</if>
|
<if test="phonenumber != null ">phonenumber = #{phonenumber},</if>
|
||||||
<if test="sex != null and sex != ''">sex = #{sex},</if>
|
<if test="sex != null and sex != ''">sex = #{sex},</if>
|
||||||
<if test="avatar != null and avatar != ''">avatar = #{avatar},</if>
|
<if test="avatar != null and avatar != ''">avatar = #{avatar},</if>
|
||||||
<if test="password != null and password != ''">password = #{password},</if>
|
<if test="password != null and password != ''">password = #{password},</if>
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
"js-cookie": "2.2.1",
|
"js-cookie": "2.2.1",
|
||||||
"jsencrypt": "3.0.0-rc.1",
|
"jsencrypt": "3.0.0-rc.1",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"path-to-regexp": "6.2.0",
|
|
||||||
"quill": "1.3.7",
|
"quill": "1.3.7",
|
||||||
"screenfull": "5.0.2",
|
"screenfull": "5.0.2",
|
||||||
"sortablejs": "1.10.2",
|
"sortablejs": "1.10.2",
|
||||||
|
@ -10,8 +10,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import pathToRegexp from 'path-to-regexp'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -49,18 +47,13 @@ export default {
|
|||||||
}
|
}
|
||||||
return name.trim() === '首页'
|
return name.trim() === '首页'
|
||||||
},
|
},
|
||||||
pathCompile(path) {
|
|
||||||
const { params } = this.$route
|
|
||||||
var toPath = pathToRegexp.compile(path)
|
|
||||||
return toPath(params)
|
|
||||||
},
|
|
||||||
handleLink(item) {
|
handleLink(item) {
|
||||||
const { redirect, path } = item
|
const { redirect, path } = item
|
||||||
if (redirect) {
|
if (redirect) {
|
||||||
this.$router.push(redirect)
|
this.$router.push(redirect)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$router.push(this.pathCompile(path))
|
this.$router.push(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
<!-- @author ruoyi 20201128 支持三级以上菜单缓存 -->
|
|
||||||
<template>
|
<template>
|
||||||
<section class="app-main">
|
<section class="app-main">
|
||||||
<transition name="fade-transform" mode="out-in">
|
<transition name="fade-transform" mode="out-in">
|
||||||
<keep-alive :max="20" :exclude="notCacheName">
|
<keep-alive :include="cachedViews">
|
||||||
<router-view :key="key" />
|
<router-view :key="key" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
@ -10,119 +9,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Global from "@/layout/components/global.js";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AppMain',
|
name: 'AppMain',
|
||||||
computed: {
|
computed: {
|
||||||
notCacheName() {
|
cachedViews() {
|
||||||
var visitedViews = this.$store.state.tagsView.visitedViews;
|
return this.$store.state.tagsView.cachedViews
|
||||||
var noCacheViews = [];
|
|
||||||
Object.keys(visitedViews).some((index) => {
|
|
||||||
if (visitedViews[index].meta.noCache) {
|
|
||||||
noCacheViews.push(visitedViews[index].name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return noCacheViews;
|
|
||||||
},
|
},
|
||||||
key() {
|
key() {
|
||||||
return this.$route.path;
|
return this.$route.path
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
mounted() {
|
}
|
||||||
// 关闭标签触发
|
|
||||||
Global.$on("removeCache", (name, view) => {
|
|
||||||
this.removeCache(name, view);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 获取有keep-alive子节点的Vnode
|
|
||||||
getVnode() {
|
|
||||||
// 判断子集非空
|
|
||||||
if (this.$children.length == 0) return false;
|
|
||||||
let vnode;
|
|
||||||
for (let item of this.$children) {
|
|
||||||
// 如果data中有key则代表找到了keep-alive下面的子集,这个key就是router-view上的key
|
|
||||||
if (item.$vnode.data.key) {
|
|
||||||
vnode = item.$vnode;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return vnode ? vnode : false;
|
|
||||||
},
|
|
||||||
// 移除keep-alive缓存
|
|
||||||
removeCache(name, view = {}) {
|
|
||||||
let vnode = this.getVnode();
|
|
||||||
if (!vnode) return false;
|
|
||||||
let componentInstance = vnode.parent.componentInstance;
|
|
||||||
// 这个key是用来获取前缀用来后面正则匹配用的
|
|
||||||
let keyStart = vnode.key.split("/")[0];
|
|
||||||
let thisKey = `${keyStart}${view.fullPath}`;
|
|
||||||
let regKey = `${keyStart}${view.path}`;
|
|
||||||
|
|
||||||
this[name]({ componentInstance, thisKey, regKey });
|
|
||||||
},
|
|
||||||
// 移除其他
|
|
||||||
closeOthersTags({ componentInstance, thisKey }) {
|
|
||||||
Object.keys(componentInstance.cache).forEach((key, index) => {
|
|
||||||
if (key != thisKey) {
|
|
||||||
// 销毁实例(这里存在多个key指向一个缓存的情况可能前面一个已经清除掉了所有要加判断)
|
|
||||||
if (componentInstance.cache[key]) {
|
|
||||||
componentInstance.cache[key].componentInstance.$destroy();
|
|
||||||
}
|
|
||||||
// 删除缓存
|
|
||||||
delete componentInstance.cache[key];
|
|
||||||
// 移除key中对应的key
|
|
||||||
componentInstance.keys.splice(index, 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 移除所有缓存
|
|
||||||
closeAllTags({ componentInstance }) {
|
|
||||||
// 销毁实例
|
|
||||||
Object.keys(componentInstance.cache).forEach((key) => {
|
|
||||||
if (componentInstance.cache[key]) {
|
|
||||||
componentInstance.cache[key].componentInstance.$destroy();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 删除缓存
|
|
||||||
componentInstance.cache = {};
|
|
||||||
// 移除key中对应的key
|
|
||||||
componentInstance.keys = [];
|
|
||||||
},
|
|
||||||
// 移除单个缓存
|
|
||||||
closeSelectedTag({ componentInstance, regKey }) {
|
|
||||||
let reg = new RegExp(`^${regKey}`);
|
|
||||||
Object.keys(componentInstance.cache).forEach((key, i) => {
|
|
||||||
if (reg.test(key)) {
|
|
||||||
// 销毁实例
|
|
||||||
if (componentInstance.cache[key]) {
|
|
||||||
componentInstance.cache[key].componentInstance.$destroy();
|
|
||||||
}
|
|
||||||
// 删除缓存
|
|
||||||
delete componentInstance.cache[key];
|
|
||||||
// 移除key中对应的key
|
|
||||||
componentInstance.keys.splice(i, 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 刷新单个缓存
|
|
||||||
refreshSelectedTag({ componentInstance, thisKey }) {
|
|
||||||
Object.keys(componentInstance.cache).forEach((key, index) => {
|
|
||||||
if (null != thisKey && key.replace("/redirect", "") == thisKey) {
|
|
||||||
// 1 销毁实例(这里存在多个key指向一个缓存的情况可能前面一个已经清除掉了所有要加判断)
|
|
||||||
if (componentInstance.cache[key]) {
|
|
||||||
componentInstance.cache[key].componentInstance.$destroy();
|
|
||||||
}
|
|
||||||
// 2 删除缓存
|
|
||||||
delete componentInstance.cache[key];
|
|
||||||
// 3 移除key中对应的key
|
|
||||||
componentInstance.keys.splice(index, 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -134,7 +31,7 @@ export default {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fixed-header + .app-main {
|
.fixed-header+.app-main {
|
||||||
padding-top: 50px;
|
padding-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +41,7 @@ export default {
|
|||||||
min-height: calc(100vh - 84px);
|
min-height: calc(100vh - 84px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.fixed-header + .app-main {
|
.fixed-header+.app-main {
|
||||||
padding-top: 84px;
|
padding-top: 84px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
mode="vertical"
|
mode="vertical"
|
||||||
>
|
>
|
||||||
<sidebar-item
|
<sidebar-item
|
||||||
v-for="(route, index) in permission_routes"
|
v-for="(route, index) in sidebarRouters"
|
||||||
:key="route.path + index"
|
:key="route.path + index"
|
||||||
:item="route"
|
:item="route"
|
||||||
:base-path="route.path"
|
:base-path="route.path"
|
||||||
@ -33,7 +33,7 @@ export default {
|
|||||||
components: { SidebarItem, Logo },
|
components: { SidebarItem, Logo },
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["settings"]),
|
...mapState(["settings"]),
|
||||||
...mapGetters(["permission_routes", "sidebar"]),
|
...mapGetters(["sidebarRouters", "sidebar"]),
|
||||||
activeMenu() {
|
activeMenu() {
|
||||||
const route = this.$route;
|
const route = this.$route;
|
||||||
const { meta, path } = route;
|
const { meta, path } = route;
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import ScrollPane from './ScrollPane'
|
import ScrollPane from './ScrollPane'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import Global from "@/layout/components/global.js";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ScrollPane },
|
components: { ScrollPane },
|
||||||
@ -145,7 +144,6 @@ export default {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Global.$emit("removeCache", "refreshSelectedTag", this.selectedTag);
|
|
||||||
},
|
},
|
||||||
closeSelectedTag(view) {
|
closeSelectedTag(view) {
|
||||||
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
|
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
|
||||||
@ -153,14 +151,12 @@ export default {
|
|||||||
this.toLastView(visitedViews, view)
|
this.toLastView(visitedViews, view)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Global.$emit("removeCache", "closeSelectedTag", view);
|
|
||||||
},
|
},
|
||||||
closeOthersTags() {
|
closeOthersTags() {
|
||||||
this.$router.push(this.selectedTag)
|
this.$router.push(this.selectedTag)
|
||||||
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
|
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
|
||||||
this.moveToCurrentTag()
|
this.moveToCurrentTag()
|
||||||
})
|
})
|
||||||
Global.$emit("removeCache", "closeOthersTags", this.selectedTag);
|
|
||||||
},
|
},
|
||||||
closeAllTags(view) {
|
closeAllTags(view) {
|
||||||
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
|
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
|
||||||
@ -169,7 +165,6 @@ export default {
|
|||||||
}
|
}
|
||||||
this.toLastView(visitedViews, view)
|
this.toLastView(visitedViews, view)
|
||||||
})
|
})
|
||||||
Global.$emit("removeCache", "closeAllTags");
|
|
||||||
},
|
},
|
||||||
toLastView(visitedViews, view) {
|
toLastView(visitedViews, view) {
|
||||||
const latestView = visitedViews.slice(-1)[0]
|
const latestView = visitedViews.slice(-1)[0]
|
||||||
|
@ -23,28 +23,18 @@ router.beforeEach((to, from, next) => {
|
|||||||
// 拉取user_info
|
// 拉取user_info
|
||||||
const roles = res.roles
|
const roles = res.roles
|
||||||
store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => {
|
store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => {
|
||||||
// 测试 默认静态页面
|
|
||||||
// store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => {
|
|
||||||
// 根据roles权限生成可访问的路由表
|
// 根据roles权限生成可访问的路由表
|
||||||
router.addRoutes(accessRoutes) // 动态添加可访问路由表
|
router.addRoutes(accessRoutes) // 动态添加可访问路由表
|
||||||
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
||||||
})
|
})
|
||||||
})
|
}).catch(err => {
|
||||||
.catch(err => {
|
store.dispatch('LogOut').then(() => {
|
||||||
store.dispatch('FedLogOut').then(() => {
|
|
||||||
Message.error(err)
|
Message.error(err)
|
||||||
next({ path: '/' })
|
next({ path: '/' })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
// 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
|
|
||||||
// if (hasPermission(store.getters.roles, to.meta.roles)) {
|
|
||||||
// next()
|
|
||||||
// } else {
|
|
||||||
// next({ path: '/401', replace: true, query: { noGoBack: true }})
|
|
||||||
// }
|
|
||||||
// 可删 ↑
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -10,6 +10,7 @@ const getters = {
|
|||||||
introduction: state => state.user.introduction,
|
introduction: state => state.user.introduction,
|
||||||
roles: state => state.user.roles,
|
roles: state => state.user.roles,
|
||||||
permissions: state => state.user.permissions,
|
permissions: state => state.user.permissions,
|
||||||
permission_routes: state => state.permission.routes
|
permission_routes: state => state.permission.routes,
|
||||||
|
sidebarRouters:state => state.permission.sidebarRouters,
|
||||||
}
|
}
|
||||||
export default getters
|
export default getters
|
||||||
|
@ -6,13 +6,17 @@ import ParentView from '@/components/ParentView';
|
|||||||
const permission = {
|
const permission = {
|
||||||
state: {
|
state: {
|
||||||
routes: [],
|
routes: [],
|
||||||
addRoutes: []
|
addRoutes: [],
|
||||||
|
sidebarRouters: []
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
SET_ROUTES: (state, routes) => {
|
SET_ROUTES: (state, routes) => {
|
||||||
state.addRoutes = routes
|
state.addRoutes = routes
|
||||||
state.routes = constantRoutes.concat(routes)
|
state.routes = constantRoutes.concat(routes)
|
||||||
}
|
},
|
||||||
|
SET_SIDEBAR_ROUTERS: (state, routers) => {
|
||||||
|
state.sidebarRouters = constantRoutes.concat(routers)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
// 生成路由
|
// 生成路由
|
||||||
@ -20,10 +24,14 @@ const permission = {
|
|||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
// 向后端请求路由数据
|
// 向后端请求路由数据
|
||||||
getRouters().then(res => {
|
getRouters().then(res => {
|
||||||
const accessedRoutes = filterAsyncRouter(res.data)
|
const sdata = JSON.parse(JSON.stringify(res.data))
|
||||||
accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
|
const rdata = JSON.parse(JSON.stringify(res.data))
|
||||||
commit('SET_ROUTES', accessedRoutes)
|
const sidebarRoutes = filterAsyncRouter(sdata)
|
||||||
resolve(accessedRoutes)
|
const rewriteRoutes = filterAsyncRouter(rdata, true)
|
||||||
|
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
|
||||||
|
commit('SET_ROUTES', rewriteRoutes)
|
||||||
|
commit('SET_SIDEBAR_ROUTERS', sidebarRoutes)
|
||||||
|
resolve(rewriteRoutes)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -31,8 +39,11 @@ const permission = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 遍历后台传来的路由字符串,转换为组件对象
|
// 遍历后台传来的路由字符串,转换为组件对象
|
||||||
function filterAsyncRouter(asyncRouterMap) {
|
function filterAsyncRouter(asyncRouterMap, isRewrite = false) {
|
||||||
return asyncRouterMap.filter(route => {
|
return asyncRouterMap.filter(route => {
|
||||||
|
if (isRewrite && route.children) {
|
||||||
|
route.children = filterChildren(route.children)
|
||||||
|
}
|
||||||
if (route.component) {
|
if (route.component) {
|
||||||
// Layout ParentView 组件特殊处理
|
// Layout ParentView 组件特殊处理
|
||||||
if (route.component === 'Layout') {
|
if (route.component === 'Layout') {
|
||||||
@ -44,14 +55,35 @@ function filterAsyncRouter(asyncRouterMap) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (route.children != null && route.children && route.children.length) {
|
if (route.children != null && route.children && route.children.length) {
|
||||||
route.children = filterAsyncRouter(route.children)
|
route.children = filterAsyncRouter(route.children, route, isRewrite)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filterChildren(childrenMap) {
|
||||||
|
var children = []
|
||||||
|
childrenMap.forEach((el, index) => {
|
||||||
|
if (el.children && el.children.length) {
|
||||||
|
if (el.component === 'ParentView') {
|
||||||
|
el.children.forEach(c => {
|
||||||
|
c.path = el.path + '/' + c.path
|
||||||
|
if (c.children && c.children.length) {
|
||||||
|
children = children.concat(filterChildren(c.children, c))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
children.push(c)
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
children = children.concat(el)
|
||||||
|
})
|
||||||
|
return children
|
||||||
|
}
|
||||||
|
|
||||||
export const loadView = (view) => { // 路由懒加载
|
export const loadView = (view) => { // 路由懒加载
|
||||||
return (resolve) => require([`@/views/${view}`], resolve)
|
return (resolve) => require([`@/views/${view}`], resolve)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default permission
|
export default permission
|
||||||
|
@ -9,9 +9,10 @@ export function checkPermi(value) {
|
|||||||
if (value && value instanceof Array && value.length > 0) {
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
const permissions = store.getters && store.getters.permissions
|
const permissions = store.getters && store.getters.permissions
|
||||||
const permissionDatas = value
|
const permissionDatas = value
|
||||||
|
const all_permission = "*:*:*";
|
||||||
|
|
||||||
const hasPermission = permissions.some(permission => {
|
const hasPermission = permissions.some(permission => {
|
||||||
return permissionDatas.includes(permission)
|
return all_permission === permission || permissionDatas.includes(permission)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
@ -33,9 +34,10 @@ export function checkRole(value) {
|
|||||||
if (value && value instanceof Array && value.length > 0) {
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
const roles = store.getters && store.getters.roles
|
const roles = store.getters && store.getters.roles
|
||||||
const permissionRoles = value
|
const permissionRoles = value
|
||||||
|
const super_admin = "admin";
|
||||||
|
|
||||||
const hasRole = roles.some(role => {
|
const hasRole = roles.some(role => {
|
||||||
return permissionRoles.includes(role)
|
return super_admin === role || permissionRoles.includes(role)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!hasRole) {
|
if (!hasRole) {
|
||||||
@ -46,4 +48,4 @@ export function checkRole(value) {
|
|||||||
console.error(`need roles! Like checkRole="['admin','editor']"`)
|
console.error(`need roles! Like checkRole="['admin','editor']"`)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ service.interceptors.request.use(config => {
|
|||||||
for (const propName of Object.keys(config.params)) {
|
for (const propName of Object.keys(config.params)) {
|
||||||
const value = config.params[propName];
|
const value = config.params[propName];
|
||||||
var part = encodeURIComponent(propName) + "=";
|
var part = encodeURIComponent(propName) + "=";
|
||||||
if (value && typeof(value) !== "undefined") {
|
if (value !== null && typeof(value) !== "undefined") {
|
||||||
if (typeof value === 'object') {
|
if (typeof value === 'object') {
|
||||||
for (const key of Object.keys(value)) {
|
for (const key of Object.keys(value)) {
|
||||||
let params = propName + '[' + key + ']';
|
let params = propName + '[' + key + ']';
|
||||||
|
@ -62,8 +62,8 @@ export function addDateRange(params, dateRange, propName) {
|
|||||||
search.params["beginTime"] = dateRange[0];
|
search.params["beginTime"] = dateRange[0];
|
||||||
search.params["endTime"] = dateRange[1];
|
search.params["endTime"] = dateRange[1];
|
||||||
} else {
|
} else {
|
||||||
search.params[propName + "BeginTime"] = dateRange[0];
|
search.params["begin" + propName] = dateRange[0];
|
||||||
search.params[propName + "EndTime"] = dateRange[1];
|
search.params["end" + propName] = dateRange[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return search;
|
return search;
|
||||||
|
@ -126,15 +126,12 @@ export default {
|
|||||||
Cookies.remove("password");
|
Cookies.remove("password");
|
||||||
Cookies.remove('rememberMe');
|
Cookies.remove('rememberMe');
|
||||||
}
|
}
|
||||||
this.$store
|
this.$store.dispatch("Login", this.loginForm).then(() => {
|
||||||
.dispatch("Login", this.loginForm)
|
this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
|
||||||
.then(() => {
|
}).catch(() => {
|
||||||
this.$router.push({ path: this.redirect || "/" });
|
this.loading = false;
|
||||||
})
|
this.getCode();
|
||||||
.catch(() => {
|
});
|
||||||
this.loading = false;
|
|
||||||
this.getCode();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { updateUserPwd } from "@/api/system/user";
|
import { updateUserPwd } from "@/api/system/user";
|
||||||
import Global from "@/layout/components/global.js";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@ -65,7 +64,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
Global.$emit("removeCache", "closeSelectedTag", this.$route);
|
|
||||||
this.$store.dispatch("tagsView/delView", this.$route);
|
this.$store.dispatch("tagsView/delView", this.$route);
|
||||||
this.$router.push({ path: "/index" });
|
this.$router.push({ path: "/index" });
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { updateUserProfile } from "@/api/system/user";
|
import { updateUserProfile } from "@/api/system/user";
|
||||||
import Global from "@/layout/components/global.js";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@ -69,7 +68,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
Global.$emit("removeCache", "closeSelectedTag", this.$route);
|
|
||||||
this.$store.dispatch("tagsView/delView", this.$route);
|
this.$store.dispatch("tagsView/delView", this.$route);
|
||||||
this.$router.push({ path: "/index" });
|
this.$router.push({ path: "/index" });
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,6 @@
|
|||||||
import { getGenTable, updateGenTable } from "@/api/tool/gen";
|
import { getGenTable, updateGenTable } from "@/api/tool/gen";
|
||||||
import { optionselect as getDictOptionselect } from "@/api/system/dict/type";
|
import { optionselect as getDictOptionselect } from "@/api/system/dict/type";
|
||||||
import { listMenu as getMenuTreeselect } from "@/api/system/menu";
|
import { listMenu as getMenuTreeselect } from "@/api/system/menu";
|
||||||
import Global from "@/layout/components/global.js";
|
|
||||||
import basicInfoForm from "./basicInfoForm";
|
import basicInfoForm from "./basicInfoForm";
|
||||||
import genInfoForm from "./genInfoForm";
|
import genInfoForm from "./genInfoForm";
|
||||||
import Sortable from 'sortablejs'
|
import Sortable from 'sortablejs'
|
||||||
@ -208,7 +207,6 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 关闭按钮 */
|
/** 关闭按钮 */
|
||||||
close() {
|
close() {
|
||||||
Global.$emit("removeCache", "closeSelectedTag", this.$route);
|
|
||||||
this.$store.dispatch("tagsView/delView", this.$route);
|
this.$store.dispatch("tagsView/delView", this.$route);
|
||||||
this.$router.push({ path: "/tool/gen", query: { t: Date.now()}})
|
this.$router.push({ path: "/tool/gen", query: { t: Date.now()}})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user