Compare commits
112 Commits
Author | SHA1 | Date | |
---|---|---|---|
0b5c7f4c96 | |||
265e3010aa | |||
b7a36bfe8a | |||
3a51c53823 | |||
df504c5c14 | |||
baeed2e8d3 | |||
2903de1561 | |||
cca2f5c62d | |||
ce54416e4f | |||
bd19892aff | |||
14a859899c | |||
f3cb18c836 | |||
7d0eb3b8c7 | |||
654aa6b30c | |||
b7cdd10f9f | |||
9bd35cb7be | |||
7a86c714fc | |||
edd090a098 | |||
3cd886785b | |||
ae5a0f9774 | |||
074b3c735d | |||
a118738d0f | |||
56fa3912ae | |||
2116ee1822 | |||
57a2eb4217 | |||
647af5b485 | |||
3f33219134 | |||
a04bb71777 | |||
63992ac906 | |||
0187344798 | |||
a9c6ba12e6 | |||
ba068eae65 | |||
1a87ee7c19 | |||
3c4b01ab83 | |||
886ce995af | |||
52264b6e2a | |||
fd7e88a518 | |||
854a6f805f | |||
1caec85f46 | |||
c86dc20743 | |||
ecc7a8be46 | |||
e23ad20186 | |||
6cf2a8edeb | |||
67198aede9 | |||
4f33da2a3f | |||
8988d0b4ab | |||
ceefa20aa2 | |||
89e1f2a53f | |||
6800a12014 | |||
e8f63b2994 | |||
ecfe7006e2 | |||
9e387dc447 | |||
231bbf6928 | |||
d6eac2dc8d | |||
b368ad764f | |||
ffd5f0ce5d | |||
a50beae599 | |||
cf7f51a633 | |||
4d46f4c1b5 | |||
a941c1b488 | |||
d6b6151aea | |||
fbc071a573 | |||
6cfff90b4a | |||
474cca921e | |||
1657e06be6 | |||
c01eeb8521 | |||
f90899d72a | |||
7e78a9167f | |||
563e11d9c1 | |||
ef92ad4d8c | |||
d8b006c15f | |||
0e2b97a886 | |||
1c7a5faae8 | |||
23868c4fad | |||
3b2669d148 | |||
1147ea5f8a | |||
a1bf5aaf8e | |||
2797c1eb3a | |||
1791d7cf40 | |||
01861f0aae | |||
a69cc94f35 | |||
c666faed66 | |||
6072239a40 | |||
a3b86d6f6d | |||
fd831d5a90 | |||
e83412b9a5 | |||
90ac416e02 | |||
5b63f0cab9 | |||
8f145bba3a | |||
6bb166b89f | |||
823e95667e | |||
566053da0c | |||
0ef007240d | |||
0a75dcdd85 | |||
4c2626ffec | |||
082b19e33a | |||
b779cf053d | |||
212012dc62 | |||
7de2cf77b4 | |||
2b9d46439f | |||
79265d59b7 | |||
093ba5b389 | |||
3807b11290 | |||
c9f25cb34e | |||
203b54e5aa | |||
403f5c5dcf | |||
c6d0b9a9ae | |||
08df2c93a9 | |||
fbbdd94999 | |||
0cae7d0058 | |||
b0965653bf | |||
e472f62523 |
16
README.md
@ -1,14 +1,17 @@
|
|||||||
## 平台简介
|
## 平台简介
|
||||||
|
|
||||||
|
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
|
||||||
|
|
||||||
* 前端采用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)
|
||||||
* 感谢[Vue-Element-Admin](https://github.com/PanJiaChen/vue-element-admin),[eladmin-web](https://gitee.com/elunez/eladmin-web?_from=gitee_search)。
|
* 特别鸣谢:[element](https://github.com/ElemeFE/element),[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin),[eladmin-web](https://github.com/elunez/eladmin-web)。
|
||||||
* 阿里云优惠券:[点我进入](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)
|
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)
|
||||||
|
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)
|
||||||
|
|
||||||
## 内置功能
|
## 内置功能
|
||||||
|
|
||||||
@ -27,8 +30,9 @@
|
|||||||
13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
|
13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
|
||||||
14. 系统接口:根据业务代码自动生成相关的api接口文档。
|
14. 系统接口:根据业务代码自动生成相关的api接口文档。
|
||||||
15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
|
15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
|
||||||
16. 在线构建器:拖动表单元素生成相应的HTML代码。
|
16. 缓存监控:对系统的缓存信息查询,命令统计等。
|
||||||
17. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
|
17. 在线构建器:拖动表单元素生成相应的HTML代码。
|
||||||
|
18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
|
||||||
|
|
||||||
## 在线体验
|
## 在线体验
|
||||||
|
|
||||||
@ -71,7 +75,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
|
||||||
<td><img src="https://oscimg.oschina.net/oscnet/up-6d73c2140ce694e3de4c05035fdc1868d4c.png"/></td>
|
<td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
21
pom.xml
@ -6,30 +6,29 @@
|
|||||||
|
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<version>3.2.0</version>
|
<version>3.4.0</version>
|
||||||
|
|
||||||
<name>ruoyi</name>
|
<name>ruoyi</name>
|
||||||
<url>http://www.ruoyi.vip</url>
|
<url>http://www.ruoyi.vip</url>
|
||||||
<description>若依管理系统</description>
|
<description>若依管理系统</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<ruoyi.version>3.2.0</ruoyi.version>
|
<ruoyi.version>3.4.0</ruoyi.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
|
||||||
<mybatis.boot.version>1.3.2</mybatis.boot.version>
|
<druid.version>1.2.4</druid.version>
|
||||||
<druid.version>1.2.1</druid.version>
|
<bitwalker.version>1.21</bitwalker.version>
|
||||||
<bitwalker.version>1.19</bitwalker.version>
|
|
||||||
<swagger.version>2.9.2</swagger.version>
|
<swagger.version>2.9.2</swagger.version>
|
||||||
<kaptcha.version>2.3.2</kaptcha.version>
|
<kaptcha.version>2.3.2</kaptcha.version>
|
||||||
<pagehelper.boot.version>1.2.5</pagehelper.boot.version>
|
<pagehelper.boot.version>1.3.0</pagehelper.boot.version>
|
||||||
<fastjson.version>1.2.74</fastjson.version>
|
<fastjson.version>1.2.75</fastjson.version>
|
||||||
<oshi.version>5.2.5</oshi.version>
|
<oshi.version>5.3.6</oshi.version>
|
||||||
<jna.version>5.5.0</jna.version>
|
<jna.version>5.6.0</jna.version>
|
||||||
<commons.io.version>2.5</commons.io.version>
|
<commons.io.version>2.5</commons.io.version>
|
||||||
<commons.fileupload.version>1.3.3</commons.fileupload.version>
|
<commons.fileupload.version>1.3.3</commons.fileupload.version>
|
||||||
<poi.version>3.17</poi.version>
|
<poi.version>4.1.2</poi.version>
|
||||||
<velocity.version>1.7</velocity.version>
|
<velocity.version>1.7</velocity.version>
|
||||||
<jwt.version>0.9.1</jwt.version>
|
<jwt.version>0.9.1</jwt.version>
|
||||||
</properties>
|
</properties>
|
||||||
@ -42,7 +41,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.17.RELEASE</version>
|
<version>2.2.13.RELEASE</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.2.0</version>
|
<version>3.4.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
@ -5,6 +5,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@ -41,17 +42,15 @@ public class CommonController
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!FileUtils.isValidFilename(fileName))
|
if (!FileUtils.checkAllowDownload(fileName))
|
||||||
{
|
{
|
||||||
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
|
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
|
||||||
}
|
}
|
||||||
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
|
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
|
||||||
String filePath = RuoYiConfig.getDownloadPath() + fileName;
|
String filePath = RuoYiConfig.getDownloadPath() + fileName;
|
||||||
|
|
||||||
response.setCharacterEncoding("utf-8");
|
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||||
response.setContentType("multipart/form-data");
|
FileUtils.setAttachmentResponseHeader(response, realFileName);
|
||||||
response.setHeader("Content-Disposition",
|
|
||||||
"attachment;fileName=" + FileUtils.setFileDownloadHeader(request, realFileName));
|
|
||||||
FileUtils.writeBytes(filePath, response.getOutputStream());
|
FileUtils.writeBytes(filePath, response.getOutputStream());
|
||||||
if (delete)
|
if (delete)
|
||||||
{
|
{
|
||||||
@ -92,18 +91,28 @@ public class CommonController
|
|||||||
* 本地资源通用下载
|
* 本地资源通用下载
|
||||||
*/
|
*/
|
||||||
@GetMapping("/common/download/resource")
|
@GetMapping("/common/download/resource")
|
||||||
public void resourceDownload(String name, HttpServletRequest request, HttpServletResponse response) throws Exception
|
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws Exception
|
||||||
{
|
{
|
||||||
// 本地资源路径
|
try
|
||||||
String localPath = RuoYiConfig.getProfile();
|
{
|
||||||
// 数据库资源地址
|
if (!FileUtils.checkAllowDownload(resource))
|
||||||
String downloadPath = localPath + StringUtils.substringAfter(name, Constants.RESOURCE_PREFIX);
|
{
|
||||||
// 下载名称
|
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
|
||||||
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
|
}
|
||||||
response.setCharacterEncoding("utf-8");
|
// 本地资源路径
|
||||||
response.setContentType("multipart/form-data");
|
String localPath = RuoYiConfig.getProfile();
|
||||||
response.setHeader("Content-Disposition",
|
// 数据库资源地址
|
||||||
"attachment;fileName=" + FileUtils.setFileDownloadHeader(request, downloadName));
|
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
|
||||||
FileUtils.writeBytes(downloadPath, response.getOutputStream());
|
// 下载名称
|
||||||
|
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
|
||||||
|
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||||
|
FileUtils.setAttachmentResponseHeader(response, downloadName);
|
||||||
|
FileUtils.writeBytes(downloadPath, response.getOutputStream());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.error("下载文件失败", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.ruoyi.web.controller.monitor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisCallback;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存监控
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/monitor/cache")
|
||||||
|
public class CacheController
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, String> redisTemplate;
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
|
||||||
|
@GetMapping()
|
||||||
|
public AjaxResult getInfo() throws Exception
|
||||||
|
{
|
||||||
|
Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
|
||||||
|
Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
|
||||||
|
Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
|
||||||
|
|
||||||
|
Map<String, Object> result = new HashMap<>(3);
|
||||||
|
result.put("info", info);
|
||||||
|
result.put("dbSize", dbSize);
|
||||||
|
|
||||||
|
List<Map<String, String>> pieList = new ArrayList<>();
|
||||||
|
commandStats.stringPropertyNames().forEach(key -> {
|
||||||
|
Map<String, String> data = new HashMap<>(2);
|
||||||
|
String property = commandStats.getProperty(key);
|
||||||
|
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
|
||||||
|
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
|
||||||
|
pieList.add(data);
|
||||||
|
});
|
||||||
|
result.put("commandStats", pieList);
|
||||||
|
return AjaxResult.success(result);
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,6 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.framework.web.domain.Server;
|
import com.ruoyi.framework.web.domain.Server;
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ import com.ruoyi.framework.web.domain.Server;
|
|||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/monitor/server")
|
@RequestMapping("/monitor/server")
|
||||||
public class ServerController extends BaseController
|
public class ServerController
|
||||||
{
|
{
|
||||||
@PreAuthorize("@ss.hasPermi('monitor:server:list')")
|
@PreAuthorize("@ss.hasPermi('monitor:server:list')")
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.web.controller.system;
|
package com.ruoyi.web.controller.system;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
@ -19,6 +20,7 @@ import com.ruoyi.common.core.domain.entity.SysDictData;
|
|||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.system.service.ISysDictDataService;
|
import com.ruoyi.system.service.ISysDictDataService;
|
||||||
import com.ruoyi.system.service.ISysDictTypeService;
|
import com.ruoyi.system.service.ISysDictTypeService;
|
||||||
@ -73,7 +75,12 @@ public class SysDictDataController extends BaseController
|
|||||||
@GetMapping(value = "/type/{dictType}")
|
@GetMapping(value = "/type/{dictType}")
|
||||||
public AjaxResult dictType(@PathVariable String dictType)
|
public AjaxResult dictType(@PathVariable String dictType)
|
||||||
{
|
{
|
||||||
return AjaxResult.success(dictTypeService.selectDictDataByType(dictType));
|
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
|
||||||
|
if (StringUtils.isNull(data))
|
||||||
|
{
|
||||||
|
data = new ArrayList<SysDictData>();
|
||||||
|
}
|
||||||
|
return AjaxResult.success(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -127,11 +127,13 @@ public class SysUserController extends BaseController
|
|||||||
{
|
{
|
||||||
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
|
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
|
||||||
}
|
}
|
||||||
else if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
|
else if (StringUtils.isNotEmpty(user.getPhonenumber())
|
||||||
|
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
|
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
|
||||||
}
|
}
|
||||||
else if (UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
|
else if (StringUtils.isNotEmpty(user.getEmail())
|
||||||
|
&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
||||||
}
|
}
|
||||||
@ -149,11 +151,13 @@ public class SysUserController extends BaseController
|
|||||||
public AjaxResult edit(@Validated @RequestBody SysUser user)
|
public AjaxResult edit(@Validated @RequestBody SysUser user)
|
||||||
{
|
{
|
||||||
userService.checkUserAllowed(user);
|
userService.checkUserAllowed(user);
|
||||||
if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
|
if (StringUtils.isNotEmpty(user.getPhonenumber())
|
||||||
|
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
|
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
|
||||||
}
|
}
|
||||||
else if (UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
|
else if (StringUtils.isNotEmpty(user.getEmail())
|
||||||
|
&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
||||||
}
|
}
|
||||||
@ -175,7 +179,7 @@ public class SysUserController extends BaseController
|
|||||||
/**
|
/**
|
||||||
* 重置密码
|
* 重置密码
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('system:user:edit')")
|
@PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
|
||||||
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
|
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
|
||||||
@PutMapping("/resetPwd")
|
@PutMapping("/resetPwd")
|
||||||
public AjaxResult resetPwd(@RequestBody SysUser user)
|
public AjaxResult resetPwd(@RequestBody SysUser user)
|
||||||
|
@ -3,9 +3,9 @@ ruoyi:
|
|||||||
# 名称
|
# 名称
|
||||||
name: RuoYi
|
name: RuoYi
|
||||||
# 版本
|
# 版本
|
||||||
version: 3.2.0
|
version: 3.4.0
|
||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2020
|
copyrightYear: 2021
|
||||||
# 实例演示开关
|
# 实例演示开关
|
||||||
demoEnabled: true
|
demoEnabled: true
|
||||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||||
@ -62,6 +62,8 @@ spring:
|
|||||||
host: localhost
|
host: localhost
|
||||||
# 端口,默认为6379
|
# 端口,默认为6379
|
||||||
port: 6379
|
port: 6379
|
||||||
|
# 数据库索引
|
||||||
|
database: 0
|
||||||
# 密码
|
# 密码
|
||||||
password:
|
password:
|
||||||
# 连接超时时间
|
# 连接超时时间
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.2.0</version>
|
<version>3.4.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -105,6 +105,27 @@ public @interface Excel
|
|||||||
*/
|
*/
|
||||||
public boolean isStatistics() default false;
|
public boolean isStatistics() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出字段对齐方式(0:默认;1:靠左;2:居中;3:靠右)
|
||||||
|
*/
|
||||||
|
Align align() default Align.AUTO;
|
||||||
|
|
||||||
|
public enum Align
|
||||||
|
{
|
||||||
|
AUTO(0), LEFT(1), CENTER(2), RIGHT(3);
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
Align(int value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int value()
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
|
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
|
||||||
*/
|
*/
|
||||||
@ -128,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)
|
||||||
|
@ -13,6 +13,9 @@ public class GenConstants
|
|||||||
/** 树表(增删改查) */
|
/** 树表(增删改查) */
|
||||||
public static final String TPL_TREE = "tree";
|
public static final String TPL_TREE = "tree";
|
||||||
|
|
||||||
|
/** 主子表(增删改查) */
|
||||||
|
public static final String TPL_SUB = "sub";
|
||||||
|
|
||||||
/** 树编码字段 */
|
/** 树编码字段 */
|
||||||
public static final String TREE_CODE = "treeCode";
|
public static final String TREE_CODE = "treeCode";
|
||||||
|
|
||||||
@ -29,15 +32,17 @@ 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" };
|
||||||
|
|
||||||
/** 数据库数字类型 */
|
/** 数据库数字类型 */
|
||||||
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
|
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
|
||||||
"bigint", "float", "float", "double", "decimal" };
|
"bit", "bigint", "float", "double", "decimal" };
|
||||||
|
|
||||||
/** 页面不需要编辑字段 */
|
/** 页面不需要编辑字段 */
|
||||||
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
|
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
|
||||||
@ -74,6 +79,12 @@ public class GenConstants
|
|||||||
/** 日期控件 */
|
/** 日期控件 */
|
||||||
public static final String HTML_DATETIME = "datetime";
|
public static final String HTML_DATETIME = "datetime";
|
||||||
|
|
||||||
|
/** 图片上传控件 */
|
||||||
|
public static final String HTML_IMAGE_UPLOAD = "imageUpload";
|
||||||
|
|
||||||
|
/** 文件上传控件 */
|
||||||
|
public static final String HTML_FILE_UPLOAD = "fileUpload";
|
||||||
|
|
||||||
/** 富文本控件 */
|
/** 富文本控件 */
|
||||||
public static final String HTML_EDITOR = "editor";
|
public static final String HTML_EDITOR = "editor";
|
||||||
|
|
||||||
|
@ -54,6 +54,9 @@ public class UserConstants
|
|||||||
/** Layout组件标识 */
|
/** Layout组件标识 */
|
||||||
public final static String LAYOUT = "Layout";
|
public final static String LAYOUT = "Layout";
|
||||||
|
|
||||||
|
/** ParentView组件标识 */
|
||||||
|
public final static String PARENT_VIEW = "ParentView";
|
||||||
|
|
||||||
/** 校验返回结果码 */
|
/** 校验返回结果码 */
|
||||||
public final static String UNIQUE = "0";
|
public final static String UNIQUE = "0";
|
||||||
public final static String NOT_UNIQUE = "1";
|
public final static String NOT_UNIQUE = "1";
|
||||||
|
@ -5,7 +5,6 @@ import java.util.Date;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity基类
|
* Entity基类
|
||||||
@ -36,14 +35,6 @@ public class BaseEntity implements Serializable
|
|||||||
/** 备注 */
|
/** 备注 */
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
/** 开始时间 */
|
|
||||||
@JsonIgnore
|
|
||||||
private String beginTime;
|
|
||||||
|
|
||||||
/** 结束时间 */
|
|
||||||
@JsonIgnore
|
|
||||||
private String endTime;
|
|
||||||
|
|
||||||
/** 请求参数 */
|
/** 请求参数 */
|
||||||
private Map<String, Object> params;
|
private Map<String, Object> params;
|
||||||
|
|
||||||
@ -107,26 +98,6 @@ public class BaseEntity implements Serializable
|
|||||||
this.remark = remark;
|
this.remark = remark;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBeginTime()
|
|
||||||
{
|
|
||||||
return beginTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBeginTime(String beginTime)
|
|
||||||
{
|
|
||||||
this.beginTime = beginTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEndTime()
|
|
||||||
{
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEndTime(String endTime)
|
|
||||||
{
|
|
||||||
this.endTime = endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Object> getParams()
|
public Map<String, Object> getParams()
|
||||||
{
|
{
|
||||||
if (params == null)
|
if (params == null)
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package com.ruoyi.common.core.redis;
|
package com.ruoyi.common.core.redis;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.BoundSetOperations;
|
||||||
import org.springframework.data.redis.core.HashOperations;
|
import org.springframework.data.redis.core.HashOperations;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.core.ValueOperations;
|
import org.springframework.data.redis.core.ValueOperations;
|
||||||
@ -136,10 +138,15 @@ public class RedisCache
|
|||||||
* @param dataSet 缓存的数据
|
* @param dataSet 缓存的数据
|
||||||
* @return 缓存数据的对象
|
* @return 缓存数据的对象
|
||||||
*/
|
*/
|
||||||
public <T> long setCacheSet(final String key, final Set<T> dataSet)
|
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
|
||||||
{
|
{
|
||||||
Long count = redisTemplate.opsForSet().add(key, dataSet);
|
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
|
||||||
return count == null ? 0 : count;
|
Iterator<T> it = dataSet.iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
setOperation.add(it.next());
|
||||||
|
}
|
||||||
|
return setOperation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,7 +66,7 @@ public class CharsetKit
|
|||||||
|
|
||||||
if (null == destCharset)
|
if (null == destCharset)
|
||||||
{
|
{
|
||||||
srcCharset = StandardCharsets.UTF_8;
|
destCharset = StandardCharsets.UTF_8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
|
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package com.ruoyi.common.utils.file;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件类型工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class FileTypeUtils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取文件类型
|
||||||
|
* <p>
|
||||||
|
* 例如: ruoyi.txt, 返回: txt
|
||||||
|
*
|
||||||
|
* @param file 文件名
|
||||||
|
* @return 后缀(不含".")
|
||||||
|
*/
|
||||||
|
public static String getFileType(File file)
|
||||||
|
{
|
||||||
|
if (null == file)
|
||||||
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
return getFileType(file.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件类型
|
||||||
|
* <p>
|
||||||
|
* 例如: ruoyi.txt, 返回: txt
|
||||||
|
*
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @return 后缀(不含".")
|
||||||
|
*/
|
||||||
|
public static String getFileType(String fileName)
|
||||||
|
{
|
||||||
|
int separatorIndex = fileName.lastIndexOf(".");
|
||||||
|
if (separatorIndex < 0)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,11 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件处理工具类
|
* 文件处理工具类
|
||||||
@ -104,6 +108,30 @@ public class FileUtils extends org.apache.commons.io.FileUtils
|
|||||||
return filename.matches(FILENAME_PATTERN);
|
return filename.matches(FILENAME_PATTERN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查文件是否可下载
|
||||||
|
*
|
||||||
|
* @param resource 需要下载的文件
|
||||||
|
* @return true 正常 false 非法
|
||||||
|
*/
|
||||||
|
public static boolean checkAllowDownload(String resource)
|
||||||
|
{
|
||||||
|
// 禁止目录上跳级别
|
||||||
|
if (StringUtils.contains(resource, ".."))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查允许下载的文件规则
|
||||||
|
if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不在允许下载的文件规则
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载文件名重新编码
|
* 下载文件名重新编码
|
||||||
*
|
*
|
||||||
@ -111,8 +139,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils
|
|||||||
* @param fileName 文件名
|
* @param fileName 文件名
|
||||||
* @return 编码后的文件名
|
* @return 编码后的文件名
|
||||||
*/
|
*/
|
||||||
public static String setFileDownloadHeader(HttpServletRequest request, String fileName)
|
public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
|
||||||
throws UnsupportedEncodingException
|
|
||||||
{
|
{
|
||||||
final String agent = request.getHeader("USER-AGENT");
|
final String agent = request.getHeader("USER-AGENT");
|
||||||
String filename = fileName;
|
String filename = fileName;
|
||||||
@ -139,4 +166,38 @@ public class FileUtils extends org.apache.commons.io.FileUtils
|
|||||||
}
|
}
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件名重新编码
|
||||||
|
*
|
||||||
|
* @param response 响应对象
|
||||||
|
* @param realFileName 真实文件名
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
|
||||||
|
{
|
||||||
|
String percentEncodedFileName = percentEncode(realFileName);
|
||||||
|
|
||||||
|
StringBuilder contentDispositionValue = new StringBuilder();
|
||||||
|
contentDispositionValue.append("attachment; filename=")
|
||||||
|
.append(percentEncodedFileName)
|
||||||
|
.append(";")
|
||||||
|
.append("filename*=")
|
||||||
|
.append("utf-8''")
|
||||||
|
.append(percentEncodedFileName);
|
||||||
|
|
||||||
|
response.setHeader("Content-disposition", contentDispositionValue.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 百分号编码工具方法
|
||||||
|
*
|
||||||
|
* @param s 需要百分号编码的字符串
|
||||||
|
* @return 百分号编码后的字符串
|
||||||
|
*/
|
||||||
|
public static String percentEncode(String s) throws UnsupportedEncodingException
|
||||||
|
{
|
||||||
|
String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
|
||||||
|
return encode.replaceAll("\\+", "%20");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,15 +18,16 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
|
|
||||||
import org.apache.poi.ss.usermodel.BorderStyle;
|
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;
|
||||||
@ -38,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;
|
||||||
@ -52,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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,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");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实体对象
|
* 实体对象
|
||||||
*/
|
*/
|
||||||
@ -240,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)))
|
||||||
@ -274,6 +291,10 @@ public class ExcelUtil<T>
|
|||||||
val = DateUtil.getJavaDate((Double) val);
|
val = DateUtil.getJavaDate((Double) val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (Boolean.TYPE == fieldType || Boolean.class == fieldType)
|
||||||
|
{
|
||||||
|
val = Convert.toBool(val, false);
|
||||||
|
}
|
||||||
if (StringUtils.isNotNull(fieldType))
|
if (StringUtils.isNotNull(fieldType))
|
||||||
{
|
{
|
||||||
Excel attr = field.getAnnotation(Excel.class);
|
Excel attr = field.getAnnotation(Excel.class);
|
||||||
@ -469,6 +490,21 @@ public class ExcelUtil<T>
|
|||||||
style.setFont(totalFont);
|
style.setFont(totalFont);
|
||||||
styles.put("total", style);
|
styles.put("total", style);
|
||||||
|
|
||||||
|
style = wb.createCellStyle();
|
||||||
|
style.cloneStyleFrom(styles.get("data"));
|
||||||
|
style.setAlignment(HorizontalAlignment.LEFT);
|
||||||
|
styles.put("data1", style);
|
||||||
|
|
||||||
|
style = wb.createCellStyle();
|
||||||
|
style.cloneStyleFrom(styles.get("data"));
|
||||||
|
style.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
styles.put("data2", style);
|
||||||
|
|
||||||
|
style = wb.createCellStyle();
|
||||||
|
style.cloneStyleFrom(styles.get("data"));
|
||||||
|
style.setAlignment(HorizontalAlignment.RIGHT);
|
||||||
|
styles.put("data3", style);
|
||||||
|
|
||||||
return styles;
|
return styles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,14 +533,53 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
if (ColumnType.STRING == attr.cellType())
|
if (ColumnType.STRING == attr.cellType())
|
||||||
{
|
{
|
||||||
cell.setCellType(CellType.STRING);
|
|
||||||
cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix());
|
cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix());
|
||||||
}
|
}
|
||||||
else if (ColumnType.NUMERIC == attr.cellType())
|
else if (ColumnType.NUMERIC == attr.cellType())
|
||||||
{
|
{
|
||||||
cell.setCellType(CellType.NUMERIC);
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -520,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()))
|
||||||
@ -545,13 +619,14 @@ public class ExcelUtil<T>
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 设置行高
|
// 设置行高
|
||||||
row.setHeight((short) (attr.height() * 20));
|
row.setHeight(maxHeight);
|
||||||
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
|
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
|
||||||
if (attr.isExport())
|
if (attr.isExport())
|
||||||
{
|
{
|
||||||
// 创建cell
|
// 创建cell
|
||||||
cell = row.createCell(column);
|
cell = row.createCell(column);
|
||||||
cell.setCellStyle(styles.get("data"));
|
int align = attr.align().value();
|
||||||
|
cell.setCellStyle(styles.get("data" + (align >= 1 && align <= 3 ? align : "")));
|
||||||
|
|
||||||
// 用于读取对象中的属性
|
// 用于读取对象中的属性
|
||||||
Object value = getTargetValue(vo, field, attr);
|
Object value = getTargetValue(vo, field, attr);
|
||||||
@ -720,7 +795,7 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
return StringUtils.stripEnd(propertyString.toString(), separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析字典值
|
* 解析字典值
|
||||||
*
|
*
|
||||||
@ -746,7 +821,7 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
return DictUtils.getDictValue(dictType, dictLabel, separator);
|
return DictUtils.getDictValue(dictType, dictLabel, separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 合计统计信息
|
* 合计统计信息
|
||||||
*/
|
*/
|
||||||
@ -783,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);
|
||||||
@ -860,7 +935,7 @@ public class ExcelUtil<T>
|
|||||||
*/
|
*/
|
||||||
private Object getValue(Object o, String name) throws Exception
|
private Object getValue(Object o, String name) throws Exception
|
||||||
{
|
{
|
||||||
if (StringUtils.isNotEmpty(name))
|
if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name))
|
||||||
{
|
{
|
||||||
Class<?> clazz = o.getClass();
|
Class<?> clazz = o.getClass();
|
||||||
Field field = clazz.getDeclaredField(name);
|
Field field = clazz.getDeclaredField(name);
|
||||||
@ -899,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -960,16 +1050,16 @@ public class ExcelUtil<T>
|
|||||||
Cell cell = row.getCell(column);
|
Cell cell = row.getCell(column);
|
||||||
if (StringUtils.isNotNull(cell))
|
if (StringUtils.isNotNull(cell))
|
||||||
{
|
{
|
||||||
if (cell.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA)
|
if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA)
|
||||||
{
|
{
|
||||||
val = cell.getNumericCellValue();
|
val = cell.getNumericCellValue();
|
||||||
if (HSSFDateUtil.isCellDateFormatted(cell))
|
if (DateUtil.isCellDateFormatted(cell))
|
||||||
{
|
{
|
||||||
val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换
|
val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((Double) val % 1 > 0)
|
if ((Double) val % 1 != 0)
|
||||||
{
|
{
|
||||||
val = new BigDecimal(val.toString());
|
val = new BigDecimal(val.toString());
|
||||||
}
|
}
|
||||||
@ -979,15 +1069,15 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cell.getCellTypeEnum() == CellType.STRING)
|
else if (cell.getCellType() == CellType.STRING)
|
||||||
{
|
{
|
||||||
val = cell.getStringCellValue();
|
val = cell.getStringCellValue();
|
||||||
}
|
}
|
||||||
else if (cell.getCellTypeEnum() == CellType.BOOLEAN)
|
else if (cell.getCellType() == CellType.BOOLEAN)
|
||||||
{
|
{
|
||||||
val = cell.getBooleanCellValue();
|
val = cell.getBooleanCellValue();
|
||||||
}
|
}
|
||||||
else if (cell.getCellTypeEnum() == CellType.ERROR)
|
else if (cell.getCellType() == CellType.ERROR)
|
||||||
{
|
{
|
||||||
val = cell.getErrorCellValue();
|
val = cell.getErrorCellValue();
|
||||||
}
|
}
|
||||||
|
@ -204,6 +204,10 @@ public class ReflectUtils
|
|||||||
args[i] = DateUtil.getJavaDate((Double) args[i]);
|
args[i] = DateUtil.getJavaDate((Double) args[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (cs[i] == boolean.class || cs[i] == Boolean.class)
|
||||||
|
{
|
||||||
|
args[i] = Convert.toBool(args[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (E) method.invoke(obj, args);
|
return (E) method.invoke(obj, args);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.2.0</version>
|
<version>3.4.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.ruoyi.framework.aspectj;
|
package com.ruoyi.framework.aspectj;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@ -210,8 +212,31 @@ public class LogAspect
|
|||||||
* @param o 对象信息。
|
* @param o 对象信息。
|
||||||
* @return 如果是需要过滤的对象,则返回true;否则返回false。
|
* @return 如果是需要过滤的对象,则返回true;否则返回false。
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
public boolean isFilterObject(final Object o)
|
public boolean isFilterObject(final Object o)
|
||||||
{
|
{
|
||||||
|
Class<?> clazz = o.getClass();
|
||||||
|
if (clazz.isArray())
|
||||||
|
{
|
||||||
|
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
|
||||||
|
}
|
||||||
|
else if (Collection.class.isAssignableFrom(clazz))
|
||||||
|
{
|
||||||
|
Collection collection = (Collection) o;
|
||||||
|
for (Iterator iter = collection.iterator(); iter.hasNext();)
|
||||||
|
{
|
||||||
|
return iter.next() instanceof MultipartFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Map.class.isAssignableFrom(clazz))
|
||||||
|
{
|
||||||
|
Map map = (Map) o;
|
||||||
|
for (Iterator iter = map.entrySet().iterator(); iter.hasNext();)
|
||||||
|
{
|
||||||
|
Map.Entry entry = (Map.Entry) iter.next();
|
||||||
|
return entry.getValue() instanceof MultipartFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
|
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.ruoyi.framework.config;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
@ -21,6 +22,7 @@ import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
|||||||
import org.springframework.core.type.classreading.MetadataReader;
|
import org.springframework.core.type.classreading.MetadataReader;
|
||||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mybatis支持*匹配扫描包
|
* Mybatis支持*匹配扫描包
|
||||||
@ -89,6 +91,28 @@ public class MyBatisConfig
|
|||||||
return typeAliasesPackage;
|
return typeAliasesPackage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Resource[] resolveMapperLocations(String[] mapperLocations)
|
||||||
|
{
|
||||||
|
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
|
||||||
|
List<Resource> resources = new ArrayList<Resource>();
|
||||||
|
if (mapperLocations != null)
|
||||||
|
{
|
||||||
|
for (String mapperLocation : mapperLocations)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Resource[] mappers = resourceResolver.getResources(mapperLocation);
|
||||||
|
resources.addAll(Arrays.asList(mappers));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resources.toArray(new Resource[resources.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
|
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
|
||||||
{
|
{
|
||||||
@ -101,7 +125,7 @@ public class MyBatisConfig
|
|||||||
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
|
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
|
||||||
sessionFactory.setDataSource(dataSource);
|
sessionFactory.setDataSource(dataSource);
|
||||||
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
|
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
|
||||||
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
|
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
|
||||||
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
|
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
|
||||||
return sessionFactory.getObject();
|
return sessionFactory.getObject();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -109,7 +109,7 @@ public class PermissionService
|
|||||||
for (SysRole sysRole : loginUser.getUser().getRoles())
|
for (SysRole sysRole : loginUser.getUser().getRoles())
|
||||||
{
|
{
|
||||||
String roleKey = sysRole.getRoleKey();
|
String roleKey = sysRole.getRoleKey();
|
||||||
if (SUPER_ADMIN.contains(roleKey) || roleKey.contains(StringUtils.trim(role)))
|
if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role)))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.2.0</version>
|
<version>3.4.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -63,10 +63,12 @@ public class GenController extends BaseController
|
|||||||
public AjaxResult getInfo(@PathVariable Long talbleId)
|
public AjaxResult getInfo(@PathVariable Long talbleId)
|
||||||
{
|
{
|
||||||
GenTable table = genTableService.selectGenTableById(talbleId);
|
GenTable table = genTableService.selectGenTableById(talbleId);
|
||||||
|
List<GenTable> tables = genTableService.selectGenTableAll();
|
||||||
List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(talbleId);
|
List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(talbleId);
|
||||||
Map<String, Object> map = new HashMap<String, Object>();
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
map.put("info", table);
|
map.put("info", table);
|
||||||
map.put("rows", list);
|
map.put("rows", list);
|
||||||
|
map.put("tables", tables);
|
||||||
return AjaxResult.success(map);
|
return AjaxResult.success(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,11 +28,17 @@ public class GenTable extends BaseEntity
|
|||||||
@NotBlank(message = "表描述不能为空")
|
@NotBlank(message = "表描述不能为空")
|
||||||
private String tableComment;
|
private String tableComment;
|
||||||
|
|
||||||
|
/** 关联父表的表名 */
|
||||||
|
private String subTableName;
|
||||||
|
|
||||||
|
/** 本表关联父表的外键名 */
|
||||||
|
private String subTableFkName;
|
||||||
|
|
||||||
/** 实体类名称(首字母大写) */
|
/** 实体类名称(首字母大写) */
|
||||||
@NotBlank(message = "实体类名称不能为空")
|
@NotBlank(message = "实体类名称不能为空")
|
||||||
private String className;
|
private String className;
|
||||||
|
|
||||||
/** 使用的模板(crud单表操作 tree树表操作) */
|
/** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */
|
||||||
private String tplCategory;
|
private String tplCategory;
|
||||||
|
|
||||||
/** 生成包路径 */
|
/** 生成包路径 */
|
||||||
@ -64,6 +70,9 @@ public class GenTable extends BaseEntity
|
|||||||
/** 主键信息 */
|
/** 主键信息 */
|
||||||
private GenTableColumn pkColumn;
|
private GenTableColumn pkColumn;
|
||||||
|
|
||||||
|
/** 子表信息 */
|
||||||
|
private GenTable subTable;
|
||||||
|
|
||||||
/** 表列信息 */
|
/** 表列信息 */
|
||||||
@Valid
|
@Valid
|
||||||
private List<GenTableColumn> columns;
|
private List<GenTableColumn> columns;
|
||||||
@ -116,6 +125,26 @@ public class GenTable extends BaseEntity
|
|||||||
this.tableComment = tableComment;
|
this.tableComment = tableComment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSubTableName()
|
||||||
|
{
|
||||||
|
return subTableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubTableName(String subTableName)
|
||||||
|
{
|
||||||
|
this.subTableName = subTableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubTableFkName()
|
||||||
|
{
|
||||||
|
return subTableFkName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubTableFkName(String subTableFkName)
|
||||||
|
{
|
||||||
|
this.subTableFkName = subTableFkName;
|
||||||
|
}
|
||||||
|
|
||||||
public String getClassName()
|
public String getClassName()
|
||||||
{
|
{
|
||||||
return className;
|
return className;
|
||||||
@ -216,6 +245,16 @@ public class GenTable extends BaseEntity
|
|||||||
this.pkColumn = pkColumn;
|
this.pkColumn = pkColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GenTable getSubTable()
|
||||||
|
{
|
||||||
|
return subTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubTable(GenTable subTable)
|
||||||
|
{
|
||||||
|
this.subTable = subTable;
|
||||||
|
}
|
||||||
|
|
||||||
public List<GenTableColumn> getColumns()
|
public List<GenTableColumn> getColumns()
|
||||||
{
|
{
|
||||||
return columns;
|
return columns;
|
||||||
@ -286,6 +325,16 @@ public class GenTable extends BaseEntity
|
|||||||
this.parentMenuName = parentMenuName;
|
this.parentMenuName = parentMenuName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSub()
|
||||||
|
{
|
||||||
|
return isSub(this.tplCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSub(String tplCategory)
|
||||||
|
{
|
||||||
|
return tplCategory != null && StringUtils.equals(GenConstants.TPL_SUB, tplCategory);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isTree()
|
public boolean isTree()
|
||||||
{
|
{
|
||||||
return isTree(this.tplCategory);
|
return isTree(this.tplCategory);
|
||||||
|
@ -59,7 +59,7 @@ public class GenTableColumn extends BaseEntity
|
|||||||
/** 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) */
|
/** 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) */
|
||||||
private String queryType;
|
private String queryType;
|
||||||
|
|
||||||
/** 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、editor富文本控件) */
|
/** 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、image图片上传控件、upload文件上传控件、editor富文本控件) */
|
||||||
private String htmlType;
|
private String htmlType;
|
||||||
|
|
||||||
/** 字典类型 */
|
/** 字典类型 */
|
||||||
@ -138,6 +138,11 @@ public class GenTableColumn extends BaseEntity
|
|||||||
return javaField;
|
return javaField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCapJavaField()
|
||||||
|
{
|
||||||
|
return StringUtils.capitalize(javaField);
|
||||||
|
}
|
||||||
|
|
||||||
public void setIsPk(String isPk)
|
public void setIsPk(String isPk)
|
||||||
{
|
{
|
||||||
this.isPk = isPk;
|
this.isPk = isPk;
|
||||||
|
@ -34,6 +34,13 @@ public interface GenTableMapper
|
|||||||
*/
|
*/
|
||||||
public List<GenTable> selectDbTableListByNames(String[] tableNames);
|
public List<GenTable> selectDbTableListByNames(String[] tableNames);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有表信息
|
||||||
|
*
|
||||||
|
* @return 表信息集合
|
||||||
|
*/
|
||||||
|
public List<GenTable> selectGenTableAll();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询表ID业务信息
|
* 查询表ID业务信息
|
||||||
*
|
*
|
||||||
|
@ -102,6 +102,17 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
return genTableMapper.selectDbTableListByNames(tableNames);
|
return genTableMapper.selectDbTableListByNames(tableNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有表信息
|
||||||
|
*
|
||||||
|
* @return 表信息集合
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<GenTable> selectGenTableAll()
|
||||||
|
{
|
||||||
|
return genTableMapper.selectGenTableAll();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改业务
|
* 修改业务
|
||||||
*
|
*
|
||||||
@ -185,9 +196,10 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
Map<String, String> dataMap = new LinkedHashMap<>();
|
Map<String, String> dataMap = new LinkedHashMap<>();
|
||||||
// 查询表信息
|
// 查询表信息
|
||||||
GenTable table = genTableMapper.selectGenTableById(tableId);
|
GenTable table = genTableMapper.selectGenTableById(tableId);
|
||||||
// 查询列信息
|
// 设置主子表信息
|
||||||
List<GenTableColumn> columns = table.getColumns();
|
setSubTable(table);
|
||||||
setPkColumn(table, columns);
|
// 设置主键列信息
|
||||||
|
setPkColumn(table);
|
||||||
VelocityInitializer.initVelocity();
|
VelocityInitializer.initVelocity();
|
||||||
|
|
||||||
VelocityContext context = VelocityUtils.prepareContext(table);
|
VelocityContext context = VelocityUtils.prepareContext(table);
|
||||||
@ -231,9 +243,10 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
{
|
{
|
||||||
// 查询表信息
|
// 查询表信息
|
||||||
GenTable table = genTableMapper.selectGenTableByName(tableName);
|
GenTable table = genTableMapper.selectGenTableByName(tableName);
|
||||||
// 查询列信息
|
// 设置主子表信息
|
||||||
List<GenTableColumn> columns = table.getColumns();
|
setSubTable(table);
|
||||||
setPkColumn(table, columns);
|
// 设置主键列信息
|
||||||
|
setPkColumn(table);
|
||||||
|
|
||||||
VelocityInitializer.initVelocity();
|
VelocityInitializer.initVelocity();
|
||||||
|
|
||||||
@ -276,6 +289,10 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
List<String> tableColumnNames = tableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
|
List<String> tableColumnNames = tableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
|
||||||
|
|
||||||
List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
|
List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
|
||||||
|
if (StringUtils.isEmpty(dbTableColumns))
|
||||||
|
{
|
||||||
|
throw new CustomException("同步数据失败,原表结构不存在");
|
||||||
|
}
|
||||||
List<String> dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
|
List<String> dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
|
||||||
|
|
||||||
dbTableColumns.forEach(column -> {
|
dbTableColumns.forEach(column -> {
|
||||||
@ -319,9 +336,10 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
{
|
{
|
||||||
// 查询表信息
|
// 查询表信息
|
||||||
GenTable table = genTableMapper.selectGenTableByName(tableName);
|
GenTable table = genTableMapper.selectGenTableByName(tableName);
|
||||||
// 查询列信息
|
// 设置主子表信息
|
||||||
List<GenTableColumn> columns = table.getColumns();
|
setSubTable(table);
|
||||||
setPkColumn(table, columns);
|
// 设置主键列信息
|
||||||
|
setPkColumn(table);
|
||||||
|
|
||||||
VelocityInitializer.initVelocity();
|
VelocityInitializer.initVelocity();
|
||||||
|
|
||||||
@ -375,6 +393,17 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
{
|
{
|
||||||
throw new CustomException("树名称字段不能为空");
|
throw new CustomException("树名称字段不能为空");
|
||||||
}
|
}
|
||||||
|
else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory()))
|
||||||
|
{
|
||||||
|
if (StringUtils.isEmpty(genTable.getSubTableName()))
|
||||||
|
{
|
||||||
|
throw new CustomException("关联子表的表名不能为空");
|
||||||
|
}
|
||||||
|
else if (StringUtils.isEmpty(genTable.getSubTableFkName()))
|
||||||
|
{
|
||||||
|
throw new CustomException("子表关联的外键名不能为空");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,11 +411,10 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
* 设置主键列信息
|
* 设置主键列信息
|
||||||
*
|
*
|
||||||
* @param table 业务表信息
|
* @param table 业务表信息
|
||||||
* @param columns 业务字段列表
|
|
||||||
*/
|
*/
|
||||||
public void setPkColumn(GenTable table, List<GenTableColumn> columns)
|
public void setPkColumn(GenTable table)
|
||||||
{
|
{
|
||||||
for (GenTableColumn column : columns)
|
for (GenTableColumn column : table.getColumns())
|
||||||
{
|
{
|
||||||
if (column.isPk())
|
if (column.isPk())
|
||||||
{
|
{
|
||||||
@ -396,7 +424,36 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
}
|
}
|
||||||
if (StringUtils.isNull(table.getPkColumn()))
|
if (StringUtils.isNull(table.getPkColumn()))
|
||||||
{
|
{
|
||||||
table.setPkColumn(columns.get(0));
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,13 @@ public interface IGenTableService
|
|||||||
*/
|
*/
|
||||||
public List<GenTable> selectDbTableListByNames(String[] tableNames);
|
public List<GenTable> selectDbTableListByNames(String[] tableNames);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有表信息
|
||||||
|
*
|
||||||
|
* @return 表信息集合
|
||||||
|
*/
|
||||||
|
public List<GenTable> selectGenTableAll();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询业务信息
|
* 查询业务信息
|
||||||
*
|
*
|
||||||
|
@ -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))
|
||||||
@ -111,6 +112,16 @@ public class GenUtils
|
|||||||
{
|
{
|
||||||
column.setHtmlType(GenConstants.HTML_SELECT);
|
column.setHtmlType(GenConstants.HTML_SELECT);
|
||||||
}
|
}
|
||||||
|
// 图片字段设置图片上传控件
|
||||||
|
else if (StringUtils.endsWithIgnoreCase(columnName, "image"))
|
||||||
|
{
|
||||||
|
column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD);
|
||||||
|
}
|
||||||
|
// 文件字段设置文件上传控件
|
||||||
|
else if (StringUtils.endsWithIgnoreCase(columnName, "file"))
|
||||||
|
{
|
||||||
|
column.setHtmlType(GenConstants.HTML_FILE_UPLOAD);
|
||||||
|
}
|
||||||
// 内容字段设置富文本控件
|
// 内容字段设置富文本控件
|
||||||
else if (StringUtils.endsWithIgnoreCase(columnName, "content"))
|
else if (StringUtils.endsWithIgnoreCase(columnName, "content"))
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ import com.ruoyi.common.constant.Constants;
|
|||||||
/**
|
/**
|
||||||
* VelocityEngine工厂
|
* VelocityEngine工厂
|
||||||
*
|
*
|
||||||
* @author RuoYi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
public class VelocityInitializer
|
public class VelocityInitializer
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,7 @@ public class VelocityUtils
|
|||||||
velocityContext.put("author", genTable.getFunctionAuthor());
|
velocityContext.put("author", genTable.getFunctionAuthor());
|
||||||
velocityContext.put("datetime", DateUtils.getDate());
|
velocityContext.put("datetime", DateUtils.getDate());
|
||||||
velocityContext.put("pkColumn", genTable.getPkColumn());
|
velocityContext.put("pkColumn", genTable.getPkColumn());
|
||||||
velocityContext.put("importList", getImportList(genTable.getColumns()));
|
velocityContext.put("importList", getImportList(genTable));
|
||||||
velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
|
velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
|
||||||
velocityContext.put("columns", genTable.getColumns());
|
velocityContext.put("columns", genTable.getColumns());
|
||||||
velocityContext.put("table", genTable);
|
velocityContext.put("table", genTable);
|
||||||
@ -63,6 +63,10 @@ public class VelocityUtils
|
|||||||
{
|
{
|
||||||
setTreeVelocityContext(velocityContext, genTable);
|
setTreeVelocityContext(velocityContext, genTable);
|
||||||
}
|
}
|
||||||
|
if (GenConstants.TPL_SUB.equals(tplCategory))
|
||||||
|
{
|
||||||
|
setSubVelocityContext(velocityContext, genTable);
|
||||||
|
}
|
||||||
return velocityContext;
|
return velocityContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,6 +100,24 @@ public class VelocityUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setSubVelocityContext(VelocityContext context, GenTable genTable)
|
||||||
|
{
|
||||||
|
GenTable subTable = genTable.getSubTable();
|
||||||
|
String subTableName = genTable.getSubTableName();
|
||||||
|
String subTableFkName = genTable.getSubTableFkName();
|
||||||
|
String subClassName = genTable.getSubTable().getClassName();
|
||||||
|
String subTableFkClassName = StringUtils.convertToCamelCase(subTableFkName);
|
||||||
|
|
||||||
|
context.put("subTable", subTable);
|
||||||
|
context.put("subTableName", subTableName);
|
||||||
|
context.put("subTableFkName", subTableFkName);
|
||||||
|
context.put("subTableFkClassName", subTableFkClassName);
|
||||||
|
context.put("subTableFkclassName", StringUtils.uncapitalize(subTableFkClassName));
|
||||||
|
context.put("subClassName", subClassName);
|
||||||
|
context.put("subclassName", StringUtils.uncapitalize(subClassName));
|
||||||
|
context.put("subImportList", getImportList(genTable.getSubTable()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取模板信息
|
* 获取模板信息
|
||||||
*
|
*
|
||||||
@ -120,6 +142,11 @@ public class VelocityUtils
|
|||||||
{
|
{
|
||||||
templates.add("vm/vue/index-tree.vue.vm");
|
templates.add("vm/vue/index-tree.vue.vm");
|
||||||
}
|
}
|
||||||
|
else if (GenConstants.TPL_SUB.equals(tplCategory))
|
||||||
|
{
|
||||||
|
templates.add("vm/vue/index.vue.vm");
|
||||||
|
templates.add("vm/java/sub-domain.java.vm");
|
||||||
|
}
|
||||||
return templates;
|
return templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +174,10 @@ public class VelocityUtils
|
|||||||
{
|
{
|
||||||
fileName = StringUtils.format("{}/domain/{}.java", javaPath, className);
|
fileName = StringUtils.format("{}/domain/{}.java", javaPath, className);
|
||||||
}
|
}
|
||||||
|
if (template.contains("sub-domain.java.vm") && StringUtils.equals(GenConstants.TPL_SUB, genTable.getTplCategory()))
|
||||||
|
{
|
||||||
|
fileName = StringUtils.format("{}/domain/{}.java", javaPath, genTable.getSubTable().getClassName());
|
||||||
|
}
|
||||||
else if (template.contains("mapper.java.vm"))
|
else if (template.contains("mapper.java.vm"))
|
||||||
{
|
{
|
||||||
fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className);
|
fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className);
|
||||||
@ -201,13 +232,19 @@ public class VelocityUtils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据列类型获取导入包
|
* 根据列类型获取导入包
|
||||||
*
|
*
|
||||||
* @param columns 列集合
|
* @param genTable 业务表对象
|
||||||
* @return 返回需要导入的包列表
|
* @return 返回需要导入的包列表
|
||||||
*/
|
*/
|
||||||
public static HashSet<String> getImportList(List<GenTableColumn> columns)
|
public static HashSet<String> getImportList(GenTable genTable)
|
||||||
{
|
{
|
||||||
|
List<GenTableColumn> columns = genTable.getColumns();
|
||||||
|
GenTable subGenTable = genTable.getSubTable();
|
||||||
HashSet<String> importList = new HashSet<String>();
|
HashSet<String> importList = new HashSet<String>();
|
||||||
|
if (StringUtils.isNotNull(subGenTable))
|
||||||
|
{
|
||||||
|
importList.add("java.util.List");
|
||||||
|
}
|
||||||
for (GenTableColumn column : columns)
|
for (GenTableColumn column : columns)
|
||||||
{
|
{
|
||||||
if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType()))
|
if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType()))
|
||||||
|
@ -5,24 +5,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<mapper namespace="com.ruoyi.generator.mapper.GenTableMapper">
|
<mapper namespace="com.ruoyi.generator.mapper.GenTableMapper">
|
||||||
|
|
||||||
<resultMap type="GenTable" id="GenTableResult">
|
<resultMap type="GenTable" id="GenTableResult">
|
||||||
<id property="tableId" column="table_id" />
|
<id property="tableId" column="table_id" />
|
||||||
<result property="tableName" column="table_name" />
|
<result property="tableName" column="table_name" />
|
||||||
<result property="tableComment" column="table_comment" />
|
<result property="tableComment" column="table_comment" />
|
||||||
<result property="className" column="class_name" />
|
<result property="subTableName" column="sub_table_name" />
|
||||||
<result property="tplCategory" column="tpl_category" />
|
<result property="subTableFkName" column="sub_table_fk_name" />
|
||||||
<result property="packageName" column="package_name" />
|
<result property="className" column="class_name" />
|
||||||
<result property="moduleName" column="module_name" />
|
<result property="tplCategory" column="tpl_category" />
|
||||||
<result property="businessName" column="business_name" />
|
<result property="packageName" column="package_name" />
|
||||||
<result property="functionName" column="function_name" />
|
<result property="moduleName" column="module_name" />
|
||||||
<result property="functionAuthor" column="function_author" />
|
<result property="businessName" column="business_name" />
|
||||||
<result property="genType" column="gen_type" />
|
<result property="functionName" column="function_name" />
|
||||||
<result property="genPath" column="gen_path" />
|
<result property="functionAuthor" column="function_author" />
|
||||||
<result property="options" column="options" />
|
<result property="genType" column="gen_type" />
|
||||||
<result property="createBy" column="create_by" />
|
<result property="genPath" column="gen_path" />
|
||||||
<result property="createTime" column="create_time" />
|
<result property="options" column="options" />
|
||||||
<result property="updateBy" column="update_by" />
|
<result property="createBy" column="create_by" />
|
||||||
<result property="updateTime" column="update_time" />
|
<result property="createTime" column="create_time" />
|
||||||
<result property="remark" column="remark" />
|
<result property="updateBy" column="update_by" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
|
<result property="remark" column="remark" />
|
||||||
<collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" />
|
<collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectGenTableVo">
|
<sql id="selectGenTableVo">
|
||||||
select table_id, table_name, table_comment, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table
|
select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectGenTableList" parameterType="GenTable" resultMap="GenTableResult">
|
<select id="selectGenTableList" parameterType="GenTable" resultMap="GenTableResult">
|
||||||
@ -64,11 +66,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="tableComment != null and tableComment != ''">
|
<if test="tableComment != null and tableComment != ''">
|
||||||
AND lower(table_comment) like lower(concat('%', #{tableComment}, '%'))
|
AND lower(table_comment) like lower(concat('%', #{tableComment}, '%'))
|
||||||
</if>
|
</if>
|
||||||
<if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
AND date_format(create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d')
|
AND date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
|
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
|
||||||
AND date_format(create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
AND date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
@ -84,11 +86,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="tableComment != null and tableComment != ''">
|
<if test="tableComment != null and tableComment != ''">
|
||||||
AND lower(table_comment) like lower(concat('%', #{tableComment}, '%'))
|
AND lower(table_comment) like lower(concat('%', #{tableComment}, '%'))
|
||||||
</if>
|
</if>
|
||||||
<if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
AND date_format(create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d')
|
AND date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
|
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
|
||||||
AND date_format(create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
AND date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
@ -108,7 +110,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult">
|
<select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult">
|
||||||
SELECT t.table_id, t.table_name, t.table_comment, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
||||||
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
||||||
FROM gen_table t
|
FROM gen_table t
|
||||||
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
||||||
@ -116,13 +118,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult">
|
<select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult">
|
||||||
SELECT t.table_id, t.table_name, t.table_comment, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
||||||
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
||||||
FROM gen_table t
|
FROM gen_table t
|
||||||
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
||||||
where t.table_name = #{tableName} order by c.sort
|
where t.table_name = #{tableName} order by c.sort
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectGenTableAll" parameterType="String" resultMap="GenTableResult">
|
||||||
|
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark,
|
||||||
|
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
||||||
|
FROM gen_table t
|
||||||
|
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
||||||
|
order by c.sort
|
||||||
|
</select>
|
||||||
|
|
||||||
<insert id="insertGenTable" parameterType="GenTable" useGeneratedKeys="true" keyProperty="tableId">
|
<insert id="insertGenTable" parameterType="GenTable" useGeneratedKeys="true" keyProperty="tableId">
|
||||||
insert into gen_table (
|
insert into gen_table (
|
||||||
<if test="tableName != null">table_name,</if>
|
<if test="tableName != null">table_name,</if>
|
||||||
@ -162,6 +172,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<set>
|
<set>
|
||||||
<if test="tableName != null">table_name = #{tableName},</if>
|
<if test="tableName != null">table_name = #{tableName},</if>
|
||||||
<if test="tableComment != null and tableComment != ''">table_comment = #{tableComment},</if>
|
<if test="tableComment != null and tableComment != ''">table_comment = #{tableComment},</if>
|
||||||
|
<if test="subTableName != null">sub_table_name = #{subTableName},</if>
|
||||||
|
<if test="subTableFkName != null">sub_table_fk_name = #{subTableFkName},</if>
|
||||||
<if test="className != null and className != ''">class_name = #{className},</if>
|
<if test="className != null and className != ''">class_name = #{className},</if>
|
||||||
<if test="functionAuthor != null and functionAuthor != ''">function_author = #{functionAuthor},</if>
|
<if test="functionAuthor != null and functionAuthor != ''">function_author = #{functionAuthor},</if>
|
||||||
<if test="genType != null and genType != ''">gen_type = #{genType},</if>
|
<if test="genType != null and genType != ''">gen_type = #{genType},</if>
|
||||||
|
@ -18,7 +18,7 @@ import com.ruoyi.common.enums.BusinessType;
|
|||||||
import ${packageName}.domain.${ClassName};
|
import ${packageName}.domain.${ClassName};
|
||||||
import ${packageName}.service.I${ClassName}Service;
|
import ${packageName}.service.I${ClassName}Service;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
#if($table.crud)
|
#if($table.crud || $table.sub)
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
#elseif($table.tree)
|
#elseif($table.tree)
|
||||||
#end
|
#end
|
||||||
@ -41,7 +41,7 @@ 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 || $table.sub)
|
||||||
public TableDataInfo list(${ClassName} ${className})
|
public TableDataInfo list(${ClassName} ${className})
|
||||||
{
|
{
|
||||||
startPage();
|
startPage();
|
||||||
|
@ -6,7 +6,7 @@ import ${import};
|
|||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import com.ruoyi.common.annotation.Excel;
|
import com.ruoyi.common.annotation.Excel;
|
||||||
#if($table.crud)
|
#if($table.crud || $table.sub)
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
#elseif($table.tree)
|
#elseif($table.tree)
|
||||||
import com.ruoyi.common.core.domain.TreeEntity;
|
import com.ruoyi.common.core.domain.TreeEntity;
|
||||||
@ -18,7 +18,7 @@ import com.ruoyi.common.core.domain.TreeEntity;
|
|||||||
* @author ${author}
|
* @author ${author}
|
||||||
* @date ${datetime}
|
* @date ${datetime}
|
||||||
*/
|
*/
|
||||||
#if($table.crud)
|
#if($table.crud || $table.sub)
|
||||||
#set($Entity="BaseEntity")
|
#set($Entity="BaseEntity")
|
||||||
#elseif($table.tree)
|
#elseif($table.tree)
|
||||||
#set($Entity="TreeEntity")
|
#set($Entity="TreeEntity")
|
||||||
@ -49,6 +49,11 @@ public class ${ClassName} extends ${Entity}
|
|||||||
private $column.javaType $column.javaField;
|
private $column.javaType $column.javaField;
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
#end
|
||||||
|
#if($table.sub)
|
||||||
|
/** $table.subTable.functionName信息 */
|
||||||
|
private List<${subClassName}> ${subclassName}List;
|
||||||
|
|
||||||
#end
|
#end
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if(!$table.isSuperColumn($column.javaField))
|
#if(!$table.isSuperColumn($column.javaField))
|
||||||
@ -69,6 +74,18 @@ public class ${ClassName} extends ${Entity}
|
|||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
#if($table.sub)
|
||||||
|
public List<${subClassName}> get${subClassName}List()
|
||||||
|
{
|
||||||
|
return ${subclassName}List;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set${subClassName}List(List<${subClassName}> ${subclassName}List)
|
||||||
|
{
|
||||||
|
this.${subclassName}List = ${subclassName}List;
|
||||||
|
}
|
||||||
|
|
||||||
|
#end
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
@ -79,6 +96,9 @@ public class ${ClassName} extends ${Entity}
|
|||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
#end
|
#end
|
||||||
.append("${column.javaField}", get${AttrName}())
|
.append("${column.javaField}", get${AttrName}())
|
||||||
|
#end
|
||||||
|
#if($table.sub)
|
||||||
|
.append("${subclassName}List", get${subClassName}List())
|
||||||
#end
|
#end
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@ package ${packageName}.mapper;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import ${packageName}.domain.${ClassName};
|
import ${packageName}.domain.${ClassName};
|
||||||
|
#if($table.sub)
|
||||||
|
import ${packageName}.domain.${subClassName};
|
||||||
|
#end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ${functionName}Mapper接口
|
* ${functionName}Mapper接口
|
||||||
@ -58,4 +61,31 @@ public interface ${ClassName}Mapper
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public int delete${ClassName}ByIds(${pkColumn.javaType}[] ${pkColumn.javaField}s);
|
public int delete${ClassName}ByIds(${pkColumn.javaType}[] ${pkColumn.javaField}s);
|
||||||
|
#if($table.sub)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除${subTable.functionName}
|
||||||
|
*
|
||||||
|
* @param customerIds 需要删除的数据ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量新增${subTable.functionName}
|
||||||
|
*
|
||||||
|
* @param ${subclassName}List ${subTable.functionName}列表
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int batch${subClassName}(List<${subClassName}> ${subclassName}List);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过${functionName}ID删除${subTable.functionName}信息
|
||||||
|
*
|
||||||
|
* @param roleId 角色ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField});
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,12 @@ import com.ruoyi.common.utils.DateUtils;
|
|||||||
#end
|
#end
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
#if($table.sub)
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import ${packageName}.domain.${subClassName};
|
||||||
|
#end
|
||||||
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;
|
||||||
@ -55,6 +61,9 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
|
|||||||
* @param ${className} ${functionName}
|
* @param ${className} ${functionName}
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
|
#if($table.sub)
|
||||||
|
@Transactional
|
||||||
|
#end
|
||||||
@Override
|
@Override
|
||||||
public int insert${ClassName}(${ClassName} ${className})
|
public int insert${ClassName}(${ClassName} ${className})
|
||||||
{
|
{
|
||||||
@ -63,7 +72,13 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
|
|||||||
${className}.setCreateTime(DateUtils.getNowDate());
|
${className}.setCreateTime(DateUtils.getNowDate());
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
#if($table.sub)
|
||||||
|
int rows = ${className}Mapper.insert${ClassName}(${className});
|
||||||
|
insert${subClassName}(${className});
|
||||||
|
return rows;
|
||||||
|
#else
|
||||||
return ${className}Mapper.insert${ClassName}(${className});
|
return ${className}Mapper.insert${ClassName}(${className});
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,6 +87,9 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
|
|||||||
* @param ${className} ${functionName}
|
* @param ${className} ${functionName}
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
|
#if($table.sub)
|
||||||
|
@Transactional
|
||||||
|
#end
|
||||||
@Override
|
@Override
|
||||||
public int update${ClassName}(${ClassName} ${className})
|
public int update${ClassName}(${ClassName} ${className})
|
||||||
{
|
{
|
||||||
@ -79,6 +97,10 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
|
|||||||
#if($column.javaField == 'updateTime')
|
#if($column.javaField == 'updateTime')
|
||||||
${className}.setUpdateTime(DateUtils.getNowDate());
|
${className}.setUpdateTime(DateUtils.getNowDate());
|
||||||
#end
|
#end
|
||||||
|
#end
|
||||||
|
#if($table.sub)
|
||||||
|
${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}());
|
||||||
|
insert${subClassName}(${className});
|
||||||
#end
|
#end
|
||||||
return ${className}Mapper.update${ClassName}(${className});
|
return ${className}Mapper.update${ClassName}(${className});
|
||||||
}
|
}
|
||||||
@ -89,9 +111,15 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
|
|||||||
* @param ${pkColumn.javaField}s 需要删除的${functionName}ID
|
* @param ${pkColumn.javaField}s 需要删除的${functionName}ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
|
#if($table.sub)
|
||||||
|
@Transactional
|
||||||
|
#end
|
||||||
@Override
|
@Override
|
||||||
public int delete${ClassName}ByIds(${pkColumn.javaType}[] ${pkColumn.javaField}s)
|
public int delete${ClassName}ByIds(${pkColumn.javaType}[] ${pkColumn.javaField}s)
|
||||||
{
|
{
|
||||||
|
#if($table.sub)
|
||||||
|
${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s);
|
||||||
|
#end
|
||||||
return ${className}Mapper.delete${ClassName}ByIds(${pkColumn.javaField}s);
|
return ${className}Mapper.delete${ClassName}ByIds(${pkColumn.javaField}s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +132,35 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
|
|||||||
@Override
|
@Override
|
||||||
public int delete${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField})
|
public int delete${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField})
|
||||||
{
|
{
|
||||||
|
#if($table.sub)
|
||||||
|
${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField});
|
||||||
|
#end
|
||||||
return ${className}Mapper.delete${ClassName}ById(${pkColumn.javaField});
|
return ${className}Mapper.delete${ClassName}ById(${pkColumn.javaField});
|
||||||
}
|
}
|
||||||
|
#if($table.sub)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增${subTable.functionName}信息
|
||||||
|
*
|
||||||
|
* @param ${className} ${functionName}对象
|
||||||
|
*/
|
||||||
|
public void insert${subClassName}(${ClassName} ${className})
|
||||||
|
{
|
||||||
|
List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List();
|
||||||
|
Long ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}();
|
||||||
|
if (StringUtils.isNotNull(${subclassName}List))
|
||||||
|
{
|
||||||
|
List<${subClassName}> list = new ArrayList<${subClassName}>();
|
||||||
|
for (${subClassName} ${subclassName} : ${subclassName}List)
|
||||||
|
{
|
||||||
|
${subclassName}.set${subTableFkClassName}(${pkColumn.javaField});
|
||||||
|
list.add(${subclassName});
|
||||||
|
}
|
||||||
|
if (list.size() > 0)
|
||||||
|
{
|
||||||
|
${className}Mapper.batch${subClassName}(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
package ${packageName}.domain;
|
||||||
|
|
||||||
|
#foreach ($import in $subImportList)
|
||||||
|
import ${import};
|
||||||
|
#end
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
import com.ruoyi.common.annotation.Excel;
|
||||||
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ${subTable.functionName}对象 ${subTableName}
|
||||||
|
*
|
||||||
|
* @author ${author}
|
||||||
|
* @date ${datetime}
|
||||||
|
*/
|
||||||
|
public class ${subClassName} extends BaseEntity
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
#foreach ($column in $subTable.columns)
|
||||||
|
#if(!$table.isSuperColumn($column.javaField))
|
||||||
|
/** $column.columnComment */
|
||||||
|
#if($column.list)
|
||||||
|
#set($parentheseIndex=$column.columnComment.indexOf("("))
|
||||||
|
#if($parentheseIndex != -1)
|
||||||
|
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
|
||||||
|
#else
|
||||||
|
#set($comment=$column.columnComment)
|
||||||
|
#end
|
||||||
|
#if($parentheseIndex != -1)
|
||||||
|
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
|
||||||
|
#elseif($column.javaType == 'Date')
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
|
||||||
|
#else
|
||||||
|
@Excel(name = "${comment}")
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
private $column.javaType $column.javaField;
|
||||||
|
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach ($column in $subTable.columns)
|
||||||
|
#if(!$table.isSuperColumn($column.javaField))
|
||||||
|
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
|
||||||
|
#set($AttrName=$column.javaField)
|
||||||
|
#else
|
||||||
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#end
|
||||||
|
public void set${AttrName}($column.javaType $column.javaField)
|
||||||
|
{
|
||||||
|
this.$column.javaField = $column.javaField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public $column.javaType get${AttrName}()
|
||||||
|
{
|
||||||
|
return $column.javaField;
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
#foreach ($column in $subTable.columns)
|
||||||
|
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
|
||||||
|
#set($AttrName=$column.javaField)
|
||||||
|
#else
|
||||||
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#end
|
||||||
|
.append("${column.javaField}", get${AttrName}())
|
||||||
|
#end
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +1,22 @@
|
|||||||
-- 菜单 SQL
|
-- 菜单 SQL
|
||||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '${functionName}菜单');
|
values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', sysdate(), '', null, '${functionName}菜单');
|
||||||
|
|
||||||
-- 按钮父菜单ID
|
-- 按钮父菜单ID
|
||||||
SELECT @parentId := LAST_INSERT_ID();
|
SELECT @parentId := LAST_INSERT_ID();
|
||||||
|
|
||||||
-- 按钮 SQL
|
-- 按钮 SQL
|
||||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
values('${functionName}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '');
|
values('${functionName}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query', '#', 'admin', sysdate(), '', null, '');
|
||||||
|
|
||||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
values('${functionName}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '');
|
values('${functionName}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add', '#', 'admin', sysdate(), '', null, '');
|
||||||
|
|
||||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
values('${functionName}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '');
|
values('${functionName}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit', '#', 'admin', sysdate(), '', null, '');
|
||||||
|
|
||||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
values('${functionName}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '');
|
values('${functionName}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove', '#', 'admin', sysdate(), '', null, '');
|
||||||
|
|
||||||
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||||||
values('${functionName}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '');
|
values('${functionName}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export', '#', 'admin', sysdate(), '', null, '');
|
@ -38,20 +38,33 @@
|
|||||||
<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
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -60,6 +73,7 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
plain
|
||||||
icon="el-icon-plus"
|
icon="el-icon-plus"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="handleAdd"
|
@click="handleAdd"
|
||||||
@ -139,6 +153,14 @@
|
|||||||
<el-form-item label="${comment}" prop="${field}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "imageUpload")
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<imageUpload v-model="form.${field}"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "fileUpload")
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<fileUpload v-model="form.${field}"/>
|
||||||
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "editor")
|
#elseif($column.htmlType == "editor")
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}">
|
||||||
<editor v-model="form.${field}" :min-height="192"/>
|
<editor v-model="form.${field}" :min-height="192"/>
|
||||||
@ -197,7 +219,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"
|
||||||
@ -226,6 +248,18 @@ import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${Busin
|
|||||||
import Treeselect from "@riophae/vue-treeselect";
|
import Treeselect from "@riophae/vue-treeselect";
|
||||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||||
#foreach($column in $columns)
|
#foreach($column in $columns)
|
||||||
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "imageUpload")
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "fileUpload")
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
|
||||||
import Editor from '@/components/Editor';
|
import Editor from '@/components/Editor';
|
||||||
#break
|
#break
|
||||||
@ -236,6 +270,18 @@ export default {
|
|||||||
name: "${BusinessName}",
|
name: "${BusinessName}",
|
||||||
components: {
|
components: {
|
||||||
#foreach($column in $columns)
|
#foreach($column in $columns)
|
||||||
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "imageUpload")
|
||||||
|
ImageUpload,
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "fileUpload")
|
||||||
|
FileUpload,
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
|
||||||
Editor,
|
Editor,
|
||||||
#break
|
#break
|
||||||
@ -267,6 +313,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
|
||||||
// 查询参数
|
// 查询参数
|
||||||
@ -313,6 +363,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;
|
||||||
@ -381,6 +446,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();
|
||||||
},
|
},
|
||||||
@ -420,19 +491,15 @@ export default {
|
|||||||
#end
|
#end
|
||||||
if (this.form.${pkColumn.javaField} != null) {
|
if (this.form.${pkColumn.javaField} != null) {
|
||||||
update${BusinessName}(this.form).then(response => {
|
update${BusinessName}(this.form).then(response => {
|
||||||
if (response.code === 200) {
|
this.msgSuccess("修改成功");
|
||||||
this.msgSuccess("修改成功");
|
this.open = false;
|
||||||
this.open = false;
|
this.getList();
|
||||||
this.getList();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
add${BusinessName}(this.form).then(response => {
|
add${BusinessName}(this.form).then(response => {
|
||||||
if (response.code === 200) {
|
this.msgSuccess("新增成功");
|
||||||
this.msgSuccess("新增成功");
|
this.open = false;
|
||||||
this.open = false;
|
this.getList();
|
||||||
this.getList();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -449,7 +516,7 @@ export default {
|
|||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.msgSuccess("删除成功");
|
this.msgSuccess("删除成功");
|
||||||
}).catch(function() {});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -38,20 +38,33 @@
|
|||||||
<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
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -60,6 +73,7 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
plain
|
||||||
icon="el-icon-plus"
|
icon="el-icon-plus"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="handleAdd"
|
@click="handleAdd"
|
||||||
@ -69,6 +83,7 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button
|
||||||
type="success"
|
type="success"
|
||||||
|
plain
|
||||||
icon="el-icon-edit"
|
icon="el-icon-edit"
|
||||||
size="mini"
|
size="mini"
|
||||||
:disabled="single"
|
:disabled="single"
|
||||||
@ -79,6 +94,7 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
|
plain
|
||||||
icon="el-icon-delete"
|
icon="el-icon-delete"
|
||||||
size="mini"
|
size="mini"
|
||||||
:disabled="multiple"
|
:disabled="multiple"
|
||||||
@ -89,13 +105,14 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button
|
||||||
type="warning"
|
type="warning"
|
||||||
|
plain
|
||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
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">
|
||||||
@ -168,6 +185,14 @@
|
|||||||
<el-form-item label="${comment}" prop="${field}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "imageUpload")
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<imageUpload v-model="form.${field}"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "fileUpload")
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<fileUpload v-model="form.${field}"/>
|
||||||
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "editor")
|
#elseif($column.htmlType == "editor")
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}">
|
||||||
<editor v-model="form.${field}" :min-height="192"/>
|
<editor v-model="form.${field}" :min-height="192"/>
|
||||||
@ -226,7 +251,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"
|
||||||
@ -240,6 +265,38 @@
|
|||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
#end
|
||||||
|
#if($table.sub)
|
||||||
|
<el-divider content-position="center">${subTable.functionName}信息</el-divider>
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd${subClassName}">添加</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDelete${subClassName}">删除</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-table :data="${subclassName}List" :row-class-name="row${subClassName}Index" @selection-change="handle${subClassName}SelectionChange" ref="${subclassName}">
|
||||||
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
|
<el-table-column label="序号" align="center" prop="index" width="50"/>
|
||||||
|
#foreach($column in $subTable.columns)
|
||||||
|
#set($javaField=$column.javaField)
|
||||||
|
#set($parentheseIndex=$column.columnComment.indexOf("("))
|
||||||
|
#if($parentheseIndex != -1)
|
||||||
|
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
|
||||||
|
#else
|
||||||
|
#set($comment=$column.columnComment)
|
||||||
|
#end
|
||||||
|
#if($column.pk || $javaField == ${subTableFkclassName})
|
||||||
|
#elseif($column.list && "" != $javaField)
|
||||||
|
<el-table-column label="$comment" prop="${javaField}">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-input v-model="scope.row.$javaField" placeholder="请输入$comment" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</el-table>
|
||||||
#end
|
#end
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
@ -253,6 +310,18 @@
|
|||||||
<script>
|
<script>
|
||||||
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName}, export${BusinessName} } from "@/api/${moduleName}/${businessName}";
|
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName}, export${BusinessName} } from "@/api/${moduleName}/${businessName}";
|
||||||
#foreach($column in $columns)
|
#foreach($column in $columns)
|
||||||
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "imageUpload")
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "fileUpload")
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
|
||||||
import Editor from '@/components/Editor';
|
import Editor from '@/components/Editor';
|
||||||
#break
|
#break
|
||||||
@ -261,18 +330,36 @@ import Editor from '@/components/Editor';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "${BusinessName}",
|
name: "${BusinessName}",
|
||||||
|
components: {
|
||||||
#foreach($column in $columns)
|
#foreach($column in $columns)
|
||||||
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "imageUpload")
|
||||||
components: { Editor },
|
ImageUpload,
|
||||||
#break
|
#break
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "fileUpload")
|
||||||
|
FileUpload,
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
|
||||||
|
Editor,
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
|
#if($table.sub)
|
||||||
|
// 子表选中数据
|
||||||
|
checked${subClassName}: [],
|
||||||
|
#end
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
single: true,
|
single: true,
|
||||||
// 非多个禁用
|
// 非多个禁用
|
||||||
@ -283,6 +370,10 @@ export default {
|
|||||||
total: 0,
|
total: 0,
|
||||||
// ${functionName}表格数据
|
// ${functionName}表格数据
|
||||||
${businessName}List: [],
|
${businessName}List: [],
|
||||||
|
#if($table.sub)
|
||||||
|
// ${subTable.functionName}表格数据
|
||||||
|
${subclassName}List: [],
|
||||||
|
#end
|
||||||
// 弹出层标题
|
// 弹出层标题
|
||||||
title: "",
|
title: "",
|
||||||
// 是否显示弹出层
|
// 是否显示弹出层
|
||||||
@ -297,6 +388,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
|
||||||
// 查询参数
|
// 查询参数
|
||||||
@ -345,6 +440,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;
|
||||||
@ -386,6 +496,9 @@ export default {
|
|||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
};
|
};
|
||||||
|
#if($table.sub)
|
||||||
|
this.${subclassName}List = [];
|
||||||
|
#end
|
||||||
this.resetForm("form");
|
this.resetForm("form");
|
||||||
},
|
},
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
@ -395,6 +508,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();
|
||||||
},
|
},
|
||||||
@ -420,6 +539,9 @@ export default {
|
|||||||
#if($column.htmlType == "checkbox")
|
#if($column.htmlType == "checkbox")
|
||||||
this.form.$column.javaField = this.form.${column.javaField}.split(",");
|
this.form.$column.javaField = this.form.${column.javaField}.split(",");
|
||||||
#end
|
#end
|
||||||
|
#end
|
||||||
|
#if($table.sub)
|
||||||
|
this.${subclassName}List = response.data.${subclassName}List;
|
||||||
#end
|
#end
|
||||||
this.open = true;
|
this.open = true;
|
||||||
this.title = "修改${functionName}";
|
this.title = "修改${functionName}";
|
||||||
@ -433,22 +555,21 @@ export default {
|
|||||||
#if($column.htmlType == "checkbox")
|
#if($column.htmlType == "checkbox")
|
||||||
this.form.$column.javaField = this.form.${column.javaField}.join(",");
|
this.form.$column.javaField = this.form.${column.javaField}.join(",");
|
||||||
#end
|
#end
|
||||||
|
#end
|
||||||
|
#if($table.sub)
|
||||||
|
this.form.${subclassName}List = this.${subclassName}List;
|
||||||
#end
|
#end
|
||||||
if (this.form.${pkColumn.javaField} != null) {
|
if (this.form.${pkColumn.javaField} != null) {
|
||||||
update${BusinessName}(this.form).then(response => {
|
update${BusinessName}(this.form).then(response => {
|
||||||
if (response.code === 200) {
|
this.msgSuccess("修改成功");
|
||||||
this.msgSuccess("修改成功");
|
this.open = false;
|
||||||
this.open = false;
|
this.getList();
|
||||||
this.getList();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
add${BusinessName}(this.form).then(response => {
|
add${BusinessName}(this.form).then(response => {
|
||||||
if (response.code === 200) {
|
this.msgSuccess("新增成功");
|
||||||
this.msgSuccess("新增成功");
|
this.open = false;
|
||||||
this.open = false;
|
this.getList();
|
||||||
this.getList();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,8 +587,42 @@ export default {
|
|||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.msgSuccess("删除成功");
|
this.msgSuccess("删除成功");
|
||||||
}).catch(function() {});
|
})
|
||||||
},
|
},
|
||||||
|
#if($table.sub)
|
||||||
|
/** ${subTable.functionName}序号 */
|
||||||
|
row${subClassName}Index({ row, rowIndex }) {
|
||||||
|
row.index = rowIndex + 1;
|
||||||
|
},
|
||||||
|
/** ${subTable.functionName}添加按钮操作 */
|
||||||
|
handleAdd${subClassName}() {
|
||||||
|
let obj = {};
|
||||||
|
#foreach($column in $subTable.columns)
|
||||||
|
#if($column.pk || $column.javaField == ${subTableFkclassName})
|
||||||
|
#elseif($column.list && "" != $javaField)
|
||||||
|
obj.$column.javaField = "";
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
this.${subclassName}List.push(obj);
|
||||||
|
},
|
||||||
|
/** ${subTable.functionName}删除按钮操作 */
|
||||||
|
handleDelete${subClassName}() {
|
||||||
|
if (this.checked${subClassName}.length == 0) {
|
||||||
|
this.$alert("请先选择要删除的${subTable.functionName}数据", "提示", { confirmButtonText: "确定", });
|
||||||
|
} else {
|
||||||
|
this.${subclassName}List.splice(this.checked${subClassName}[0].index - 1, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 单选框选中数据 */
|
||||||
|
handle${subClassName}SelectionChange(selection) {
|
||||||
|
if (selection.length > 1) {
|
||||||
|
this.$refs.${subclassName}.clearSelection();
|
||||||
|
this.$refs.${subclassName}.toggleRowSelection(selection.pop());
|
||||||
|
} else {
|
||||||
|
this.checked${subClassName} = selection;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
#end
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
handleExport() {
|
||||||
const queryParams = this.queryParams;
|
const queryParams = this.queryParams;
|
||||||
@ -479,7 +634,7 @@ export default {
|
|||||||
return export${BusinessName}(queryParams);
|
return export${BusinessName}(queryParams);
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
this.download(response.msg);
|
this.download(response.msg);
|
||||||
}).catch(function() {});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -9,6 +9,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="${column.javaField}" column="${column.columnName}" />
|
<result property="${column.javaField}" column="${column.columnName}" />
|
||||||
#end
|
#end
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
#if($table.sub)
|
||||||
|
|
||||||
|
<resultMap id="${ClassName}${subClassName}Result" type="${ClassName}" extends="${ClassName}Result">
|
||||||
|
<collection property="${subclassName}List" notNullColumn="${subTable.pkColumn.columnName}" javaType="java.util.List" resultMap="${subClassName}Result" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<resultMap type="${subClassName}" id="${subClassName}Result">
|
||||||
|
#foreach ($column in $subTable.columns)
|
||||||
|
<result property="${column.javaField}" column="${column.columnName}" />
|
||||||
|
#end
|
||||||
|
</resultMap>
|
||||||
|
#end
|
||||||
|
|
||||||
<sql id="select${ClassName}Vo">
|
<sql id="select${ClassName}Vo">
|
||||||
select#foreach($column in $columns) $column.columnName#if($velocityCount != $columns.size()),#end#end from ${tableName}
|
select#foreach($column in $columns) $column.columnName#if($velocityCount != $columns.size()),#end#end from ${tableName}
|
||||||
@ -46,9 +58,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="select${ClassName}ById" parameterType="${pkColumn.javaType}" resultMap="${ClassName}Result">
|
<select id="select${ClassName}ById" parameterType="${pkColumn.javaType}" resultMap="#if($table.sub)${ClassName}${subClassName}Result#else${ClassName}Result#end">
|
||||||
|
#if($table.crud || $table.tree)
|
||||||
<include refid="select${ClassName}Vo"/>
|
<include refid="select${ClassName}Vo"/>
|
||||||
where ${pkColumn.columnName} = #{${pkColumn.javaField}}
|
where ${pkColumn.columnName} = #{${pkColumn.javaField}}
|
||||||
|
#elseif($table.sub)
|
||||||
|
select#foreach($column in $columns) a.$column.columnName#if($velocityCount != $columns.size()),#end#end,
|
||||||
|
#foreach($column in $subTable.columns) b.$column.columnName#if($velocityCount != $subTable.columns.size()),#end#end
|
||||||
|
|
||||||
|
from ${tableName} a
|
||||||
|
left join ${subTableName} b on b.${subTableFkName} = a.${pkColumn.columnName}
|
||||||
|
where a.${pkColumn.columnName} = #{${pkColumn.javaField}}
|
||||||
|
#end
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<insert id="insert${ClassName}" parameterType="${ClassName}"#if($pkColumn.increment) useGeneratedKeys="true" keyProperty="$pkColumn.javaField"#end>
|
<insert id="insert${ClassName}" parameterType="${ClassName}"#if($pkColumn.increment) useGeneratedKeys="true" keyProperty="$pkColumn.javaField"#end>
|
||||||
@ -91,5 +112,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
#{${pkColumn.javaField}}
|
#{${pkColumn.javaField}}
|
||||||
</foreach>
|
</foreach>
|
||||||
</delete>
|
</delete>
|
||||||
|
#if($table.sub)
|
||||||
|
|
||||||
|
<delete id="delete${subClassName}By${subTableFkClassName}s" parameterType="String">
|
||||||
|
delete from ${subTableName} where ${subTableFkName} in
|
||||||
|
<foreach item="${subTableFkclassName}" collection="array" open="(" separator="," close=")">
|
||||||
|
#{${subTableFkclassName}}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="delete${subClassName}By${subTableFkClassName}" parameterType="Long">
|
||||||
|
delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<insert id="batch${subClassName}">
|
||||||
|
insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($velocityCount != $subTable.columns.size()),#end#end) values
|
||||||
|
<foreach item="item" index="index" collection="list" separator=",">
|
||||||
|
(#foreach($column in $subTable.columns) #{item.$column.javaField}#if($velocityCount != $subTable.columns.size()),#end#end)
|
||||||
|
</foreach>
|
||||||
|
</insert>
|
||||||
|
#end
|
||||||
</mapper>
|
</mapper>
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.2.0</version>
|
<version>3.4.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -35,11 +35,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="invokeTarget != null and invokeTarget != ''">
|
<if test="invokeTarget != null and invokeTarget != ''">
|
||||||
AND invoke_target like concat('%', #{invokeTarget}, '%')
|
AND invoke_target like concat('%', #{invokeTarget}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
and date_format(create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d')
|
and date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
|
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
|
||||||
and date_format(create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
and date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.2.0</version>
|
<version>3.4.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -26,6 +26,14 @@ public interface SysRoleMenuMapper
|
|||||||
*/
|
*/
|
||||||
public int deleteRoleMenuByRoleId(Long roleId);
|
public int deleteRoleMenuByRoleId(Long roleId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除角色菜单关联信息
|
||||||
|
*
|
||||||
|
* @param ids 需要删除的数据ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int deleteRoleMenu(Long[] ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量新增角色菜单信息
|
* 批量新增角色菜单信息
|
||||||
*
|
*
|
||||||
|
@ -364,6 +364,10 @@ public class SysMenuServiceImpl implements ISysMenuService
|
|||||||
{
|
{
|
||||||
component = menu.getComponent();
|
component = menu.getComponent();
|
||||||
}
|
}
|
||||||
|
else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu))
|
||||||
|
{
|
||||||
|
component = UserConstants.PARENT_VIEW;
|
||||||
|
}
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,6 +383,17 @@ public class SysMenuServiceImpl implements ISysMenuService
|
|||||||
&& menu.getIsFrame().equals(UserConstants.NO_FRAME);
|
&& menu.getIsFrame().equals(UserConstants.NO_FRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为parent_view组件
|
||||||
|
*
|
||||||
|
* @param menu 菜单信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public boolean isParentView(SysMenu menu)
|
||||||
|
{
|
||||||
|
return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据父节点的ID获取所有子节点
|
* 根据父节点的ID获取所有子节点
|
||||||
*
|
*
|
||||||
|
@ -290,8 +290,13 @@ public class SysRoleServiceImpl implements ISysRoleService
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public int deleteRoleById(Long roleId)
|
public int deleteRoleById(Long roleId)
|
||||||
{
|
{
|
||||||
|
// 删除角色与菜单关联
|
||||||
|
roleMenuMapper.deleteRoleMenuByRoleId(roleId);
|
||||||
|
// 删除角色与部门关联
|
||||||
|
roleDeptMapper.deleteRoleDeptByRoleId(roleId);
|
||||||
return roleMapper.deleteRoleById(roleId);
|
return roleMapper.deleteRoleById(roleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +307,7 @@ public class SysRoleServiceImpl implements ISysRoleService
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public int deleteRoleByIds(Long[] roleIds)
|
public int deleteRoleByIds(Long[] roleIds)
|
||||||
{
|
{
|
||||||
for (Long roleId : roleIds)
|
for (Long roleId : roleIds)
|
||||||
@ -313,6 +319,10 @@ public class SysRoleServiceImpl implements ISysRoleService
|
|||||||
throw new CustomException(String.format("%1$s已分配,不能删除", role.getRoleName()));
|
throw new CustomException(String.format("%1$s已分配,不能删除", role.getRoleName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 删除角色与菜单关联
|
||||||
|
roleMenuMapper.deleteRoleMenu(roleIds);
|
||||||
|
// 删除角色与部门关联
|
||||||
|
roleDeptMapper.deleteRoleDept(roleIds);
|
||||||
return roleMapper.deleteRoleByIds(roleIds);
|
return roleMapper.deleteRoleByIds(roleIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,6 +363,7 @@ public class SysUserServiceImpl implements ISysUserService
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public int deleteUserById(Long userId)
|
public int deleteUserById(Long userId)
|
||||||
{
|
{
|
||||||
// 删除用户与角色关联
|
// 删除用户与角色关联
|
||||||
@ -379,12 +380,17 @@ public class SysUserServiceImpl implements ISysUserService
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public int deleteUserByIds(Long[] userIds)
|
public int deleteUserByIds(Long[] userIds)
|
||||||
{
|
{
|
||||||
for (Long userId : userIds)
|
for (Long userId : userIds)
|
||||||
{
|
{
|
||||||
checkUserAllowed(new SysUser(userId));
|
checkUserAllowed(new SysUser(userId));
|
||||||
}
|
}
|
||||||
|
// 删除用户与角色关联
|
||||||
|
userRoleMapper.deleteUserRole(userIds);
|
||||||
|
// 删除用户与岗位关联
|
||||||
|
userPostMapper.deleteUserPost(userIds);
|
||||||
return userMapper.deleteUserByIds(userIds);
|
return userMapper.deleteUserByIds(userIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,11 +50,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="configKey != null and configKey != ''">
|
<if test="configKey != null and configKey != ''">
|
||||||
AND config_key like concat('%', #{configKey}, '%')
|
AND config_key like concat('%', #{configKey}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
and date_format(create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d')
|
and date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
|
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
|
||||||
and date_format(create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
and date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
@ -32,11 +32,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="dictType != null and dictType != ''">
|
<if test="dictType != null and dictType != ''">
|
||||||
AND dict_type like concat('%', #{dictType}, '%')
|
AND dict_type like concat('%', #{dictType}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
and date_format(create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d')
|
and date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
|
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
|
||||||
and date_format(create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
and date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
@ -33,11 +33,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="userName != null and userName != ''">
|
<if test="userName != null and userName != ''">
|
||||||
AND user_name like concat('%', #{userName}, '%')
|
AND user_name like concat('%', #{userName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
and date_format(login_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d')
|
and date_format(login_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
|
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
|
||||||
and date_format(login_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
and date_format(login_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
order by info_id desc
|
order by info_id desc
|
||||||
|
@ -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>
|
||||||
|
@ -54,11 +54,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="operName != null and operName != ''">
|
<if test="operName != null and operName != ''">
|
||||||
AND oper_name like concat('%', #{operName}, '%')
|
AND oper_name like concat('%', #{operName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
and date_format(oper_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d')
|
and date_format(oper_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
|
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
|
||||||
and date_format(oper_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
and date_format(oper_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
order by oper_id desc
|
order by oper_id desc
|
||||||
|
@ -42,11 +42,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="roleKey != null and roleKey != ''">
|
<if test="roleKey != null and roleKey != ''">
|
||||||
AND r.role_key like concat('%', #{roleKey}, '%')
|
AND r.role_key like concat('%', #{roleKey}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
and date_format(r.create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d')
|
and date_format(r.create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
|
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
|
||||||
and date_format(r.create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
and date_format(r.create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<!-- 数据范围过滤 -->
|
<!-- 数据范围过滤 -->
|
||||||
${params.dataScope}
|
${params.dataScope}
|
||||||
|
@ -17,6 +17,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
delete from sys_role_menu where role_id=#{roleId}
|
delete from sys_role_menu where role_id=#{roleId}
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteRoleMenu" parameterType="Long">
|
||||||
|
delete from sys_role_menu where role_id in
|
||||||
|
<foreach collection="array" item="roleId" open="(" separator="," close=")">
|
||||||
|
#{roleId}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
|
||||||
<insert id="batchRoleMenu">
|
<insert id="batchRoleMenu">
|
||||||
insert into sys_role_menu(role_id, menu_id) values
|
insert into sys_role_menu(role_id, menu_id) values
|
||||||
<foreach item="item" index="index" collection="list" separator=",">
|
<foreach item="item" index="index" collection="list" separator=",">
|
||||||
|
@ -68,11 +68,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="phonenumber != null and phonenumber != ''">
|
<if test="phonenumber != null and phonenumber != ''">
|
||||||
AND u.phonenumber like concat('%', #{phonenumber}, '%')
|
AND u.phonenumber like concat('%', #{phonenumber}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
AND date_format(u.create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d')
|
AND date_format(u.create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
|
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
|
||||||
AND date_format(u.create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
AND date_format(u.create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||||
</if>
|
</if>
|
||||||
<if test="deptId != null and deptId != 0">
|
<if test="deptId != null and deptId != 0">
|
||||||
AND (u.dept_id = #{deptId} OR u.dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE find_in_set(#{deptId}, ancestors) ))
|
AND (u.dept_id = #{deptId} OR u.dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE find_in_set(#{deptId}, ancestors) ))
|
||||||
@ -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>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ruoyi",
|
"name": "ruoyi",
|
||||||
"version": "3.2.0",
|
"version": "3.4.0",
|
||||||
"description": "若依管理系统",
|
"description": "若依管理系统",
|
||||||
"author": "若依",
|
"author": "若依",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -9,11 +9,7 @@
|
|||||||
"build:prod": "vue-cli-service build",
|
"build:prod": "vue-cli-service build",
|
||||||
"build:stage": "vue-cli-service build --mode staging",
|
"build:stage": "vue-cli-service build --mode staging",
|
||||||
"preview": "node build/index.js --preview",
|
"preview": "node build/index.js --preview",
|
||||||
"lint": "eslint --ext .js,.vue src",
|
"lint": "eslint --ext .js,.vue src"
|
||||||
"test:unit": "jest --clearCache && vue-cli-service test:unit",
|
|
||||||
"test:ci": "npm run lint && npm run test:unit",
|
|
||||||
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
|
|
||||||
"new": "plop"
|
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
@ -41,59 +37,44 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@riophae/vue-treeselect": "0.4.0",
|
"@riophae/vue-treeselect": "0.4.0",
|
||||||
"axios": "0.18.1",
|
"axios": "0.21.0",
|
||||||
"clipboard": "2.0.4",
|
"clipboard": "2.0.6",
|
||||||
"core-js": "3.6.5",
|
"core-js": "3.8.1",
|
||||||
"echarts": "4.2.1",
|
"echarts": "4.9.0",
|
||||||
"element-ui": "2.13.2",
|
"element-ui": "2.15.0",
|
||||||
"file-saver": "2.0.1",
|
"file-saver": "2.0.4",
|
||||||
"js-beautify": "1.10.2",
|
"fuse.js": "6.4.3",
|
||||||
"fuse.js": "3.4.4",
|
"highlight.js": "9.18.5",
|
||||||
"js-cookie": "2.2.0",
|
"js-beautify": "1.13.0",
|
||||||
|
"js-cookie": "2.2.1",
|
||||||
"jsencrypt": "3.0.0-rc.1",
|
"jsencrypt": "3.0.0-rc.1",
|
||||||
"normalize.css": "7.0.0",
|
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"path-to-regexp": "2.4.0",
|
|
||||||
"screenfull": "4.2.0",
|
|
||||||
"sortablejs": "1.8.4",
|
|
||||||
"vue": "2.6.10",
|
|
||||||
"vue-count-to": "1.0.13",
|
|
||||||
"quill": "1.3.7",
|
"quill": "1.3.7",
|
||||||
"vue-cropper": "0.4.9",
|
"screenfull": "5.0.2",
|
||||||
"vue-router": "3.0.2",
|
"sortablejs": "1.10.2",
|
||||||
"vue-splitpane": "1.0.4",
|
"vue": "2.6.12",
|
||||||
"vuedraggable": "2.20.0",
|
"vue-count-to": "1.0.13",
|
||||||
"vuex": "3.1.0"
|
"vue-cropper": "0.5.5",
|
||||||
|
"vue-router": "3.4.9",
|
||||||
|
"vuedraggable": "2.24.3",
|
||||||
|
"vuex": "3.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "4.4.4",
|
"@vue/cli-plugin-babel": "4.4.6",
|
||||||
"@vue/cli-plugin-eslint": "4.4.4",
|
"@vue/cli-plugin-eslint": "4.4.6",
|
||||||
"@vue/cli-plugin-unit-jest": "4.4.4",
|
"@vue/cli-service": "4.4.6",
|
||||||
"@vue/cli-service": "4.4.4",
|
|
||||||
"@vue/test-utils": "1.0.0-beta.29",
|
|
||||||
"autoprefixer": "9.5.1",
|
|
||||||
"babel-eslint": "10.1.0",
|
"babel-eslint": "10.1.0",
|
||||||
"babel-jest": "23.6.0",
|
"chalk": "4.1.0",
|
||||||
"babel-plugin-dynamic-import-node": "2.3.3",
|
|
||||||
"chalk": "2.4.2",
|
|
||||||
"chokidar": "2.1.5",
|
|
||||||
"connect": "3.6.6",
|
"connect": "3.6.6",
|
||||||
"eslint": "6.7.2",
|
"eslint": "7.15.0",
|
||||||
"eslint-plugin-vue": "6.2.2",
|
"eslint-plugin-vue": "7.2.0",
|
||||||
"html-webpack-plugin": "3.2.0",
|
"lint-staged": "10.5.3",
|
||||||
"husky": "1.3.1",
|
"runjs": "4.4.2",
|
||||||
"lint-staged": "8.1.5",
|
"sass": "1.32.0",
|
||||||
"mockjs": "1.0.1-beta3",
|
"sass-loader": "10.1.0",
|
||||||
"plop": "2.3.0",
|
"script-ext-html-webpack-plugin": "2.1.5",
|
||||||
"runjs": "4.3.2",
|
"svg-sprite-loader": "5.1.1",
|
||||||
"node-sass": "4.14.1",
|
"vue-template-compiler": "2.6.12"
|
||||||
"sass-loader": "8.0.2",
|
|
||||||
"script-ext-html-webpack-plugin": "2.1.3",
|
|
||||||
"script-loader": "0.7.2",
|
|
||||||
"serve-static": "1.13.2",
|
|
||||||
"svg-sprite-loader": "4.1.3",
|
|
||||||
"svgo": "1.2.0",
|
|
||||||
"vue-template-compiler": "2.6.10"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.9",
|
"node": ">=8.9",
|
||||||
|
9
ruoyi-ui/src/api/monitor/cache.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询缓存详细
|
||||||
|
export function getCache() {
|
||||||
|
return request({
|
||||||
|
url: '/monitor/cache',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
1
ruoyi-ui/src/assets/icons/svg/redis.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1605865043777" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="856" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M1023.786667 611.84c-0.426667 9.770667-13.354667 20.693333-39.893334 34.56-54.613333 28.458667-337.749333 144.896-397.994666 176.298667-60.288 31.402667-93.738667 31.104-141.354667 8.32-47.616-22.741333-348.842667-144.469333-403.114667-170.368-27.093333-12.970667-40.917333-23.893333-41.386666-34.218667v103.509333c0 10.325333 14.250667 21.290667 41.386666 34.261334 54.272 25.941333 355.541333 147.626667 403.114667 170.368 47.616 22.784 81.066667 23.082667 141.354667-8.362667 60.245333-31.402667 343.338667-147.797333 397.994666-176.298667 27.776-14.464 40.106667-25.728 40.106667-35.925333v-102.058667l-0.213333-0.085333z m0-168.746667c-0.512 9.770667-13.397333 20.650667-39.893334 34.517334-54.613333 28.458667-337.749333 144.896-397.994666 176.298666-60.288 31.402667-93.738667 31.104-141.354667 8.362667-47.616-22.741333-348.842667-144.469333-403.114667-170.410667-27.093333-12.928-40.917333-23.893333-41.386666-34.176v103.509334c0 10.325333 14.250667 21.248 41.386666 34.218666 54.272 25.941333 355.498667 147.626667 403.114667 170.368 47.616 22.784 81.066667 23.082667 141.354667-8.32 60.245333-31.402667 343.338667-147.84 397.994666-176.298666 27.776-14.506667 40.106667-25.770667 40.106667-35.968v-102.058667l-0.256-0.042667z m0-175.018666c0.469333-10.410667-13.141333-19.541333-40.533334-29.610667-53.248-19.498667-334.634667-131.498667-388.522666-151.253333-53.888-19.712-75.818667-18.901333-139.093334 3.84C392.234667 113.706667 92.629333 231.253333 39.338667 252.074667c-26.666667 10.496-39.68 20.181333-39.253334 30.506666V386.133333c0 10.325333 14.250667 21.248 41.386667 34.218667 54.272 25.941333 355.498667 147.669333 403.114667 170.410667 47.616 22.741333 81.066667 23.04 141.354666-8.362667 60.245333-31.402667 343.338667-147.84 397.994667-176.298667 27.776-14.506667 40.106667-25.770667 40.106667-35.968V268.074667h-0.341334zM366.677333 366.08l237.269334-36.437333-71.68 105.088-165.546667-68.650667z m524.8-94.634667l-140.330666 55.466667-15.232 5.973333-140.245334-55.466666 155.392-61.44 140.373334 55.466666z m-411.989333-101.674666l-22.954667-42.325334 71.594667 27.989334 67.498667-22.101334-18.261334 43.733334 68.778667 25.770666-88.704 9.216-19.882667 47.786667-32.085333-53.290667-102.4-9.216 76.416-27.562666z m-176.768 59.733333c70.058667 0 126.805333 21.973333 126.805333 49.109333s-56.746667 49.152-126.805333 49.152-126.848-22.058667-126.848-49.152c0-27.136 56.789333-49.152 126.848-49.152z" p-id="857"></path></svg>
|
After Width: | Height: | Size: 2.8 KiB |
39
ruoyi-ui/src/assets/images/dark.svg
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<defs>
|
||||||
|
<filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1">
|
||||||
|
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||||
|
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||||
|
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
|
||||||
|
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
<rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect>
|
||||||
|
<filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4">
|
||||||
|
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||||
|
<feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||||
|
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<g id="配置面板" width="48" height="40" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="setting-copy-2" width="48" height="40" transform="translate(-1190.000000, -136.000000)">
|
||||||
|
<g id="Group-8" width="48" height="40" transform="translate(1167.000000, 0.000000)">
|
||||||
|
<g id="Group-5-Copy-5" filter="url(#filter-1)" transform="translate(25.000000, 137.000000)">
|
||||||
|
<mask id="mask-3" fill="white">
|
||||||
|
<use xlink:href="#path-2"></use>
|
||||||
|
</mask>
|
||||||
|
<g id="Rectangle-18">
|
||||||
|
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
|
||||||
|
<use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use>
|
||||||
|
</g>
|
||||||
|
<rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect>
|
||||||
|
<rect id="Rectangle-18" fill="#303648" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
39
ruoyi-ui/src/assets/images/light.svg
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<defs>
|
||||||
|
<filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1">
|
||||||
|
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||||
|
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||||
|
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
|
||||||
|
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
<rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect>
|
||||||
|
<filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4">
|
||||||
|
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||||
|
<feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||||
|
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<g id="配置面板" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="setting-copy-2" transform="translate(-1254.000000, -136.000000)">
|
||||||
|
<g id="Group-8" transform="translate(1167.000000, 0.000000)">
|
||||||
|
<g id="Group-5" filter="url(#filter-1)" transform="translate(89.000000, 137.000000)">
|
||||||
|
<mask id="mask-3" fill="white">
|
||||||
|
<use xlink:href="#path-2"></use>
|
||||||
|
</mask>
|
||||||
|
<g id="Rectangle-18">
|
||||||
|
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
|
||||||
|
<use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use>
|
||||||
|
</g>
|
||||||
|
<rect id="Rectangle-18" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect>
|
||||||
|
<rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 509 KiB After Width: | Height: | Size: 509 KiB |
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
@ -220,8 +220,8 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translate(50%, -50%);
|
transform: translate(50%, -50%);
|
||||||
width: 180px;
|
width: 200px;
|
||||||
height: 180px;
|
height: 200px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
box-shadow: 0 0 4px #ccc;
|
box-shadow: 0 0 4px #ccc;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -237,4 +237,4 @@
|
|||||||
.top-right-btn {
|
.top-right-btn {
|
||||||
position: relative;
|
position: relative;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-container {
|
.sidebar-container {
|
||||||
|
-webkit-transition: width .28s;
|
||||||
transition: width 0.28s;
|
transition: width 0.28s;
|
||||||
width: $sideBarWidth !important;
|
width: $sideBarWidth !important;
|
||||||
background-color: $menuBg;
|
background-color: $menuBg;
|
||||||
@ -19,6 +20,8 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1001;
|
z-index: 1001;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
-webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
|
||||||
|
box-shadow: 2px 0 6px rgba(0,21,41,.35);
|
||||||
|
|
||||||
// reset element-ui css
|
// reset element-ui css
|
||||||
.horizontal-collapse-transition {
|
.horizontal-collapse-transition {
|
||||||
@ -73,17 +76,25 @@
|
|||||||
.submenu-title-noDropdown,
|
.submenu-title-noDropdown,
|
||||||
.el-submenu__title {
|
.el-submenu__title {
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $menuHover !important;
|
background-color: rgba(0, 0, 0, 0.06) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-active>.el-submenu__title {
|
& .theme-dark .is-active > .el-submenu__title {
|
||||||
color: $subMenuActiveText !important;
|
color: $subMenuActiveText !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .nest-menu .el-submenu>.el-submenu__title,
|
& .nest-menu .el-submenu>.el-submenu__title,
|
||||||
& .el-submenu .el-menu-item {
|
& .el-submenu .el-menu-item {
|
||||||
min-width: $sideBarWidth !important;
|
min-width: $sideBarWidth !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.06) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .theme-dark .nest-menu .el-submenu>.el-submenu__title,
|
||||||
|
& .theme-dark .el-submenu .el-menu-item {
|
||||||
background-color: $subMenuBg !important;
|
background-color: $subMenuBg !important;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -190,7 +201,7 @@
|
|||||||
.el-menu-item {
|
.el-menu-item {
|
||||||
&:hover {
|
&:hover {
|
||||||
// you can use $subMenuHover
|
// you can use $subMenuHover
|
||||||
background-color: $menuHover !important;
|
background-color: rgba(0, 0, 0, 0.06) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,11 @@ $subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951
|
|||||||
|
|
||||||
$menuBg:#304156;
|
$menuBg:#304156;
|
||||||
$menuHover:#263445;
|
$menuHover:#263445;
|
||||||
|
$sidebarTitle: #ffffff;
|
||||||
|
|
||||||
|
$menuLightBg:#ffffff;
|
||||||
|
$menuLightHover:#f0f1f5;
|
||||||
|
$sidebarLightTitle: #001529;
|
||||||
|
|
||||||
$subMenuBg:#1f2d3d;
|
$subMenuBg:#1f2d3d;
|
||||||
$subMenuHover:#001528;
|
$subMenuHover:#001528;
|
||||||
@ -29,7 +34,11 @@ $sideBarWidth: 200px;
|
|||||||
subMenuActiveText: $subMenuActiveText;
|
subMenuActiveText: $subMenuActiveText;
|
||||||
menuBg: $menuBg;
|
menuBg: $menuBg;
|
||||||
menuHover: $menuHover;
|
menuHover: $menuHover;
|
||||||
|
menuLightBg: $menuLightBg;
|
||||||
|
menuLightHover: $menuLightHover;
|
||||||
subMenuBg: $subMenuBg;
|
subMenuBg: $subMenuBg;
|
||||||
subMenuHover: $subMenuHover;
|
subMenuHover: $subMenuHover;
|
||||||
sideBarWidth: $sideBarWidth;
|
sideBarWidth: $sideBarWidth;
|
||||||
|
sidebarTitle: $sidebarTitle;
|
||||||
|
sidebarLightTitle: $sidebarLightTitle
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
179
ruoyi-ui/src/components/FileUpload/index.vue
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
<template>
|
||||||
|
<div class="upload-file">
|
||||||
|
<el-upload
|
||||||
|
:action="uploadFileUrl"
|
||||||
|
:before-upload="handleBeforeUpload"
|
||||||
|
:file-list="fileList"
|
||||||
|
:limit="1"
|
||||||
|
:on-error="handleUploadError"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:on-success="handleUploadSuccess"
|
||||||
|
:show-file-list="false"
|
||||||
|
:headers="headers"
|
||||||
|
class="upload-file-uploader"
|
||||||
|
ref="upload"
|
||||||
|
>
|
||||||
|
<!-- 上传按钮 -->
|
||||||
|
<el-button size="mini" type="primary">选取文件</el-button>
|
||||||
|
<!-- 上传提示 -->
|
||||||
|
<div class="el-upload__tip" slot="tip" v-if="showTip">
|
||||||
|
请上传
|
||||||
|
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
|
||||||
|
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
|
||||||
|
的文件
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
|
||||||
|
<!-- 文件列表 -->
|
||||||
|
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
|
||||||
|
<li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in list">
|
||||||
|
<el-link :href="file.url" :underline="false" target="_blank">
|
||||||
|
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
||||||
|
</el-link>
|
||||||
|
<div class="ele-upload-list__item-content-action">
|
||||||
|
<el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</transition-group>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getToken } from "@/utils/auth";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 值
|
||||||
|
value: [String, Object, Array],
|
||||||
|
// 大小限制(MB)
|
||||||
|
fileSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 5,
|
||||||
|
},
|
||||||
|
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||||
|
fileType: {
|
||||||
|
type: Array,
|
||||||
|
default: () => ["doc", "xls", "ppt", "txt", "pdf"],
|
||||||
|
},
|
||||||
|
// 是否显示提示
|
||||||
|
isShowTip: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer " + getToken(),
|
||||||
|
},
|
||||||
|
fileList: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 是否显示提示
|
||||||
|
showTip() {
|
||||||
|
return this.isShowTip && (this.fileType || this.fileSize);
|
||||||
|
},
|
||||||
|
// 列表
|
||||||
|
list() {
|
||||||
|
let temp = 1;
|
||||||
|
if (this.value) {
|
||||||
|
// 首先将值转为数组
|
||||||
|
const list = Array.isArray(this.value) ? this.value : [this.value];
|
||||||
|
// 然后将数组转为对象数组
|
||||||
|
return list.map((item) => {
|
||||||
|
if (typeof item === "string") {
|
||||||
|
item = { name: item, url: item };
|
||||||
|
}
|
||||||
|
item.uid = item.uid || new Date().getTime() + temp++;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.fileList = [];
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 上传前校检格式和大小
|
||||||
|
handleBeforeUpload(file) {
|
||||||
|
// 校检文件类型
|
||||||
|
if (this.fileType) {
|
||||||
|
let fileExtension = "";
|
||||||
|
if (file.name.lastIndexOf(".") > -1) {
|
||||||
|
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
|
||||||
|
}
|
||||||
|
const isTypeOk = this.fileType.some((type) => {
|
||||||
|
if (file.type.indexOf(type) > -1) return true;
|
||||||
|
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
if (!isTypeOk) {
|
||||||
|
this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 校检文件大小
|
||||||
|
if (this.fileSize) {
|
||||||
|
const isLt = file.size / 1024 / 1024 < this.fileSize;
|
||||||
|
if (!isLt) {
|
||||||
|
this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
// 文件个数超出
|
||||||
|
handleExceed() {
|
||||||
|
this.$message.error(`只允许上传单个文件`);
|
||||||
|
},
|
||||||
|
// 上传失败
|
||||||
|
handleUploadError(err) {
|
||||||
|
this.$message.error("上传失败, 请重试");
|
||||||
|
},
|
||||||
|
// 上传成功回调
|
||||||
|
handleUploadSuccess(res, file) {
|
||||||
|
this.$message.success("上传成功");
|
||||||
|
this.$emit("input", res.url);
|
||||||
|
},
|
||||||
|
// 删除文件
|
||||||
|
handleDelete(index) {
|
||||||
|
this.fileList.splice(index, 1);
|
||||||
|
this.$emit("input", '');
|
||||||
|
},
|
||||||
|
// 获取文件名称
|
||||||
|
getFileName(name) {
|
||||||
|
if (name.lastIndexOf("/") > -1) {
|
||||||
|
return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.fileList = this.list;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.upload-file-uploader {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.upload-file-list .el-upload-list__item {
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
line-height: 2;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.upload-file-list .ele-upload-list__item-content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
.ele-upload-list__item-content-action .el-link {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -12,7 +12,7 @@
|
|||||||
class="header-search-select"
|
class="header-search-select"
|
||||||
@change="change"
|
@change="change"
|
||||||
>
|
>
|
||||||
<el-option v-for="item in options" :key="item.path" :value="item" :label="item.title.join(' > ')" />
|
<el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<script>
|
<script>
|
||||||
// fuse is a lightweight fuzzy-search module
|
// fuse is a lightweight fuzzy-search module
|
||||||
// make search results more in line with expectations
|
// make search results more in line with expectations
|
||||||
import Fuse from 'fuse.js'
|
import Fuse from 'fuse.js/dist/fuse.min.js'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -167,7 +167,7 @@ export default {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
||||||
/deep/ .el-input__inner {
|
::v-deep .el-input__inner {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
|
100
ruoyi-ui/src/components/ImageUpload/index.vue
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<template>
|
||||||
|
<div class="component-upload-image">
|
||||||
|
<el-upload
|
||||||
|
:action="uploadImgUrl"
|
||||||
|
list-type="picture-card"
|
||||||
|
:on-success="handleUploadSuccess"
|
||||||
|
:before-upload="handleBeforeUpload"
|
||||||
|
:on-error="handleUploadError"
|
||||||
|
name="file"
|
||||||
|
:show-file-list="false"
|
||||||
|
:headers="headers"
|
||||||
|
style="display: inline-block; vertical-align: top"
|
||||||
|
>
|
||||||
|
<el-image v-if="!value" :src="value">
|
||||||
|
<div slot="error" class="image-slot">
|
||||||
|
<i class="el-icon-plus" />
|
||||||
|
</div>
|
||||||
|
</el-image>
|
||||||
|
<div v-else class="image">
|
||||||
|
<el-image :src="value" :style="`width:150px;height:150px;`" fit="fill"/>
|
||||||
|
<div class="mask">
|
||||||
|
<div class="actions">
|
||||||
|
<span title="预览" @click.stop="dialogVisible = true">
|
||||||
|
<i class="el-icon-zoom-in" />
|
||||||
|
</span>
|
||||||
|
<span title="移除" @click.stop="removeImage">
|
||||||
|
<i class="el-icon-delete" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
<el-dialog :visible.sync="dialogVisible" title="预览" width="800" append-to-body>
|
||||||
|
<img :src="value" style="display: block; max-width: 100%; margin: 0 auto;">
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getToken } from "@/utils/auth";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer " + getToken(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
removeImage() {
|
||||||
|
this.$emit("input", "");
|
||||||
|
},
|
||||||
|
handleUploadSuccess(res) {
|
||||||
|
this.$emit("input", res.url);
|
||||||
|
this.loading.close();
|
||||||
|
},
|
||||||
|
handleBeforeUpload() {
|
||||||
|
this.loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
text: "上传中",
|
||||||
|
background: "rgba(0, 0, 0, 0.7)",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleUploadError() {
|
||||||
|
this.$message({
|
||||||
|
type: "error",
|
||||||
|
message: "上传失败",
|
||||||
|
});
|
||||||
|
this.loading.close();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.image {
|
||||||
|
position: relative;
|
||||||
|
.mask {
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
&:hover .mask {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,3 +1,3 @@
|
|||||||
<template >
|
<template >
|
||||||
<router-view />
|
<router-view />
|
||||||
</template>
|
</template>
|
@ -1,4 +1,3 @@
|
|||||||
<!-- @author Shiyn/ huangmx 20200807优化-->
|
|
||||||
<template>
|
<template>
|
||||||
<div class="top-right-btn">
|
<div class="top-right-btn">
|
||||||
<el-row>
|
<el-row>
|
||||||
@ -8,31 +7,74 @@
|
|||||||
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
|
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
|
||||||
<el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
|
<el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
|
||||||
|
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" />
|
||||||
|
</el-tooltip>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-dialog :title="title" :visible.sync="open" append-to-body>
|
||||||
|
<el-transfer
|
||||||
|
:titles="['显示', '隐藏']"
|
||||||
|
v-model="value"
|
||||||
|
:data="columns"
|
||||||
|
@change="dataChange"
|
||||||
|
></el-transfer>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "RightToolbar",
|
name: "RightToolbar",
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {
|
||||||
|
// 显隐数据
|
||||||
|
value: [],
|
||||||
|
// 弹出层标题
|
||||||
|
title: "显示/隐藏",
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
showSearch: {
|
showSearch: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
columns: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
//搜索
|
// 搜索
|
||||||
toggleSearch() {
|
toggleSearch() {
|
||||||
this.$emit("update:showSearch", !this.showSearch);
|
this.$emit("update:showSearch", !this.showSearch);
|
||||||
},
|
},
|
||||||
//刷新
|
// 刷新
|
||||||
refresh() {
|
refresh() {
|
||||||
this.$emit("queryTable");
|
this.$emit("queryTable");
|
||||||
},
|
},
|
||||||
|
// 右侧列表元素变化
|
||||||
|
dataChange(data) {
|
||||||
|
for (var item in this.columns) {
|
||||||
|
const key = this.columns[item].key;
|
||||||
|
this.columns[item].visible = !data.includes(key);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 打开显隐列dialog
|
||||||
|
showColumn() {
|
||||||
|
this.open = true;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep .el-transfer__button {
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 12px;
|
||||||
|
display: block;
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
::v-deep .el-transfer__button:first-child {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -22,11 +22,8 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
click() {
|
click() {
|
||||||
if (!screenfull.enabled) {
|
if (!screenfull.isEnabled) {
|
||||||
this.$message({
|
this.$message({ message: '你的浏览器不支持全屏', type: 'warning' })
|
||||||
message: 'you browser can not work',
|
|
||||||
type: 'warning'
|
|
||||||
})
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
screenfull.toggle()
|
screenfull.toggle()
|
||||||
@ -35,12 +32,12 @@ export default {
|
|||||||
this.isFullscreen = screenfull.isFullscreen
|
this.isFullscreen = screenfull.isFullscreen
|
||||||
},
|
},
|
||||||
init() {
|
init() {
|
||||||
if (screenfull.enabled) {
|
if (screenfull.isEnabled) {
|
||||||
screenfull.on('change', this.change)
|
screenfull.on('change', this.change)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
if (screenfull.enabled) {
|
if (screenfull.isEnabled) {
|
||||||
screenfull.off('change', this.change)
|
screenfull.off('change', this.change)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,47 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="drawer-container">
|
<div class="drawer-container">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="drawer-title">系统布局配置</h3>
|
<div class="setting-drawer-content">
|
||||||
|
<div class="setting-drawer-title">
|
||||||
|
<h3 class="drawer-title">主题风格设置</h3>
|
||||||
|
</div>
|
||||||
|
<div class="setting-drawer-block-checbox">
|
||||||
|
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
|
||||||
|
<img src="@/assets/images/dark.svg" alt="dark">
|
||||||
|
<div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
||||||
|
<i aria-label="图标: check" class="anticon anticon-check">
|
||||||
|
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true"
|
||||||
|
focusable="false" class="">
|
||||||
|
<path
|
||||||
|
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
|
||||||
|
</svg>
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
|
||||||
|
<img src="@/assets/images/light.svg" alt="light">
|
||||||
|
<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
||||||
|
<i aria-label="图标: check" class="anticon anticon-check">
|
||||||
|
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true"
|
||||||
|
focusable="false" class="">
|
||||||
|
<path
|
||||||
|
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
|
||||||
|
</svg>
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="drawer-item">
|
<div class="drawer-item">
|
||||||
<span>主题颜色</span>
|
<span>主题颜色</span>
|
||||||
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
|
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<el-divider/>
|
||||||
|
|
||||||
|
<h3 class="drawer-title">系统布局配置</h3>
|
||||||
|
|
||||||
<div class="drawer-item">
|
<div class="drawer-item">
|
||||||
<span>开启 Tags-Views</span>
|
<span>开启 Tags-Views</span>
|
||||||
<el-switch v-model="tagsView" class="drawer-switch" />
|
<el-switch v-model="tagsView" class="drawer-switch" />
|
||||||
@ -36,6 +70,12 @@ export default {
|
|||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
theme() {
|
||||||
|
return this.$store.state.settings.theme
|
||||||
|
},
|
||||||
|
sideTheme() {
|
||||||
|
return this.$store.state.settings.sideTheme
|
||||||
|
},
|
||||||
fixedHeader: {
|
fixedHeader: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.settings.fixedHeader
|
return this.$store.state.settings.fixedHeader
|
||||||
@ -76,33 +116,82 @@ export default {
|
|||||||
key: 'theme',
|
key: 'theme',
|
||||||
value: val
|
value: val
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
handleTheme(val) {
|
||||||
|
this.$store.dispatch('settings/changeSetting', {
|
||||||
|
key: 'sideTheme',
|
||||||
|
value: val
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.drawer-container {
|
.setting-drawer-content {
|
||||||
padding: 24px;
|
.setting-drawer-title {
|
||||||
font-size: 14px;
|
margin-bottom: 12px;
|
||||||
line-height: 1.5;
|
color: rgba(0, 0, 0, .85);
|
||||||
word-wrap: break-word;
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
.drawer-title {
|
.setting-drawer-block-checbox {
|
||||||
margin-bottom: 12px;
|
display: flex;
|
||||||
color: rgba(0, 0, 0, .85);
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.setting-drawer-block-checbox-item {
|
||||||
|
position: relative;
|
||||||
|
margin-right: 16px;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-drawer-block-checbox-selectIcon {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 15px;
|
||||||
|
padding-left: 24px;
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-container {
|
||||||
|
padding: 24px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 22px;
|
line-height: 1.5;
|
||||||
}
|
word-wrap: break-word;
|
||||||
|
|
||||||
.drawer-item {
|
.drawer-title {
|
||||||
color: rgba(0, 0, 0, .65);
|
margin-bottom: 12px;
|
||||||
font-size: 14px;
|
color: rgba(0, 0, 0, .85);
|
||||||
padding: 12px 0;
|
font-size: 14px;
|
||||||
}
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
.drawer-switch {
|
.drawer-item {
|
||||||
float: right
|
color: rgba(0, 0, 0, .65);
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-switch {
|
||||||
|
float: right
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sidebar-logo-container" :class="{'collapse':collapse}">
|
<div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }">
|
||||||
<transition name="sidebarLogoFade">
|
<transition name="sidebarLogoFade">
|
||||||
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
||||||
<img v-if="logo" :src="logo" class="sidebar-logo">
|
<img v-if="logo" :src="logo" class="sidebar-logo">
|
||||||
<h1 v-else class="sidebar-title">{{ title }} </h1>
|
<h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.sidebarTitle : variables.sidebarLightTitle }">{{ title }} </h1>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
||||||
<img v-if="logo" :src="logo" class="sidebar-logo">
|
<img v-if="logo" :src="logo" class="sidebar-logo">
|
||||||
<h1 class="sidebar-title">{{ title }} </h1>
|
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.sidebarTitle : variables.sidebarLightTitle }">{{ title }} </h1>
|
||||||
</router-link>
|
</router-link>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import logoImg from '@/assets/logo/logo.png'
|
import logoImg from '@/assets/logo/logo.png'
|
||||||
|
import variables from '@/assets/styles/variables.scss'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SidebarLogo',
|
name: 'SidebarLogo',
|
||||||
@ -24,6 +25,14 @@ export default {
|
|||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
variables() {
|
||||||
|
return variables;
|
||||||
|
},
|
||||||
|
sideTheme() {
|
||||||
|
return this.$store.state.settings.sideTheme
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: '若依管理系统',
|
title: '若依管理系统',
|
||||||
|
@ -56,6 +56,9 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
hasOneShowingChild(children = [], parent) {
|
hasOneShowingChild(children = [], parent) {
|
||||||
|
if (!children) {
|
||||||
|
children = [];
|
||||||
|
}
|
||||||
const showingChildren = children.filter(item => {
|
const showingChildren = children.filter(item => {
|
||||||
if (item.hidden) {
|
if (item.hidden) {
|
||||||
return false
|
return false
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="{'has-logo':showLogo}">
|
<div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }">
|
||||||
<logo v-if="showLogo" :collapse="isCollapse" />
|
<logo v-if="showLogo" :collapse="isCollapse" />
|
||||||
<el-scrollbar wrap-class="scrollbar-wrapper">
|
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
|
||||||
<el-menu
|
<el-menu
|
||||||
:default-active="activeMenu"
|
:default-active="activeMenu"
|
||||||
:collapse="isCollapse"
|
:collapse="isCollapse"
|
||||||
:background-color="variables.menuBg"
|
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg"
|
||||||
:text-color="variables.menuText"
|
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuText : 'rgba(0,0,0,.65)'"
|
||||||
:unique-opened="true"
|
:unique-opened="true"
|
||||||
:active-text-color="settings.theme"
|
:active-text-color="settings.theme"
|
||||||
:collapse-transition="false"
|
:collapse-transition="false"
|
||||||
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;
|
||||||
|
@ -82,7 +82,7 @@ export default {
|
|||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
/deep/ {
|
::v-deep {
|
||||||
.el-scrollbar__bar {
|
.el-scrollbar__bar {
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
closeOthersTags() {
|
closeOthersTags() {
|
||||||
this.$router.push(this.selectedTag)
|
this.$router.push(this.selectedTag).catch(()=>{});
|
||||||
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
|
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
|
||||||
this.moveToCurrentTag()
|
this.moveToCurrentTag()
|
||||||
})
|
})
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="classObj" class="app-wrapper">
|
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
|
||||||
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
|
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
||||||
<sidebar class="sidebar-container" />
|
<sidebar class="sidebar-container" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }" />
|
||||||
<div :class="{hasTagsView:needTagsView}" class="main-container">
|
<div :class="{hasTagsView:needTagsView}" class="main-container">
|
||||||
<div :class="{'fixed-header':fixedHeader}">
|
<div :class="{'fixed-header':fixedHeader}">
|
||||||
<navbar />
|
<navbar />
|
||||||
@ -20,6 +20,7 @@ import RightPanel from '@/components/RightPanel'
|
|||||||
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
|
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
|
||||||
import ResizeMixin from './mixin/ResizeHandler'
|
import ResizeMixin from './mixin/ResizeHandler'
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
|
import variables from '@/assets/styles/variables.scss'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Layout',
|
name: 'Layout',
|
||||||
@ -34,6 +35,8 @@ export default {
|
|||||||
mixins: [ResizeMixin],
|
mixins: [ResizeMixin],
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
|
theme: state => state.settings.theme,
|
||||||
|
sideTheme: state => state.settings.sideTheme,
|
||||||
sidebar: state => state.app.sidebar,
|
sidebar: state => state.app.sidebar,
|
||||||
device: state => state.app.device,
|
device: state => state.app.device,
|
||||||
showSettings: state => state.settings.showSettings,
|
showSettings: state => state.settings.showSettings,
|
||||||
@ -47,6 +50,9 @@ export default {
|
|||||||
withoutAnimation: this.sidebar.withoutAnimation,
|
withoutAnimation: this.sidebar.withoutAnimation,
|
||||||
mobile: this.device === 'mobile'
|
mobile: this.device === 'mobile'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
variables() {
|
||||||
|
return variables;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -2,8 +2,6 @@ import Vue from 'vue'
|
|||||||
|
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
import 'normalize.css/normalize.css' // a modern alternative to CSS resets
|
|
||||||
|
|
||||||
import Element from 'element-ui'
|
import Element from 'element-ui'
|
||||||
import './assets/styles/element-variables.scss'
|
import './assets/styles/element-variables.scss'
|
||||||
|
|
||||||
@ -20,7 +18,7 @@ import { getDicts } from "@/api/system/dict/data";
|
|||||||
import { getConfigKey } from "@/api/system/config";
|
import { getConfigKey } from "@/api/system/config";
|
||||||
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, download, handleTree } from "@/utils/ruoyi";
|
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, download, handleTree } from "@/utils/ruoyi";
|
||||||
import Pagination from "@/components/Pagination";
|
import Pagination from "@/components/Pagination";
|
||||||
//自定义表格工具扩展
|
// 自定义表格工具扩展
|
||||||
import RightToolbar from "@/components/RightToolbar"
|
import RightToolbar from "@/components/RightToolbar"
|
||||||
|
|
||||||
// 全局方法挂载
|
// 全局方法挂载
|
||||||
|
@ -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 {
|
||||||
|
@ -5,6 +5,7 @@ Vue.use(Router)
|
|||||||
|
|
||||||
/* Layout */
|
/* Layout */
|
||||||
import Layout from '@/layout'
|
import Layout from '@/layout'
|
||||||
|
import ParentView from '@/components/ParentView';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: 路由配置项
|
* Note: 路由配置项
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
title: '若依管理系统',
|
title: '若依管理系统',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||||
|
*/
|
||||||
|
sideTheme: 'theme-dark',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否系统布局配置
|
* 是否系统布局配置
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
import { constantRoutes } from '@/router'
|
import { constantRoutes } from '@/router'
|
||||||
import { getRouters } from '@/api/menu'
|
import { getRouters } from '@/api/menu'
|
||||||
import Layout from '@/layout/index'
|
import Layout from '@/layout/index'
|
||||||
|
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: {
|
||||||
// 生成路由
|
// 生成路由
|
||||||
@ -19,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, false, true)
|
||||||
|
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
|
||||||
|
commit('SET_ROUTES', rewriteRoutes)
|
||||||
|
commit('SET_SIDEBAR_ROUTERS', sidebarRoutes)
|
||||||
|
resolve(rewriteRoutes)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -30,25 +39,57 @@ const permission = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 遍历后台传来的路由字符串,转换为组件对象
|
// 遍历后台传来的路由字符串,转换为组件对象
|
||||||
function filterAsyncRouter(asyncRouterMap) {
|
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
|
||||||
return asyncRouterMap.filter(route => {
|
return asyncRouterMap.filter(route => {
|
||||||
|
if (type && route.children) {
|
||||||
|
route.children = filterChildren(route.children)
|
||||||
|
}
|
||||||
if (route.component) {
|
if (route.component) {
|
||||||
// Layout组件特殊处理
|
// Layout ParentView 组件特殊处理
|
||||||
if (route.component === 'Layout') {
|
if (route.component === 'Layout') {
|
||||||
route.component = Layout
|
route.component = Layout
|
||||||
|
} else if (route.component === 'ParentView') {
|
||||||
|
route.component = ParentView
|
||||||
} else {
|
} else {
|
||||||
route.component = loadView(route.component)
|
route.component = loadView(route.component)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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, type)
|
||||||
|
} else {
|
||||||
|
delete route['children']
|
||||||
|
delete route['redirect']
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filterChildren(childrenMap, lastRouter = false) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastRouter) {
|
||||||
|
el.path = lastRouter.path + '/' + el.path
|
||||||
|
}
|
||||||
|
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
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import variables from '@/assets/styles/element-variables.scss'
|
import variables from '@/assets/styles/element-variables.scss'
|
||||||
import defaultSettings from '@/settings'
|
import defaultSettings from '@/settings'
|
||||||
|
|
||||||
const { showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings
|
const { sideTheme, showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
theme: variables.theme,
|
theme: variables.theme,
|
||||||
|
sideTheme: sideTheme,
|
||||||
showSettings: showSettings,
|
showSettings: showSettings,
|
||||||
tagsView: tagsView,
|
tagsView: tagsView,
|
||||||
fixedHeader: fixedHeader,
|
fixedHeader: fixedHeader,
|
||||||
|
@ -51,7 +51,7 @@ const user = {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
getInfo(state.token).then(res => {
|
getInfo(state.token).then(res => {
|
||||||
const user = res.user
|
const user = res.user
|
||||||
const avatar = user.avatar == "" ? require("@/assets/image/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
|
const avatar = user.avatar == "" ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
|
||||||
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
|
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
|
||||||
commit('SET_ROLES', res.roles)
|
commit('SET_ROLES', res.roles)
|
||||||
commit('SET_PERMISSIONS', res.permissions)
|
commit('SET_PERMISSIONS', res.permissions)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import JSEncrypt from 'jsencrypt/bin/jsencrypt'
|
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
|
||||||
|
|
||||||
// 密钥对生成 http://web.chacuo.net/netrsakeypair
|
// 密钥对生成 http://web.chacuo.net/netrsakeypair
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -1,81 +1,103 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { Notification, MessageBox, Message } from 'element-ui'
|
import { Notification, MessageBox, Message } from 'element-ui'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
import errorCode from '@/utils/errorCode'
|
import errorCode from '@/utils/errorCode'
|
||||||
|
|
||||||
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
|
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
|
||||||
// 创建axios实例
|
// 创建axios实例
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||||
baseURL: process.env.VUE_APP_BASE_API,
|
baseURL: process.env.VUE_APP_BASE_API,
|
||||||
// 超时
|
// 超时
|
||||||
timeout: 10000
|
timeout: 10000
|
||||||
})
|
})
|
||||||
// request拦截器
|
// request拦截器
|
||||||
service.interceptors.request.use(config => {
|
service.interceptors.request.use(config => {
|
||||||
// 是否需要设置 token
|
// 是否需要设置 token
|
||||||
const isToken = (config.headers || {}).isToken === false
|
const isToken = (config.headers || {}).isToken === false
|
||||||
if (getToken() && !isToken) {
|
if (getToken() && !isToken) {
|
||||||
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
|
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||||
}
|
}
|
||||||
return config
|
// get请求映射params参数
|
||||||
}, error => {
|
if (config.method === 'get' && config.params) {
|
||||||
console.log(error)
|
let url = config.url + '?';
|
||||||
Promise.reject(error)
|
for (const propName of Object.keys(config.params)) {
|
||||||
})
|
const value = config.params[propName];
|
||||||
|
var part = encodeURIComponent(propName) + "=";
|
||||||
// 响应拦截器
|
if (value !== null && typeof(value) !== "undefined") {
|
||||||
service.interceptors.response.use(res => {
|
if (typeof value === 'object') {
|
||||||
// 未设置状态码则默认成功状态
|
for (const key of Object.keys(value)) {
|
||||||
const code = res.data.code || 200;
|
let params = propName + '[' + key + ']';
|
||||||
// 获取错误信息
|
var subPart = encodeURIComponent(params) + "=";
|
||||||
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
url += subPart + encodeURIComponent(value[key]) + "&";
|
||||||
if (code === 401) {
|
}
|
||||||
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
|
} else {
|
||||||
confirmButtonText: '重新登录',
|
url += part + encodeURIComponent(value) + "&";
|
||||||
cancelButtonText: '取消',
|
}
|
||||||
type: 'warning'
|
}
|
||||||
}
|
}
|
||||||
).then(() => {
|
url = url.slice(0, -1);
|
||||||
store.dispatch('LogOut').then(() => {
|
config.params = {};
|
||||||
location.href = '/index';
|
config.url = url;
|
||||||
})
|
}
|
||||||
})
|
return config
|
||||||
} else if (code === 500) {
|
}, error => {
|
||||||
Message({
|
console.log(error)
|
||||||
message: msg,
|
Promise.reject(error)
|
||||||
type: 'error'
|
})
|
||||||
})
|
|
||||||
return Promise.reject(new Error(msg))
|
// 响应拦截器
|
||||||
} else if (code !== 200) {
|
service.interceptors.response.use(res => {
|
||||||
Notification.error({
|
// 未设置状态码则默认成功状态
|
||||||
title: msg
|
const code = res.data.code || 200;
|
||||||
})
|
// 获取错误信息
|
||||||
return Promise.reject('error')
|
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
||||||
} else {
|
if (code === 401) {
|
||||||
return res.data
|
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
|
||||||
}
|
confirmButtonText: '重新登录',
|
||||||
},
|
cancelButtonText: '取消',
|
||||||
error => {
|
type: 'warning'
|
||||||
console.log('err' + error)
|
}
|
||||||
let { message } = error;
|
).then(() => {
|
||||||
if (message == "Network Error") {
|
store.dispatch('LogOut').then(() => {
|
||||||
message = "后端接口连接异常";
|
location.href = '/index';
|
||||||
}
|
})
|
||||||
else if (message.includes("timeout")) {
|
})
|
||||||
message = "系统接口请求超时";
|
} else if (code === 500) {
|
||||||
}
|
Message({
|
||||||
else if (message.includes("Request failed with status code")) {
|
message: msg,
|
||||||
message = "系统接口" + message.substr(message.length - 3) + "异常";
|
type: 'error'
|
||||||
}
|
})
|
||||||
Message({
|
return Promise.reject(new Error(msg))
|
||||||
message: message,
|
} else if (code !== 200) {
|
||||||
type: 'error',
|
Notification.error({
|
||||||
duration: 5 * 1000
|
title: msg
|
||||||
})
|
})
|
||||||
return Promise.reject(error)
|
return Promise.reject('error')
|
||||||
}
|
} else {
|
||||||
)
|
return res.data
|
||||||
|
}
|
||||||
export default service
|
},
|
||||||
|
error => {
|
||||||
|
console.log('err' + error)
|
||||||
|
let { message } = error;
|
||||||
|
if (message == "Network Error") {
|
||||||
|
message = "后端接口连接异常";
|
||||||
|
}
|
||||||
|
else if (message.includes("timeout")) {
|
||||||
|
message = "系统接口请求超时";
|
||||||
|
}
|
||||||
|
else if (message.includes("Request failed with status code")) {
|
||||||
|
message = "系统接口" + message.substr(message.length - 3) + "异常";
|
||||||
|
}
|
||||||
|
Message({
|
||||||
|
message: message,
|
||||||
|
type: 'error',
|
||||||
|
duration: 5 * 1000
|
||||||
|
})
|
||||||
|
return Promise.reject(error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export default service
|
||||||
|
@ -54,13 +54,17 @@ export function resetForm(refName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 添加日期范围
|
// 添加日期范围
|
||||||
export function addDateRange(params, dateRange) {
|
export function addDateRange(params, dateRange, propName) {
|
||||||
var search = params;
|
var search = params;
|
||||||
search.beginTime = "";
|
search.params = {};
|
||||||
search.endTime = "";
|
|
||||||
if (null != dateRange && '' != dateRange) {
|
if (null != dateRange && '' != dateRange) {
|
||||||
search.beginTime = dateRange[0];
|
if (typeof(propName) === "undefined") {
|
||||||
search.endTime = dateRange[1];
|
search.params["beginTime"] = dateRange[0];
|
||||||
|
search.params["endTime"] = dateRange[1];
|
||||||
|
} else {
|
||||||
|
search.params["begin" + propName] = dateRange[0];
|
||||||
|
search.params["end" + propName] = dateRange[1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return search;
|
return search;
|
||||||
}
|
}
|
||||||
|
@ -1,98 +1,602 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dashboard-editor-container">
|
<div class="app-container home">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :sm="24" :lg="24">
|
||||||
|
<blockquote class="text-warning" style="font-size: 14px">
|
||||||
|
领取阿里云通用云产品1888优惠券
|
||||||
|
<br />
|
||||||
|
<el-link
|
||||||
|
href="https://www.aliyun.com/minisite/goods?userCode=brki8iof"
|
||||||
|
type="primary"
|
||||||
|
target="_blank"
|
||||||
|
>https://www.aliyun.com/minisite/goods?userCode=brki8iof</el-link
|
||||||
|
>
|
||||||
|
<br />
|
||||||
|
领取腾讯云通用云产品2860优惠券
|
||||||
|
<br />
|
||||||
|
<el-link
|
||||||
|
href="https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console"
|
||||||
|
type="primary"
|
||||||
|
target="_blank"
|
||||||
|
>https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console</el-link
|
||||||
|
>
|
||||||
|
<br />
|
||||||
|
阿里云服务器折扣区
|
||||||
|
<el-link href="http://aly.ruoyi.vip" type="primary" target="_blank"
|
||||||
|
>>☛☛点我进入☚☚</el-link
|
||||||
|
>
|
||||||
|
腾讯云服务器秒杀区
|
||||||
|
<el-link href="http://txy.ruoyi.vip" type="primary" target="_blank"
|
||||||
|
>>☛☛点我进入☚☚</el-link
|
||||||
|
><br />
|
||||||
|
<h4 class="text-danger">
|
||||||
|
云产品通用红包,可叠加官网常规优惠使用。(仅限新用户)
|
||||||
|
</h4>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
<panel-group @handleSetLineChartData="handleSetLineChartData" />
|
<hr />
|
||||||
|
|
||||||
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
|
|
||||||
<line-chart :chart-data="lineChartData" />
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row :gutter="32">
|
|
||||||
<el-col :xs="24" :sm="24" :lg="8">
|
|
||||||
<div class="chart-wrapper">
|
|
||||||
<raddar-chart />
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="24" :lg="8">
|
|
||||||
<div class="chart-wrapper">
|
|
||||||
<pie-chart />
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="24" :lg="8">
|
|
||||||
<div class="chart-wrapper">
|
|
||||||
<bar-chart />
|
|
||||||
</div>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :sm="24" :lg="12" style="padding-left: 20px">
|
||||||
|
<h2>若依后台管理框架</h2>
|
||||||
|
<p>
|
||||||
|
一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了若依管理系统。,她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>当前版本:</b> <span>v{{ version }}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<el-tag type="danger">¥免费开源</el-tag>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-cloudy"
|
||||||
|
plain
|
||||||
|
@click="goTarget('https://gitee.com/y_project/RuoYi-Vue')"
|
||||||
|
>访问码云</el-button
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-s-home"
|
||||||
|
plain
|
||||||
|
@click="goTarget('http://ruoyi.vip')"
|
||||||
|
>访问主页</el-button
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :sm="24" :lg="12" style="padding-left: 50px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<h2>技术选型</h2>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="6">
|
||||||
|
<h4>后端技术</h4>
|
||||||
|
<ul>
|
||||||
|
<li>SpringBoot</li>
|
||||||
|
<li>Spring Security</li>
|
||||||
|
<li>JWT</li>
|
||||||
|
<li>MyBatis</li>
|
||||||
|
<li>Druid</li>
|
||||||
|
<li>Fastjson</li>
|
||||||
|
<li>...</li>
|
||||||
|
</ul>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<h4>前端技术</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Vue</li>
|
||||||
|
<li>Vuex</li>
|
||||||
|
<li>Element-ui</li>
|
||||||
|
<li>Axios</li>
|
||||||
|
<li>Sass</li>
|
||||||
|
<li>Quill</li>
|
||||||
|
<li>...</li>
|
||||||
|
</ul>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-divider />
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :xs="24" :sm="24" :md="12" :lg="8">
|
||||||
|
<el-card class="update-log">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>联系信息</span>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<p>
|
||||||
|
<i class="el-icon-s-promotion"></i> 官网:<el-link
|
||||||
|
href="http://www.ruoyi.vip"
|
||||||
|
target="_blank"
|
||||||
|
>http://www.ruoyi.vip</el-link
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="el-icon-user-solid"></i> QQ群:<s>满937441</s>
|
||||||
|
<s>满887144332</s> <s>满180251782</s>
|
||||||
|
<a href="https://jq.qq.com/?_wv=1027&k=4WWwqNxN" target="_blank"
|
||||||
|
> 104180207</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="el-icon-chat-dot-round"></i> 微信:<a
|
||||||
|
href="javascript:;"
|
||||||
|
>/ *若依</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="el-icon-money"></i> 支付宝:<a
|
||||||
|
href="javascript:;"
|
||||||
|
class="支付宝信息"
|
||||||
|
>/ *若依</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="12" :lg="8">
|
||||||
|
<el-card class="update-log">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>更新日志</span>
|
||||||
|
</div>
|
||||||
|
<el-collapse accordion>
|
||||||
|
<el-collapse-item title="v3.4.0 - 2021-02-22">
|
||||||
|
<ol>
|
||||||
|
<li>代码生成模板支持主子表</li>
|
||||||
|
<li>表格右侧工具栏组件支持显隐列</li>
|
||||||
|
<li>图片组件添加预览&移除功能</li>
|
||||||
|
<li>Excel注解支持Image图片导出</li>
|
||||||
|
<li>操作按钮组调整为朴素按钮样式</li>
|
||||||
|
<li>代码生成支持文件上传组件</li>
|
||||||
|
<li>代码生成日期控件区分范围</li>
|
||||||
|
<li>代码生成数据库文本类型生成表单文本域</li>
|
||||||
|
<li>用户手机邮箱&菜单组件修改允许空字符串</li>
|
||||||
|
<li>升级SpringBoot到最新版本2.2.13 提升启动速度</li>
|
||||||
|
<li>升级druid到最新版本v1.2.4</li>
|
||||||
|
<li>升级fastjson到最新版1.2.75</li>
|
||||||
|
<li>升级element-ui到最新版本2.15.0</li>
|
||||||
|
<li>修复IE11浏览器报错问题</li>
|
||||||
|
<li>优化多级菜单之间切换无法缓存的问题</li>
|
||||||
|
<li>修复四级菜单无法显示问题</li>
|
||||||
|
<li>修正侧边栏静态路由丢失问题</li>
|
||||||
|
<li>修复角色管理-编辑角色-功能权限显示异常</li>
|
||||||
|
<li>配置文件新增redis数据库索引属性</li>
|
||||||
|
<li>权限工具类增加admin判断</li>
|
||||||
|
<li>角色非自定义权限范围清空选择值</li>
|
||||||
|
<li>修复导入数据为负浮点数时丢失精度问题</li>
|
||||||
|
<li>移除path-to-regexp正则匹配插件</li>
|
||||||
|
<li>修复生成树表代码异常</li>
|
||||||
|
<li>修改ip字段长度防止ipv6地址长度不够</li>
|
||||||
|
<li>防止get请求参数值为false或0等特殊值会导致无法正确的传参</li>
|
||||||
|
<li>登录后push添加catch防止出现检查错误</li>
|
||||||
|
<li>其他细节优化</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
<el-collapse-item title="v3.3.0 - 2020-12-14">
|
||||||
|
<ol>
|
||||||
|
<li>新增缓存监控功能</li>
|
||||||
|
<li>支持主题风格配置</li>
|
||||||
|
<li>修复多级菜单之间切换无法缓存的问题</li>
|
||||||
|
<li>多级菜单自动配置组件</li>
|
||||||
|
<li>代码生成预览支持高亮显示</li>
|
||||||
|
<li>支持Get请求映射Params参数</li>
|
||||||
|
<li>删除用户和角色解绑关联</li>
|
||||||
|
<li>去除用户手机邮箱部门必填验证</li>
|
||||||
|
<li>Excel支持注解align对齐方式</li>
|
||||||
|
<li>Excel支持导入Boolean型数据</li>
|
||||||
|
<li>优化头像样式,鼠标移入悬停遮罩</li>
|
||||||
|
<li>代码生成预览提供滚动机制</li>
|
||||||
|
<li>代码生成删除多余的数字float类型</li>
|
||||||
|
<li>修正转换字符串的目标字符集属性</li>
|
||||||
|
<li>回显数据字典防止空值报错</li>
|
||||||
|
<li>日志记录增加过滤多文件场景</li>
|
||||||
|
<li>修改缓存Set方法可能导致嵌套的问题</li>
|
||||||
|
<li>移除前端一些多余的依赖</li>
|
||||||
|
<li>防止安全扫描YUI出现的风险提示</li>
|
||||||
|
<li>修改node-sass为dart-sass</li>
|
||||||
|
<li>升级SpringBoot到最新版本2.1.18</li>
|
||||||
|
<li>升级poi到最新版本4.1.2</li>
|
||||||
|
<li>升级oshi到最新版本v5.3.6</li>
|
||||||
|
<li>升级bitwalker到最新版本1.21</li>
|
||||||
|
<li>升级axios到最新版本0.21.0</li>
|
||||||
|
<li>升级element-ui到最新版本2.14.1</li>
|
||||||
|
<li>升级vue到最新版本2.6.12</li>
|
||||||
|
<li>升级vuex到最新版本3.6.0</li>
|
||||||
|
<li>升级vue-cli到版本4.5.9</li>
|
||||||
|
<li>升级vue-router到最新版本3.4.9</li>
|
||||||
|
<li>升级vue-cli到最新版本4.4.6</li>
|
||||||
|
<li>升级vue-cropper到最新版本0.5.5</li>
|
||||||
|
<li>升级clipboard到最新版本2.0.6</li>
|
||||||
|
<li>升级core-js到最新版本3.8.1</li>
|
||||||
|
<li>升级echarts到最新版本4.9.0</li>
|
||||||
|
<li>升级file-saver到最新版本2.0.4</li>
|
||||||
|
<li>升级fuse.js到最新版本6.4.3</li>
|
||||||
|
<li>升级js-beautify到最新版本1.13.0</li>
|
||||||
|
<li>升级js-cookie到最新版本2.2.1</li>
|
||||||
|
<li>升级path-to-regexp到最新版本6.2.0</li>
|
||||||
|
<li>升级quill到最新版本1.3.7</li>
|
||||||
|
<li>升级screenfull到最新版本5.0.2</li>
|
||||||
|
<li>升级sortablejs到最新版本1.10.2</li>
|
||||||
|
<li>升级vuedraggable到最新版本2.24.3</li>
|
||||||
|
<li>升级chalk到最新版本4.1.0</li>
|
||||||
|
<li>升级eslint到最新版本7.15.0</li>
|
||||||
|
<li>升级eslint-plugin-vue到最新版本7.2.0</li>
|
||||||
|
<li>升级lint-staged到最新版本10.5.3</li>
|
||||||
|
<li>升级runjs到最新版本4.4.2</li>
|
||||||
|
<li>升级sass-loader到最新版本10.1.0</li>
|
||||||
|
<li>升级script-ext-html-webpack-plugin到最新版本2.1.5</li>
|
||||||
|
<li>升级svg-sprite-loader到最新版本5.1.1</li>
|
||||||
|
<li>升级vue-template-compiler到最新版本2.6.12</li>
|
||||||
|
<li>其他细节优化</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
<el-collapse-item title="v3.2.1 - 2020-11-18">
|
||||||
|
<ol>
|
||||||
|
<li>阻止任意文件下载漏洞</li>
|
||||||
|
<li>代码生成支持上传控件</li>
|
||||||
|
<li>新增图片上传组件</li>
|
||||||
|
<li>调整默认首页</li>
|
||||||
|
<li>升级druid到最新版本v1.2.2</li>
|
||||||
|
<li>mapperLocations配置支持分隔符</li>
|
||||||
|
<li>权限信息调整</li>
|
||||||
|
<li>调整sql默认时间</li>
|
||||||
|
<li>解决代码生成没有bit类型的问题</li>
|
||||||
|
<li>升级pagehelper到最新版1.3.0</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
<el-collapse-item title="v3.2.0 - 2020-10-10">
|
||||||
|
<ol>
|
||||||
|
<li>升级springboot版本到2.1.17 提升安全性</li>
|
||||||
|
<li>升级oshi到最新版本v5.2.5</li>
|
||||||
|
<li>升级druid到最新版本v1.2.1</li>
|
||||||
|
<li>升级jjwt到版本0.9.1</li>
|
||||||
|
<li>升级fastjson到最新版1.2.74</li>
|
||||||
|
<li>修改sass为node-sass,避免el-icon图标乱码</li>
|
||||||
|
<li>代码生成支持同步数据库</li>
|
||||||
|
<li>代码生成支持富文本控件</li>
|
||||||
|
<li>代码生成页面时不忽略remark属性</li>
|
||||||
|
<li>代码生成添加select必填选项</li>
|
||||||
|
<li>Excel导出类型NUMERIC支持精度浮点类型</li>
|
||||||
|
<li>Excel导出targetAttr优化获取值,防止get方法不规范</li>
|
||||||
|
<li>Excel注解支持自动统计数据总和</li>
|
||||||
|
<li>Excel注解支持设置BigDecimal精度&舍入规则</li>
|
||||||
|
<li>菜单&数据权限新增(展开/折叠 全选/全不选 父子联动)</li>
|
||||||
|
<li>允许用户分配到部门父节点</li>
|
||||||
|
<li>菜单新增是否缓存keep-alive</li>
|
||||||
|
<li>表格操作列间距调整</li>
|
||||||
|
<li>限制系统内置参数不允许删除</li>
|
||||||
|
<li>富文本组件优化,支持自定义高度&图片冲突问题</li>
|
||||||
|
<li>富文本工具栏样式对齐</li>
|
||||||
|
<li>导入excel整形值校验优化</li>
|
||||||
|
<li>修复页签关闭所有时固定标签路由不刷新问题</li>
|
||||||
|
<li>表单构建布局型组件新增按钮</li>
|
||||||
|
<li>左侧菜单文字过长显示省略号</li>
|
||||||
|
<li>修正根节点为子部门时,树状结构显示问题</li>
|
||||||
|
<li>修正调用目标字符串最大长度</li>
|
||||||
|
<li>修正菜单提示信息错误</li>
|
||||||
|
<li>修正定时任务执行一次权限标识</li>
|
||||||
|
<li>修正数据库字符串类型nvarchar</li>
|
||||||
|
<li>优化递归子节点</li>
|
||||||
|
<li>优化数据权限判断</li>
|
||||||
|
<li>其他细节优化</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
|
||||||
|
<el-collapse-item title="v3.1.0 - 2020-08-13">
|
||||||
|
<ol>
|
||||||
|
<li>表格工具栏右侧添加刷新&显隐查询组件</li>
|
||||||
|
<li>后端支持CORS跨域请求</li>
|
||||||
|
<li>代码生成支持选择上级菜单</li>
|
||||||
|
<li>代码生成支持自定义路径</li>
|
||||||
|
<li>代码生成支持复选框</li>
|
||||||
|
<li>Excel导出导入支持dictType字典类型</li>
|
||||||
|
<li>Excel支持分割字符串组内容</li>
|
||||||
|
<li>验证码类型支持(数组计算、字符验证)</li>
|
||||||
|
<li>升级vue-cli版本到4.4.4</li>
|
||||||
|
<li>修改 node-sass 为 dart-sass</li>
|
||||||
|
<li>表单类型为Integer/Long设置整形默认值</li>
|
||||||
|
<li>代码生成器默认mapper路径与默认mapperScan路径不一致</li>
|
||||||
|
<li>优化防重复提交拦截器</li>
|
||||||
|
<li>优化上级菜单不能选择自己</li>
|
||||||
|
<li>修复角色的权限分配后,未实时生效问题</li>
|
||||||
|
<li>修复在线用户日志记录类型</li>
|
||||||
|
<li>修复富文本空格和缩进保存后不生效问题</li>
|
||||||
|
<li>修复在线用户判断逻辑</li>
|
||||||
|
<li>唯一限制条件只返回单条数据</li>
|
||||||
|
<li>添加获取当前的环境配置方法</li>
|
||||||
|
<li>超时登录后页面跳转到首页</li>
|
||||||
|
<li>全局异常状态汉化拦截处理</li>
|
||||||
|
<li>HTML过滤器改为将html转义</li>
|
||||||
|
<li>检查字符支持小数点&降级改成异常提醒</li>
|
||||||
|
<li>其他细节优化</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
|
||||||
|
<el-collapse-item title="v3.0.0 - 2020-07-20">
|
||||||
|
<ol>
|
||||||
|
<li>单应用调整为多模块项目</li>
|
||||||
|
<li>升级element-ui版本到2.13.2</li>
|
||||||
|
<li>删除babel,提高编译速度。</li>
|
||||||
|
<li>新增菜单默认主类目</li>
|
||||||
|
<li>编码文件名修改为uuid方式</li>
|
||||||
|
<li>定时任务cron表达式验证</li>
|
||||||
|
<li>角色权限修改时已有权限未自动勾选异常修复</li>
|
||||||
|
<li>防止切换权限用户后登录出现404</li>
|
||||||
|
<li>Excel支持sort导出排序</li>
|
||||||
|
<li>创建用户不允许选择超级管理员角色</li>
|
||||||
|
<li>修复代码生成导入表结构出现异常页面不提醒问题</li>
|
||||||
|
<li>修复代码生成点击多次表修改数据不变化的问题</li>
|
||||||
|
<li>修复头像上传成功二次打开无法改变裁剪框大小和位置问题</li>
|
||||||
|
<li>修复布局为small者mini用户表单显示错位问题</li>
|
||||||
|
<li>修复热部署导致的强换异常问题</li>
|
||||||
|
<li>修改用户管理复选框宽度,防止部分浏览器出现省略号</li>
|
||||||
|
<li>IpUtils工具,清除Xss特殊字符,防止Xff注入攻击</li>
|
||||||
|
<li>生成domain 如果是浮点型 统一用BigDecimal</li>
|
||||||
|
<li>定时任务调整label-width,防止部署出现错位</li>
|
||||||
|
<li>调整表头固定列默认样式</li>
|
||||||
|
<li>代码生成模板调整,字段为String并且必填则加空串条件</li>
|
||||||
|
<li>代码生成字典Integer/Long使用parseInt</li>
|
||||||
|
<li>
|
||||||
|
修复dict_sort不可update为0的问题&查询返回增加dict_sort升序排序
|
||||||
|
</li>
|
||||||
|
<li>修正岗位导出权限注解</li>
|
||||||
|
<li>禁止加密密文返回前端</li>
|
||||||
|
<li>修复代码生成页面中的查询条件创建时间未生效的问题</li>
|
||||||
|
<li>修复首页搜索菜单外链无法点击跳转问题</li>
|
||||||
|
<li>修复菜单管理选择图标,backspace删除时不过滤数据</li>
|
||||||
|
<li>用户管理部门分支节点不可检查&显示计数</li>
|
||||||
|
<li>数据范围过滤属性调整</li>
|
||||||
|
<li>其他细节优化</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
|
||||||
|
<el-collapse-item title="v2.3.0 - 2020-06-01">
|
||||||
|
<ol>
|
||||||
|
<li>升级fastjson到最新版1.2.70 修复高危安全漏洞</li>
|
||||||
|
<li>dev启动默认打开浏览器</li>
|
||||||
|
<li>vue-cli使用默认source-map</li>
|
||||||
|
<li>slidebar eslint报错优化</li>
|
||||||
|
<li>当tags-view滚动关闭右键菜单</li>
|
||||||
|
<li>字典管理添加缓存读取</li>
|
||||||
|
<li>参数管理支持缓存操作</li>
|
||||||
|
<li>支持一级菜单(和主页同级)在main区域显示</li>
|
||||||
|
<li>限制外链地址必须以http(s)开头</li>
|
||||||
|
<li>tagview & sidebar 主题颜色与element ui(全局)同步</li>
|
||||||
|
<li>修改数据源类型优先级,先根据方法,再根据类</li>
|
||||||
|
<li>支持是否需要设置token属性,自定义返回码消息。</li>
|
||||||
|
<li>swagger请求前缀加入配置。</li>
|
||||||
|
<li>登录地点设置内容过长则隐藏显示</li>
|
||||||
|
<li>修复定时任务执行一次按钮后不提示消息问题</li>
|
||||||
|
<li>修改上级部门(选择项排除本身和下级)</li>
|
||||||
|
<li>通用http发送方法增加参数 contentType 编码类型</li>
|
||||||
|
<li>更换IP地址查询接口</li>
|
||||||
|
<li>修复页签变量undefined</li>
|
||||||
|
<li>添加校验部门包含未停用的子部门</li>
|
||||||
|
<li>修改定时任务详情下次执行时间日期显示错误</li>
|
||||||
|
<li>角色管理查询设置默认排序字段</li>
|
||||||
|
<li>swagger添加enable参数控制是否启用</li>
|
||||||
|
<li>只对json类型请求构建可重复读取inputStream的request</li>
|
||||||
|
<li>修改代码生成字典字段int类型没有自动选中问题</li>
|
||||||
|
<li>vuex用户名取值修正</li>
|
||||||
|
<li>表格树模板去掉多余的)</li>
|
||||||
|
<li>代码生成序号修正</li>
|
||||||
|
<li>全屏情况下不调整上外边距</li>
|
||||||
|
<li>代码生成Date字段添加默认格式</li>
|
||||||
|
<li>用户管理角色选择权限控制</li>
|
||||||
|
<li>修复路由懒加载报错问题</li>
|
||||||
|
<li>模板sql.vm添加菜单状态</li>
|
||||||
|
<li>设置用户名称不能修改</li>
|
||||||
|
<li>dialog添加append-to-body属性,防止ie遮罩</li>
|
||||||
|
<li>菜单区分状态和显示隐藏功能</li>
|
||||||
|
<li>升级fastjson到最新版1.2.68 修复安全加固</li>
|
||||||
|
<li>修复代码生成如果选择字典类型缺失逗号问题</li>
|
||||||
|
<li>登录请求params更换为data,防止暴露url</li>
|
||||||
|
<li>日志返回时间格式处理</li>
|
||||||
|
<li>添加handle控制允许拖动的元素</li>
|
||||||
|
<li>布局设置点击扩大范围</li>
|
||||||
|
<li>代码生成列属性排序查询</li>
|
||||||
|
<li>代码生成列支持拖动排序</li>
|
||||||
|
<li>修复时间格式不支持ios问题</li>
|
||||||
|
<li>表单构建添加父级class,防止冲突</li>
|
||||||
|
<li>定时任务并发属性修正</li>
|
||||||
|
<li>角色禁用&菜单隐藏不查询权限</li>
|
||||||
|
<li>其他细节优化</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
|
||||||
|
<el-collapse-item title="v2.2.0 - 2020-03-18">
|
||||||
|
<ol>
|
||||||
|
<li>系统监控新增定时任务功能</li>
|
||||||
|
<li>添加一个打包Web工程bat</li>
|
||||||
|
<li>修复页签鼠标滚轮按下的时候,可以关闭不可关闭的tag</li>
|
||||||
|
<li>修复点击退出登录有时会无提示问题</li>
|
||||||
|
<li>修复防重复提交注解无效问题</li>
|
||||||
|
<li>修复通知公告批量删除异常问题</li>
|
||||||
|
<li>添加菜单时路由地址必填限制</li>
|
||||||
|
<li>代码生成字段描述可编辑</li>
|
||||||
|
<li>修复用户修改个人信息导致缓存不过期问题</li>
|
||||||
|
<li>个人信息创建时间获取正确属性值</li>
|
||||||
|
<li>操作日志详细显示正确类型</li>
|
||||||
|
<li>导入表单击行数据时选中对应的复选框</li>
|
||||||
|
<li>批量替换表前缀逻辑调整</li>
|
||||||
|
<li>固定重定向路径表达式</li>
|
||||||
|
<li>升级element-ui版本到2.13.0</li>
|
||||||
|
<li>操作日志排序调整</li>
|
||||||
|
<li>修复charts切换侧边栏或者缩放窗口显示bug</li>
|
||||||
|
<li>其他细节优化</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
|
||||||
|
<el-collapse-item title="v2.1.0 - 2020-02-24">
|
||||||
|
<ol>
|
||||||
|
<li>新增表单构建</li>
|
||||||
|
<li>代码生成支持树表结构</li>
|
||||||
|
<li>新增用户导入</li>
|
||||||
|
<li>修复动态加载路由页面刷新问题</li>
|
||||||
|
<li>修复地址开关无效问题</li>
|
||||||
|
<li>汉化错误提示页面</li>
|
||||||
|
<li>代码生成已知问题修改</li>
|
||||||
|
<li>修复多数据源下配置关闭出现异常处理</li>
|
||||||
|
<li>添加HTML过滤器,用于去除XSS漏洞隐患</li>
|
||||||
|
<li>修复上传头像控制台出现异常</li>
|
||||||
|
<li>修改用户管理分页不正确的问题</li>
|
||||||
|
<li>修复验证码记录提示错误</li>
|
||||||
|
<li>修复request.js缺少Message引用</li>
|
||||||
|
<li>修复表格时间为空出现的异常</li>
|
||||||
|
<li>添加Jackson日期反序列化时区配置</li>
|
||||||
|
<li>调整根据用户权限加载菜单数据树形结构</li>
|
||||||
|
<li>调整成功登陆不恢复按钮,防止多次点击</li>
|
||||||
|
<li>修改用户个人资料同步缓存信息</li>
|
||||||
|
<li>修复页面同时出现el-upload和Editor不显示处理</li>
|
||||||
|
<li>修复在角色管理页修改菜单权限偶尔未选中问题</li>
|
||||||
|
<li>配置文件新增redis密码属性</li>
|
||||||
|
<li>设置mybatis全局的配置文件</li>
|
||||||
|
<li>其他细节优化</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
|
||||||
|
<el-collapse-item title="v2.0.0 - 2019-12-02">
|
||||||
|
<ol>
|
||||||
|
<li>新增代码生成</li>
|
||||||
|
<li>新增@RepeatSubmit注解,防止重复提交</li>
|
||||||
|
<li>新增菜单主目录添加/删除操作</li>
|
||||||
|
<li>日志记录过滤特殊对象,防止转换异常</li>
|
||||||
|
<li>修改代码生成路由脚本错误</li>
|
||||||
|
<li>用户上传头像实时同步缓存,无需重新登录</li>
|
||||||
|
<li>调整切换页签后不重新加载数据</li>
|
||||||
|
<li>添加jsencrypt实现参数的前端加密</li>
|
||||||
|
<li>系统退出删除用户缓存记录</li>
|
||||||
|
<li>其他细节优化</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
<el-collapse-item title="v1.1.0 - 2019-11-11">
|
||||||
|
<ol>
|
||||||
|
<li>新增在线用户管理</li>
|
||||||
|
<li>新增按钮组功能实现(批量删除、导出、清空)</li>
|
||||||
|
<li>新增查询条件重置按钮</li>
|
||||||
|
<li>新增Swagger全局Token配置</li>
|
||||||
|
<li>新增后端参数校验</li>
|
||||||
|
<li>修复字典管理页面的日期查询异常</li>
|
||||||
|
<li>修改时间函数命名防止冲突</li>
|
||||||
|
<li>去除菜单上级校验,默认为顶级</li>
|
||||||
|
<li>修复用户密码无法修改问题</li>
|
||||||
|
<li>修复菜单类型为按钮时不显示权限标识</li>
|
||||||
|
<li>其他细节优化</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
<el-collapse-item title="v1.0.0 - 2019-10-08">
|
||||||
|
<ol>
|
||||||
|
<li>若依前后端分离系统正式发布</li>
|
||||||
|
</ol>
|
||||||
|
</el-collapse-item>
|
||||||
|
</el-collapse>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="12" :lg="8">
|
||||||
|
<el-card class="update-log">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>捐赠支持</span>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<img
|
||||||
|
src="https://oscimg.oschina.net/oscnet/up-d6695f82666e5018f715c41cb7ee60d3b73.png"
|
||||||
|
alt="donate"
|
||||||
|
width="100%"
|
||||||
|
/>
|
||||||
|
<span style="display: inline-block; height: 30px; line-height: 30px"
|
||||||
|
>你可以请作者喝杯咖啡表示鼓励</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PanelGroup from './dashboard/PanelGroup'
|
|
||||||
import LineChart from './dashboard/LineChart'
|
|
||||||
import RaddarChart from './dashboard/RaddarChart'
|
|
||||||
import PieChart from './dashboard/PieChart'
|
|
||||||
import BarChart from './dashboard/BarChart'
|
|
||||||
|
|
||||||
const lineChartData = {
|
|
||||||
newVisitis: {
|
|
||||||
expectedData: [100, 120, 161, 134, 105, 160, 165],
|
|
||||||
actualData: [120, 82, 91, 154, 162, 140, 145]
|
|
||||||
},
|
|
||||||
messages: {
|
|
||||||
expectedData: [200, 192, 120, 144, 160, 130, 140],
|
|
||||||
actualData: [180, 160, 151, 106, 145, 150, 130]
|
|
||||||
},
|
|
||||||
purchases: {
|
|
||||||
expectedData: [80, 100, 121, 104, 105, 90, 100],
|
|
||||||
actualData: [120, 90, 100, 138, 142, 130, 130]
|
|
||||||
},
|
|
||||||
shoppings: {
|
|
||||||
expectedData: [130, 140, 141, 142, 145, 150, 160],
|
|
||||||
actualData: [120, 82, 91, 154, 162, 140, 130]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Index',
|
name: "index",
|
||||||
components: {
|
|
||||||
PanelGroup,
|
|
||||||
LineChart,
|
|
||||||
RaddarChart,
|
|
||||||
PieChart,
|
|
||||||
BarChart
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
lineChartData: lineChartData.newVisitis
|
// 版本号
|
||||||
}
|
version: "3.4.0",
|
||||||
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleSetLineChartData(type) {
|
goTarget(href) {
|
||||||
this.lineChartData = lineChartData[type]
|
window.open(href, "_blank");
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style scoped lang="scss">
|
||||||
.dashboard-editor-container {
|
.home {
|
||||||
padding: 32px;
|
blockquote {
|
||||||
background-color: rgb(240, 242, 245);
|
padding: 10px 20px;
|
||||||
position: relative;
|
margin: 0 0 20px;
|
||||||
|
font-size: 17.5px;
|
||||||
.chart-wrapper {
|
border-left: 5px solid #eee;
|
||||||
background: #fff;
|
}
|
||||||
padding: 16px 16px 0;
|
hr {
|
||||||
margin-bottom: 32px;
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border: 0;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
}
|
||||||
|
.col-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width:1024px) {
|
ul {
|
||||||
.chart-wrapper {
|
padding: 0;
|
||||||
padding: 8px;
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #676a6c;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
b {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-log {
|
||||||
|
ol {
|
||||||
|
display: block;
|
||||||
|
list-style-type: decimal;
|
||||||
|
margin-block-start: 1em;
|
||||||
|
margin-block-end: 1em;
|
||||||
|
margin-inline-start: 0;
|
||||||
|
margin-inline-end: 0;
|
||||||
|
padding-inline-start: 40px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|