mirror of
https://gitee.com/y_project/RuoYi-Vue.git
synced 2025-12-08 15:02:29 +08:00
Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8499225192 | |||
| 4a5e45d160 | |||
| 188e50ff1c | |||
| bd66cc7260 | |||
| 866b47000c | |||
| f38f8b2c3e | |||
| faa86ac946 | |||
| ad280e824c | |||
| 6e1aa42ebe | |||
| 315901041f | |||
| 91263711d4 | |||
| 9372d3401f | |||
| 0eaa090f4b | |||
| a5adee3c5f | |||
| 075e96466f | |||
| 41496b6d8a | |||
| 4a401984c1 | |||
| e5faee66c8 | |||
| 7558c176eb | |||
| 4a5b0e6079 | |||
| 08637e31e5 | |||
| 512b157801 | |||
| 5e8efaa94a | |||
| 5f11fed41b | |||
| b60b5de750 | |||
| 41ff3843e6 | |||
| 6a2e8a35e9 | |||
| 769165575f | |||
| 18c8d4ec9c | |||
| 191fd29301 | |||
| 47510fe2de | |||
| 725c7dcea2 | |||
| 158ccaebe0 | |||
| 7b9060af26 | |||
| 1a2f20e859 | |||
| 09faecb5d3 | |||
| d46e62a21a | |||
| fa88922637 | |||
| 65159934ab | |||
| 1642bba612 | |||
| a7a61fee8d | |||
| db6d5d34e6 | |||
| 9ceca3a68e | |||
| cf2579612c | |||
| c0355a0f5a | |||
| 8ff013552a | |||
| 673249d373 | |||
| fe3a92a812 | |||
| 67b6a0e11b | |||
| bc70351e34 | |||
| fe0c1fcb5b | |||
| 9f39dfd0c1 | |||
| 131abe876d | |||
| 46708ceee4 | |||
| ecd201550f | |||
| ff3f3f2631 | |||
| d3cc8f0fb7 | |||
| 6cafa3373e | |||
| 42fbf09dde | |||
| 88b0f5bcb2 | |||
| e852fdb687 | |||
| baf2f6f46b | |||
| e19f1abfeb | |||
| 38ed092de7 | |||
| 27a037ed3d | |||
| 87173cbe75 | |||
| 29a5b6da53 | |||
| b1d2139559 | |||
| 43d78c2cf5 | |||
| 8f4eb24bf2 | |||
| a9f9133e31 | |||
| 09810ccf1d | |||
| 0d9fb8b5c0 | |||
| c6b0efcdc2 | |||
| 84fef1f675 | |||
| 11fed08b56 | |||
| f83b6fbfa2 | |||
| eef81e6ca9 | |||
| 5a03a754e8 | |||
| 245dea7215 | |||
| 51632f8e60 | |||
| 525ebf92d2 | |||
| d3b23a831e | |||
| 89ab3bd058 | |||
| 9e16beb48f | |||
| 8d5ecc7ff4 | |||
| 6e314dd3e8 | |||
| 193c256e71 | |||
| 4df52a6b40 | |||
| 079b7eeecf | |||
| ba24010709 | |||
| bd257f85e6 | |||
| 40c7ca34a8 | |||
| 1ef73d7360 | |||
| bd233fd62f | |||
| fabddc518a | |||
| ca61b6c68d | |||
| 51e5cf2a09 | |||
| 00acc37916 | |||
| 511ff0f125 | |||
| bf46e38c29 | |||
| 698a5198d9 |
@ -1,11 +1,11 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
|
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
|
||||||
</p>
|
</p>
|
||||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.9</h1>
|
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.9.0</h1>
|
||||||
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
|
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
|
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
|
||||||
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.9-brightgreen.svg"></a>
|
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.9.0-brightgreen.svg"></a>
|
||||||
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
|
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -92,4 +92,4 @@
|
|||||||
|
|
||||||
## 若依前后端分离交流群
|
## 若依前后端分离交流群
|
||||||
|
|
||||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=5bVB1og) [](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [](https://jq.qq.com/?_wv=1027&k=51G72yr) [](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [](https://jq.qq.com/?_wv=1027&k=SpyH2875) [](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) 点击按钮入群。
|
QQ群: [](https://jq.qq.com/?_wv=1027&k=5bVB1og) [](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [](https://jq.qq.com/?_wv=1027&k=51G72yr) [](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [](https://jq.qq.com/?_wv=1027&k=SpyH2875) [](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=F58bgRa-Dp-rsQJThiJqIYv8t4-lWfXh&authKey=UmUs4CVG5OPA1whvsa4uSespOvyd8%2FAr9olEGaWAfdLmfKQk%2FVBp2YU3u2xXXt76&noverify=0&group_code=224622315) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Nxb2EQ5qozWa218Wbs7zgBnjLSNk_tVT&authKey=obBKXj6SBKgrFTJZx0AqQnIYbNOvBB2kmgwWvGhzxR67RoRr84%2Bus5OadzMcdJl5&noverify=0&group_code=287842588) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=numtK1M_I4eVd2Gvg8qtbuL8JgX42qNh&authKey=giV9XWMaFZTY%2FqPlmWbkB9g3fi0Ev5CwEtT9Tgei0oUlFFCQLDp4ozWRiVIzubIm&noverify=0&group_code=187944233) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G6r5KGCaa3pqdbUSXNIgYloyb8e0_L0D&authKey=4w8tF1eGW7%2FedWn%2FHAypQksdrML%2BDHolQSx7094Agm7Luakj9EbfPnSTxSi2T1LQ&noverify=0&group_code=228578329) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GsOo-OLz53J8y_9TPoO6XXSGNRTgbFxA&authKey=R7Uy%2Feq%2BZsoKNqHvRKhiXpypW7DAogoWapOawUGHokJSBIBIre2%2FoiAZeZBSLuBc&noverify=0&group_code=191164766) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=PmYavuzsOthVqfdAPbo4uAeIbu7Ttjgc&authKey=p52l8%2FXa4PS1JcEmS3VccKSwOPJUZ1ZfQ69MEKzbrooNUljRtlKjvsXf04bxNp3G&noverify=0&group_code=174569686) 点击按钮入群。
|
||||||
Binary file not shown.
14
pom.xml
14
pom.xml
@ -6,14 +6,14 @@
|
|||||||
|
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<version>3.8.9</version>
|
<version>3.9.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.8.9</ruoyi.version>
|
<ruoyi.version>3.9.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>
|
||||||
@ -24,16 +24,16 @@
|
|||||||
<swagger.version>3.0.0</swagger.version>
|
<swagger.version>3.0.0</swagger.version>
|
||||||
<kaptcha.version>2.3.3</kaptcha.version>
|
<kaptcha.version>2.3.3</kaptcha.version>
|
||||||
<pagehelper.boot.version>1.4.7</pagehelper.boot.version>
|
<pagehelper.boot.version>1.4.7</pagehelper.boot.version>
|
||||||
<fastjson.version>2.0.53</fastjson.version>
|
<fastjson.version>2.0.58</fastjson.version>
|
||||||
<oshi.version>6.6.5</oshi.version>
|
<oshi.version>6.8.3</oshi.version>
|
||||||
<commons.io.version>2.13.0</commons.io.version>
|
<commons.io.version>2.19.0</commons.io.version>
|
||||||
<poi.version>4.1.2</poi.version>
|
<poi.version>4.1.2</poi.version>
|
||||||
<velocity.version>2.3</velocity.version>
|
<velocity.version>2.3</velocity.version>
|
||||||
<jwt.version>0.9.1</jwt.version>
|
<jwt.version>0.9.1</jwt.version>
|
||||||
<!-- override dependency version -->
|
<!-- override dependency version -->
|
||||||
<tomcat.version>9.0.96</tomcat.version>
|
<tomcat.version>9.0.112</tomcat.version>
|
||||||
<logback.version>1.2.13</logback.version>
|
<logback.version>1.2.13</logback.version>
|
||||||
<spring-security.version>5.7.12</spring-security.version>
|
<spring-security.version>5.7.14</spring-security.version>
|
||||||
<spring-framework.version>5.3.39</spring-framework.version>
|
<spring-framework.version>5.3.39</spring-framework.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.8.9</version>
|
<version>3.9.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.ruoyi.common.config.RuoYiConfig;
|
import com.ruoyi.common.config.RuoYiConfig;
|
||||||
import com.ruoyi.common.constant.Constants;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||||
@ -35,7 +34,7 @@ public class CommonController
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ServerConfig serverConfig;
|
private ServerConfig serverConfig;
|
||||||
|
|
||||||
private static final String FILE_DELIMETER = ",";
|
private static final String FILE_DELIMITER = ",";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用下载请求
|
* 通用下载请求
|
||||||
@ -120,10 +119,10 @@ public class CommonController
|
|||||||
originalFilenames.add(file.getOriginalFilename());
|
originalFilenames.add(file.getOriginalFilename());
|
||||||
}
|
}
|
||||||
AjaxResult ajax = AjaxResult.success();
|
AjaxResult ajax = AjaxResult.success();
|
||||||
ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
|
ajax.put("urls", StringUtils.join(urls, FILE_DELIMITER));
|
||||||
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
|
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMITER));
|
||||||
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
|
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMITER));
|
||||||
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
|
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMITER));
|
||||||
return ajax;
|
return ajax;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -148,7 +147,7 @@ public class CommonController
|
|||||||
// 本地资源路径
|
// 本地资源路径
|
||||||
String localPath = RuoYiConfig.getProfile();
|
String localPath = RuoYiConfig.getProfile();
|
||||||
// 数据库资源地址
|
// 数据库资源地址
|
||||||
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
|
String downloadPath = localPath + FileUtils.stripPrefix(resource);
|
||||||
// 下载名称
|
// 下载名称
|
||||||
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
|
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
|
||||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.web.controller.system;
|
package com.ruoyi.web.controller.system;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -13,10 +14,14 @@ import com.ruoyi.common.core.domain.entity.SysMenu;
|
|||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.common.core.domain.model.LoginBody;
|
import com.ruoyi.common.core.domain.model.LoginBody;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
|
import com.ruoyi.common.core.text.Convert;
|
||||||
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.framework.web.service.SysLoginService;
|
import com.ruoyi.framework.web.service.SysLoginService;
|
||||||
import com.ruoyi.framework.web.service.SysPermissionService;
|
import com.ruoyi.framework.web.service.SysPermissionService;
|
||||||
import com.ruoyi.framework.web.service.TokenService;
|
import com.ruoyi.framework.web.service.TokenService;
|
||||||
|
import com.ruoyi.system.service.ISysConfigService;
|
||||||
import com.ruoyi.system.service.ISysMenuService;
|
import com.ruoyi.system.service.ISysMenuService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,6 +44,9 @@ public class SysLoginController
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TokenService tokenService;
|
private TokenService tokenService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysConfigService configService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录方法
|
* 登录方法
|
||||||
*
|
*
|
||||||
@ -79,6 +87,8 @@ public class SysLoginController
|
|||||||
ajax.put("user", user);
|
ajax.put("user", user);
|
||||||
ajax.put("roles", roles);
|
ajax.put("roles", roles);
|
||||||
ajax.put("permissions", permissions);
|
ajax.put("permissions", permissions);
|
||||||
|
ajax.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
|
||||||
|
ajax.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
|
||||||
return ajax;
|
return ajax;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,4 +104,28 @@ public class SysLoginController
|
|||||||
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
|
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
|
||||||
return AjaxResult.success(menuService.buildMenus(menus));
|
return AjaxResult.success(menuService.buildMenus(menus));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查初始密码是否提醒修改
|
||||||
|
public boolean initPasswordIsModify(Date pwdUpdateDate)
|
||||||
|
{
|
||||||
|
Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
|
||||||
|
return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查密码是否过期
|
||||||
|
public boolean passwordIsExpiration(Date pwdUpdateDate)
|
||||||
|
{
|
||||||
|
Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
|
||||||
|
if (passwordValidateDays != null && passwordValidateDays > 0)
|
||||||
|
{
|
||||||
|
if (StringUtils.isNull(pwdUpdateDate))
|
||||||
|
{
|
||||||
|
// 如果从未修改过初始密码,直接提醒过期
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Date nowDate = DateUtils.getNowDate();
|
||||||
|
return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,9 +17,11 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
|||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||||
|
import com.ruoyi.common.utils.file.FileUtils;
|
||||||
import com.ruoyi.common.utils.file.MimeTypeUtils;
|
import com.ruoyi.common.utils.file.MimeTypeUtils;
|
||||||
import com.ruoyi.framework.web.service.TokenService;
|
import com.ruoyi.framework.web.service.TokenService;
|
||||||
import com.ruoyi.system.service.ISysUserService;
|
import com.ruoyi.system.service.ISysUserService;
|
||||||
@ -93,8 +95,9 @@ public class SysProfileController extends BaseController
|
|||||||
String oldPassword = params.get("oldPassword");
|
String oldPassword = params.get("oldPassword");
|
||||||
String newPassword = params.get("newPassword");
|
String newPassword = params.get("newPassword");
|
||||||
LoginUser loginUser = getLoginUser();
|
LoginUser loginUser = getLoginUser();
|
||||||
String userName = loginUser.getUsername();
|
Long userId = loginUser.getUserId();
|
||||||
String password = loginUser.getPassword();
|
SysUser user = userService.selectUserById(userId);
|
||||||
|
String password = user.getPassword();
|
||||||
if (!SecurityUtils.matchesPassword(oldPassword, password))
|
if (!SecurityUtils.matchesPassword(oldPassword, password))
|
||||||
{
|
{
|
||||||
return error("修改密码失败,旧密码错误");
|
return error("修改密码失败,旧密码错误");
|
||||||
@ -104,9 +107,10 @@ public class SysProfileController extends BaseController
|
|||||||
return error("新密码不能与旧密码相同");
|
return error("新密码不能与旧密码相同");
|
||||||
}
|
}
|
||||||
newPassword = SecurityUtils.encryptPassword(newPassword);
|
newPassword = SecurityUtils.encryptPassword(newPassword);
|
||||||
if (userService.resetUserPwd(userName, newPassword) > 0)
|
if (userService.resetUserPwd(userId, newPassword) > 0)
|
||||||
{
|
{
|
||||||
// 更新缓存用户密码
|
// 更新缓存用户密码&密码最后更新时间
|
||||||
|
loginUser.getUser().setPwdUpdateDate(DateUtils.getNowDate());
|
||||||
loginUser.getUser().setPassword(newPassword);
|
loginUser.getUser().setPassword(newPassword);
|
||||||
tokenService.setLoginUser(loginUser);
|
tokenService.setLoginUser(loginUser);
|
||||||
return success();
|
return success();
|
||||||
@ -124,9 +128,14 @@ public class SysProfileController extends BaseController
|
|||||||
if (!file.isEmpty())
|
if (!file.isEmpty())
|
||||||
{
|
{
|
||||||
LoginUser loginUser = getLoginUser();
|
LoginUser loginUser = getLoginUser();
|
||||||
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
|
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION, true);
|
||||||
if (userService.updateUserAvatar(loginUser.getUsername(), avatar))
|
if (userService.updateUserAvatar(loginUser.getUserId(), avatar))
|
||||||
{
|
{
|
||||||
|
String oldAvatar = loginUser.getUser().getAvatar();
|
||||||
|
if (StringUtils.isNotEmpty(oldAvatar))
|
||||||
|
{
|
||||||
|
FileUtils.deleteFile(RuoYiConfig.getProfile() + FileUtils.stripPrefix(oldAvatar));
|
||||||
|
}
|
||||||
AjaxResult ajax = AjaxResult.success();
|
AjaxResult ajax = AjaxResult.success();
|
||||||
ajax.put("imgUrl", avatar);
|
ajax.put("imgUrl", avatar);
|
||||||
// 更新缓存用户头像
|
// 更新缓存用户头像
|
||||||
|
|||||||
@ -3,9 +3,9 @@ ruoyi:
|
|||||||
# 名称
|
# 名称
|
||||||
name: RuoYi
|
name: RuoYi
|
||||||
# 版本
|
# 版本
|
||||||
version: 3.8.9
|
version: 3.9.0
|
||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2024
|
copyrightYear: 2025
|
||||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||||
profile: D:/ruoyi/uploadPath
|
profile: D:/ruoyi/uploadPath
|
||||||
# 获取ip地址开关
|
# 获取ip地址开关
|
||||||
@ -119,6 +119,13 @@ swagger:
|
|||||||
# 请求前缀
|
# 请求前缀
|
||||||
pathMapping: /dev-api
|
pathMapping: /dev-api
|
||||||
|
|
||||||
|
# 防盗链配置
|
||||||
|
referer:
|
||||||
|
# 防盗链开关
|
||||||
|
enabled: false
|
||||||
|
# 允许的域名列表
|
||||||
|
allowed-domains: localhost,127.0.0.1,ruoyi.vip,www.ruoyi.vip
|
||||||
|
|
||||||
# 防止XSS攻击
|
# 防止XSS攻击
|
||||||
xss:
|
xss:
|
||||||
# 过滤开关
|
# 过滤开关
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.8.9</version>
|
<version>3.9.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@ -83,12 +83,12 @@ public class Constants
|
|||||||
/**
|
/**
|
||||||
* 角色权限分隔符
|
* 角色权限分隔符
|
||||||
*/
|
*/
|
||||||
public static final String ROLE_DELIMETER = ",";
|
public static final String ROLE_DELIMITER = ",";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限标识分隔符
|
* 权限标识分隔符
|
||||||
*/
|
*/
|
||||||
public static final String PERMISSION_DELIMETER = ",";
|
public static final String PERMISSION_DELIMITER = ",";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码有效期(分钟)
|
* 验证码有效期(分钟)
|
||||||
@ -158,7 +158,7 @@ public class Constants
|
|||||||
/**
|
/**
|
||||||
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
|
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
|
||||||
*/
|
*/
|
||||||
public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" };
|
public static final String[] JSON_WHITELIST_STR = { "com.ruoyi" };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
|
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import java.util.List;
|
|||||||
import javax.validation.constraints.*;
|
import javax.validation.constraints.*;
|
||||||
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.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.ruoyi.common.annotation.Excel;
|
import com.ruoyi.common.annotation.Excel;
|
||||||
import com.ruoyi.common.annotation.Excel.ColumnType;
|
import com.ruoyi.common.annotation.Excel.ColumnType;
|
||||||
import com.ruoyi.common.annotation.Excel.Type;
|
import com.ruoyi.common.annotation.Excel.Type;
|
||||||
@ -55,8 +56,8 @@ public class SysUser extends BaseEntity
|
|||||||
/** 密码 */
|
/** 密码 */
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
/** 帐号状态(0正常 1停用) */
|
/** 账号状态(0正常 1停用) */
|
||||||
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
|
@Excel(name = "账号状态", readConverterExp = "0=正常,1=停用")
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
/** 删除标志(0代表存在 2代表删除) */
|
/** 删除标志(0代表存在 2代表删除) */
|
||||||
@ -70,6 +71,9 @@ public class SysUser extends BaseEntity
|
|||||||
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
|
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
|
||||||
private Date loginDate;
|
private Date loginDate;
|
||||||
|
|
||||||
|
/** 密码最后更新时间 */
|
||||||
|
private Date pwdUpdateDate;
|
||||||
|
|
||||||
/** 部门对象 */
|
/** 部门对象 */
|
||||||
@Excels({
|
@Excels({
|
||||||
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
|
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
|
||||||
@ -197,6 +201,7 @@ public class SysUser extends BaseEntity
|
|||||||
this.avatar = avatar;
|
this.avatar = avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
||||||
public String getPassword()
|
public String getPassword()
|
||||||
{
|
{
|
||||||
return password;
|
return password;
|
||||||
@ -247,6 +252,16 @@ public class SysUser extends BaseEntity
|
|||||||
this.loginDate = loginDate;
|
this.loginDate = loginDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Date getPwdUpdateDate()
|
||||||
|
{
|
||||||
|
return pwdUpdateDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPwdUpdateDate(Date pwdUpdateDate)
|
||||||
|
{
|
||||||
|
this.pwdUpdateDate = pwdUpdateDate;
|
||||||
|
}
|
||||||
|
|
||||||
public SysDept getDept()
|
public SysDept getDept()
|
||||||
{
|
{
|
||||||
return dept;
|
return dept;
|
||||||
@ -313,6 +328,7 @@ public class SysUser extends BaseEntity
|
|||||||
.append("delFlag", getDelFlag())
|
.append("delFlag", getDelFlag())
|
||||||
.append("loginIp", getLoginIp())
|
.append("loginIp", getLoginIp())
|
||||||
.append("loginDate", getLoginDate())
|
.append("loginDate", getLoginDate())
|
||||||
|
.append("pwdUpdateDate", getPwdUpdateDate())
|
||||||
.append("createBy", getCreateBy())
|
.append("createBy", getCreateBy())
|
||||||
.append("createTime", getCreateTime())
|
.append("createTime", getCreateTime())
|
||||||
.append("updateBy", getUpdateBy())
|
.append("updateBy", getUpdateBy())
|
||||||
|
|||||||
@ -37,7 +37,7 @@ public class TableDataInfo implements Serializable
|
|||||||
* @param list 列表数据
|
* @param list 列表数据
|
||||||
* @param total 总记录数
|
* @param total 总记录数
|
||||||
*/
|
*/
|
||||||
public TableDataInfo(List<?> list, int total)
|
public TableDataInfo(List<?> list, long total)
|
||||||
{
|
{
|
||||||
this.rows = list;
|
this.rows = list;
|
||||||
this.total = total;
|
this.total = total;
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import java.nio.charset.Charset;
|
|||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型转换器
|
* 类型转换器
|
||||||
@ -541,7 +540,7 @@ public class Convert
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为boolean<br>
|
* 转换为boolean<br>
|
||||||
* String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
|
* String支持的值为:true、false、yes、ok、no、1、0、是、否, 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
* @param value 被转换的值
|
* @param value 被转换的值
|
||||||
@ -570,10 +569,12 @@ public class Convert
|
|||||||
case "yes":
|
case "yes":
|
||||||
case "ok":
|
case "ok":
|
||||||
case "1":
|
case "1":
|
||||||
|
case "是":
|
||||||
return true;
|
return true;
|
||||||
case "false":
|
case "false":
|
||||||
case "no":
|
case "no":
|
||||||
case "0":
|
case "0":
|
||||||
|
case "否":
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
@ -796,14 +797,23 @@ public class Convert
|
|||||||
{
|
{
|
||||||
return (String) obj;
|
return (String) obj;
|
||||||
}
|
}
|
||||||
else if (obj instanceof byte[])
|
else if (obj instanceof byte[] || obj instanceof Byte[])
|
||||||
{
|
{
|
||||||
return str((byte[]) obj, charset);
|
if (obj instanceof byte[])
|
||||||
}
|
{
|
||||||
else if (obj instanceof Byte[])
|
return str((byte[]) obj, charset);
|
||||||
{
|
}
|
||||||
byte[] bytes = ArrayUtils.toPrimitive((Byte[]) obj);
|
else
|
||||||
return str(bytes, charset);
|
{
|
||||||
|
Byte[] bytes = (Byte[]) obj;
|
||||||
|
int length = bytes.length;
|
||||||
|
byte[] dest = new byte[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
dest[i] = bytes[i];
|
||||||
|
}
|
||||||
|
return str(dest, charset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (obj instanceof ByteBuffer)
|
else if (obj instanceof ByteBuffer)
|
||||||
{
|
{
|
||||||
@ -959,9 +969,7 @@ public class Convert
|
|||||||
c[i] = (char) (c[i] - 65248);
|
c[i] = (char) (c[i] - 65248);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String returnString = new String(c);
|
return new String(c);
|
||||||
|
|
||||||
return returnString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,77 @@
|
|||||||
|
package com.ruoyi.common.filter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 防盗链过滤器
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class RefererFilter implements Filter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 允许的域名列表
|
||||||
|
*/
|
||||||
|
public List<String> allowedDomains;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException
|
||||||
|
{
|
||||||
|
String domains = filterConfig.getInitParameter("allowedDomains");
|
||||||
|
this.allowedDomains = Arrays.asList(domains.split(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||||
|
throws IOException, ServletException
|
||||||
|
{
|
||||||
|
HttpServletRequest req = (HttpServletRequest) request;
|
||||||
|
HttpServletResponse resp = (HttpServletResponse) response;
|
||||||
|
|
||||||
|
String referer = req.getHeader("Referer");
|
||||||
|
|
||||||
|
// 如果Referer为空,拒绝访问
|
||||||
|
if (referer == null || referer.isEmpty())
|
||||||
|
{
|
||||||
|
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied: Referer header is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查Referer是否在允许的域名列表中
|
||||||
|
boolean allowed = false;
|
||||||
|
for (String domain : allowedDomains)
|
||||||
|
{
|
||||||
|
if (referer.contains(domain))
|
||||||
|
{
|
||||||
|
allowed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据检查结果决定是否放行
|
||||||
|
if (allowed)
|
||||||
|
{
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied: Referer '" + referer + "' is not allowed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -108,7 +108,6 @@ public class Arith
|
|||||||
"The scale must be a positive integer or zero");
|
"The scale must be a positive integer or zero");
|
||||||
}
|
}
|
||||||
BigDecimal b = new BigDecimal(Double.toString(v));
|
BigDecimal b = new BigDecimal(Double.toString(v));
|
||||||
BigDecimal one = BigDecimal.ONE;
|
return b.divide(BigDecimal.ONE, scale, RoundingMode.HALF_UP).doubleValue();
|
||||||
return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
package com.ruoyi.common.utils;
|
package com.ruoyi.common.utils;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.ruoyi.common.constant.CacheConstants;
|
import com.ruoyi.common.constant.CacheConstants;
|
||||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||||
@ -89,37 +91,25 @@ public class DictUtils
|
|||||||
*/
|
*/
|
||||||
public static String getDictLabel(String dictType, String dictValue, String separator)
|
public static String getDictLabel(String dictType, String dictValue, String separator)
|
||||||
{
|
{
|
||||||
StringBuilder propertyString = new StringBuilder();
|
|
||||||
List<SysDictData> datas = getDictCache(dictType);
|
List<SysDictData> datas = getDictCache(dictType);
|
||||||
if (StringUtils.isNull(datas))
|
if (StringUtils.isNull(datas) || StringUtils.isEmpty(dictValue))
|
||||||
{
|
{
|
||||||
return StringUtils.EMPTY;
|
return StringUtils.EMPTY;
|
||||||
}
|
}
|
||||||
if (StringUtils.containsAny(separator, dictValue))
|
Map<String, String> dictMap = datas.stream().collect(HashMap::new, (map, dict) -> map.put(dict.getDictValue(), dict.getDictLabel()), Map::putAll);
|
||||||
|
if (!StringUtils.contains(dictValue, separator))
|
||||||
{
|
{
|
||||||
for (SysDictData dict : datas)
|
return dictMap.getOrDefault(dictValue, StringUtils.EMPTY);
|
||||||
|
}
|
||||||
|
StringBuilder labelBuilder = new StringBuilder();
|
||||||
|
for (String seperatedValue : dictValue.split(separator))
|
||||||
|
{
|
||||||
|
if (dictMap.containsKey(seperatedValue))
|
||||||
{
|
{
|
||||||
for (String value : dictValue.split(separator))
|
labelBuilder.append(dictMap.get(seperatedValue)).append(separator);
|
||||||
{
|
|
||||||
if (value.equals(dict.getDictValue()))
|
|
||||||
{
|
|
||||||
propertyString.append(dict.getDictLabel()).append(separator);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
return StringUtils.removeEnd(labelBuilder.toString(), separator);
|
||||||
{
|
|
||||||
for (SysDictData dict : datas)
|
|
||||||
{
|
|
||||||
if (dictValue.equals(dict.getDictValue()))
|
|
||||||
{
|
|
||||||
return dict.getDictLabel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -132,37 +122,25 @@ public class DictUtils
|
|||||||
*/
|
*/
|
||||||
public static String getDictValue(String dictType, String dictLabel, String separator)
|
public static String getDictValue(String dictType, String dictLabel, String separator)
|
||||||
{
|
{
|
||||||
StringBuilder propertyString = new StringBuilder();
|
|
||||||
List<SysDictData> datas = getDictCache(dictType);
|
List<SysDictData> datas = getDictCache(dictType);
|
||||||
if (StringUtils.isNull(datas))
|
if (StringUtils.isNull(datas) || StringUtils.isEmpty(dictLabel))
|
||||||
{
|
{
|
||||||
return StringUtils.EMPTY;
|
return StringUtils.EMPTY;
|
||||||
}
|
}
|
||||||
if (StringUtils.containsAny(separator, dictLabel))
|
Map<String, String> dictMap = datas.stream().collect(HashMap::new, (map, dict) -> map.put(dict.getDictLabel(), dict.getDictValue()), Map::putAll);
|
||||||
|
if (!StringUtils.contains(dictLabel, separator))
|
||||||
{
|
{
|
||||||
for (SysDictData dict : datas)
|
return dictMap.getOrDefault(dictLabel, StringUtils.EMPTY);
|
||||||
|
}
|
||||||
|
StringBuilder valueBuilder = new StringBuilder();
|
||||||
|
for (String seperatedValue : dictLabel.split(separator))
|
||||||
|
{
|
||||||
|
if (dictMap.containsKey(seperatedValue))
|
||||||
{
|
{
|
||||||
for (String label : dictLabel.split(separator))
|
valueBuilder.append(dictMap.get(seperatedValue)).append(separator);
|
||||||
{
|
|
||||||
if (label.equals(dict.getDictLabel()))
|
|
||||||
{
|
|
||||||
propertyString.append(dict.getDictValue()).append(separator);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
return StringUtils.removeEnd(valueBuilder.toString(), separator);
|
||||||
{
|
|
||||||
for (SysDictData dict : datas)
|
|
||||||
{
|
|
||||||
if (dictLabel.equals(dict.getDictLabel()))
|
|
||||||
{
|
|
||||||
return dict.getDictValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -286,6 +286,32 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
|||||||
return str.substring(start, end);
|
return str.substring(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在字符串中查找第一个出现的 `open` 和最后一个出现的 `close` 之间的子字符串
|
||||||
|
*
|
||||||
|
* @param str 要截取的字符串
|
||||||
|
* @param open 起始字符串
|
||||||
|
* @param close 结束字符串
|
||||||
|
* @return 截取结果
|
||||||
|
*/
|
||||||
|
public static String substringBetweenLast(final String str, final String open, final String close)
|
||||||
|
{
|
||||||
|
if (isEmpty(str) || isEmpty(open) || isEmpty(close))
|
||||||
|
{
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
final int start = str.indexOf(open);
|
||||||
|
if (start != INDEX_NOT_FOUND)
|
||||||
|
{
|
||||||
|
final int end = str.lastIndexOf(close);
|
||||||
|
if (end != INDEX_NOT_FOUND)
|
||||||
|
{
|
||||||
|
return str.substring(start + open.length(), end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否为空,并且不是空白字符
|
* 判断是否为空,并且不是空白字符
|
||||||
*
|
*
|
||||||
@ -355,6 +381,18 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
|||||||
return new HashSet<String>(str2List(str, sep, true, false));
|
return new HashSet<String>(str2List(str, sep, true, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符串转list
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
* @param sep 分隔符
|
||||||
|
* @return list集合
|
||||||
|
*/
|
||||||
|
public static final List<String> str2List(String str, String sep)
|
||||||
|
{
|
||||||
|
return str2List(str, sep, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字符串转list
|
* 字符串转list
|
||||||
*
|
*
|
||||||
|
|||||||
@ -13,11 +13,12 @@ import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
|
|||||||
import com.ruoyi.common.exception.file.InvalidExtensionException;
|
import com.ruoyi.common.exception.file.InvalidExtensionException;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.common.utils.uuid.IdUtils;
|
||||||
import com.ruoyi.common.utils.uuid.Seq;
|
import com.ruoyi.common.utils.uuid.Seq;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传工具类
|
* 文件上传工具类
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
public class FileUploadUtils
|
public class FileUploadUtils
|
||||||
@ -102,15 +103,35 @@ public class FileUploadUtils
|
|||||||
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
|
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
|
||||||
InvalidExtensionException
|
InvalidExtensionException
|
||||||
{
|
{
|
||||||
int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
|
return upload(baseDir, file, allowedExtension, false);
|
||||||
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
*
|
||||||
|
* @param baseDir 相对应用的基目录
|
||||||
|
* @param file 上传的文件
|
||||||
|
* @param useCustomNaming 系统自定义文件名
|
||||||
|
* @param allowedExtension 上传文件类型
|
||||||
|
* @return 返回上传成功的文件名
|
||||||
|
* @throws FileSizeLimitExceededException 如果超出最大大小
|
||||||
|
* @throws FileNameLengthLimitExceededException 文件名太长
|
||||||
|
* @throws IOException 比如读写文件出错时
|
||||||
|
* @throws InvalidExtensionException 文件校验异常
|
||||||
|
*/
|
||||||
|
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension, boolean useCustomNaming)
|
||||||
|
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
|
||||||
|
InvalidExtensionException
|
||||||
|
{
|
||||||
|
int fileNameLength = Objects.requireNonNull(file.getOriginalFilename()).length();
|
||||||
|
if (fileNameLength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
|
||||||
{
|
{
|
||||||
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
|
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertAllowed(file, allowedExtension);
|
assertAllowed(file, allowedExtension);
|
||||||
|
|
||||||
String fileName = extractFilename(file);
|
String fileName = useCustomNaming ? uuidFilename(file) : extractFilename(file);
|
||||||
|
|
||||||
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
|
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
|
||||||
file.transferTo(Paths.get(absPath));
|
file.transferTo(Paths.get(absPath));
|
||||||
@ -118,12 +139,19 @@ public class FileUploadUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编码文件名
|
* 编码文件名(日期格式目录 + 原文件名 + 序列值 + 后缀)
|
||||||
*/
|
*/
|
||||||
public static final String extractFilename(MultipartFile file)
|
public static final String extractFilename(MultipartFile file)
|
||||||
{
|
{
|
||||||
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
|
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
|
||||||
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编编码文件名(日期格式目录 + UUID + 后缀)
|
||||||
|
*/
|
||||||
|
public static final String uuidFilename(MultipartFile file)
|
||||||
|
{
|
||||||
|
return StringUtils.format("{}/{}.{}", DateUtils.datePath(), IdUtils.fastSimpleUUID(), getExtension(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
|
public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
|
||||||
@ -216,7 +244,7 @@ public class FileUploadUtils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件名的后缀
|
* 获取文件名的后缀
|
||||||
*
|
*
|
||||||
* @param file 表单文件
|
* @param file 表单文件
|
||||||
* @return 后缀名
|
* @return 后缀名
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -11,13 +11,14 @@ import java.net.URLEncoder;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import com.ruoyi.common.config.RuoYiConfig;
|
import com.ruoyi.common.config.RuoYiConfig;
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.uuid.IdUtils;
|
import com.ruoyi.common.utils.uuid.IdUtils;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件处理工具类
|
* 文件处理工具类
|
||||||
@ -103,6 +104,17 @@ public class FileUtils
|
|||||||
return FileUploadUtils.getPathFileName(uploadDir, pathName);
|
return FileUploadUtils.getPathFileName(uploadDir, pathName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除路径中的请求前缀片段
|
||||||
|
*
|
||||||
|
* @param filePath 文件路径
|
||||||
|
* @return 移除后的文件路径
|
||||||
|
*/
|
||||||
|
public static String stripPrefix(String filePath)
|
||||||
|
{
|
||||||
|
return StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除文件
|
* 删除文件
|
||||||
*
|
*
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import com.ruoyi.common.constant.Constants;
|
import com.ruoyi.common.constant.Constants;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用http发送方法
|
* 通用http发送方法
|
||||||
@ -125,6 +126,19 @@ public class HttpUtils
|
|||||||
* @return 所代表远程资源的响应结果
|
* @return 所代表远程资源的响应结果
|
||||||
*/
|
*/
|
||||||
public static String sendPost(String url, String param)
|
public static String sendPost(String url, String param)
|
||||||
|
{
|
||||||
|
return sendPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向指定 URL 发送POST方法的请求
|
||||||
|
*
|
||||||
|
* @param url 发送请求的 URL
|
||||||
|
* @param param 请求参数
|
||||||
|
* @param contentType 内容类型
|
||||||
|
* @return 所代表远程资源的响应结果
|
||||||
|
*/
|
||||||
|
public static String sendPost(String url, String param, String contentType)
|
||||||
{
|
{
|
||||||
PrintWriter out = null;
|
PrintWriter out = null;
|
||||||
BufferedReader in = null;
|
BufferedReader in = null;
|
||||||
@ -138,7 +152,7 @@ public class HttpUtils
|
|||||||
conn.setRequestProperty("connection", "Keep-Alive");
|
conn.setRequestProperty("connection", "Keep-Alive");
|
||||||
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||||
conn.setRequestProperty("Accept-Charset", "utf-8");
|
conn.setRequestProperty("Accept-Charset", "utf-8");
|
||||||
conn.setRequestProperty("contentType", "utf-8");
|
conn.setRequestProperty("Content-Type", contentType);
|
||||||
conn.setDoOutput(true);
|
conn.setDoOutput(true);
|
||||||
conn.setDoInput(true);
|
conn.setDoInput(true);
|
||||||
out = new PrintWriter(conn.getOutputStream());
|
out = new PrintWriter(conn.getOutputStream());
|
||||||
@ -190,6 +204,11 @@ public class HttpUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String sendSSLPost(String url, String param)
|
public static String sendSSLPost(String url, String param)
|
||||||
|
{
|
||||||
|
return sendSSLPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String sendSSLPost(String url, String param, String contentType)
|
||||||
{
|
{
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
String urlNameString = url + "?" + param;
|
String urlNameString = url + "?" + param;
|
||||||
@ -204,7 +223,7 @@ public class HttpUtils
|
|||||||
conn.setRequestProperty("connection", "Keep-Alive");
|
conn.setRequestProperty("connection", "Keep-Alive");
|
||||||
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||||
conn.setRequestProperty("Accept-Charset", "utf-8");
|
conn.setRequestProperty("Accept-Charset", "utf-8");
|
||||||
conn.setRequestProperty("contentType", "utf-8");
|
conn.setRequestProperty("Content-Type", contentType);
|
||||||
conn.setDoOutput(true);
|
conn.setDoOutput(true);
|
||||||
conn.setDoInput(true);
|
conn.setDoInput(true);
|
||||||
|
|
||||||
|
|||||||
@ -95,6 +95,8 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
|
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
|
||||||
|
|
||||||
|
public static final String SEPARATOR = ",";
|
||||||
|
|
||||||
public static final String FORMULA_REGEX_STR = "=|-|\\+|@";
|
public static final String FORMULA_REGEX_STR = "=|-|\\+|@";
|
||||||
|
|
||||||
public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
|
public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
|
||||||
@ -172,23 +174,18 @@ public class ExcelUtil<T>
|
|||||||
/**
|
/**
|
||||||
* 对象的子列表方法
|
* 对象的子列表方法
|
||||||
*/
|
*/
|
||||||
private Method subMethod;
|
private Map<String, Method> subMethods;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对象的子列表属性
|
* 对象的子列表属性
|
||||||
*/
|
*/
|
||||||
private List<Field> subFields;
|
private Map<String, List<Field>> subFieldsMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统计列表
|
* 统计列表
|
||||||
*/
|
*/
|
||||||
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");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实体对象
|
* 实体对象
|
||||||
*/
|
*/
|
||||||
@ -255,7 +252,10 @@ public class ExcelUtil<T>
|
|||||||
int titleLastCol = this.fields.size() - 1;
|
int titleLastCol = this.fields.size() - 1;
|
||||||
if (isSubList())
|
if (isSubList())
|
||||||
{
|
{
|
||||||
titleLastCol = titleLastCol + subFields.size() - 1;
|
for (List<Field> currentSubFields : subFieldsMap.values())
|
||||||
|
{
|
||||||
|
titleLastCol = titleLastCol + currentSubFields.size() - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0);
|
Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0);
|
||||||
titleRow.setHeightInPoints(30);
|
titleRow.setHeightInPoints(30);
|
||||||
@ -275,16 +275,17 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
Row subRow = sheet.createRow(rownum);
|
Row subRow = sheet.createRow(rownum);
|
||||||
int column = 0;
|
int column = 0;
|
||||||
int subFieldSize = subFields != null ? subFields.size() : 0;
|
|
||||||
for (Object[] objects : fields)
|
for (Object[] objects : fields)
|
||||||
{
|
{
|
||||||
Field field = (Field) objects[0];
|
Field field = (Field) objects[0];
|
||||||
Excel attr = (Excel) objects[1];
|
Excel attr = (Excel) objects[1];
|
||||||
|
CellStyle cellStyle = styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()));
|
||||||
if (Collection.class.isAssignableFrom(field.getType()))
|
if (Collection.class.isAssignableFrom(field.getType()))
|
||||||
{
|
{
|
||||||
Cell cell = subRow.createCell(column);
|
Cell cell = subRow.createCell(column);
|
||||||
cell.setCellValue(attr.name());
|
cell.setCellValue(attr.name());
|
||||||
cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
|
cell.setCellStyle(cellStyle);
|
||||||
|
int subFieldSize = subFieldsMap != null ? subFieldsMap.get(field.getName()).size() : 0;
|
||||||
if (subFieldSize > 1)
|
if (subFieldSize > 1)
|
||||||
{
|
{
|
||||||
CellRangeAddress cellAddress = new CellRangeAddress(rownum, rownum, column, column + subFieldSize - 1);
|
CellRangeAddress cellAddress = new CellRangeAddress(rownum, rownum, column, column + subFieldSize - 1);
|
||||||
@ -296,7 +297,7 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
Cell cell = subRow.createCell(column++);
|
Cell cell = subRow.createCell(column++);
|
||||||
cell.setCellValue(attr.name());
|
cell.setCellValue(attr.name());
|
||||||
cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
|
cell.setCellStyle(cellStyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rownum++;
|
rownum++;
|
||||||
@ -360,7 +361,7 @@ public class ExcelUtil<T>
|
|||||||
throw new IOException("文件sheet不存在");
|
throw new IOException("文件sheet不存在");
|
||||||
}
|
}
|
||||||
boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook);
|
boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook);
|
||||||
Map<String, PictureData> pictures;
|
Map<String, List<PictureData>> pictures = null;
|
||||||
if (isXSSFWorkbook)
|
if (isXSSFWorkbook)
|
||||||
{
|
{
|
||||||
pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb);
|
pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb);
|
||||||
@ -377,7 +378,11 @@ public class ExcelUtil<T>
|
|||||||
Map<String, Integer> cellMap = new HashMap<String, Integer>();
|
Map<String, Integer> cellMap = new HashMap<String, Integer>();
|
||||||
// 获取表头
|
// 获取表头
|
||||||
Row heard = sheet.getRow(titleNum);
|
Row heard = sheet.getRow(titleNum);
|
||||||
for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)
|
if (heard == null)
|
||||||
|
{
|
||||||
|
throw new UtilException("文件标题行为空,请检查Excel文件格式");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < heard.getLastCellNum(); i++)
|
||||||
{
|
{
|
||||||
Cell cell = heard.getCell(i);
|
Cell cell = heard.getCell(i);
|
||||||
if (StringUtils.isNotNull(cell))
|
if (StringUtils.isNotNull(cell))
|
||||||
@ -385,10 +390,6 @@ public class ExcelUtil<T>
|
|||||||
String value = this.getCellValue(heard, i).toString();
|
String value = this.getCellValue(heard, i).toString();
|
||||||
cellMap.put(value, i);
|
cellMap.put(value, i);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
cellMap.put(null, i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 有数据时才处理 得到类的所有field.
|
// 有数据时才处理 得到类的所有field.
|
||||||
List<Object[]> fields = this.getFields();
|
List<Object[]> fields = this.getFields();
|
||||||
@ -426,7 +427,7 @@ public class ExcelUtil<T>
|
|||||||
if (String.class == fieldType)
|
if (String.class == fieldType)
|
||||||
{
|
{
|
||||||
String s = Convert.toStr(val);
|
String s = Convert.toStr(val);
|
||||||
if (StringUtils.endsWith(s, ".0"))
|
if (s.matches("^\\d+\\.0$"))
|
||||||
{
|
{
|
||||||
val = StringUtils.substringBefore(s, ".0");
|
val = StringUtils.substringBefore(s, ".0");
|
||||||
}
|
}
|
||||||
@ -504,16 +505,15 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures))
|
else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures))
|
||||||
{
|
{
|
||||||
PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey());
|
StringBuilder propertyString = new StringBuilder();
|
||||||
if (image == null)
|
List<PictureData> images = pictures.get(row.getRowNum() + "_" + entry.getKey());
|
||||||
|
for (PictureData picture : images)
|
||||||
{
|
{
|
||||||
val = "";
|
byte[] data = picture.getData();
|
||||||
}
|
String fileName = FileUtils.writeImportBytes(data);
|
||||||
else
|
propertyString.append(fileName).append(SEPARATOR);
|
||||||
{
|
|
||||||
byte[] data = image.getData();
|
|
||||||
val = FileUtils.writeImportBytes(data);
|
|
||||||
}
|
}
|
||||||
|
val = StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
|
||||||
}
|
}
|
||||||
ReflectUtils.invokeSetter(entity, propertyName, val);
|
ReflectUtils.invokeSetter(entity, propertyName, val);
|
||||||
}
|
}
|
||||||
@ -701,7 +701,8 @@ public class ExcelUtil<T>
|
|||||||
Excel excel = (Excel) os[1];
|
Excel excel = (Excel) os[1];
|
||||||
if (Collection.class.isAssignableFrom(field.getType()))
|
if (Collection.class.isAssignableFrom(field.getType()))
|
||||||
{
|
{
|
||||||
for (Field subField : subFields)
|
List<Field> currentSubFields = subFieldsMap.get(field.getName());
|
||||||
|
for (Field subField : currentSubFields)
|
||||||
{
|
{
|
||||||
Excel subExcel = subField.getAnnotation(Excel.class);
|
Excel subExcel = subField.getAnnotation(Excel.class);
|
||||||
this.createHeadCell(subExcel, row, column++);
|
this.createHeadCell(subExcel, row, column++);
|
||||||
@ -714,7 +715,7 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
if (Type.EXPORT.equals(type))
|
if (Type.EXPORT.equals(type))
|
||||||
{
|
{
|
||||||
fillExcelData(index, row);
|
fillExcelData(index);
|
||||||
addStatisticsRow();
|
addStatisticsRow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -724,10 +725,9 @@ public class ExcelUtil<T>
|
|||||||
* 填充excel数据
|
* 填充excel数据
|
||||||
*
|
*
|
||||||
* @param index 序号
|
* @param index 序号
|
||||||
* @param row 单元格行
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void fillExcelData(int index, Row row)
|
public void fillExcelData(int index)
|
||||||
{
|
{
|
||||||
int startNo = index * sheetSize;
|
int startNo = index * sheetSize;
|
||||||
int endNo = Math.min(startNo + sheetSize, list.size());
|
int endNo = Math.min(startNo + sheetSize, list.size());
|
||||||
@ -735,7 +735,7 @@ public class ExcelUtil<T>
|
|||||||
|
|
||||||
for (int i = startNo; i < endNo; i++)
|
for (int i = startNo; i < endNo; i++)
|
||||||
{
|
{
|
||||||
row = sheet.createRow(currentRowNum);
|
Row row = sheet.createRow(currentRowNum);
|
||||||
T vo = (T) list.get(i);
|
T vo = (T) list.get(i);
|
||||||
int column = 0;
|
int column = 0;
|
||||||
int maxSubListSize = getCurrentMaxSubListSize(vo);
|
int maxSubListSize = getCurrentMaxSubListSize(vo);
|
||||||
@ -748,6 +748,7 @@ public class ExcelUtil<T>
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Collection<?> subList = (Collection<?>) getTargetValue(vo, field, excel);
|
Collection<?> subList = (Collection<?>) getTargetValue(vo, field, excel);
|
||||||
|
List<Field> currentSubFields = subFieldsMap.get(field.getName());
|
||||||
if (subList != null && !subList.isEmpty())
|
if (subList != null && !subList.isEmpty())
|
||||||
{
|
{
|
||||||
int subIndex = 0;
|
int subIndex = 0;
|
||||||
@ -760,15 +761,15 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
int subColumn = column;
|
int subColumn = column;
|
||||||
for (Field subField : subFields)
|
for (Field subField : currentSubFields)
|
||||||
{
|
{
|
||||||
Excel subExcel = subField.getAnnotation(Excel.class);
|
Excel subExcel = subField.getAnnotation(Excel.class);
|
||||||
addCell(subExcel, subRow, (T) subVo, subField, subColumn++);
|
addCell(subExcel, subRow, (T) subVo, subField, subColumn++);
|
||||||
}
|
}
|
||||||
subIndex++;
|
subIndex++;
|
||||||
}
|
}
|
||||||
column += subFields.size();
|
|
||||||
}
|
}
|
||||||
|
column += currentSubFields.size();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -860,6 +861,7 @@ public class ExcelUtil<T>
|
|||||||
style = wb.createCellStyle();
|
style = wb.createCellStyle();
|
||||||
style.setAlignment(HorizontalAlignment.CENTER);
|
style.setAlignment(HorizontalAlignment.CENTER);
|
||||||
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
style.setDataFormat(dataFormat.getFormat("######0.00"));
|
||||||
Font totalFont = wb.createFont();
|
Font totalFont = wb.createFont();
|
||||||
totalFont.setFontName("Arial");
|
totalFont.setFontName("Arial");
|
||||||
totalFont.setFontHeightInPoints((short) 10);
|
totalFont.setFontHeightInPoints((short) 10);
|
||||||
@ -1037,12 +1039,15 @@ public class ExcelUtil<T>
|
|||||||
else if (ColumnType.IMAGE == attr.cellType())
|
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);
|
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);
|
String propertyValue = Convert.toStr(value);
|
||||||
if (StringUtils.isNotEmpty(imagePath))
|
if (StringUtils.isNotEmpty(propertyValue))
|
||||||
{
|
{
|
||||||
byte[] data = ImageUtils.getImage(imagePath);
|
List<String> imagePaths = StringUtils.str2List(propertyValue, SEPARATOR);
|
||||||
getDrawingPatriarch(cell.getSheet()).createPicture(anchor,
|
for (String imagePath : imagePaths)
|
||||||
cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));
|
{
|
||||||
|
byte[] data = ImageUtils.getImage(imagePath);
|
||||||
|
getDrawingPatriarch(cell.getSheet()).createPicture(anchor, cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1131,7 +1136,7 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
// 创建cell
|
// 创建cell
|
||||||
cell = row.createCell(column);
|
cell = row.createCell(column);
|
||||||
if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge())
|
if (isSubListValue(vo) && getListCellValue(vo) > 1 && attr.needMerge())
|
||||||
{
|
{
|
||||||
if (subMergedLastRowNum >= subMergedFirstRowNum)
|
if (subMergedLastRowNum >= subMergedFirstRowNum)
|
||||||
{
|
{
|
||||||
@ -1148,6 +1153,7 @@ public class ExcelUtil<T>
|
|||||||
String dictType = attr.dictType();
|
String dictType = attr.dictType();
|
||||||
if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
|
if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
|
||||||
{
|
{
|
||||||
|
cell.getCellStyle().setDataFormat(this.wb.getCreationHelper().createDataFormat().getFormat(dateFormat));
|
||||||
cell.setCellValue(parseDateToStr(dateFormat, value));
|
cell.setCellValue(parseDateToStr(dateFormat, value));
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
|
else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
|
||||||
@ -1237,18 +1243,36 @@ public class ExcelUtil<T>
|
|||||||
public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol)
|
public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol)
|
||||||
{
|
{
|
||||||
String hideSheetName = "combo_" + firstCol + "_" + endCol;
|
String hideSheetName = "combo_" + firstCol + "_" + endCol;
|
||||||
Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据
|
Sheet hideSheet = null;
|
||||||
for (int i = 0; i < textlist.length; i++)
|
String hideSheetDataName = hideSheetName + "_data";
|
||||||
|
Name name = wb.getName(hideSheetDataName);
|
||||||
|
if (name != null)
|
||||||
{
|
{
|
||||||
hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);
|
// 名称已存在,尝试从名称的引用中找到sheet名称
|
||||||
|
String refersToFormula = name.getRefersToFormula();
|
||||||
|
if (StringUtils.isNotEmpty(refersToFormula) && refersToFormula.contains("!"))
|
||||||
|
{
|
||||||
|
String sheetNameFromFormula = refersToFormula.substring(0, refersToFormula.indexOf("!"));
|
||||||
|
hideSheet = wb.getSheet(sheetNameFromFormula);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 创建名称,可被其他单元格引用
|
|
||||||
Name name = wb.createName();
|
if (hideSheet == null)
|
||||||
name.setNameName(hideSheetName + "_data");
|
{
|
||||||
name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);
|
hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据
|
||||||
|
for (int i = 0; i < textlist.length; i++)
|
||||||
|
{
|
||||||
|
hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);
|
||||||
|
}
|
||||||
|
// 创建名称,可被其他单元格引用
|
||||||
|
name = wb.createName();
|
||||||
|
name.setNameName(hideSheetDataName);
|
||||||
|
name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);
|
||||||
|
}
|
||||||
|
|
||||||
DataValidationHelper helper = sheet.getDataValidationHelper();
|
DataValidationHelper helper = sheet.getDataValidationHelper();
|
||||||
// 加载下拉列表内容
|
// 加载下拉列表内容
|
||||||
DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data");
|
DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetDataName);
|
||||||
// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
|
// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
|
||||||
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
|
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
|
||||||
// 数据有效性对象
|
// 数据有效性对象
|
||||||
@ -1286,7 +1310,7 @@ public class ExcelUtil<T>
|
|||||||
public static String convertByExp(String propertyValue, String converterExp, String separator)
|
public static String convertByExp(String propertyValue, String converterExp, String separator)
|
||||||
{
|
{
|
||||||
StringBuilder propertyString = new StringBuilder();
|
StringBuilder propertyString = new StringBuilder();
|
||||||
String[] convertSource = converterExp.split(",");
|
String[] convertSource = converterExp.split(SEPARATOR);
|
||||||
for (String item : convertSource)
|
for (String item : convertSource)
|
||||||
{
|
{
|
||||||
String[] itemArray = item.split("=");
|
String[] itemArray = item.split("=");
|
||||||
@ -1323,7 +1347,7 @@ public class ExcelUtil<T>
|
|||||||
public static String reverseByExp(String propertyValue, String converterExp, String separator)
|
public static String reverseByExp(String propertyValue, String converterExp, String separator)
|
||||||
{
|
{
|
||||||
StringBuilder propertyString = new StringBuilder();
|
StringBuilder propertyString = new StringBuilder();
|
||||||
String[] convertSource = converterExp.split(",");
|
String[] convertSource = converterExp.split(SEPARATOR);
|
||||||
for (String item : convertSource)
|
for (String item : convertSource)
|
||||||
{
|
{
|
||||||
String[] itemArray = item.split("=");
|
String[] itemArray = item.split("=");
|
||||||
@ -1437,7 +1461,7 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
cell = row.createCell(key);
|
cell = row.createCell(key);
|
||||||
cell.setCellStyle(styles.get("total"));
|
cell.setCellStyle(styles.get("total"));
|
||||||
cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key)));
|
cell.setCellValue(statistics.get(key));
|
||||||
}
|
}
|
||||||
statistics.clear();
|
statistics.clear();
|
||||||
}
|
}
|
||||||
@ -1448,8 +1472,7 @@ public class ExcelUtil<T>
|
|||||||
*/
|
*/
|
||||||
public String encodingFilename(String filename)
|
public String encodingFilename(String filename)
|
||||||
{
|
{
|
||||||
filename = UUID.randomUUID() + "_" + filename + ".xlsx";
|
return UUID.randomUUID() + "_" + filename + ".xlsx";
|
||||||
return filename;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1537,6 +1560,8 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
List<Object[]> fields = new ArrayList<Object[]>();
|
List<Object[]> fields = new ArrayList<Object[]>();
|
||||||
List<Field> tempFields = new ArrayList<>();
|
List<Field> tempFields = new ArrayList<>();
|
||||||
|
subFieldsMap = new HashMap<>();
|
||||||
|
subMethods = new HashMap<>();
|
||||||
tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
|
tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
|
||||||
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
|
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
|
||||||
if (StringUtils.isNotEmpty(includeFields))
|
if (StringUtils.isNotEmpty(includeFields))
|
||||||
@ -1584,10 +1609,11 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
if (Collection.class.isAssignableFrom(field.getType()))
|
if (Collection.class.isAssignableFrom(field.getType()))
|
||||||
{
|
{
|
||||||
subMethod = getSubMethod(field.getName(), clazz);
|
String fieldName = field.getName();
|
||||||
|
subMethods.put(fieldName, getSubMethod(fieldName, clazz));
|
||||||
ParameterizedType pt = (ParameterizedType) field.getGenericType();
|
ParameterizedType pt = (ParameterizedType) field.getGenericType();
|
||||||
Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
|
Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
|
||||||
this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);
|
subFieldsMap.put(fieldName, FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1656,7 +1682,8 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
this.sheet = wb.createSheet();
|
this.sheet = wb.createSheet();
|
||||||
this.createTitle();
|
this.createTitle();
|
||||||
wb.setSheetName(index, sheetName + index);
|
int actualIndex = wb.getSheetIndex(this.sheet);
|
||||||
|
wb.setSheetName(actualIndex, sheetName + index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1750,30 +1777,24 @@ public class ExcelUtil<T>
|
|||||||
* @param workbook 工作簿对象
|
* @param workbook 工作簿对象
|
||||||
* @return Map key:图片单元格索引(1_1)String,value:图片流PictureData
|
* @return Map key:图片单元格索引(1_1)String,value:图片流PictureData
|
||||||
*/
|
*/
|
||||||
public static Map<String, PictureData> getSheetPictures03(HSSFSheet sheet, HSSFWorkbook workbook)
|
public static Map<String, List<PictureData>> getSheetPictures03(HSSFSheet sheet, HSSFWorkbook workbook)
|
||||||
{
|
{
|
||||||
Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>();
|
Map<String, List<PictureData>> sheetIndexPicMap = new HashMap<>();
|
||||||
List<HSSFPictureData> pictures = workbook.getAllPictures();
|
List<HSSFPictureData> pictures = workbook.getAllPictures();
|
||||||
if (!pictures.isEmpty())
|
if (!pictures.isEmpty() && sheet.getDrawingPatriarch() != null)
|
||||||
{
|
{
|
||||||
for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren())
|
for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren())
|
||||||
{
|
{
|
||||||
HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();
|
|
||||||
if (shape instanceof HSSFPicture)
|
if (shape instanceof HSSFPicture)
|
||||||
{
|
{
|
||||||
HSSFPicture pic = (HSSFPicture) shape;
|
HSSFPicture pic = (HSSFPicture) shape;
|
||||||
int pictureIndex = pic.getPictureIndex() - 1;
|
HSSFClientAnchor anchor = (HSSFClientAnchor) pic.getAnchor();
|
||||||
HSSFPictureData picData = pictures.get(pictureIndex);
|
|
||||||
String picIndex = anchor.getRow1() + "_" + anchor.getCol1();
|
String picIndex = anchor.getRow1() + "_" + anchor.getCol1();
|
||||||
sheetIndexPicMap.put(picIndex, picData);
|
sheetIndexPicMap.computeIfAbsent(picIndex, k -> new ArrayList<>()).add(pic.getPictureData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sheetIndexPicMap;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return sheetIndexPicMap;
|
|
||||||
}
|
}
|
||||||
|
return sheetIndexPicMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1783,16 +1804,15 @@ public class ExcelUtil<T>
|
|||||||
* @param workbook 工作簿对象
|
* @param workbook 工作簿对象
|
||||||
* @return Map key:图片单元格索引(1_1)String,value:图片流PictureData
|
* @return Map key:图片单元格索引(1_1)String,value:图片流PictureData
|
||||||
*/
|
*/
|
||||||
public static Map<String, PictureData> getSheetPictures07(XSSFSheet sheet, XSSFWorkbook workbook)
|
public static Map<String, List<PictureData>> getSheetPictures07(XSSFSheet sheet, XSSFWorkbook workbook)
|
||||||
{
|
{
|
||||||
Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>();
|
Map<String, List<PictureData>> sheetIndexPicMap = new HashMap<>();
|
||||||
for (POIXMLDocumentPart dr : sheet.getRelations())
|
for (POIXMLDocumentPart dr : sheet.getRelations())
|
||||||
{
|
{
|
||||||
if (dr instanceof XSSFDrawing)
|
if (dr instanceof XSSFDrawing)
|
||||||
{
|
{
|
||||||
XSSFDrawing drawing = (XSSFDrawing) dr;
|
XSSFDrawing drawing = (XSSFDrawing) dr;
|
||||||
List<XSSFShape> shapes = drawing.getShapes();
|
for (XSSFShape shape : drawing.getShapes())
|
||||||
for (XSSFShape shape : shapes)
|
|
||||||
{
|
{
|
||||||
if (shape instanceof XSSFPicture)
|
if (shape instanceof XSSFPicture)
|
||||||
{
|
{
|
||||||
@ -1800,7 +1820,7 @@ public class ExcelUtil<T>
|
|||||||
XSSFClientAnchor anchor = pic.getPreferredSize();
|
XSSFClientAnchor anchor = pic.getPreferredSize();
|
||||||
CTMarker ctMarker = anchor.getFrom();
|
CTMarker ctMarker = anchor.getFrom();
|
||||||
String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol();
|
String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol();
|
||||||
sheetIndexPicMap.put(picIndex, pic.getPictureData());
|
sheetIndexPicMap.computeIfAbsent(picIndex, k -> new ArrayList<>()).add(pic.getPictureData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1846,7 +1866,7 @@ public class ExcelUtil<T>
|
|||||||
*/
|
*/
|
||||||
public boolean isSubList()
|
public boolean isSubList()
|
||||||
{
|
{
|
||||||
return StringUtils.isNotNull(subFields) && subFields.size() > 0;
|
return !StringUtils.isEmpty(subFieldsMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1854,24 +1874,32 @@ public class ExcelUtil<T>
|
|||||||
*/
|
*/
|
||||||
public boolean isSubListValue(T vo)
|
public boolean isSubListValue(T vo)
|
||||||
{
|
{
|
||||||
return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0;
|
return !StringUtils.isEmpty(subFieldsMap) && getListCellValue(vo) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取集合的值
|
* 获取集合的值
|
||||||
*/
|
*/
|
||||||
public Collection<?> getListCellValue(Object obj)
|
public int getListCellValue(Object obj)
|
||||||
{
|
{
|
||||||
Object value;
|
Collection<?> value;
|
||||||
|
int max = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
value = subMethod.invoke(obj, new Object[] {});
|
for (String s : subMethods.keySet())
|
||||||
|
{
|
||||||
|
value = (Collection<?>) subMethods.get(s).invoke(obj);
|
||||||
|
if (value.size() > max)
|
||||||
|
{
|
||||||
|
max = value.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
return new ArrayList<Object>();
|
return 0;
|
||||||
}
|
}
|
||||||
return (Collection<?>) value;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.common.utils.spring;
|
package com.ruoyi.common.utils.spring;
|
||||||
|
|
||||||
|
import org.springframework.aop.framework.Advised;
|
||||||
import org.springframework.aop.framework.AopContext;
|
import org.springframework.aop.framework.AopContext;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
@ -120,7 +121,12 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T getAopProxy(T invoker)
|
public static <T> T getAopProxy(T invoker)
|
||||||
{
|
{
|
||||||
return (T) AopContext.currentProxy();
|
Object proxy = AopContext.currentProxy();
|
||||||
|
if (((Advised) proxy).getTargetSource().getTargetClass() == invoker.getClass())
|
||||||
|
{
|
||||||
|
return (T) proxy;
|
||||||
|
}
|
||||||
|
return invoker;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.8.9</version>
|
<version>3.9.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@ -94,7 +94,7 @@ public class DataScopeAspect
|
|||||||
List<String> conditions = new ArrayList<String>();
|
List<String> conditions = new ArrayList<String>();
|
||||||
List<String> scopeCustomIds = new ArrayList<String>();
|
List<String> scopeCustomIds = new ArrayList<String>();
|
||||||
user.getRoles().forEach(role -> {
|
user.getRoles().forEach(role -> {
|
||||||
if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
|
if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && (StringUtils.isEmpty(permission) || StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))))
|
||||||
{
|
{
|
||||||
scopeCustomIds.add(Convert.toStr(role.getRoleId()));
|
scopeCustomIds.add(Convert.toStr(role.getRoleId()));
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ public class DataScopeAspect
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
|
if (StringUtils.isNotEmpty(permission) && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,9 +20,11 @@ import com.alibaba.fastjson2.JSON;
|
|||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
|
import com.ruoyi.common.core.text.Convert;
|
||||||
import com.ruoyi.common.enums.BusinessStatus;
|
import com.ruoyi.common.enums.BusinessStatus;
|
||||||
import com.ruoyi.common.enums.HttpMethod;
|
import com.ruoyi.common.enums.HttpMethod;
|
||||||
import com.ruoyi.common.filter.PropertyPreExcludeFilter;
|
import com.ruoyi.common.filter.PropertyPreExcludeFilter;
|
||||||
|
import com.ruoyi.common.utils.ExceptionUtil;
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
import com.ruoyi.common.utils.ServletUtils;
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
@ -48,11 +50,14 @@ public class LogAspect
|
|||||||
/** 计算操作消耗时间 */
|
/** 计算操作消耗时间 */
|
||||||
private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
|
private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
|
||||||
|
|
||||||
|
/** 参数最大长度限制 */
|
||||||
|
private static final int PARAM_MAX_LENGTH = 2000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理请求前执行
|
* 处理请求前执行
|
||||||
*/
|
*/
|
||||||
@Before(value = "@annotation(controllerLog)")
|
@Before(value = "@annotation(controllerLog)")
|
||||||
public void boBefore(JoinPoint joinPoint, Log controllerLog)
|
public void doBefore(JoinPoint joinPoint, Log controllerLog)
|
||||||
{
|
{
|
||||||
TIME_THREADLOCAL.set(System.currentTimeMillis());
|
TIME_THREADLOCAL.set(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
@ -107,7 +112,7 @@ public class LogAspect
|
|||||||
if (e != null)
|
if (e != null)
|
||||||
{
|
{
|
||||||
operLog.setStatus(BusinessStatus.FAIL.ordinal());
|
operLog.setStatus(BusinessStatus.FAIL.ordinal());
|
||||||
operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
|
operLog.setErrorMsg(StringUtils.substring(Convert.toStr(e.getMessage(), ExceptionUtil.getExceptionMessage(e)), 0, 2000));
|
||||||
}
|
}
|
||||||
// 设置方法名称
|
// 设置方法名称
|
||||||
String className = joinPoint.getTarget().getClass().getName();
|
String className = joinPoint.getTarget().getClass().getName();
|
||||||
@ -170,16 +175,16 @@ public class LogAspect
|
|||||||
*/
|
*/
|
||||||
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception
|
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception
|
||||||
{
|
{
|
||||||
Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
|
|
||||||
String requestMethod = operLog.getRequestMethod();
|
String requestMethod = operLog.getRequestMethod();
|
||||||
|
Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
|
||||||
if (StringUtils.isEmpty(paramsMap) && StringUtils.equalsAny(requestMethod, HttpMethod.PUT.name(), HttpMethod.POST.name(), HttpMethod.DELETE.name()))
|
if (StringUtils.isEmpty(paramsMap) && StringUtils.equalsAny(requestMethod, HttpMethod.PUT.name(), HttpMethod.POST.name(), HttpMethod.DELETE.name()))
|
||||||
{
|
{
|
||||||
String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
|
String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
|
||||||
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
|
operLog.setOperParam(params);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000));
|
operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, PARAM_MAX_LENGTH));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +193,7 @@ public class LogAspect
|
|||||||
*/
|
*/
|
||||||
private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames)
|
private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames)
|
||||||
{
|
{
|
||||||
String params = "";
|
StringBuilder params = new StringBuilder();
|
||||||
if (paramsArray != null && paramsArray.length > 0)
|
if (paramsArray != null && paramsArray.length > 0)
|
||||||
{
|
{
|
||||||
for (Object o : paramsArray)
|
for (Object o : paramsArray)
|
||||||
@ -198,15 +203,20 @@ public class LogAspect
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));
|
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));
|
||||||
params += jsonObj.toString() + " ";
|
params.append(jsonObj).append(" ");
|
||||||
|
if (params.length() >= PARAM_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
return StringUtils.substring(params.toString(), 0, PARAM_MAX_LENGTH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
log.error("请求参数拼装异常 msg:{}, 参数:{}", e.getMessage(), paramsArray, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return params.trim();
|
return params.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -8,6 +8,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
|
import com.ruoyi.common.filter.RefererFilter;
|
||||||
import com.ruoyi.common.filter.RepeatableFilter;
|
import com.ruoyi.common.filter.RepeatableFilter;
|
||||||
import com.ruoyi.common.filter.XssFilter;
|
import com.ruoyi.common.filter.XssFilter;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
@ -26,6 +28,9 @@ public class FilterConfig
|
|||||||
@Value("${xss.urlPatterns}")
|
@Value("${xss.urlPatterns}")
|
||||||
private String urlPatterns;
|
private String urlPatterns;
|
||||||
|
|
||||||
|
@Value("${referer.allowed-domains}")
|
||||||
|
private String allowedDomains;
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
|
@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
|
||||||
@ -43,6 +48,23 @@ public class FilterConfig
|
|||||||
return registration;
|
return registration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty(value = "referer.enabled", havingValue = "true")
|
||||||
|
public FilterRegistrationBean refererFilterRegistration()
|
||||||
|
{
|
||||||
|
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||||
|
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||||
|
registration.setFilter(new RefererFilter());
|
||||||
|
registration.addUrlPatterns(Constants.RESOURCE_PREFIX + "/*");
|
||||||
|
registration.setName("refererFilter");
|
||||||
|
registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
|
||||||
|
Map<String, String> initParameters = new HashMap<String, String>();
|
||||||
|
initParameters.put("allowedDomains", allowedDomains);
|
||||||
|
registration.setInitParameters(initParameters);
|
||||||
|
return registration;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
@Bean
|
@Bean
|
||||||
public FilterRegistrationBean someFilterRegistration()
|
public FilterRegistrationBean someFilterRegistration()
|
||||||
|
|||||||
@ -55,7 +55,6 @@ public class ResourcesConfig implements WebMvcConfigurer
|
|||||||
public CorsFilter corsFilter()
|
public CorsFilter corsFilter()
|
||||||
{
|
{
|
||||||
CorsConfiguration config = new CorsConfiguration();
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
config.setAllowCredentials(true);
|
|
||||||
// 设置访问源地址
|
// 设置访问源地址
|
||||||
config.addAllowedOriginPattern("*");
|
config.addAllowedOriginPattern("*");
|
||||||
// 设置访问源请求头
|
// 设置访问源请求头
|
||||||
|
|||||||
@ -53,7 +53,7 @@ public class PermissionService
|
|||||||
/**
|
/**
|
||||||
* 验证用户是否具有以下任意一个权限
|
* 验证用户是否具有以下任意一个权限
|
||||||
*
|
*
|
||||||
* @param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表
|
* @param permissions 以 PERMISSION_DELIMITER 为分隔符的权限列表
|
||||||
* @return 用户是否具有以下任意一个权限
|
* @return 用户是否具有以下任意一个权限
|
||||||
*/
|
*/
|
||||||
public boolean hasAnyPermi(String permissions)
|
public boolean hasAnyPermi(String permissions)
|
||||||
@ -69,7 +69,7 @@ public class PermissionService
|
|||||||
}
|
}
|
||||||
PermissionContextHolder.setContext(permissions);
|
PermissionContextHolder.setContext(permissions);
|
||||||
Set<String> authorities = loginUser.getPermissions();
|
Set<String> authorities = loginUser.getPermissions();
|
||||||
for (String permission : permissions.split(Constants.PERMISSION_DELIMETER))
|
for (String permission : permissions.split(Constants.PERMISSION_DELIMITER))
|
||||||
{
|
{
|
||||||
if (permission != null && hasPermissions(authorities, permission))
|
if (permission != null && hasPermissions(authorities, permission))
|
||||||
{
|
{
|
||||||
@ -121,7 +121,7 @@ public class PermissionService
|
|||||||
/**
|
/**
|
||||||
* 验证用户是否具有以下任意一个角色
|
* 验证用户是否具有以下任意一个角色
|
||||||
*
|
*
|
||||||
* @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
|
* @param roles 以 ROLE_DELIMITER 为分隔符的角色列表
|
||||||
* @return 用户是否具有以下任意一个角色
|
* @return 用户是否具有以下任意一个角色
|
||||||
*/
|
*/
|
||||||
public boolean hasAnyRoles(String roles)
|
public boolean hasAnyRoles(String roles)
|
||||||
@ -135,7 +135,7 @@ public class PermissionService
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (String role : roles.split(Constants.ROLE_DELIMETER))
|
for (String role : roles.split(Constants.ROLE_DELIMITER))
|
||||||
{
|
{
|
||||||
if (hasRole(role))
|
if (hasRole(role))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import org.springframework.stereotype.Component;
|
|||||||
import com.ruoyi.common.constant.CacheConstants;
|
import com.ruoyi.common.constant.CacheConstants;
|
||||||
import com.ruoyi.common.constant.Constants;
|
import com.ruoyi.common.constant.Constants;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.core.redis.RedisCache;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
@ -172,10 +171,6 @@ public class SysLoginService
|
|||||||
*/
|
*/
|
||||||
public void recordLoginInfo(Long userId)
|
public void recordLoginInfo(Long userId)
|
||||||
{
|
{
|
||||||
SysUser sysUser = new SysUser();
|
userService.updateLoginInfo(userId, IpUtils.getIpAddr(), DateUtils.getNowDate());
|
||||||
sysUser.setUserId(userId);
|
|
||||||
sysUser.setLoginIp(IpUtils.getIpAddr());
|
|
||||||
sysUser.setLoginDate(DateUtils.getNowDate());
|
|
||||||
userService.updateUserProfile(sysUser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import java.util.Set;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
@ -39,7 +40,7 @@ public class SysPermissionService
|
|||||||
// 管理员拥有所有权限
|
// 管理员拥有所有权限
|
||||||
if (user.isAdmin())
|
if (user.isAdmin())
|
||||||
{
|
{
|
||||||
roles.add("admin");
|
roles.add(Constants.SUPER_ADMIN);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -60,7 +61,7 @@ public class SysPermissionService
|
|||||||
// 管理员拥有所有权限
|
// 管理员拥有所有权限
|
||||||
if (user.isAdmin())
|
if (user.isAdmin())
|
||||||
{
|
{
|
||||||
perms.add("*:*:*");
|
perms.add(Constants.ALL_PERMISSION);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -70,7 +71,7 @@ public class SysPermissionService
|
|||||||
// 多角色设置permissions属性,以便数据权限匹配权限
|
// 多角色设置permissions属性,以便数据权限匹配权限
|
||||||
for (SysRole role : roles)
|
for (SysRole role : roles)
|
||||||
{
|
{
|
||||||
if (StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL))
|
if (StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && !role.isAdmin())
|
||||||
{
|
{
|
||||||
Set<String> rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId());
|
Set<String> rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId());
|
||||||
role.setPermissions(rolePerms);
|
role.setPermissions(rolePerms);
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import com.ruoyi.common.core.domain.model.RegisterBody;
|
|||||||
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.core.redis.RedisCache;
|
||||||
import com.ruoyi.common.exception.user.CaptchaException;
|
import com.ruoyi.common.exception.user.CaptchaException;
|
||||||
import com.ruoyi.common.exception.user.CaptchaExpireException;
|
import com.ruoyi.common.exception.user.CaptchaExpireException;
|
||||||
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.MessageUtils;
|
import com.ruoyi.common.utils.MessageUtils;
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
@ -76,6 +77,7 @@ public class SysRegisterService
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sysUser.setNickName(username);
|
sysUser.setNickName(username);
|
||||||
|
sysUser.setPwdUpdateDate(DateUtils.getNowDate());
|
||||||
sysUser.setPassword(SecurityUtils.encryptPassword(password));
|
sysUser.setPassword(SecurityUtils.encryptPassword(password));
|
||||||
boolean regFlag = userService.registerUser(sysUser);
|
boolean regFlag = userService.registerUser(sysUser);
|
||||||
if (!regFlag)
|
if (!regFlag)
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import io.jsonwebtoken.SignatureAlgorithm;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* token验证处理
|
* token验证处理
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@ -49,14 +49,14 @@ public class TokenService
|
|||||||
|
|
||||||
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
|
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
|
||||||
|
|
||||||
private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
|
private static final Long MILLIS_MINUTE_TWENTY = 20 * 60 * 1000L;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisCache redisCache;
|
private RedisCache redisCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户身份信息
|
* 获取用户身份信息
|
||||||
*
|
*
|
||||||
* @return 用户信息
|
* @return 用户信息
|
||||||
*/
|
*/
|
||||||
public LoginUser getLoginUser(HttpServletRequest request)
|
public LoginUser getLoginUser(HttpServletRequest request)
|
||||||
@ -107,7 +107,7 @@ public class TokenService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建令牌
|
* 创建令牌
|
||||||
*
|
*
|
||||||
* @param loginUser 用户信息
|
* @param loginUser 用户信息
|
||||||
* @return 令牌
|
* @return 令牌
|
||||||
*/
|
*/
|
||||||
@ -120,20 +120,21 @@ public class TokenService
|
|||||||
|
|
||||||
Map<String, Object> claims = new HashMap<>();
|
Map<String, Object> claims = new HashMap<>();
|
||||||
claims.put(Constants.LOGIN_USER_KEY, token);
|
claims.put(Constants.LOGIN_USER_KEY, token);
|
||||||
|
claims.put(Constants.JWT_USERNAME, loginUser.getUsername());
|
||||||
return createToken(claims);
|
return createToken(claims);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证令牌有效期,相差不足20分钟,自动刷新缓存
|
* 验证令牌有效期,相差不足20分钟,自动刷新缓存
|
||||||
*
|
*
|
||||||
* @param loginUser
|
* @param loginUser 登录信息
|
||||||
* @return 令牌
|
* @return 令牌
|
||||||
*/
|
*/
|
||||||
public void verifyToken(LoginUser loginUser)
|
public void verifyToken(LoginUser loginUser)
|
||||||
{
|
{
|
||||||
long expireTime = loginUser.getExpireTime();
|
long expireTime = loginUser.getExpireTime();
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
|
if (expireTime - currentTime <= MILLIS_MINUTE_TWENTY)
|
||||||
{
|
{
|
||||||
refreshToken(loginUser);
|
refreshToken(loginUser);
|
||||||
}
|
}
|
||||||
@ -141,7 +142,7 @@ public class TokenService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 刷新令牌有效期
|
* 刷新令牌有效期
|
||||||
*
|
*
|
||||||
* @param loginUser 登录信息
|
* @param loginUser 登录信息
|
||||||
*/
|
*/
|
||||||
public void refreshToken(LoginUser loginUser)
|
public void refreshToken(LoginUser loginUser)
|
||||||
@ -155,7 +156,7 @@ public class TokenService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置用户代理信息
|
* 设置用户代理信息
|
||||||
*
|
*
|
||||||
* @param loginUser 登录信息
|
* @param loginUser 登录信息
|
||||||
*/
|
*/
|
||||||
public void setUserAgent(LoginUser loginUser)
|
public void setUserAgent(LoginUser loginUser)
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.8.9</version>
|
<version>3.9.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@ -64,7 +64,7 @@ public class GenController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改代码生成业务
|
* 获取代码生成信息
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('tool:gen:query')")
|
@PreAuthorize("@ss.hasPermi('tool:gen:query')")
|
||||||
@GetMapping(value = "/{tableId}")
|
@GetMapping(value = "/{tableId}")
|
||||||
|
|||||||
@ -128,9 +128,9 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
int row = genTableMapper.updateGenTable(genTable);
|
int row = genTableMapper.updateGenTable(genTable);
|
||||||
if (row > 0)
|
if (row > 0)
|
||||||
{
|
{
|
||||||
for (GenTableColumn cenTableColumn : genTable.getColumns())
|
for (GenTableColumn genTableColumn : genTable.getColumns())
|
||||||
{
|
{
|
||||||
genTableColumnMapper.updateGenTableColumn(cenTableColumn);
|
genTableColumnMapper.updateGenTableColumn(genTableColumn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -424,16 +424,16 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
{
|
{
|
||||||
throw new ServiceException("树名称字段不能为空");
|
throw new ServiceException("树名称字段不能为空");
|
||||||
}
|
}
|
||||||
else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory()))
|
}
|
||||||
|
else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory()))
|
||||||
|
{
|
||||||
|
if (StringUtils.isEmpty(genTable.getSubTableName()))
|
||||||
{
|
{
|
||||||
if (StringUtils.isEmpty(genTable.getSubTableName()))
|
throw new ServiceException("关联子表的表名不能为空");
|
||||||
{
|
}
|
||||||
throw new ServiceException("关联子表的表名不能为空");
|
else if (StringUtils.isEmpty(genTable.getSubTableFkName()))
|
||||||
}
|
{
|
||||||
else if (StringUtils.isEmpty(genTable.getSubTableFkName()))
|
throw new ServiceException("子表关联的外键名不能为空");
|
||||||
{
|
|
||||||
throw new ServiceException("子表关联的外键名不能为空");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,9 +71,9 @@ public class ${ClassName} extends ${Entity}
|
|||||||
{
|
{
|
||||||
return $column.javaField;
|
return $column.javaField;
|
||||||
}
|
}
|
||||||
#end
|
|
||||||
#end
|
|
||||||
|
|
||||||
|
#end
|
||||||
|
#end
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
public List<${subClassName}> get${subClassName}List()
|
public List<${subClassName}> get${subClassName}List()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -75,7 +75,7 @@
|
|||||||
icon="el-icon-plus"
|
icon="el-icon-plus"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="handleAdd"
|
@click="handleAdd"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:add']"
|
v-hasPermi="['${permissionPrefix}:add']"
|
||||||
>新增</el-button>
|
>新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
@ -144,21 +144,21 @@
|
|||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-edit"
|
icon="el-icon-edit"
|
||||||
@click="handleUpdate(scope.row)"
|
@click="handleUpdate(scope.row)"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:edit']"
|
v-hasPermi="['${permissionPrefix}:edit']"
|
||||||
>修改</el-button>
|
>修改</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-plus"
|
icon="el-icon-plus"
|
||||||
@click="handleAdd(scope.row)"
|
@click="handleAdd(scope.row)"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:add']"
|
v-hasPermi="['${permissionPrefix}:add']"
|
||||||
>新增</el-button>
|
>新增</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-delete"
|
icon="el-icon-delete"
|
||||||
@click="handleDelete(scope.row)"
|
@click="handleDelete(scope.row)"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:remove']"
|
v-hasPermi="['${permissionPrefix}:remove']"
|
||||||
>删除</el-button>
|
>删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -283,9 +283,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}";
|
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}"
|
||||||
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"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "${BusinessName}",
|
name: "${BusinessName}",
|
||||||
@ -346,18 +346,18 @@ export default {
|
|||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 查询${functionName}列表 */
|
/** 查询${functionName}列表 */
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
this.queryParams.params = {};
|
this.queryParams.params = {}
|
||||||
#break
|
#break
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
@ -365,40 +365,40 @@ export default {
|
|||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
if (null != this.daterange${AttrName} && '' != this.daterange${AttrName}) {
|
if (null != this.daterange${AttrName} && '' != this.daterange${AttrName}) {
|
||||||
this.queryParams.params["begin${AttrName}"] = this.daterange${AttrName}[0];
|
this.queryParams.params["begin${AttrName}"] = this.daterange${AttrName}[0]
|
||||||
this.queryParams.params["end${AttrName}"] = this.daterange${AttrName}[1];
|
this.queryParams.params["end${AttrName}"] = this.daterange${AttrName}[1]
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
#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
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
/** 转换${functionName}数据结构 */
|
/** 转换${functionName}数据结构 */
|
||||||
normalizer(node) {
|
normalizer(node) {
|
||||||
if (node.children && !node.children.length) {
|
if (node.children && !node.children.length) {
|
||||||
delete node.children;
|
delete node.children
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
id: node.${treeCode},
|
id: node.${treeCode},
|
||||||
label: node.${treeName},
|
label: node.${treeName},
|
||||||
children: node.children
|
children: node.children
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
/** 查询${functionName}下拉树结构 */
|
/** 查询${functionName}下拉树结构 */
|
||||||
getTreeselect() {
|
getTreeselect() {
|
||||||
list${BusinessName}().then(response => {
|
list${BusinessName}().then(response => {
|
||||||
this.${businessName}Options = [];
|
this.${businessName}Options = []
|
||||||
const data = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] };
|
const data = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] }
|
||||||
data.children = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
|
data.children = this.handleTree(response.data, "${treeCode}", "${treeParentCode}")
|
||||||
this.${businessName}Options.push(data);
|
this.${businessName}Options.push(data)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
cancel() {
|
cancel() {
|
||||||
this.open = false;
|
this.open = false
|
||||||
this.reset();
|
this.reset()
|
||||||
},
|
},
|
||||||
// 表单重置
|
// 表单重置
|
||||||
reset() {
|
reset() {
|
||||||
@ -410,61 +410,61 @@ export default {
|
|||||||
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
};
|
}
|
||||||
this.resetForm("form");
|
this.resetForm("form")
|
||||||
},
|
},
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
this.daterange${AttrName} = [];
|
this.daterange${AttrName} = []
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
this.resetForm("queryForm");
|
this.resetForm("queryForm")
|
||||||
this.handleQuery();
|
this.handleQuery()
|
||||||
},
|
},
|
||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
handleAdd(row) {
|
handleAdd(row) {
|
||||||
this.reset();
|
this.reset()
|
||||||
this.getTreeselect();
|
this.getTreeselect()
|
||||||
if (row != null && row.${treeCode}) {
|
if (row != null && row.${treeCode}) {
|
||||||
this.form.${treeParentCode} = row.${treeCode};
|
this.form.${treeParentCode} = row.${treeCode}
|
||||||
} else {
|
} else {
|
||||||
this.form.${treeParentCode} = 0;
|
this.form.${treeParentCode} = 0
|
||||||
}
|
}
|
||||||
this.open = true;
|
this.open = true
|
||||||
this.title = "添加${functionName}";
|
this.title = "添加${functionName}"
|
||||||
},
|
},
|
||||||
/** 展开/折叠操作 */
|
/** 展开/折叠操作 */
|
||||||
toggleExpandAll() {
|
toggleExpandAll() {
|
||||||
this.refreshTable = false;
|
this.refreshTable = false
|
||||||
this.isExpandAll = !this.isExpandAll;
|
this.isExpandAll = !this.isExpandAll
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.refreshTable = true;
|
this.refreshTable = true
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
handleUpdate(row) {
|
handleUpdate(row) {
|
||||||
this.reset();
|
this.reset()
|
||||||
this.getTreeselect();
|
this.getTreeselect()
|
||||||
if (row != null) {
|
if (row != null) {
|
||||||
this.form.${treeParentCode} = row.${treeParentCode};
|
this.form.${treeParentCode} = row.${treeParentCode}
|
||||||
}
|
}
|
||||||
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
||||||
this.form = response.data;
|
this.form = response.data
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#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
|
#end
|
||||||
this.open = true;
|
this.open = true
|
||||||
this.title = "修改${functionName}";
|
this.title = "修改${functionName}"
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
submitForm() {
|
submitForm() {
|
||||||
@ -472,34 +472,34 @@ export default {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#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
|
#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 => {
|
||||||
this.#[[$modal]]#.msgSuccess("修改成功");
|
this.#[[$modal]]#.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 => {
|
||||||
this.#[[$modal]]#.msgSuccess("新增成功");
|
this.#[[$modal]]#.msgSuccess("新增成功")
|
||||||
this.open = false;
|
this.open = false
|
||||||
this.getList();
|
this.getList()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
handleDelete(row) {
|
handleDelete(row) {
|
||||||
this.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + row.${pkColumn.javaField} + '"的数据项?').then(function() {
|
this.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + row.${pkColumn.javaField} + '"的数据项?').then(function() {
|
||||||
return del${BusinessName}(row.${pkColumn.javaField});
|
return del${BusinessName}(row.${pkColumn.javaField})
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.getList();
|
this.getList()
|
||||||
this.#[[$modal]]#.msgSuccess("删除成功");
|
this.#[[$modal]]#.msgSuccess("删除成功")
|
||||||
}).catch(() => {});
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -75,7 +75,7 @@
|
|||||||
icon="el-icon-plus"
|
icon="el-icon-plus"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="handleAdd"
|
@click="handleAdd"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:add']"
|
v-hasPermi="['${permissionPrefix}:add']"
|
||||||
>新增</el-button>
|
>新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
@ -86,7 +86,7 @@
|
|||||||
size="mini"
|
size="mini"
|
||||||
:disabled="single"
|
:disabled="single"
|
||||||
@click="handleUpdate"
|
@click="handleUpdate"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:edit']"
|
v-hasPermi="['${permissionPrefix}:edit']"
|
||||||
>修改</el-button>
|
>修改</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
@ -97,7 +97,7 @@
|
|||||||
size="mini"
|
size="mini"
|
||||||
:disabled="multiple"
|
:disabled="multiple"
|
||||||
@click="handleDelete"
|
@click="handleDelete"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:remove']"
|
v-hasPermi="['${permissionPrefix}:remove']"
|
||||||
>删除</el-button>
|
>删除</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
@ -107,7 +107,7 @@
|
|||||||
icon="el-icon-download"
|
icon="el-icon-download"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:export']"
|
v-hasPermi="['${permissionPrefix}: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>
|
||||||
@ -158,14 +158,14 @@
|
|||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-edit"
|
icon="el-icon-edit"
|
||||||
@click="handleUpdate(scope.row)"
|
@click="handleUpdate(scope.row)"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:edit']"
|
v-hasPermi="['${permissionPrefix}:edit']"
|
||||||
>修改</el-button>
|
>修改</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-delete"
|
icon="el-icon-delete"
|
||||||
@click="handleDelete(scope.row)"
|
@click="handleDelete(scope.row)"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:remove']"
|
v-hasPermi="['${permissionPrefix}:remove']"
|
||||||
>删除</el-button>
|
>删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -353,7 +353,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}";
|
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "${BusinessName}",
|
name: "${BusinessName}",
|
||||||
@ -423,18 +423,18 @@ export default {
|
|||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 查询${functionName}列表 */
|
/** 查询${functionName}列表 */
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
this.queryParams.params = {};
|
this.queryParams.params = {}
|
||||||
#break
|
#break
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
@ -442,21 +442,21 @@ export default {
|
|||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
if (null != this.daterange${AttrName} && '' != this.daterange${AttrName}) {
|
if (null != this.daterange${AttrName} && '' != this.daterange${AttrName}) {
|
||||||
this.queryParams.params["begin${AttrName}"] = this.daterange${AttrName}[0];
|
this.queryParams.params["begin${AttrName}"] = this.daterange${AttrName}[0]
|
||||||
this.queryParams.params["end${AttrName}"] = this.daterange${AttrName}[1];
|
this.queryParams.params["end${AttrName}"] = this.daterange${AttrName}[1]
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
#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
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
cancel() {
|
cancel() {
|
||||||
this.open = false;
|
this.open = false
|
||||||
this.reset();
|
this.reset()
|
||||||
},
|
},
|
||||||
// 表单重置
|
// 表单重置
|
||||||
reset() {
|
reset() {
|
||||||
@ -468,27 +468,27 @@ export default {
|
|||||||
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
};
|
}
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
this.${subclassName}List = [];
|
this.${subclassName}List = []
|
||||||
#end
|
#end
|
||||||
this.resetForm("form");
|
this.resetForm("form")
|
||||||
},
|
},
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
this.queryParams.pageNum = 1;
|
this.queryParams.pageNum = 1
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
this.daterange${AttrName} = [];
|
this.daterange${AttrName} = []
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
this.resetForm("queryForm");
|
this.resetForm("queryForm")
|
||||||
this.handleQuery();
|
this.handleQuery()
|
||||||
},
|
},
|
||||||
// 多选框选中数据
|
// 多选框选中数据
|
||||||
handleSelectionChange(selection) {
|
handleSelectionChange(selection) {
|
||||||
@ -498,27 +498,27 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.reset();
|
this.reset()
|
||||||
this.open = true;
|
this.open = true
|
||||||
this.title = "添加${functionName}";
|
this.title = "添加${functionName}"
|
||||||
},
|
},
|
||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
handleUpdate(row) {
|
handleUpdate(row) {
|
||||||
this.reset();
|
this.reset()
|
||||||
const ${pkColumn.javaField} = row.${pkColumn.javaField} || this.ids
|
const ${pkColumn.javaField} = row.${pkColumn.javaField} || this.ids
|
||||||
get${BusinessName}(${pkColumn.javaField}).then(response => {
|
get${BusinessName}(${pkColumn.javaField}).then(response => {
|
||||||
this.form = response.data;
|
this.form = response.data
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#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
|
#end
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
this.${subclassName}List = response.data.${subclassName}List;
|
this.${subclassName}List = response.data.${subclassName}List
|
||||||
#end
|
#end
|
||||||
this.open = true;
|
this.open = true
|
||||||
this.title = "修改${functionName}";
|
this.title = "修改${functionName}"
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
submitForm() {
|
submitForm() {
|
||||||
@ -526,64 +526,64 @@ export default {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#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
|
#end
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
this.form.${subclassName}List = this.${subclassName}List;
|
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 => {
|
||||||
this.#[[$modal]]#.msgSuccess("修改成功");
|
this.#[[$modal]]#.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 => {
|
||||||
this.#[[$modal]]#.msgSuccess("新增成功");
|
this.#[[$modal]]#.msgSuccess("新增成功")
|
||||||
this.open = false;
|
this.open = false
|
||||||
this.getList();
|
this.getList()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
handleDelete(row) {
|
handleDelete(row) {
|
||||||
const ${pkColumn.javaField}s = row.${pkColumn.javaField} || this.ids;
|
const ${pkColumn.javaField}s = row.${pkColumn.javaField} || this.ids
|
||||||
this.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + ${pkColumn.javaField}s + '"的数据项?').then(function() {
|
this.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + ${pkColumn.javaField}s + '"的数据项?').then(function() {
|
||||||
return del${BusinessName}(${pkColumn.javaField}s);
|
return del${BusinessName}(${pkColumn.javaField}s)
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.getList();
|
this.getList()
|
||||||
this.#[[$modal]]#.msgSuccess("删除成功");
|
this.#[[$modal]]#.msgSuccess("删除成功")
|
||||||
}).catch(() => {});
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
/** ${subTable.functionName}序号 */
|
/** ${subTable.functionName}序号 */
|
||||||
row${subClassName}Index({ row, rowIndex }) {
|
row${subClassName}Index({ row, rowIndex }) {
|
||||||
row.index = rowIndex + 1;
|
row.index = rowIndex + 1
|
||||||
},
|
},
|
||||||
/** ${subTable.functionName}添加按钮操作 */
|
/** ${subTable.functionName}添加按钮操作 */
|
||||||
handleAdd${subClassName}() {
|
handleAdd${subClassName}() {
|
||||||
let obj = {};
|
let obj = {}
|
||||||
#foreach($column in $subTable.columns)
|
#foreach($column in $subTable.columns)
|
||||||
#if($column.pk || $column.javaField == ${subTableFkclassName})
|
#if($column.pk || $column.javaField == ${subTableFkclassName})
|
||||||
#elseif($column.list && "" != $javaField)
|
#elseif($column.list && "" != $javaField)
|
||||||
obj.$column.javaField = "";
|
obj.$column.javaField = ""
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
this.${subclassName}List.push(obj);
|
this.${subclassName}List.push(obj)
|
||||||
},
|
},
|
||||||
/** ${subTable.functionName}删除按钮操作 */
|
/** ${subTable.functionName}删除按钮操作 */
|
||||||
handleDelete${subClassName}() {
|
handleDelete${subClassName}() {
|
||||||
if (this.checked${subClassName}.length == 0) {
|
if (this.checked${subClassName}.length == 0) {
|
||||||
this.#[[$modal]]#.msgError("请先选择要删除的${subTable.functionName}数据");
|
this.#[[$modal]]#.msgError("请先选择要删除的${subTable.functionName}数据")
|
||||||
} else {
|
} else {
|
||||||
const ${subclassName}List = this.${subclassName}List;
|
const ${subclassName}List = this.${subclassName}List
|
||||||
const checked${subClassName} = this.checked${subClassName};
|
const checked${subClassName} = this.checked${subClassName}
|
||||||
this.${subclassName}List = ${subclassName}List.filter(function(item) {
|
this.${subclassName}List = ${subclassName}List.filter(function(item) {
|
||||||
return checked${subClassName}.indexOf(item.index) == -1
|
return checked${subClassName}.indexOf(item.index) == -1
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/** 复选框选中数据 */
|
/** 复选框选中数据 */
|
||||||
@ -598,5 +598,5 @@ export default {
|
|||||||
}, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
|
}, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -73,7 +73,7 @@
|
|||||||
plain
|
plain
|
||||||
icon="Plus"
|
icon="Plus"
|
||||||
@click="handleAdd"
|
@click="handleAdd"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:add']"
|
v-hasPermi="['${permissionPrefix}:add']"
|
||||||
>新增</el-button>
|
>新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
@ -136,9 +136,9 @@
|
|||||||
#end
|
#end
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button>
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${permissionPrefix}:edit']">修改</el-button>
|
||||||
<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button>
|
<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['${permissionPrefix}:add']">新增</el-button>
|
||||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button>
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${permissionPrefix}:remove']">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -271,26 +271,26 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="${BusinessName}">
|
<script setup name="${BusinessName}">
|
||||||
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}";
|
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}"
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance()
|
||||||
#if(${dicts} != '')
|
#if(${dicts} != '')
|
||||||
#set($dictsNoSymbol=$dicts.replace("'", ""))
|
#set($dictsNoSymbol=$dicts.replace("'", ""))
|
||||||
const { ${dictsNoSymbol} } = proxy.useDict(${dicts});
|
const { ${dictsNoSymbol} } = proxy.useDict(${dicts})
|
||||||
#end
|
#end
|
||||||
|
|
||||||
const ${businessName}List = ref([]);
|
const ${businessName}List = ref([])
|
||||||
const ${businessName}Options = ref([]);
|
const ${businessName}Options = ref([])
|
||||||
const open = ref(false);
|
const open = ref(false)
|
||||||
const loading = ref(true);
|
const loading = ref(true)
|
||||||
const showSearch = ref(true);
|
const showSearch = ref(true)
|
||||||
const title = ref("");
|
const title = ref("")
|
||||||
const isExpandAll = ref(true);
|
const isExpandAll = ref(true)
|
||||||
const refreshTable = ref(true);
|
const refreshTable = ref(true)
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
const daterange${AttrName} = ref([]);
|
const daterange${AttrName} = ref([])
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@ -318,48 +318,48 @@ const data = reactive({
|
|||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
const { queryParams, form, rules } = toRefs(data);
|
const { queryParams, form, rules } = toRefs(data)
|
||||||
|
|
||||||
/** 查询${functionName}列表 */
|
/** 查询${functionName}列表 */
|
||||||
function getList() {
|
function getList() {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
queryParams.value.params = {};
|
queryParams.value.params = {}
|
||||||
#break
|
#break
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
if (null != daterange${AttrName} && '' != daterange${AttrName}) {
|
if (null != daterange${AttrName}.value && '' != daterange${AttrName}.value) {
|
||||||
queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0];
|
queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0]
|
||||||
queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1];
|
queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1]
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
list${BusinessName}(queryParams.value).then(response => {
|
list${BusinessName}(queryParams.value).then(response => {
|
||||||
${businessName}List.value = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}");
|
${businessName}List.value = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}")
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询${functionName}下拉树结构 */
|
/** 查询${functionName}下拉树结构 */
|
||||||
function getTreeselect() {
|
function getTreeselect() {
|
||||||
list${BusinessName}().then(response => {
|
list${BusinessName}().then(response => {
|
||||||
${businessName}Options.value = [];
|
${businessName}Options.value = []
|
||||||
const data = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] };
|
const data = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] }
|
||||||
data.children = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}");
|
data.children = proxy.handleTree(response.data, "${treeCode}", "${treeParentCode}")
|
||||||
${businessName}Options.value.push(data);
|
${businessName}Options.value.push(data)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
function cancel() {
|
function cancel() {
|
||||||
open.value = false;
|
open.value = false
|
||||||
reset();
|
reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表单重置
|
// 表单重置
|
||||||
@ -372,13 +372,13 @@ function reset() {
|
|||||||
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
};
|
}
|
||||||
proxy.resetForm("${businessName}Ref");
|
proxy.resetForm("${businessName}Ref")
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
getList();
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
@ -386,52 +386,52 @@ function resetQuery() {
|
|||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
daterange${AttrName}.value = [];
|
daterange${AttrName}.value = []
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
proxy.resetForm("queryRef");
|
proxy.resetForm("queryRef")
|
||||||
handleQuery();
|
handleQuery()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
function handleAdd(row) {
|
function handleAdd(row) {
|
||||||
reset();
|
reset()
|
||||||
getTreeselect();
|
getTreeselect()
|
||||||
if (row != null && row.${treeCode}) {
|
if (row != null && row.${treeCode}) {
|
||||||
form.value.${treeParentCode} = row.${treeCode};
|
form.value.${treeParentCode} = row.${treeCode}
|
||||||
} else {
|
} else {
|
||||||
form.value.${treeParentCode} = 0;
|
form.value.${treeParentCode} = 0
|
||||||
}
|
}
|
||||||
open.value = true;
|
open.value = true
|
||||||
title.value = "添加${functionName}";
|
title.value = "添加${functionName}"
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 展开/折叠操作 */
|
/** 展开/折叠操作 */
|
||||||
function toggleExpandAll() {
|
function toggleExpandAll() {
|
||||||
refreshTable.value = false;
|
refreshTable.value = false
|
||||||
isExpandAll.value = !isExpandAll.value;
|
isExpandAll.value = !isExpandAll.value
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
refreshTable.value = true;
|
refreshTable.value = true
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
async function handleUpdate(row) {
|
async function handleUpdate(row) {
|
||||||
reset();
|
reset()
|
||||||
await getTreeselect();
|
await getTreeselect()
|
||||||
if (row != null) {
|
if (row != null) {
|
||||||
form.value.${treeParentCode} = row.${treeParentCode};
|
form.value.${treeParentCode} = row.${treeParentCode}
|
||||||
}
|
}
|
||||||
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
||||||
form.value = response.data;
|
form.value = response.data
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "checkbox")
|
#if($column.htmlType == "checkbox")
|
||||||
form.value.$column.javaField = form.value.${column.javaField}.split(",");
|
form.value.$column.javaField = form.value.${column.javaField}.split(",")
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
open.value = true;
|
open.value = true
|
||||||
title.value = "修改${functionName}";
|
title.value = "修改${functionName}"
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
@ -440,35 +440,35 @@ function submitForm() {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "checkbox")
|
#if($column.htmlType == "checkbox")
|
||||||
form.value.$column.javaField = form.value.${column.javaField}.join(",");
|
form.value.$column.javaField = form.value.${column.javaField}.join(",")
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
if (form.value.${pkColumn.javaField} != null) {
|
if (form.value.${pkColumn.javaField} != null) {
|
||||||
update${BusinessName}(form.value).then(response => {
|
update${BusinessName}(form.value).then(response => {
|
||||||
proxy.#[[$modal]]#.msgSuccess("修改成功");
|
proxy.#[[$modal]]#.msgSuccess("修改成功")
|
||||||
open.value = false;
|
open.value = false
|
||||||
getList();
|
getList()
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
add${BusinessName}(form.value).then(response => {
|
add${BusinessName}(form.value).then(response => {
|
||||||
proxy.#[[$modal]]#.msgSuccess("新增成功");
|
proxy.#[[$modal]]#.msgSuccess("新增成功")
|
||||||
open.value = false;
|
open.value = false
|
||||||
getList();
|
getList()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
function handleDelete(row) {
|
function handleDelete(row) {
|
||||||
proxy.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + row.${pkColumn.javaField} + '"的数据项?').then(function() {
|
proxy.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + row.${pkColumn.javaField} + '"的数据项?').then(function() {
|
||||||
return del${BusinessName}(row.${pkColumn.javaField});
|
return del${BusinessName}(row.${pkColumn.javaField})
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
getList();
|
getList()
|
||||||
proxy.#[[$modal]]#.msgSuccess("删除成功");
|
proxy.#[[$modal]]#.msgSuccess("删除成功")
|
||||||
}).catch(() => {});
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
getList();
|
getList()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -73,7 +73,7 @@
|
|||||||
plain
|
plain
|
||||||
icon="Plus"
|
icon="Plus"
|
||||||
@click="handleAdd"
|
@click="handleAdd"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:add']"
|
v-hasPermi="['${permissionPrefix}:add']"
|
||||||
>新增</el-button>
|
>新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
@ -83,7 +83,7 @@
|
|||||||
icon="Edit"
|
icon="Edit"
|
||||||
:disabled="single"
|
:disabled="single"
|
||||||
@click="handleUpdate"
|
@click="handleUpdate"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:edit']"
|
v-hasPermi="['${permissionPrefix}:edit']"
|
||||||
>修改</el-button>
|
>修改</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
@ -93,7 +93,7 @@
|
|||||||
icon="Delete"
|
icon="Delete"
|
||||||
:disabled="multiple"
|
:disabled="multiple"
|
||||||
@click="handleDelete"
|
@click="handleDelete"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:remove']"
|
v-hasPermi="['${permissionPrefix}:remove']"
|
||||||
>删除</el-button>
|
>删除</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
@ -102,7 +102,7 @@
|
|||||||
plain
|
plain
|
||||||
icon="Download"
|
icon="Download"
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
v-hasPermi="['${moduleName}:${businessName}:export']"
|
v-hasPermi="['${permissionPrefix}:export']"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
@ -148,8 +148,8 @@
|
|||||||
#end
|
#end
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button>
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${permissionPrefix}:edit']">修改</el-button>
|
||||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button>
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${permissionPrefix}:remove']">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -343,33 +343,33 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="${BusinessName}">
|
<script setup name="${BusinessName}">
|
||||||
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}";
|
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}"
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance()
|
||||||
#if(${dicts} != '')
|
#if(${dicts} != '')
|
||||||
#set($dictsNoSymbol=$dicts.replace("'", ""))
|
#set($dictsNoSymbol=$dicts.replace("'", ""))
|
||||||
const { ${dictsNoSymbol} } = proxy.useDict(${dicts});
|
const { ${dictsNoSymbol} } = proxy.useDict(${dicts})
|
||||||
#end
|
#end
|
||||||
|
|
||||||
const ${businessName}List = ref([]);
|
const ${businessName}List = ref([])
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
const ${subclassName}List = ref([]);
|
const ${subclassName}List = ref([])
|
||||||
#end
|
#end
|
||||||
const open = ref(false);
|
const open = ref(false)
|
||||||
const loading = ref(true);
|
const loading = ref(true)
|
||||||
const showSearch = ref(true);
|
const showSearch = ref(true)
|
||||||
const ids = ref([]);
|
const ids = ref([])
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
const checked${subClassName} = ref([]);
|
const checked${subClassName} = ref([])
|
||||||
#end
|
#end
|
||||||
const single = ref(true);
|
const single = ref(true)
|
||||||
const multiple = ref(true);
|
const multiple = ref(true)
|
||||||
const total = ref(0);
|
const total = ref(0)
|
||||||
const title = ref("");
|
const title = ref("")
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
const daterange${AttrName} = ref([]);
|
const daterange${AttrName} = ref([])
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@ -399,39 +399,39 @@ const data = reactive({
|
|||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
const { queryParams, form, rules } = toRefs(data);
|
const { queryParams, form, rules } = toRefs(data)
|
||||||
|
|
||||||
/** 查询${functionName}列表 */
|
/** 查询${functionName}列表 */
|
||||||
function getList() {
|
function getList() {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
queryParams.value.params = {};
|
queryParams.value.params = {}
|
||||||
#break
|
#break
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
if (null != daterange${AttrName} && '' != daterange${AttrName}) {
|
if (null != daterange${AttrName}.value && '' != daterange${AttrName}.value) {
|
||||||
queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0];
|
queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0]
|
||||||
queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1];
|
queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1]
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
list${BusinessName}(queryParams.value).then(response => {
|
list${BusinessName}(queryParams.value).then(response => {
|
||||||
${businessName}List.value = response.rows;
|
${businessName}List.value = response.rows
|
||||||
total.value = response.total;
|
total.value = response.total
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
function cancel() {
|
function cancel() {
|
||||||
open.value = false;
|
open.value = false
|
||||||
reset();
|
reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表单重置
|
// 表单重置
|
||||||
@ -444,17 +444,17 @@ function reset() {
|
|||||||
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
};
|
}
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
${subclassName}List.value = [];
|
${subclassName}List.value = []
|
||||||
#end
|
#end
|
||||||
proxy.resetForm("${businessName}Ref");
|
proxy.resetForm("${businessName}Ref")
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
queryParams.value.pageNum = 1;
|
queryParams.value.pageNum = 1
|
||||||
getList();
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
@ -462,44 +462,44 @@ function resetQuery() {
|
|||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
daterange${AttrName}.value = [];
|
daterange${AttrName}.value = []
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
proxy.resetForm("queryRef");
|
proxy.resetForm("queryRef")
|
||||||
handleQuery();
|
handleQuery()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 多选框选中数据
|
// 多选框选中数据
|
||||||
function handleSelectionChange(selection) {
|
function handleSelectionChange(selection) {
|
||||||
ids.value = selection.map(item => item.${pkColumn.javaField});
|
ids.value = selection.map(item => item.${pkColumn.javaField})
|
||||||
single.value = selection.length != 1;
|
single.value = selection.length != 1
|
||||||
multiple.value = !selection.length;
|
multiple.value = !selection.length
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
reset();
|
reset()
|
||||||
open.value = true;
|
open.value = true
|
||||||
title.value = "添加${functionName}";
|
title.value = "添加${functionName}"
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
function handleUpdate(row) {
|
function handleUpdate(row) {
|
||||||
reset();
|
reset()
|
||||||
const _${pkColumn.javaField} = row.${pkColumn.javaField} || ids.value
|
const _${pkColumn.javaField} = row.${pkColumn.javaField} || ids.value
|
||||||
get${BusinessName}(_${pkColumn.javaField}).then(response => {
|
get${BusinessName}(_${pkColumn.javaField}).then(response => {
|
||||||
form.value = response.data;
|
form.value = response.data
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "checkbox")
|
#if($column.htmlType == "checkbox")
|
||||||
form.value.$column.javaField = form.value.${column.javaField}.split(",");
|
form.value.$column.javaField = form.value.${column.javaField}.split(",")
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
${subclassName}List.value = response.data.${subclassName}List;
|
${subclassName}List.value = response.data.${subclassName}List
|
||||||
#end
|
#end
|
||||||
open.value = true;
|
open.value = true
|
||||||
title.value = "修改${functionName}";
|
title.value = "修改${functionName}"
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
@ -508,68 +508,68 @@ function submitForm() {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "checkbox")
|
#if($column.htmlType == "checkbox")
|
||||||
form.value.$column.javaField = form.value.${column.javaField}.join(",");
|
form.value.$column.javaField = form.value.${column.javaField}.join(",")
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
form.value.${subclassName}List = ${subclassName}List.value;
|
form.value.${subclassName}List = ${subclassName}List.value
|
||||||
#end
|
#end
|
||||||
if (form.value.${pkColumn.javaField} != null) {
|
if (form.value.${pkColumn.javaField} != null) {
|
||||||
update${BusinessName}(form.value).then(response => {
|
update${BusinessName}(form.value).then(response => {
|
||||||
proxy.#[[$modal]]#.msgSuccess("修改成功");
|
proxy.#[[$modal]]#.msgSuccess("修改成功")
|
||||||
open.value = false;
|
open.value = false
|
||||||
getList();
|
getList()
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
add${BusinessName}(form.value).then(response => {
|
add${BusinessName}(form.value).then(response => {
|
||||||
proxy.#[[$modal]]#.msgSuccess("新增成功");
|
proxy.#[[$modal]]#.msgSuccess("新增成功")
|
||||||
open.value = false;
|
open.value = false
|
||||||
getList();
|
getList()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
function handleDelete(row) {
|
function handleDelete(row) {
|
||||||
const _${pkColumn.javaField}s = row.${pkColumn.javaField} || ids.value;
|
const _${pkColumn.javaField}s = row.${pkColumn.javaField} || ids.value
|
||||||
proxy.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + _${pkColumn.javaField}s + '"的数据项?').then(function() {
|
proxy.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + _${pkColumn.javaField}s + '"的数据项?').then(function() {
|
||||||
return del${BusinessName}(_${pkColumn.javaField}s);
|
return del${BusinessName}(_${pkColumn.javaField}s)
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
getList();
|
getList()
|
||||||
proxy.#[[$modal]]#.msgSuccess("删除成功");
|
proxy.#[[$modal]]#.msgSuccess("删除成功")
|
||||||
}).catch(() => {});
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
#if($table.sub)
|
#if($table.sub)
|
||||||
/** ${subTable.functionName}序号 */
|
/** ${subTable.functionName}序号 */
|
||||||
function row${subClassName}Index({ row, rowIndex }) {
|
function row${subClassName}Index({ row, rowIndex }) {
|
||||||
row.index = rowIndex + 1;
|
row.index = rowIndex + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ${subTable.functionName}添加按钮操作 */
|
/** ${subTable.functionName}添加按钮操作 */
|
||||||
function handleAdd${subClassName}() {
|
function handleAdd${subClassName}() {
|
||||||
let obj = {};
|
let obj = {}
|
||||||
#foreach($column in $subTable.columns)
|
#foreach($column in $subTable.columns)
|
||||||
#if($column.pk || $column.javaField == ${subTableFkclassName})
|
#if($column.pk || $column.javaField == ${subTableFkclassName})
|
||||||
#elseif($column.list && "" != $javaField)
|
#elseif($column.list && "" != $javaField)
|
||||||
obj.$column.javaField = "";
|
obj.$column.javaField = ""
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
${subclassName}List.value.push(obj);
|
${subclassName}List.value.push(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ${subTable.functionName}删除按钮操作 */
|
/** ${subTable.functionName}删除按钮操作 */
|
||||||
function handleDelete${subClassName}() {
|
function handleDelete${subClassName}() {
|
||||||
if (checked${subClassName}.value.length == 0) {
|
if (checked${subClassName}.value.length == 0) {
|
||||||
proxy.#[[$modal]]#.msgError("请先选择要删除的${subTable.functionName}数据");
|
proxy.#[[$modal]]#.msgError("请先选择要删除的${subTable.functionName}数据")
|
||||||
} else {
|
} else {
|
||||||
const ${subclassName}s = ${subclassName}List.value;
|
const ${subclassName}s = ${subclassName}List.value
|
||||||
const checked${subClassName}s = checked${subClassName}.value;
|
const checked${subClassName}s = checked${subClassName}.value
|
||||||
${subclassName}List.value = ${subclassName}s.filter(function(item) {
|
${subclassName}List.value = ${subclassName}s.filter(function(item) {
|
||||||
return checked${subClassName}s.indexOf(item.index) == -1
|
return checked${subClassName}s.indexOf(item.index) == -1
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,5 +586,5 @@ function handleExport() {
|
|||||||
}, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
|
}, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
|
||||||
}
|
}
|
||||||
|
|
||||||
getList();
|
getList()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.8.9</version>
|
<version>3.9.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@ -177,7 +177,7 @@ public class SysJobController extends BaseController
|
|||||||
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
|
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
|
||||||
@Log(title = "定时任务", businessType = BusinessType.DELETE)
|
@Log(title = "定时任务", businessType = BusinessType.DELETE)
|
||||||
@DeleteMapping("/{jobIds}")
|
@DeleteMapping("/{jobIds}")
|
||||||
public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException
|
public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException
|
||||||
{
|
{
|
||||||
jobService.deleteJobByIds(jobIds);
|
jobService.deleteJobByIds(jobIds);
|
||||||
return success();
|
return success();
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package com.ruoyi.quartz.util;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import org.quartz.Job;
|
import org.quartz.Job;
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
import org.quartz.JobExecutionException;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import com.ruoyi.common.constant.Constants;
|
import com.ruoyi.common.constant.Constants;
|
||||||
@ -31,7 +30,7 @@ public abstract class AbstractQuartzJob implements Job
|
|||||||
private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();
|
private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext context) throws JobExecutionException
|
public void execute(JobExecutionContext context)
|
||||||
{
|
{
|
||||||
SysJob sysJob = new SysJob();
|
SysJob sysJob = new SysJob();
|
||||||
BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
|
BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
|
||||||
|
|||||||
@ -105,7 +105,7 @@ public class JobInvokeUtil
|
|||||||
*/
|
*/
|
||||||
public static List<Object[]> getMethodParams(String invokeTarget)
|
public static List<Object[]> getMethodParams(String invokeTarget)
|
||||||
{
|
{
|
||||||
String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")");
|
String methodStr = StringUtils.substringBetweenLast(invokeTarget, "(", ")");
|
||||||
if (StringUtils.isEmpty(methodStr))
|
if (StringUtils.isEmpty(methodStr))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -131,11 +131,11 @@ public class ScheduleUtils
|
|||||||
int count = StringUtils.countMatches(packageName, ".");
|
int count = StringUtils.countMatches(packageName, ".");
|
||||||
if (count > 1)
|
if (count > 1)
|
||||||
{
|
{
|
||||||
return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR);
|
return StringUtils.startsWithAny(invokeTarget, Constants.JOB_WHITELIST_STR);
|
||||||
}
|
}
|
||||||
Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]);
|
Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]);
|
||||||
String beanPackageName = obj.getClass().getPackage().getName();
|
String beanPackageName = obj.getClass().getPackage().getName();
|
||||||
return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR)
|
return StringUtils.startsWithAny(beanPackageName, Constants.JOB_WHITELIST_STR)
|
||||||
&& !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR);
|
&& !StringUtils.startsWithAny(beanPackageName, Constants.JOB_ERROR_STR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.8.9</version>
|
<version>3.9.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.system.mapper;
|
package com.ruoyi.system.mapper;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
@ -70,20 +71,39 @@ public interface SysUserMapper
|
|||||||
/**
|
/**
|
||||||
* 修改用户头像
|
* 修改用户头像
|
||||||
*
|
*
|
||||||
* @param userName 用户名
|
* @param userId 用户ID
|
||||||
* @param avatar 头像地址
|
* @param avatar 头像地址
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar);
|
public int updateUserAvatar(@Param("userId") Long userId, @Param("avatar") String avatar);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改用户状态
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @param status 状态
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateUserStatus(@Param("userId") Long userId, @Param("status") String status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户登录信息(IP和登录时间)
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @param loginIp 登录IP地址
|
||||||
|
* @param loginDate 登录时间
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int updateLoginInfo(@Param("userId") Long userId, @Param("loginIp") String loginIp, @Param("loginDate") Date loginDate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置用户密码
|
* 重置用户密码
|
||||||
*
|
*
|
||||||
* @param userName 用户名
|
* @param userId 用户ID
|
||||||
* @param password 密码
|
* @param password 密码
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public int resetUserPwd(@Param("userName") String userName, @Param("password") String password);
|
public int resetUserPwd(@Param("userId") Long userId, @Param("password") String password);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过用户ID删除用户
|
* 通过用户ID删除用户
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.system.service;
|
package com.ruoyi.system.service;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
|
|
||||||
@ -155,11 +156,21 @@ public interface ISysUserService
|
|||||||
/**
|
/**
|
||||||
* 修改用户头像
|
* 修改用户头像
|
||||||
*
|
*
|
||||||
* @param userName 用户名
|
* @param userId 用户ID
|
||||||
* @param avatar 头像地址
|
* @param avatar 头像地址
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public boolean updateUserAvatar(String userName, String avatar);
|
public boolean updateUserAvatar(Long userId, String avatar);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户登录信息(IP和登录时间)
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @param loginIp 登录IP地址
|
||||||
|
* @param loginDate 登录时间
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public void updateLoginInfo(Long userId, String loginIp, Date loginDate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置用户密码
|
* 重置用户密码
|
||||||
@ -172,11 +183,11 @@ public interface ISysUserService
|
|||||||
/**
|
/**
|
||||||
* 重置用户密码
|
* 重置用户密码
|
||||||
*
|
*
|
||||||
* @param userName 用户名
|
* @param userId 用户ID
|
||||||
* @param password 密码
|
* @param password 密码
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public int resetUserPwd(String userName, String password);
|
public int resetUserPwd(Long userId, String password);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过用户ID删除用户
|
* 通过用户ID删除用户
|
||||||
|
|||||||
@ -365,7 +365,7 @@ public class SysMenuServiceImpl implements ISysMenuService
|
|||||||
/**
|
/**
|
||||||
* 获取路由名称,如没有配置路由名称则取路由地址
|
* 获取路由名称,如没有配置路由名称则取路由地址
|
||||||
*
|
*
|
||||||
* @param routerName 路由名称
|
* @param name 路由名称
|
||||||
* @param path 路由地址
|
* @param path 路由地址
|
||||||
* @return 路由名称(驼峰格式)
|
* @return 路由名称(驼峰格式)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.ruoyi.system.service.impl;
|
package com.ruoyi.system.service.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
@ -326,7 +327,7 @@ public class SysUserServiceImpl implements ISysUserService
|
|||||||
@Override
|
@Override
|
||||||
public int updateUserStatus(SysUser user)
|
public int updateUserStatus(SysUser user)
|
||||||
{
|
{
|
||||||
return userMapper.updateUser(user);
|
return userMapper.updateUserStatus(user.getUserId(), user.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -344,14 +345,27 @@ public class SysUserServiceImpl implements ISysUserService
|
|||||||
/**
|
/**
|
||||||
* 修改用户头像
|
* 修改用户头像
|
||||||
*
|
*
|
||||||
* @param userName 用户名
|
* @param userId 用户ID
|
||||||
* @param avatar 头像地址
|
* @param avatar 头像地址
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean updateUserAvatar(String userName, String avatar)
|
public boolean updateUserAvatar(Long userId, String avatar)
|
||||||
{
|
{
|
||||||
return userMapper.updateUserAvatar(userName, avatar) > 0;
|
return userMapper.updateUserAvatar(userId, avatar) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户登录信息(IP和登录时间)
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @param loginIp 登录IP地址
|
||||||
|
* @param loginDate 登录时间
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public void updateLoginInfo(Long userId, String loginIp, Date loginDate)
|
||||||
|
{
|
||||||
|
userMapper.updateLoginInfo(userId, loginIp, loginDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -363,20 +377,20 @@ public class SysUserServiceImpl implements ISysUserService
|
|||||||
@Override
|
@Override
|
||||||
public int resetPwd(SysUser user)
|
public int resetPwd(SysUser user)
|
||||||
{
|
{
|
||||||
return userMapper.updateUser(user);
|
return userMapper.resetUserPwd(user.getUserId(), user.getPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置用户密码
|
* 重置用户密码
|
||||||
*
|
*
|
||||||
* @param userName 用户名
|
* @param userId 用户ID
|
||||||
* @param password 密码
|
* @param password 密码
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int resetUserPwd(String userName, String password)
|
public int resetUserPwd(Long userId, String password)
|
||||||
{
|
{
|
||||||
return userMapper.resetUserPwd(userName, password);
|
return userMapper.resetUserPwd(userId, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -517,6 +531,7 @@ public class SysUserServiceImpl implements ISysUserService
|
|||||||
checkUserDataScope(u.getUserId());
|
checkUserDataScope(u.getUserId());
|
||||||
deptService.checkDeptDataScope(user.getDeptId());
|
deptService.checkDeptDataScope(user.getDeptId());
|
||||||
user.setUserId(u.getUserId());
|
user.setUserId(u.getUserId());
|
||||||
|
user.setDeptId(u.getDeptId());
|
||||||
user.setUpdateBy(operName);
|
user.setUpdateBy(operName);
|
||||||
userMapper.updateUser(user);
|
userMapper.updateUser(user);
|
||||||
successNum++;
|
successNum++;
|
||||||
|
|||||||
@ -5,26 +5,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<mapper namespace="com.ruoyi.system.mapper.SysUserMapper">
|
<mapper namespace="com.ruoyi.system.mapper.SysUserMapper">
|
||||||
|
|
||||||
<resultMap type="SysUser" id="SysUserResult">
|
<resultMap type="SysUser" id="SysUserResult">
|
||||||
<id property="userId" column="user_id" />
|
<id property="userId" column="user_id" />
|
||||||
<result property="deptId" column="dept_id" />
|
<result property="deptId" column="dept_id" />
|
||||||
<result property="userName" column="user_name" />
|
<result property="userName" column="user_name" />
|
||||||
<result property="nickName" column="nick_name" />
|
<result property="nickName" column="nick_name" />
|
||||||
<result property="email" column="email" />
|
<result property="email" column="email" />
|
||||||
<result property="phonenumber" column="phonenumber" />
|
<result property="phonenumber" column="phonenumber" />
|
||||||
<result property="sex" column="sex" />
|
<result property="sex" column="sex" />
|
||||||
<result property="avatar" column="avatar" />
|
<result property="avatar" column="avatar" />
|
||||||
<result property="password" column="password" />
|
<result property="password" column="password" />
|
||||||
<result property="status" column="status" />
|
<result property="status" column="status" />
|
||||||
<result property="delFlag" column="del_flag" />
|
<result property="delFlag" column="del_flag" />
|
||||||
<result property="loginIp" column="login_ip" />
|
<result property="loginIp" column="login_ip" />
|
||||||
<result property="loginDate" column="login_date" />
|
<result property="loginDate" column="login_date" />
|
||||||
<result property="createBy" column="create_by" />
|
<result property="pwdUpdateDate" column="pwd_update_date" />
|
||||||
<result property="createTime" column="create_time" />
|
<result property="createBy" column="create_by" />
|
||||||
<result property="updateBy" column="update_by" />
|
<result property="createTime" column="create_time" />
|
||||||
<result property="updateTime" column="update_time" />
|
<result property="updateBy" column="update_by" />
|
||||||
<result property="remark" column="remark" />
|
<result property="updateTime" column="update_time" />
|
||||||
<association property="dept" javaType="SysDept" resultMap="deptResult" />
|
<result property="remark" column="remark" />
|
||||||
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
|
<association property="dept" javaType="SysDept" resultMap="deptResult" />
|
||||||
|
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<resultMap id="deptResult" type="SysDept">
|
<resultMap id="deptResult" type="SysDept">
|
||||||
@ -47,7 +48,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectUserVo">
|
<sql id="selectUserVo">
|
||||||
select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
|
select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.pwd_update_date, u.create_by, u.create_time, u.remark,
|
||||||
d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
|
d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
|
||||||
r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
|
r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
|
||||||
from sys_user u
|
from sys_user u
|
||||||
@ -154,6 +155,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="sex != null and sex != ''">sex,</if>
|
<if test="sex != null and sex != ''">sex,</if>
|
||||||
<if test="password != null and password != ''">password,</if>
|
<if test="password != null and password != ''">password,</if>
|
||||||
<if test="status != null and status != ''">status,</if>
|
<if test="status != null and status != ''">status,</if>
|
||||||
|
<if test="pwdUpdateDate != null">pwd_update_date,</if>
|
||||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||||
<if test="remark != null and remark != ''">remark,</if>
|
<if test="remark != null and remark != ''">remark,</if>
|
||||||
create_time
|
create_time
|
||||||
@ -168,6 +170,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="sex != null and sex != ''">#{sex},</if>
|
<if test="sex != null and sex != ''">#{sex},</if>
|
||||||
<if test="password != null and password != ''">#{password},</if>
|
<if test="password != null and password != ''">#{password},</if>
|
||||||
<if test="status != null and status != ''">#{status},</if>
|
<if test="status != null and status != ''">#{status},</if>
|
||||||
|
<if test="pwdUpdateDate != null">#{pwdUpdateDate},</if>
|
||||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||||
<if test="remark != null and remark != ''">#{remark},</if>
|
<if test="remark != null and remark != ''">#{remark},</if>
|
||||||
sysdate()
|
sysdate()
|
||||||
@ -177,8 +180,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<update id="updateUser" parameterType="SysUser">
|
<update id="updateUser" parameterType="SysUser">
|
||||||
update sys_user
|
update sys_user
|
||||||
<set>
|
<set>
|
||||||
<if test="deptId != null and deptId != 0">dept_id = #{deptId},</if>
|
<if test="deptId != 0">dept_id = #{deptId},</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 ">email = #{email},</if>
|
<if test="email != null ">email = #{email},</if>
|
||||||
<if test="phonenumber != null ">phonenumber = #{phonenumber},</if>
|
<if test="phonenumber != null ">phonenumber = #{phonenumber},</if>
|
||||||
@ -196,15 +198,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</update>
|
</update>
|
||||||
|
|
||||||
<update id="updateUserStatus" parameterType="SysUser">
|
<update id="updateUserStatus" parameterType="SysUser">
|
||||||
update sys_user set status = #{status} where user_id = #{userId}
|
update sys_user set status = #{status}, update_time = sysdate() where user_id = #{userId}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
<update id="updateUserAvatar" parameterType="SysUser">
|
<update id="updateUserAvatar" parameterType="SysUser">
|
||||||
update sys_user set avatar = #{avatar} where user_name = #{userName}
|
update sys_user set avatar = #{avatar}, update_time = sysdate() where user_id = #{userId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="updateLoginInfo" parameterType="SysUser">
|
||||||
|
update sys_user set login_ip = #{loginIp}, login_date = #{loginDate} where user_id = #{userId}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
<update id="resetUserPwd" parameterType="SysUser">
|
<update id="resetUserPwd" parameterType="SysUser">
|
||||||
update sys_user set password = #{password} where user_name = #{userName}
|
update sys_user set pwd_update_date = sysdate(), password = #{password}, update_time = sysdate() where user_id = #{userId}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
<delete id="deleteUserById" parameterType="Long">
|
<delete id="deleteUserById" parameterType="Long">
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
# 忽略build目录下类型为js的文件的语法检查
|
|
||||||
build/*.js
|
|
||||||
# 忽略src/assets目录下文件的语法检查
|
|
||||||
src/assets
|
|
||||||
# 忽略public目录下文件的语法检查
|
|
||||||
public
|
|
||||||
# 忽略当前目录下为js的文件的语法检查
|
|
||||||
*.js
|
|
||||||
# 忽略当前目录下为vue的文件的语法检查
|
|
||||||
*.vue
|
|
||||||
@ -1,199 +0,0 @@
|
|||||||
// ESlint 检查配置
|
|
||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
parserOptions: {
|
|
||||||
parser: 'babel-eslint',
|
|
||||||
sourceType: 'module'
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
node: true,
|
|
||||||
es6: true,
|
|
||||||
},
|
|
||||||
extends: ['plugin:vue/recommended', 'eslint:recommended'],
|
|
||||||
|
|
||||||
// add your custom rules here
|
|
||||||
//it is base on https://github.com/vuejs/eslint-config-vue
|
|
||||||
rules: {
|
|
||||||
"vue/max-attributes-per-line": [2, {
|
|
||||||
"singleline": 10,
|
|
||||||
"multiline": {
|
|
||||||
"max": 1,
|
|
||||||
"allowFirstLine": false
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
"vue/singleline-html-element-content-newline": "off",
|
|
||||||
"vue/multiline-html-element-content-newline":"off",
|
|
||||||
"vue/name-property-casing": ["error", "PascalCase"],
|
|
||||||
"vue/no-v-html": "off",
|
|
||||||
'accessor-pairs': 2,
|
|
||||||
'arrow-spacing': [2, {
|
|
||||||
'before': true,
|
|
||||||
'after': true
|
|
||||||
}],
|
|
||||||
'block-spacing': [2, 'always'],
|
|
||||||
'brace-style': [2, '1tbs', {
|
|
||||||
'allowSingleLine': true
|
|
||||||
}],
|
|
||||||
'camelcase': [0, {
|
|
||||||
'properties': 'always'
|
|
||||||
}],
|
|
||||||
'comma-dangle': [2, 'never'],
|
|
||||||
'comma-spacing': [2, {
|
|
||||||
'before': false,
|
|
||||||
'after': true
|
|
||||||
}],
|
|
||||||
'comma-style': [2, 'last'],
|
|
||||||
'constructor-super': 2,
|
|
||||||
'curly': [2, 'multi-line'],
|
|
||||||
'dot-location': [2, 'property'],
|
|
||||||
'eol-last': 2,
|
|
||||||
'eqeqeq': ["error", "always", {"null": "ignore"}],
|
|
||||||
'generator-star-spacing': [2, {
|
|
||||||
'before': true,
|
|
||||||
'after': true
|
|
||||||
}],
|
|
||||||
'handle-callback-err': [2, '^(err|error)$'],
|
|
||||||
'indent': [2, 2, {
|
|
||||||
'SwitchCase': 1
|
|
||||||
}],
|
|
||||||
'jsx-quotes': [2, 'prefer-single'],
|
|
||||||
'key-spacing': [2, {
|
|
||||||
'beforeColon': false,
|
|
||||||
'afterColon': true
|
|
||||||
}],
|
|
||||||
'keyword-spacing': [2, {
|
|
||||||
'before': true,
|
|
||||||
'after': true
|
|
||||||
}],
|
|
||||||
'new-cap': [2, {
|
|
||||||
'newIsCap': true,
|
|
||||||
'capIsNew': false
|
|
||||||
}],
|
|
||||||
'new-parens': 2,
|
|
||||||
'no-array-constructor': 2,
|
|
||||||
'no-caller': 2,
|
|
||||||
'no-console': 'off',
|
|
||||||
'no-class-assign': 2,
|
|
||||||
'no-cond-assign': 2,
|
|
||||||
'no-const-assign': 2,
|
|
||||||
'no-control-regex': 0,
|
|
||||||
'no-delete-var': 2,
|
|
||||||
'no-dupe-args': 2,
|
|
||||||
'no-dupe-class-members': 2,
|
|
||||||
'no-dupe-keys': 2,
|
|
||||||
'no-duplicate-case': 2,
|
|
||||||
'no-empty-character-class': 2,
|
|
||||||
'no-empty-pattern': 2,
|
|
||||||
'no-eval': 2,
|
|
||||||
'no-ex-assign': 2,
|
|
||||||
'no-extend-native': 2,
|
|
||||||
'no-extra-bind': 2,
|
|
||||||
'no-extra-boolean-cast': 2,
|
|
||||||
'no-extra-parens': [2, 'functions'],
|
|
||||||
'no-fallthrough': 2,
|
|
||||||
'no-floating-decimal': 2,
|
|
||||||
'no-func-assign': 2,
|
|
||||||
'no-implied-eval': 2,
|
|
||||||
'no-inner-declarations': [2, 'functions'],
|
|
||||||
'no-invalid-regexp': 2,
|
|
||||||
'no-irregular-whitespace': 2,
|
|
||||||
'no-iterator': 2,
|
|
||||||
'no-label-var': 2,
|
|
||||||
'no-labels': [2, {
|
|
||||||
'allowLoop': false,
|
|
||||||
'allowSwitch': false
|
|
||||||
}],
|
|
||||||
'no-lone-blocks': 2,
|
|
||||||
'no-mixed-spaces-and-tabs': 2,
|
|
||||||
'no-multi-spaces': 2,
|
|
||||||
'no-multi-str': 2,
|
|
||||||
'no-multiple-empty-lines': [2, {
|
|
||||||
'max': 1
|
|
||||||
}],
|
|
||||||
'no-native-reassign': 2,
|
|
||||||
'no-negated-in-lhs': 2,
|
|
||||||
'no-new-object': 2,
|
|
||||||
'no-new-require': 2,
|
|
||||||
'no-new-symbol': 2,
|
|
||||||
'no-new-wrappers': 2,
|
|
||||||
'no-obj-calls': 2,
|
|
||||||
'no-octal': 2,
|
|
||||||
'no-octal-escape': 2,
|
|
||||||
'no-path-concat': 2,
|
|
||||||
'no-proto': 2,
|
|
||||||
'no-redeclare': 2,
|
|
||||||
'no-regex-spaces': 2,
|
|
||||||
'no-return-assign': [2, 'except-parens'],
|
|
||||||
'no-self-assign': 2,
|
|
||||||
'no-self-compare': 2,
|
|
||||||
'no-sequences': 2,
|
|
||||||
'no-shadow-restricted-names': 2,
|
|
||||||
'no-spaced-func': 2,
|
|
||||||
'no-sparse-arrays': 2,
|
|
||||||
'no-this-before-super': 2,
|
|
||||||
'no-throw-literal': 2,
|
|
||||||
'no-trailing-spaces': 2,
|
|
||||||
'no-undef': 2,
|
|
||||||
'no-undef-init': 2,
|
|
||||||
'no-unexpected-multiline': 2,
|
|
||||||
'no-unmodified-loop-condition': 2,
|
|
||||||
'no-unneeded-ternary': [2, {
|
|
||||||
'defaultAssignment': false
|
|
||||||
}],
|
|
||||||
'no-unreachable': 2,
|
|
||||||
'no-unsafe-finally': 2,
|
|
||||||
'no-unused-vars': [2, {
|
|
||||||
'vars': 'all',
|
|
||||||
'args': 'none'
|
|
||||||
}],
|
|
||||||
'no-useless-call': 2,
|
|
||||||
'no-useless-computed-key': 2,
|
|
||||||
'no-useless-constructor': 2,
|
|
||||||
'no-useless-escape': 0,
|
|
||||||
'no-whitespace-before-property': 2,
|
|
||||||
'no-with': 2,
|
|
||||||
'one-var': [2, {
|
|
||||||
'initialized': 'never'
|
|
||||||
}],
|
|
||||||
'operator-linebreak': [2, 'after', {
|
|
||||||
'overrides': {
|
|
||||||
'?': 'before',
|
|
||||||
':': 'before'
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
'padded-blocks': [2, 'never'],
|
|
||||||
'quotes': [2, 'single', {
|
|
||||||
'avoidEscape': true,
|
|
||||||
'allowTemplateLiterals': true
|
|
||||||
}],
|
|
||||||
'semi': [2, 'never'],
|
|
||||||
'semi-spacing': [2, {
|
|
||||||
'before': false,
|
|
||||||
'after': true
|
|
||||||
}],
|
|
||||||
'space-before-blocks': [2, 'always'],
|
|
||||||
'space-before-function-paren': [2, 'never'],
|
|
||||||
'space-in-parens': [2, 'never'],
|
|
||||||
'space-infix-ops': 2,
|
|
||||||
'space-unary-ops': [2, {
|
|
||||||
'words': true,
|
|
||||||
'nonwords': false
|
|
||||||
}],
|
|
||||||
'spaced-comment': [2, 'always', {
|
|
||||||
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
|
|
||||||
}],
|
|
||||||
'template-curly-spacing': [2, 'never'],
|
|
||||||
'use-isnan': 2,
|
|
||||||
'valid-typeof': 2,
|
|
||||||
'wrap-iife': [2, 'any'],
|
|
||||||
'yield-star-spacing': [2, 'both'],
|
|
||||||
'yoda': [2, 'never'],
|
|
||||||
'prefer-const': 2,
|
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
|
||||||
'object-curly-spacing': [2, 'always', {
|
|
||||||
objectsInObjects: false
|
|
||||||
}],
|
|
||||||
'array-bracket-spacing': [2, 'never']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ruoyi",
|
"name": "ruoyi",
|
||||||
"version": "3.8.9",
|
"version": "3.9.0",
|
||||||
"description": "若依管理系统",
|
"description": "若依管理系统",
|
||||||
"author": "若依",
|
"author": "若依",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -8,19 +8,7 @@
|
|||||||
"dev": "vue-cli-service serve",
|
"dev": "vue-cli-service serve",
|
||||||
"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"
|
|
||||||
},
|
|
||||||
"husky": {
|
|
||||||
"hooks": {
|
|
||||||
"pre-commit": "lint-staged"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint-staged": {
|
|
||||||
"src/**/*.{js,vue}": [
|
|
||||||
"eslint --fix",
|
|
||||||
"git add"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"vue",
|
"vue",
|
||||||
@ -56,24 +44,17 @@
|
|||||||
"vue": "2.6.12",
|
"vue": "2.6.12",
|
||||||
"vue-count-to": "1.0.13",
|
"vue-count-to": "1.0.13",
|
||||||
"vue-cropper": "0.5.5",
|
"vue-cropper": "0.5.5",
|
||||||
"vue-meta": "2.4.0",
|
|
||||||
"vue-router": "3.4.9",
|
"vue-router": "3.4.9",
|
||||||
"vuedraggable": "2.24.3",
|
"vuedraggable": "2.24.3",
|
||||||
"vuex": "3.6.0"
|
"vuex": "3.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "4.4.6",
|
"@vue/cli-plugin-babel": "4.4.6",
|
||||||
"@vue/cli-plugin-eslint": "4.4.6",
|
|
||||||
"@vue/cli-service": "4.4.6",
|
"@vue/cli-service": "4.4.6",
|
||||||
"babel-eslint": "10.1.0",
|
|
||||||
"babel-plugin-dynamic-import-node": "2.3.3",
|
"babel-plugin-dynamic-import-node": "2.3.3",
|
||||||
"chalk": "4.1.0",
|
"chalk": "4.1.0",
|
||||||
"compression-webpack-plugin": "6.1.2",
|
"compression-webpack-plugin": "6.1.2",
|
||||||
"connect": "3.6.6",
|
"connect": "3.6.6",
|
||||||
"eslint": "7.15.0",
|
|
||||||
"eslint-plugin-vue": "7.2.0",
|
|
||||||
"lint-staged": "10.5.3",
|
|
||||||
"runjs": "4.4.2",
|
|
||||||
"sass": "1.32.13",
|
"sass": "1.32.13",
|
||||||
"sass-loader": "10.1.1",
|
"sass-loader": "10.1.1",
|
||||||
"script-ext-html-webpack-plugin": "2.1.5",
|
"script-ext-html-webpack-plugin": "2.1.5",
|
||||||
|
|||||||
@ -6,20 +6,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ThemePicker from "@/components/ThemePicker";
|
import ThemePicker from "@/components/ThemePicker"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
components: { ThemePicker },
|
components: { ThemePicker }
|
||||||
metaInfo() {
|
}
|
||||||
return {
|
|
||||||
title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
|
|
||||||
titleTemplate: title => {
|
|
||||||
return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
#app .theme-picker {
|
#app .theme-picker {
|
||||||
|
|||||||
1
ruoyi-ui/src/assets/icons/svg/enter.svg
Normal file
1
ruoyi-ui/src/assets/icons/svg/enter.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="1746590936918" class="icon" viewBox="0 0 1194 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5378" xmlns:xlink="http://www.w3.org/1999/xlink" width="233.203125" height="200"><path d="M1151.9144 325.11999969V89.12a57.04000031 57.04000031 0 0 0-28.8-49.44 58.15999969 58.15999969 0 0 0-57.76000031 0 57.04000031 57.04000031 0 0 0-28.8 49.44v235.99999969c0.24 84.31999969-33.6 152.56000031-94.08 212.00000062-60.07999969 59.83999969-141.84 80.64-227.04 80.4H225.91440031L388.07439969 457.11999969a56.80000031 56.80000031 0 0 0 12.40000031-62.16 57.76000031 57.76000031 0 0 0-94.00000031-18.63999938L48.8744 631.20000031a56.88 56.88 0 0 0 0 80.79999938l264.96 262.56a58.08 58.08 0 0 0 96.55999969-25.59999938 56.80000031 56.80000031 0 0 0-14.95999969-55.2L232.07439969 731.67999969h483.44000062c116.56000031 0 226.15999969-32.08000031 308.64-113.76 82.15999969-80.80000031 128.23999969-178.15999969 127.83999938-292.87999969" p-id="5379"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
1
ruoyi-ui/src/assets/icons/svg/more-up.svg
Normal file
1
ruoyi-ui/src/assets/icons/svg/more-up.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="1746760911144" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12537" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M395.21211 182.914448c0 62.669318 49.541323 113.472378 110.642936 113.472378 61.093427 0 110.652146-50.80306 110.65214601-113.472378 0-62.685691-49.559742-113.487727-110.65214601-113.487727C444.75241 69.426721 395.21211 120.22978 395.21211 182.914448zM395.21211 523.34693101c0 62.668295 49.541323 113.487727 110.642936 113.48772699 61.093427 0 110.652146-50.820456 110.652146-113.487727 0-62.669318-49.559742-113.472378-110.652146-113.472378C444.75241 409.874553 395.21211 460.67761301 395.21211 523.34693101zM395.21211 841.084529c0 62.686714 49.541323 113.488751 110.642936 113.488751 61.093427 0 110.652146-50.80203599 110.65214601-113.488751 0-62.669318-49.559742-113.471354-110.65214601-113.471354C444.75241 727.614198 395.21211 778.416234 395.21211 841.084529z" p-id="12538"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -129,10 +129,6 @@ aside {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination-container {
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-center {
|
.text-center {
|
||||||
text-align: center
|
text-align: center
|
||||||
}
|
}
|
||||||
|
|||||||
@ -117,11 +117,9 @@
|
|||||||
|
|
||||||
/** 表格布局 **/
|
/** 表格布局 **/
|
||||||
.pagination-container {
|
.pagination-container {
|
||||||
position: relative;
|
display: flex;
|
||||||
height: 32px;
|
justify-content: flex-end;
|
||||||
margin-bottom: 10px;
|
margin-top: 20px;
|
||||||
margin-top: 15px;
|
|
||||||
padding: 10px 20px !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tree border */
|
/* tree border */
|
||||||
@ -132,11 +130,6 @@
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination-container .el-pagination {
|
|
||||||
right: 0;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.pagination-container .el-pagination > .el-pagination__jump {
|
.pagination-container .el-pagination > .el-pagination__jump {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
@ -201,8 +194,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-box {
|
.card-box {
|
||||||
padding-right: 15px;
|
|
||||||
padding-left: 15px;
|
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
z-index: 1001;
|
z-index: 1001;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
-webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
|
-webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
|
||||||
box-shadow: 2px 0 6px rgba(0,21,41,.35);
|
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
// reset element-ui css
|
// reset element-ui css
|
||||||
.horizontal-collapse-transition {
|
.horizontal-collapse-transition {
|
||||||
|
|||||||
@ -71,58 +71,58 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
// 单选按钮值变化时
|
// 单选按钮值变化时
|
||||||
radioChange() {
|
radioChange() {
|
||||||
('day rachange');
|
('day rachange')
|
||||||
if (this.radioValue !== 2 && this.cron.week !== '?') {
|
if (this.radioValue !== 2 && this.cron.week !== '?') {
|
||||||
this.$emit('update', 'week', '?', 'day')
|
this.$emit('update', 'week', '?', 'day')
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (this.radioValue) {
|
switch (this.radioValue) {
|
||||||
case 1:
|
case 1:
|
||||||
this.$emit('update', 'day', '*');
|
this.$emit('update', 'day', '*')
|
||||||
break;
|
break
|
||||||
case 2:
|
case 2:
|
||||||
this.$emit('update', 'day', '?');
|
this.$emit('update', 'day', '?')
|
||||||
break;
|
break
|
||||||
case 3:
|
case 3:
|
||||||
this.$emit('update', 'day', this.cycleTotal);
|
this.$emit('update', 'day', this.cycleTotal)
|
||||||
break;
|
break
|
||||||
case 4:
|
case 4:
|
||||||
this.$emit('update', 'day', this.averageTotal);
|
this.$emit('update', 'day', this.averageTotal)
|
||||||
break;
|
break
|
||||||
case 5:
|
case 5:
|
||||||
this.$emit('update', 'day', this.workday + 'W');
|
this.$emit('update', 'day', this.workday + 'W')
|
||||||
break;
|
break
|
||||||
case 6:
|
case 6:
|
||||||
this.$emit('update', 'day', 'L');
|
this.$emit('update', 'day', 'L')
|
||||||
break;
|
break
|
||||||
case 7:
|
case 7:
|
||||||
this.$emit('update', 'day', this.checkboxString);
|
this.$emit('update', 'day', this.checkboxString)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
('day rachange end');
|
('day rachange end')
|
||||||
},
|
},
|
||||||
// 周期两个值变化时
|
// 周期两个值变化时
|
||||||
cycleChange() {
|
cycleChange() {
|
||||||
if (this.radioValue == '3') {
|
if (this.radioValue == '3') {
|
||||||
this.$emit('update', 'day', this.cycleTotal);
|
this.$emit('update', 'day', this.cycleTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 平均两个值变化时
|
// 平均两个值变化时
|
||||||
averageChange() {
|
averageChange() {
|
||||||
if (this.radioValue == '4') {
|
if (this.radioValue == '4') {
|
||||||
this.$emit('update', 'day', this.averageTotal);
|
this.$emit('update', 'day', this.averageTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 最近工作日值变化时
|
// 最近工作日值变化时
|
||||||
workdayChange() {
|
workdayChange() {
|
||||||
if (this.radioValue == '5') {
|
if (this.radioValue == '5') {
|
||||||
this.$emit('update', 'day', this.workdayCheck + 'W');
|
this.$emit('update', 'day', this.workdayCheck + 'W')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// checkbox值变化时
|
// checkbox值变化时
|
||||||
checkboxChange() {
|
checkboxChange() {
|
||||||
if (this.radioValue == '7') {
|
if (this.radioValue == '7') {
|
||||||
this.$emit('update', 'day', this.checkboxString);
|
this.$emit('update', 'day', this.checkboxString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -138,23 +138,23 @@ export default {
|
|||||||
cycleTotal: function () {
|
cycleTotal: function () {
|
||||||
const cycle01 = this.checkNum(this.cycle01, 1, 30)
|
const cycle01 = this.checkNum(this.cycle01, 1, 30)
|
||||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 31, 31)
|
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 31, 31)
|
||||||
return cycle01 + '-' + cycle02;
|
return cycle01 + '-' + cycle02
|
||||||
},
|
},
|
||||||
// 计算平均用到的值
|
// 计算平均用到的值
|
||||||
averageTotal: function () {
|
averageTotal: function () {
|
||||||
const average01 = this.checkNum(this.average01, 1, 30)
|
const average01 = this.checkNum(this.average01, 1, 30)
|
||||||
const average02 = this.checkNum(this.average02, 1, 31 - average01 || 0)
|
const average02 = this.checkNum(this.average02, 1, 31 - average01 || 0)
|
||||||
return average01 + '/' + average02;
|
return average01 + '/' + average02
|
||||||
},
|
},
|
||||||
// 计算工作日格式
|
// 计算工作日格式
|
||||||
workdayCheck: function () {
|
workdayCheck: function () {
|
||||||
const workday = this.checkNum(this.workday, 1, 31)
|
const workday = this.checkNum(this.workday, 1, 31)
|
||||||
return workday;
|
return workday
|
||||||
},
|
},
|
||||||
// 计算勾选的checkbox值合集
|
// 计算勾选的checkbox值合集
|
||||||
checkboxString: function () {
|
checkboxString: function () {
|
||||||
let str = this.checkboxList.join();
|
let str = this.checkboxList.join()
|
||||||
return str == '' ? '*' : str;
|
return str == '' ? '*' : str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,42 +52,42 @@ export default {
|
|||||||
// 单选按钮值变化时
|
// 单选按钮值变化时
|
||||||
radioChange() {
|
radioChange() {
|
||||||
if (this.cron.min === '*') {
|
if (this.cron.min === '*') {
|
||||||
this.$emit('update', 'min', '0', 'hour');
|
this.$emit('update', 'min', '0', 'hour')
|
||||||
}
|
}
|
||||||
if (this.cron.second === '*') {
|
if (this.cron.second === '*') {
|
||||||
this.$emit('update', 'second', '0', 'hour');
|
this.$emit('update', 'second', '0', 'hour')
|
||||||
}
|
}
|
||||||
switch (this.radioValue) {
|
switch (this.radioValue) {
|
||||||
case 1:
|
case 1:
|
||||||
this.$emit('update', 'hour', '*')
|
this.$emit('update', 'hour', '*')
|
||||||
break;
|
break
|
||||||
case 2:
|
case 2:
|
||||||
this.$emit('update', 'hour', this.cycleTotal);
|
this.$emit('update', 'hour', this.cycleTotal)
|
||||||
break;
|
break
|
||||||
case 3:
|
case 3:
|
||||||
this.$emit('update', 'hour', this.averageTotal);
|
this.$emit('update', 'hour', this.averageTotal)
|
||||||
break;
|
break
|
||||||
case 4:
|
case 4:
|
||||||
this.$emit('update', 'hour', this.checkboxString);
|
this.$emit('update', 'hour', this.checkboxString)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 周期两个值变化时
|
// 周期两个值变化时
|
||||||
cycleChange() {
|
cycleChange() {
|
||||||
if (this.radioValue == '2') {
|
if (this.radioValue == '2') {
|
||||||
this.$emit('update', 'hour', this.cycleTotal);
|
this.$emit('update', 'hour', this.cycleTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 平均两个值变化时
|
// 平均两个值变化时
|
||||||
averageChange() {
|
averageChange() {
|
||||||
if (this.radioValue == '3') {
|
if (this.radioValue == '3') {
|
||||||
this.$emit('update', 'hour', this.averageTotal);
|
this.$emit('update', 'hour', this.averageTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// checkbox值变化时
|
// checkbox值变化时
|
||||||
checkboxChange() {
|
checkboxChange() {
|
||||||
if (this.radioValue == '4') {
|
if (this.radioValue == '4') {
|
||||||
this.$emit('update', 'hour', this.checkboxString);
|
this.$emit('update', 'hour', this.checkboxString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -102,18 +102,18 @@ export default {
|
|||||||
cycleTotal: function () {
|
cycleTotal: function () {
|
||||||
const cycle01 = this.checkNum(this.cycle01, 0, 22)
|
const cycle01 = this.checkNum(this.cycle01, 0, 22)
|
||||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 23)
|
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 23)
|
||||||
return cycle01 + '-' + cycle02;
|
return cycle01 + '-' + cycle02
|
||||||
},
|
},
|
||||||
// 计算平均用到的值
|
// 计算平均用到的值
|
||||||
averageTotal: function () {
|
averageTotal: function () {
|
||||||
const average01 = this.checkNum(this.average01, 0, 22)
|
const average01 = this.checkNum(this.average01, 0, 22)
|
||||||
const average02 = this.checkNum(this.average02, 1, 23 - average01 || 0)
|
const average02 = this.checkNum(this.average02, 1, 23 - average01 || 0)
|
||||||
return average01 + '/' + average02;
|
return average01 + '/' + average02
|
||||||
},
|
},
|
||||||
// 计算勾选的checkbox值合集
|
// 计算勾选的checkbox值合集
|
||||||
checkboxString: function () {
|
checkboxString: function () {
|
||||||
let str = this.checkboxList.join();
|
let str = this.checkboxList.join()
|
||||||
return str == '' ? '*' : str;
|
return str == '' ? '*' : str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,14 +113,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CrontabSecond from "./second.vue";
|
import CrontabSecond from "./second.vue"
|
||||||
import CrontabMin from "./min.vue";
|
import CrontabMin from "./min.vue"
|
||||||
import CrontabHour from "./hour.vue";
|
import CrontabHour from "./hour.vue"
|
||||||
import CrontabDay from "./day.vue";
|
import CrontabDay from "./day.vue"
|
||||||
import CrontabMonth from "./month.vue";
|
import CrontabMonth from "./month.vue"
|
||||||
import CrontabWeek from "./week.vue";
|
import CrontabWeek from "./week.vue"
|
||||||
import CrontabYear from "./year.vue";
|
import CrontabYear from "./year.vue"
|
||||||
import CrontabResult from "./result.vue";
|
import CrontabResult from "./result.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@ -137,19 +137,19 @@ export default {
|
|||||||
week: "?",
|
week: "?",
|
||||||
year: "",
|
year: "",
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
name: "vcrontab",
|
name: "vcrontab",
|
||||||
props: ["expression", "hideComponent"],
|
props: ["expression", "hideComponent"],
|
||||||
methods: {
|
methods: {
|
||||||
shouldHide(key) {
|
shouldHide(key) {
|
||||||
if (this.hideComponent && this.hideComponent.includes(key)) return false;
|
if (this.hideComponent && this.hideComponent.includes(key)) return false
|
||||||
return true;
|
return true
|
||||||
},
|
},
|
||||||
resolveExp() {
|
resolveExp() {
|
||||||
// 反解析 表达式
|
// 反解析 表达式
|
||||||
if (this.expression) {
|
if (this.expression) {
|
||||||
let arr = this.expression.split(" ");
|
let arr = this.expression.split(" ")
|
||||||
if (arr.length >= 6) {
|
if (arr.length >= 6) {
|
||||||
//6 位以上是合法表达式
|
//6 位以上是合法表达式
|
||||||
let obj = {
|
let obj = {
|
||||||
@ -160,160 +160,160 @@ export default {
|
|||||||
month: arr[4],
|
month: arr[4],
|
||||||
week: arr[5],
|
week: arr[5],
|
||||||
year: arr[6] ? arr[6] : "",
|
year: arr[6] ? arr[6] : "",
|
||||||
};
|
}
|
||||||
this.crontabValueObj = {
|
this.crontabValueObj = {
|
||||||
...obj,
|
...obj,
|
||||||
};
|
}
|
||||||
for (let i in obj) {
|
for (let i in obj) {
|
||||||
if (obj[i]) this.changeRadio(i, obj[i]);
|
if (obj[i]) this.changeRadio(i, obj[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 没有传入的表达式 则还原
|
// 没有传入的表达式 则还原
|
||||||
this.clearCron();
|
this.clearCron()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// tab切换值
|
// tab切换值
|
||||||
tabCheck(index) {
|
tabCheck(index) {
|
||||||
this.tabActive = index;
|
this.tabActive = index
|
||||||
},
|
},
|
||||||
// 由子组件触发,更改表达式组成的字段值
|
// 由子组件触发,更改表达式组成的字段值
|
||||||
updateCrontabValue(name, value, from) {
|
updateCrontabValue(name, value, from) {
|
||||||
"updateCrontabValue", name, value, from;
|
"updateCrontabValue", name, value, from
|
||||||
this.crontabValueObj[name] = value;
|
this.crontabValueObj[name] = value
|
||||||
if (from && from !== name) {
|
if (from && from !== name) {
|
||||||
console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
|
console.log(`来自组件 ${from} 改变了 ${name} ${value}`)
|
||||||
this.changeRadio(name, value);
|
this.changeRadio(name, value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 赋值到组件
|
// 赋值到组件
|
||||||
changeRadio(name, value) {
|
changeRadio(name, value) {
|
||||||
let arr = ["second", "min", "hour", "month"],
|
let arr = ["second", "min", "hour", "month"],
|
||||||
refName = "cron" + name,
|
refName = "cron" + name,
|
||||||
insValue;
|
insValue
|
||||||
|
|
||||||
if (!this.$refs[refName]) return;
|
if (!this.$refs[refName]) return
|
||||||
|
|
||||||
if (arr.includes(name)) {
|
if (arr.includes(name)) {
|
||||||
if (value === "*") {
|
if (value === "*") {
|
||||||
insValue = 1;
|
insValue = 1
|
||||||
} else if (value.indexOf("-") > -1) {
|
} else if (value.indexOf("-") > -1) {
|
||||||
let indexArr = value.split("-");
|
let indexArr = value.split("-")
|
||||||
isNaN(indexArr[0])
|
isNaN(indexArr[0])
|
||||||
? (this.$refs[refName].cycle01 = 0)
|
? (this.$refs[refName].cycle01 = 0)
|
||||||
: (this.$refs[refName].cycle01 = indexArr[0]);
|
: (this.$refs[refName].cycle01 = indexArr[0])
|
||||||
this.$refs[refName].cycle02 = indexArr[1];
|
this.$refs[refName].cycle02 = indexArr[1]
|
||||||
insValue = 2;
|
insValue = 2
|
||||||
} else if (value.indexOf("/") > -1) {
|
} else if (value.indexOf("/") > -1) {
|
||||||
let indexArr = value.split("/");
|
let indexArr = value.split("/")
|
||||||
isNaN(indexArr[0])
|
isNaN(indexArr[0])
|
||||||
? (this.$refs[refName].average01 = 0)
|
? (this.$refs[refName].average01 = 0)
|
||||||
: (this.$refs[refName].average01 = indexArr[0]);
|
: (this.$refs[refName].average01 = indexArr[0])
|
||||||
this.$refs[refName].average02 = indexArr[1];
|
this.$refs[refName].average02 = indexArr[1]
|
||||||
insValue = 3;
|
insValue = 3
|
||||||
} else {
|
} else {
|
||||||
insValue = 4;
|
insValue = 4
|
||||||
this.$refs[refName].checkboxList = value.split(",");
|
this.$refs[refName].checkboxList = value.split(",")
|
||||||
}
|
}
|
||||||
} else if (name == "day") {
|
} else if (name == "day") {
|
||||||
if (value === "*") {
|
if (value === "*") {
|
||||||
insValue = 1;
|
insValue = 1
|
||||||
} else if (value == "?") {
|
} else if (value == "?") {
|
||||||
insValue = 2;
|
insValue = 2
|
||||||
} else if (value.indexOf("-") > -1) {
|
} else if (value.indexOf("-") > -1) {
|
||||||
let indexArr = value.split("-");
|
let indexArr = value.split("-")
|
||||||
isNaN(indexArr[0])
|
isNaN(indexArr[0])
|
||||||
? (this.$refs[refName].cycle01 = 0)
|
? (this.$refs[refName].cycle01 = 0)
|
||||||
: (this.$refs[refName].cycle01 = indexArr[0]);
|
: (this.$refs[refName].cycle01 = indexArr[0])
|
||||||
this.$refs[refName].cycle02 = indexArr[1];
|
this.$refs[refName].cycle02 = indexArr[1]
|
||||||
insValue = 3;
|
insValue = 3
|
||||||
} else if (value.indexOf("/") > -1) {
|
} else if (value.indexOf("/") > -1) {
|
||||||
let indexArr = value.split("/");
|
let indexArr = value.split("/")
|
||||||
isNaN(indexArr[0])
|
isNaN(indexArr[0])
|
||||||
? (this.$refs[refName].average01 = 0)
|
? (this.$refs[refName].average01 = 0)
|
||||||
: (this.$refs[refName].average01 = indexArr[0]);
|
: (this.$refs[refName].average01 = indexArr[0])
|
||||||
this.$refs[refName].average02 = indexArr[1];
|
this.$refs[refName].average02 = indexArr[1]
|
||||||
insValue = 4;
|
insValue = 4
|
||||||
} else if (value.indexOf("W") > -1) {
|
} else if (value.indexOf("W") > -1) {
|
||||||
let indexArr = value.split("W");
|
let indexArr = value.split("W")
|
||||||
isNaN(indexArr[0])
|
isNaN(indexArr[0])
|
||||||
? (this.$refs[refName].workday = 0)
|
? (this.$refs[refName].workday = 0)
|
||||||
: (this.$refs[refName].workday = indexArr[0]);
|
: (this.$refs[refName].workday = indexArr[0])
|
||||||
insValue = 5;
|
insValue = 5
|
||||||
} else if (value === "L") {
|
} else if (value === "L") {
|
||||||
insValue = 6;
|
insValue = 6
|
||||||
} else {
|
} else {
|
||||||
this.$refs[refName].checkboxList = value.split(",");
|
this.$refs[refName].checkboxList = value.split(",")
|
||||||
insValue = 7;
|
insValue = 7
|
||||||
}
|
}
|
||||||
} else if (name == "week") {
|
} else if (name == "week") {
|
||||||
if (value === "*") {
|
if (value === "*") {
|
||||||
insValue = 1;
|
insValue = 1
|
||||||
} else if (value == "?") {
|
} else if (value == "?") {
|
||||||
insValue = 2;
|
insValue = 2
|
||||||
} else if (value.indexOf("-") > -1) {
|
} else if (value.indexOf("-") > -1) {
|
||||||
let indexArr = value.split("-");
|
let indexArr = value.split("-")
|
||||||
isNaN(indexArr[0])
|
isNaN(indexArr[0])
|
||||||
? (this.$refs[refName].cycle01 = 0)
|
? (this.$refs[refName].cycle01 = 0)
|
||||||
: (this.$refs[refName].cycle01 = indexArr[0]);
|
: (this.$refs[refName].cycle01 = indexArr[0])
|
||||||
this.$refs[refName].cycle02 = indexArr[1];
|
this.$refs[refName].cycle02 = indexArr[1]
|
||||||
insValue = 3;
|
insValue = 3
|
||||||
} else if (value.indexOf("#") > -1) {
|
} else if (value.indexOf("#") > -1) {
|
||||||
let indexArr = value.split("#");
|
let indexArr = value.split("#")
|
||||||
isNaN(indexArr[0])
|
isNaN(indexArr[0])
|
||||||
? (this.$refs[refName].average01 = 1)
|
? (this.$refs[refName].average01 = 1)
|
||||||
: (this.$refs[refName].average01 = indexArr[0]);
|
: (this.$refs[refName].average01 = indexArr[0])
|
||||||
this.$refs[refName].average02 = indexArr[1];
|
this.$refs[refName].average02 = indexArr[1]
|
||||||
insValue = 4;
|
insValue = 4
|
||||||
} else if (value.indexOf("L") > -1) {
|
} else if (value.indexOf("L") > -1) {
|
||||||
let indexArr = value.split("L");
|
let indexArr = value.split("L")
|
||||||
isNaN(indexArr[0])
|
isNaN(indexArr[0])
|
||||||
? (this.$refs[refName].weekday = 1)
|
? (this.$refs[refName].weekday = 1)
|
||||||
: (this.$refs[refName].weekday = indexArr[0]);
|
: (this.$refs[refName].weekday = indexArr[0])
|
||||||
insValue = 5;
|
insValue = 5
|
||||||
} else {
|
} else {
|
||||||
this.$refs[refName].checkboxList = value.split(",");
|
this.$refs[refName].checkboxList = value.split(",")
|
||||||
insValue = 6;
|
insValue = 6
|
||||||
}
|
}
|
||||||
} else if (name == "year") {
|
} else if (name == "year") {
|
||||||
if (value == "") {
|
if (value == "") {
|
||||||
insValue = 1;
|
insValue = 1
|
||||||
} else if (value == "*") {
|
} else if (value == "*") {
|
||||||
insValue = 2;
|
insValue = 2
|
||||||
} else if (value.indexOf("-") > -1) {
|
} else if (value.indexOf("-") > -1) {
|
||||||
insValue = 3;
|
insValue = 3
|
||||||
} else if (value.indexOf("/") > -1) {
|
} else if (value.indexOf("/") > -1) {
|
||||||
insValue = 4;
|
insValue = 4
|
||||||
} else {
|
} else {
|
||||||
this.$refs[refName].checkboxList = value.split(",");
|
this.$refs[refName].checkboxList = value.split(",")
|
||||||
insValue = 5;
|
insValue = 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$refs[refName].radioValue = insValue;
|
this.$refs[refName].radioValue = insValue
|
||||||
},
|
},
|
||||||
// 表单选项的子组件校验数字格式(通过-props传递)
|
// 表单选项的子组件校验数字格式(通过-props传递)
|
||||||
checkNumber(value, minLimit, maxLimit) {
|
checkNumber(value, minLimit, maxLimit) {
|
||||||
// 检查必须为整数
|
// 检查必须为整数
|
||||||
value = Math.floor(value);
|
value = Math.floor(value)
|
||||||
if (value < minLimit) {
|
if (value < minLimit) {
|
||||||
value = minLimit;
|
value = minLimit
|
||||||
} else if (value > maxLimit) {
|
} else if (value > maxLimit) {
|
||||||
value = maxLimit;
|
value = maxLimit
|
||||||
}
|
}
|
||||||
return value;
|
return value
|
||||||
},
|
},
|
||||||
// 隐藏弹窗
|
// 隐藏弹窗
|
||||||
hidePopup() {
|
hidePopup() {
|
||||||
this.$emit("hide");
|
this.$emit("hide")
|
||||||
},
|
},
|
||||||
// 填充表达式
|
// 填充表达式
|
||||||
submitFill() {
|
submitFill() {
|
||||||
this.$emit("fill", this.crontabValueString);
|
this.$emit("fill", this.crontabValueString)
|
||||||
this.hidePopup();
|
this.hidePopup()
|
||||||
},
|
},
|
||||||
clearCron() {
|
clearCron() {
|
||||||
// 还原选择项
|
// 还原选择项
|
||||||
("准备还原");
|
("准备还原")
|
||||||
this.crontabValueObj = {
|
this.crontabValueObj = {
|
||||||
second: "*",
|
second: "*",
|
||||||
min: "*",
|
min: "*",
|
||||||
@ -322,15 +322,15 @@ export default {
|
|||||||
month: "*",
|
month: "*",
|
||||||
week: "?",
|
week: "?",
|
||||||
year: "",
|
year: "",
|
||||||
};
|
}
|
||||||
for (let j in this.crontabValueObj) {
|
for (let j in this.crontabValueObj) {
|
||||||
this.changeRadio(j, this.crontabValueObj[j]);
|
this.changeRadio(j, this.crontabValueObj[j])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
crontabValueString: function() {
|
crontabValueString: function() {
|
||||||
let obj = this.crontabValueObj;
|
let obj = this.crontabValueObj
|
||||||
let str =
|
let str =
|
||||||
obj.second +
|
obj.second +
|
||||||
" " +
|
" " +
|
||||||
@ -343,8 +343,8 @@ export default {
|
|||||||
obj.month +
|
obj.month +
|
||||||
" " +
|
" " +
|
||||||
obj.week +
|
obj.week +
|
||||||
(obj.year == "" ? "" : " " + obj.year);
|
(obj.year == "" ? "" : " " + obj.year)
|
||||||
return str;
|
return str
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
@ -364,9 +364,9 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted: function() {
|
mounted: function() {
|
||||||
this.resolveExp();
|
this.resolveExp()
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.pop_btn {
|
.pop_btn {
|
||||||
|
|||||||
@ -54,35 +54,35 @@ export default {
|
|||||||
radioChange() {
|
radioChange() {
|
||||||
switch (this.radioValue) {
|
switch (this.radioValue) {
|
||||||
case 1:
|
case 1:
|
||||||
this.$emit('update', 'min', '*', 'min');
|
this.$emit('update', 'min', '*', 'min')
|
||||||
break;
|
break
|
||||||
case 2:
|
case 2:
|
||||||
this.$emit('update', 'min', this.cycleTotal, 'min');
|
this.$emit('update', 'min', this.cycleTotal, 'min')
|
||||||
break;
|
break
|
||||||
case 3:
|
case 3:
|
||||||
this.$emit('update', 'min', this.averageTotal, 'min');
|
this.$emit('update', 'min', this.averageTotal, 'min')
|
||||||
break;
|
break
|
||||||
case 4:
|
case 4:
|
||||||
this.$emit('update', 'min', this.checkboxString, 'min');
|
this.$emit('update', 'min', this.checkboxString, 'min')
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 周期两个值变化时
|
// 周期两个值变化时
|
||||||
cycleChange() {
|
cycleChange() {
|
||||||
if (this.radioValue == '2') {
|
if (this.radioValue == '2') {
|
||||||
this.$emit('update', 'min', this.cycleTotal, 'min');
|
this.$emit('update', 'min', this.cycleTotal, 'min')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 平均两个值变化时
|
// 平均两个值变化时
|
||||||
averageChange() {
|
averageChange() {
|
||||||
if (this.radioValue == '3') {
|
if (this.radioValue == '3') {
|
||||||
this.$emit('update', 'min', this.averageTotal, 'min');
|
this.$emit('update', 'min', this.averageTotal, 'min')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// checkbox值变化时
|
// checkbox值变化时
|
||||||
checkboxChange() {
|
checkboxChange() {
|
||||||
if (this.radioValue == '4') {
|
if (this.radioValue == '4') {
|
||||||
this.$emit('update', 'min', this.checkboxString, 'min');
|
this.$emit('update', 'min', this.checkboxString, 'min')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -98,18 +98,18 @@ export default {
|
|||||||
cycleTotal: function () {
|
cycleTotal: function () {
|
||||||
const cycle01 = this.checkNum(this.cycle01, 0, 58)
|
const cycle01 = this.checkNum(this.cycle01, 0, 58)
|
||||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
|
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
|
||||||
return cycle01 + '-' + cycle02;
|
return cycle01 + '-' + cycle02
|
||||||
},
|
},
|
||||||
// 计算平均用到的值
|
// 计算平均用到的值
|
||||||
averageTotal: function () {
|
averageTotal: function () {
|
||||||
const average01 = this.checkNum(this.average01, 0, 58)
|
const average01 = this.checkNum(this.average01, 0, 58)
|
||||||
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
|
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
|
||||||
return average01 + '/' + average02;
|
return average01 + '/' + average02
|
||||||
},
|
},
|
||||||
// 计算勾选的checkbox值合集
|
// 计算勾选的checkbox值合集
|
||||||
checkboxString: function () {
|
checkboxString: function () {
|
||||||
let str = this.checkboxList.join();
|
let str = this.checkboxList.join()
|
||||||
return str == '' ? '*' : str;
|
return str == '' ? '*' : str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,35 +53,35 @@ export default {
|
|||||||
radioChange() {
|
radioChange() {
|
||||||
switch (this.radioValue) {
|
switch (this.radioValue) {
|
||||||
case 1:
|
case 1:
|
||||||
this.$emit('update', 'month', '*');
|
this.$emit('update', 'month', '*')
|
||||||
break;
|
break
|
||||||
case 2:
|
case 2:
|
||||||
this.$emit('update', 'month', this.cycleTotal);
|
this.$emit('update', 'month', this.cycleTotal)
|
||||||
break;
|
break
|
||||||
case 3:
|
case 3:
|
||||||
this.$emit('update', 'month', this.averageTotal);
|
this.$emit('update', 'month', this.averageTotal)
|
||||||
break;
|
break
|
||||||
case 4:
|
case 4:
|
||||||
this.$emit('update', 'month', this.checkboxString);
|
this.$emit('update', 'month', this.checkboxString)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 周期两个值变化时
|
// 周期两个值变化时
|
||||||
cycleChange() {
|
cycleChange() {
|
||||||
if (this.radioValue == '2') {
|
if (this.radioValue == '2') {
|
||||||
this.$emit('update', 'month', this.cycleTotal);
|
this.$emit('update', 'month', this.cycleTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 平均两个值变化时
|
// 平均两个值变化时
|
||||||
averageChange() {
|
averageChange() {
|
||||||
if (this.radioValue == '3') {
|
if (this.radioValue == '3') {
|
||||||
this.$emit('update', 'month', this.averageTotal);
|
this.$emit('update', 'month', this.averageTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// checkbox值变化时
|
// checkbox值变化时
|
||||||
checkboxChange() {
|
checkboxChange() {
|
||||||
if (this.radioValue == '4') {
|
if (this.radioValue == '4') {
|
||||||
this.$emit('update', 'month', this.checkboxString);
|
this.$emit('update', 'month', this.checkboxString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -96,18 +96,18 @@ export default {
|
|||||||
cycleTotal: function () {
|
cycleTotal: function () {
|
||||||
const cycle01 = this.checkNum(this.cycle01, 1, 11)
|
const cycle01 = this.checkNum(this.cycle01, 1, 11)
|
||||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 12)
|
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 12)
|
||||||
return cycle01 + '-' + cycle02;
|
return cycle01 + '-' + cycle02
|
||||||
},
|
},
|
||||||
// 计算平均用到的值
|
// 计算平均用到的值
|
||||||
averageTotal: function () {
|
averageTotal: function () {
|
||||||
const average01 = this.checkNum(this.average01, 1, 11)
|
const average01 = this.checkNum(this.average01, 1, 11)
|
||||||
const average02 = this.checkNum(this.average02, 1, 12 - average01 || 0)
|
const average02 = this.checkNum(this.average02, 1, 12 - average01 || 0)
|
||||||
return average01 + '/' + average02;
|
return average01 + '/' + average02
|
||||||
},
|
},
|
||||||
// 计算勾选的checkbox值合集
|
// 计算勾选的checkbox值合集
|
||||||
checkboxString: function () {
|
checkboxString: function () {
|
||||||
let str = this.checkboxList.join();
|
let str = this.checkboxList.join()
|
||||||
return str == '' ? '*' : str;
|
return str == '' ? '*' : str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,135 +27,135 @@ export default {
|
|||||||
expressionChange() {
|
expressionChange() {
|
||||||
|
|
||||||
// 计算开始-隐藏结果
|
// 计算开始-隐藏结果
|
||||||
this.isShow = false;
|
this.isShow = false
|
||||||
// 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年]
|
// 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年]
|
||||||
let ruleArr = this.$options.propsData.ex.split(' ');
|
let ruleArr = this.$options.propsData.ex.split(' ')
|
||||||
// 用于记录进入循环的次数
|
// 用于记录进入循环的次数
|
||||||
let nums = 0;
|
let nums = 0
|
||||||
// 用于暂时存符号时间规则结果的数组
|
// 用于暂时存符号时间规则结果的数组
|
||||||
let resultArr = [];
|
let resultArr = []
|
||||||
// 获取当前时间精确至[年、月、日、时、分、秒]
|
// 获取当前时间精确至[年、月、日、时、分、秒]
|
||||||
let nTime = new Date();
|
let nTime = new Date()
|
||||||
let nYear = nTime.getFullYear();
|
let nYear = nTime.getFullYear()
|
||||||
let nMonth = nTime.getMonth() + 1;
|
let nMonth = nTime.getMonth() + 1
|
||||||
let nDay = nTime.getDate();
|
let nDay = nTime.getDate()
|
||||||
let nHour = nTime.getHours();
|
let nHour = nTime.getHours()
|
||||||
let nMin = nTime.getMinutes();
|
let nMin = nTime.getMinutes()
|
||||||
let nSecond = nTime.getSeconds();
|
let nSecond = nTime.getSeconds()
|
||||||
// 根据规则获取到近100年可能年数组、月数组等等
|
// 根据规则获取到近100年可能年数组、月数组等等
|
||||||
this.getSecondArr(ruleArr[0]);
|
this.getSecondArr(ruleArr[0])
|
||||||
this.getMinArr(ruleArr[1]);
|
this.getMinArr(ruleArr[1])
|
||||||
this.getHourArr(ruleArr[2]);
|
this.getHourArr(ruleArr[2])
|
||||||
this.getDayArr(ruleArr[3]);
|
this.getDayArr(ruleArr[3])
|
||||||
this.getMonthArr(ruleArr[4]);
|
this.getMonthArr(ruleArr[4])
|
||||||
this.getWeekArr(ruleArr[5]);
|
this.getWeekArr(ruleArr[5])
|
||||||
this.getYearArr(ruleArr[6], nYear);
|
this.getYearArr(ruleArr[6], nYear)
|
||||||
// 将获取到的数组赋值-方便使用
|
// 将获取到的数组赋值-方便使用
|
||||||
let sDate = this.dateArr[0];
|
let sDate = this.dateArr[0]
|
||||||
let mDate = this.dateArr[1];
|
let mDate = this.dateArr[1]
|
||||||
let hDate = this.dateArr[2];
|
let hDate = this.dateArr[2]
|
||||||
let DDate = this.dateArr[3];
|
let DDate = this.dateArr[3]
|
||||||
let MDate = this.dateArr[4];
|
let MDate = this.dateArr[4]
|
||||||
let YDate = this.dateArr[5];
|
let YDate = this.dateArr[5]
|
||||||
// 获取当前时间在数组中的索引
|
// 获取当前时间在数组中的索引
|
||||||
let sIdx = this.getIndex(sDate, nSecond);
|
let sIdx = this.getIndex(sDate, nSecond)
|
||||||
let mIdx = this.getIndex(mDate, nMin);
|
let mIdx = this.getIndex(mDate, nMin)
|
||||||
let hIdx = this.getIndex(hDate, nHour);
|
let hIdx = this.getIndex(hDate, nHour)
|
||||||
let DIdx = this.getIndex(DDate, nDay);
|
let DIdx = this.getIndex(DDate, nDay)
|
||||||
let MIdx = this.getIndex(MDate, nMonth);
|
let MIdx = this.getIndex(MDate, nMonth)
|
||||||
let YIdx = this.getIndex(YDate, nYear);
|
let YIdx = this.getIndex(YDate, nYear)
|
||||||
// 重置月日时分秒的函数(后面用的比较多)
|
// 重置月日时分秒的函数(后面用的比较多)
|
||||||
const resetSecond = function () {
|
const resetSecond = function () {
|
||||||
sIdx = 0;
|
sIdx = 0
|
||||||
nSecond = sDate[sIdx]
|
nSecond = sDate[sIdx]
|
||||||
}
|
}
|
||||||
const resetMin = function () {
|
const resetMin = function () {
|
||||||
mIdx = 0;
|
mIdx = 0
|
||||||
nMin = mDate[mIdx]
|
nMin = mDate[mIdx]
|
||||||
resetSecond();
|
resetSecond()
|
||||||
}
|
}
|
||||||
const resetHour = function () {
|
const resetHour = function () {
|
||||||
hIdx = 0;
|
hIdx = 0
|
||||||
nHour = hDate[hIdx]
|
nHour = hDate[hIdx]
|
||||||
resetMin();
|
resetMin()
|
||||||
}
|
}
|
||||||
const resetDay = function () {
|
const resetDay = function () {
|
||||||
DIdx = 0;
|
DIdx = 0
|
||||||
nDay = DDate[DIdx]
|
nDay = DDate[DIdx]
|
||||||
resetHour();
|
resetHour()
|
||||||
}
|
}
|
||||||
const resetMonth = function () {
|
const resetMonth = function () {
|
||||||
MIdx = 0;
|
MIdx = 0
|
||||||
nMonth = MDate[MIdx]
|
nMonth = MDate[MIdx]
|
||||||
resetDay();
|
resetDay()
|
||||||
}
|
}
|
||||||
// 如果当前年份不为数组中当前值
|
// 如果当前年份不为数组中当前值
|
||||||
if (nYear !== YDate[YIdx]) {
|
if (nYear !== YDate[YIdx]) {
|
||||||
resetMonth();
|
resetMonth()
|
||||||
}
|
}
|
||||||
// 如果当前月份不为数组中当前值
|
// 如果当前月份不为数组中当前值
|
||||||
if (nMonth !== MDate[MIdx]) {
|
if (nMonth !== MDate[MIdx]) {
|
||||||
resetDay();
|
resetDay()
|
||||||
}
|
}
|
||||||
// 如果当前“日”不为数组中当前值
|
// 如果当前“日”不为数组中当前值
|
||||||
if (nDay !== DDate[DIdx]) {
|
if (nDay !== DDate[DIdx]) {
|
||||||
resetHour();
|
resetHour()
|
||||||
}
|
}
|
||||||
// 如果当前“时”不为数组中当前值
|
// 如果当前“时”不为数组中当前值
|
||||||
if (nHour !== hDate[hIdx]) {
|
if (nHour !== hDate[hIdx]) {
|
||||||
resetMin();
|
resetMin()
|
||||||
}
|
}
|
||||||
// 如果当前“分”不为数组中当前值
|
// 如果当前“分”不为数组中当前值
|
||||||
if (nMin !== mDate[mIdx]) {
|
if (nMin !== mDate[mIdx]) {
|
||||||
resetSecond();
|
resetSecond()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 循环年份数组
|
// 循环年份数组
|
||||||
goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
|
goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
|
||||||
let YY = YDate[Yi];
|
let YY = YDate[Yi]
|
||||||
// 如果到达最大值时
|
// 如果到达最大值时
|
||||||
if (nMonth > MDate[MDate.length - 1]) {
|
if (nMonth > MDate[MDate.length - 1]) {
|
||||||
resetMonth();
|
resetMonth()
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
// 循环月份数组
|
// 循环月份数组
|
||||||
goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
|
goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
|
||||||
// 赋值、方便后面运算
|
// 赋值、方便后面运算
|
||||||
let MM = MDate[Mi];
|
let MM = MDate[Mi];
|
||||||
MM = MM < 10 ? '0' + MM : MM;
|
MM = MM < 10 ? '0' + MM : MM
|
||||||
// 如果到达最大值时
|
// 如果到达最大值时
|
||||||
if (nDay > DDate[DDate.length - 1]) {
|
if (nDay > DDate[DDate.length - 1]) {
|
||||||
resetDay();
|
resetDay()
|
||||||
if (Mi == MDate.length - 1) {
|
if (Mi == MDate.length - 1) {
|
||||||
resetMonth();
|
resetMonth()
|
||||||
continue goYear;
|
continue goYear
|
||||||
}
|
}
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
// 循环日期数组
|
// 循环日期数组
|
||||||
goDay: for (let Di = DIdx; Di < DDate.length; Di++) {
|
goDay: for (let Di = DIdx; Di < DDate.length; Di++) {
|
||||||
// 赋值、方便后面运算
|
// 赋值、方便后面运算
|
||||||
let DD = DDate[Di];
|
let DD = DDate[Di]
|
||||||
let thisDD = DD < 10 ? '0' + DD : DD;
|
let thisDD = DD < 10 ? '0' + DD : DD
|
||||||
|
|
||||||
// 如果到达最大值时
|
// 如果到达最大值时
|
||||||
if (nHour > hDate[hDate.length - 1]) {
|
if (nHour > hDate[hDate.length - 1]) {
|
||||||
resetHour();
|
resetHour()
|
||||||
if (Di == DDate.length - 1) {
|
if (Di == DDate.length - 1) {
|
||||||
resetDay();
|
resetDay()
|
||||||
if (Mi == MDate.length - 1) {
|
if (Mi == MDate.length - 1) {
|
||||||
resetMonth();
|
resetMonth()
|
||||||
continue goYear;
|
continue goYear
|
||||||
}
|
}
|
||||||
continue goMonth;
|
continue goMonth
|
||||||
}
|
}
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断日期的合法性,不合法的话也是跳出当前循环
|
// 判断日期的合法性,不合法的话也是跳出当前循环
|
||||||
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') {
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') {
|
||||||
resetDay();
|
resetDay()
|
||||||
continue goMonth;
|
continue goMonth
|
||||||
}
|
}
|
||||||
// 如果日期规则中有值时
|
// 如果日期规则中有值时
|
||||||
if (this.dayRule == 'lastDay') {
|
if (this.dayRule == 'lastDay') {
|
||||||
@ -163,84 +163,83 @@ export default {
|
|||||||
|
|
||||||
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
DD--;
|
DD--
|
||||||
|
thisDD = DD < 10 ? '0' + DD : DD
|
||||||
thisDD = DD < 10 ? '0' + DD : DD;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (this.dayRule == 'workDay') {
|
} else if (this.dayRule == 'workDay') {
|
||||||
// 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
|
// 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
|
||||||
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
DD--;
|
DD--
|
||||||
thisDD = DD < 10 ? '0' + DD : DD;
|
thisDD = DD < 10 ? '0' + DD : DD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 获取达到条件的日期是星期X
|
// 获取达到条件的日期是星期X
|
||||||
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week')
|
||||||
// 当星期日时
|
// 当星期日时
|
||||||
if (thisWeek == 1) {
|
if (thisWeek == 1) {
|
||||||
// 先找下一个日,并判断是否为月底
|
// 先找下一个日,并判断是否为月底
|
||||||
DD++;
|
DD++
|
||||||
thisDD = DD < 10 ? '0' + DD : DD;
|
thisDD = DD < 10 ? '0' + DD : DD
|
||||||
// 判断下一日已经不是合法日期
|
// 判断下一日已经不是合法日期
|
||||||
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
DD -= 3;
|
DD -= 3
|
||||||
}
|
}
|
||||||
} else if (thisWeek == 7) {
|
} else if (thisWeek == 7) {
|
||||||
// 当星期6时只需判断不是1号就可进行操作
|
// 当星期6时只需判断不是1号就可进行操作
|
||||||
if (this.dayRuleSup !== 1) {
|
if (this.dayRuleSup !== 1) {
|
||||||
DD--;
|
DD--
|
||||||
} else {
|
} else {
|
||||||
DD += 2;
|
DD += 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (this.dayRule == 'weekDay') {
|
} else if (this.dayRule == 'weekDay') {
|
||||||
// 如果指定了是星期几
|
// 如果指定了是星期几
|
||||||
// 获取当前日期是属于星期几
|
// 获取当前日期是属于星期几
|
||||||
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week')
|
||||||
// 校验当前星期是否在星期池(dayRuleSup)中
|
// 校验当前星期是否在星期池(dayRuleSup)中
|
||||||
if (this.dayRuleSup.indexOf(thisWeek) < 0) {
|
if (this.dayRuleSup.indexOf(thisWeek) < 0) {
|
||||||
// 如果到达最大值时
|
// 如果到达最大值时
|
||||||
if (Di == DDate.length - 1) {
|
if (Di == DDate.length - 1) {
|
||||||
resetDay();
|
resetDay()
|
||||||
if (Mi == MDate.length - 1) {
|
if (Mi == MDate.length - 1) {
|
||||||
resetMonth();
|
resetMonth()
|
||||||
continue goYear;
|
continue goYear
|
||||||
}
|
}
|
||||||
continue goMonth;
|
continue goMonth
|
||||||
}
|
}
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
} else if (this.dayRule == 'assWeek') {
|
} else if (this.dayRule == 'assWeek') {
|
||||||
// 如果指定了是第几周的星期几
|
// 如果指定了是第几周的星期几
|
||||||
// 获取每月1号是属于星期几
|
// 获取每月1号是属于星期几
|
||||||
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week')
|
||||||
if (this.dayRuleSup[1] >= thisWeek) {
|
if (this.dayRuleSup[1] >= thisWeek) {
|
||||||
DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1;
|
DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1
|
||||||
} else {
|
} else {
|
||||||
DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1;
|
DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1
|
||||||
}
|
}
|
||||||
} else if (this.dayRule == 'lastWeek') {
|
} else if (this.dayRule == 'lastWeek') {
|
||||||
// 如果指定了每月最后一个星期几
|
// 如果指定了每月最后一个星期几
|
||||||
// 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
|
// 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
|
||||||
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
DD--;
|
DD--
|
||||||
thisDD = DD < 10 ? '0' + DD : DD;
|
thisDD = DD < 10 ? '0' + DD : DD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 获取月末最后一天是星期几
|
// 获取月末最后一天是星期几
|
||||||
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week')
|
||||||
// 找到要求中最近的那个星期几
|
// 找到要求中最近的那个星期几
|
||||||
if (this.dayRuleSup < thisWeek) {
|
if (this.dayRuleSup < thisWeek) {
|
||||||
DD -= thisWeek - this.dayRuleSup;
|
DD -= thisWeek - this.dayRuleSup
|
||||||
} else if (this.dayRuleSup > thisWeek) {
|
} else if (this.dayRuleSup > thisWeek) {
|
||||||
DD -= 7 - (this.dayRuleSup - thisWeek)
|
DD -= 7 - (this.dayRuleSup - thisWeek)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 判断时间值是否小于10置换成“05”这种格式
|
// 判断时间值是否小于10置换成“05”这种格式
|
||||||
DD = DD < 10 ? '0' + DD : DD;
|
DD = DD < 10 ? '0' + DD : DD
|
||||||
|
|
||||||
// 循环“时”数组
|
// 循环“时”数组
|
||||||
goHour: for (let hi = hIdx; hi < hDate.length; hi++) {
|
goHour: for (let hi = hIdx; hi < hDate.length; hi++) {
|
||||||
@ -248,76 +247,76 @@ export default {
|
|||||||
|
|
||||||
// 如果到达最大值时
|
// 如果到达最大值时
|
||||||
if (nMin > mDate[mDate.length - 1]) {
|
if (nMin > mDate[mDate.length - 1]) {
|
||||||
resetMin();
|
resetMin()
|
||||||
if (hi == hDate.length - 1) {
|
if (hi == hDate.length - 1) {
|
||||||
resetHour();
|
resetHour()
|
||||||
if (Di == DDate.length - 1) {
|
if (Di == DDate.length - 1) {
|
||||||
resetDay();
|
resetDay()
|
||||||
if (Mi == MDate.length - 1) {
|
if (Mi == MDate.length - 1) {
|
||||||
resetMonth();
|
resetMonth()
|
||||||
continue goYear;
|
continue goYear
|
||||||
}
|
}
|
||||||
continue goMonth;
|
continue goMonth
|
||||||
}
|
}
|
||||||
continue goDay;
|
continue goDay
|
||||||
}
|
}
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
// 循环"分"数组
|
// 循环"分"数组
|
||||||
goMin: for (let mi = mIdx; mi < mDate.length; mi++) {
|
goMin: for (let mi = mIdx; mi < mDate.length; mi++) {
|
||||||
let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi];
|
let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi]
|
||||||
|
|
||||||
// 如果到达最大值时
|
// 如果到达最大值时
|
||||||
if (nSecond > sDate[sDate.length - 1]) {
|
if (nSecond > sDate[sDate.length - 1]) {
|
||||||
resetSecond();
|
resetSecond()
|
||||||
if (mi == mDate.length - 1) {
|
if (mi == mDate.length - 1) {
|
||||||
resetMin();
|
resetMin()
|
||||||
if (hi == hDate.length - 1) {
|
if (hi == hDate.length - 1) {
|
||||||
resetHour();
|
resetHour()
|
||||||
if (Di == DDate.length - 1) {
|
if (Di == DDate.length - 1) {
|
||||||
resetDay();
|
resetDay()
|
||||||
if (Mi == MDate.length - 1) {
|
if (Mi == MDate.length - 1) {
|
||||||
resetMonth();
|
resetMonth()
|
||||||
continue goYear;
|
continue goYear
|
||||||
}
|
}
|
||||||
continue goMonth;
|
continue goMonth
|
||||||
}
|
}
|
||||||
continue goDay;
|
continue goDay
|
||||||
}
|
}
|
||||||
continue goHour;
|
continue goHour
|
||||||
}
|
}
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
// 循环"秒"数组
|
// 循环"秒"数组
|
||||||
goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) {
|
goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) {
|
||||||
let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si];
|
let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si]
|
||||||
// 添加当前时间(时间合法性在日期循环时已经判断)
|
// 添加当前时间(时间合法性在日期循环时已经判断)
|
||||||
if (MM !== '00' && DD !== '00') {
|
if (MM !== '00' && DD !== '00') {
|
||||||
resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
|
resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
|
||||||
nums++;
|
nums++
|
||||||
}
|
}
|
||||||
// 如果条数满了就退出循环
|
// 如果条数满了就退出循环
|
||||||
if (nums == 5) break goYear;
|
if (nums == 5) break goYear
|
||||||
// 如果到达最大值时
|
// 如果到达最大值时
|
||||||
if (si == sDate.length - 1) {
|
if (si == sDate.length - 1) {
|
||||||
resetSecond();
|
resetSecond()
|
||||||
if (mi == mDate.length - 1) {
|
if (mi == mDate.length - 1) {
|
||||||
resetMin();
|
resetMin()
|
||||||
if (hi == hDate.length - 1) {
|
if (hi == hDate.length - 1) {
|
||||||
resetHour();
|
resetHour()
|
||||||
if (Di == DDate.length - 1) {
|
if (Di == DDate.length - 1) {
|
||||||
resetDay();
|
resetDay()
|
||||||
if (Mi == MDate.length - 1) {
|
if (Mi == MDate.length - 1) {
|
||||||
resetMonth();
|
resetMonth()
|
||||||
continue goYear;
|
continue goYear
|
||||||
}
|
}
|
||||||
continue goMonth;
|
continue goMonth
|
||||||
}
|
}
|
||||||
continue goDay;
|
continue goDay
|
||||||
}
|
}
|
||||||
continue goHour;
|
continue goHour
|
||||||
}
|
}
|
||||||
continue goMin;
|
continue goMin
|
||||||
}
|
}
|
||||||
} //goSecond
|
} //goSecond
|
||||||
} //goMin
|
} //goMin
|
||||||
@ -327,33 +326,33 @@ export default {
|
|||||||
}
|
}
|
||||||
// 判断100年内的结果条数
|
// 判断100年内的结果条数
|
||||||
if (resultArr.length == 0) {
|
if (resultArr.length == 0) {
|
||||||
this.resultList = ['没有达到条件的结果!'];
|
this.resultList = ['没有达到条件的结果!']
|
||||||
} else {
|
} else {
|
||||||
this.resultList = resultArr;
|
this.resultList = resultArr
|
||||||
if (resultArr.length !== 5) {
|
if (resultArr.length !== 5) {
|
||||||
this.resultList.push('最近100年内只有上面' + resultArr.length + '条结果!')
|
this.resultList.push('最近100年内只有上面' + resultArr.length + '条结果!')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 计算完成-显示结果
|
// 计算完成-显示结果
|
||||||
this.isShow = true;
|
this.isShow = true
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
// 用于计算某位数字在数组中的索引
|
// 用于计算某位数字在数组中的索引
|
||||||
getIndex(arr, value) {
|
getIndex(arr, value) {
|
||||||
if (value <= arr[0] || value > arr[arr.length - 1]) {
|
if (value <= arr[0] || value > arr[arr.length - 1]) {
|
||||||
return 0;
|
return 0
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < arr.length - 1; i++) {
|
for (let i = 0; i < arr.length - 1; i++) {
|
||||||
if (value > arr[i] && value <= arr[i + 1]) {
|
if (value > arr[i] && value <= arr[i + 1]) {
|
||||||
return i + 1;
|
return i + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 获取"年"数组
|
// 获取"年"数组
|
||||||
getYearArr(rule, year) {
|
getYearArr(rule, year) {
|
||||||
this.dateArr[5] = this.getOrderArr(year, year + 100);
|
this.dateArr[5] = this.getOrderArr(year, year + 100)
|
||||||
if (rule !== undefined) {
|
if (rule !== undefined) {
|
||||||
if (rule.indexOf('-') >= 0) {
|
if (rule.indexOf('-') >= 0) {
|
||||||
this.dateArr[5] = this.getCycleArr(rule, year + 100, false)
|
this.dateArr[5] = this.getCycleArr(rule, year + 100, false)
|
||||||
@ -366,7 +365,7 @@ export default {
|
|||||||
},
|
},
|
||||||
// 获取"月"数组
|
// 获取"月"数组
|
||||||
getMonthArr(rule) {
|
getMonthArr(rule) {
|
||||||
this.dateArr[4] = this.getOrderArr(1, 12);
|
this.dateArr[4] = this.getOrderArr(1, 12)
|
||||||
if (rule.indexOf('-') >= 0) {
|
if (rule.indexOf('-') >= 0) {
|
||||||
this.dateArr[4] = this.getCycleArr(rule, 12, false)
|
this.dateArr[4] = this.getCycleArr(rule, 12, false)
|
||||||
} else if (rule.indexOf('/') >= 0) {
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
@ -380,58 +379,58 @@ export default {
|
|||||||
// 只有当日期规则的两个值均为“”时则表达日期是有选项的
|
// 只有当日期规则的两个值均为“”时则表达日期是有选项的
|
||||||
if (this.dayRule == '' && this.dayRuleSup == '') {
|
if (this.dayRule == '' && this.dayRuleSup == '') {
|
||||||
if (rule.indexOf('-') >= 0) {
|
if (rule.indexOf('-') >= 0) {
|
||||||
this.dayRule = 'weekDay';
|
this.dayRule = 'weekDay'
|
||||||
this.dayRuleSup = this.getCycleArr(rule, 7, false)
|
this.dayRuleSup = this.getCycleArr(rule, 7, false)
|
||||||
} else if (rule.indexOf('#') >= 0) {
|
} else if (rule.indexOf('#') >= 0) {
|
||||||
this.dayRule = 'assWeek';
|
this.dayRule = 'assWeek'
|
||||||
let matchRule = rule.match(/[0-9]{1}/g);
|
let matchRule = rule.match(/[0-9]{1}/g)
|
||||||
this.dayRuleSup = [Number(matchRule[1]), Number(matchRule[0])];
|
this.dayRuleSup = [Number(matchRule[1]), Number(matchRule[0])]
|
||||||
this.dateArr[3] = [1];
|
this.dateArr[3] = [1]
|
||||||
if (this.dayRuleSup[1] == 7) {
|
if (this.dayRuleSup[1] == 7) {
|
||||||
this.dayRuleSup[1] = 0;
|
this.dayRuleSup[1] = 0
|
||||||
}
|
}
|
||||||
} else if (rule.indexOf('L') >= 0) {
|
} else if (rule.indexOf('L') >= 0) {
|
||||||
this.dayRule = 'lastWeek';
|
this.dayRule = 'lastWeek'
|
||||||
this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
|
this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0])
|
||||||
this.dateArr[3] = [31];
|
this.dateArr[3] = [31]
|
||||||
if (this.dayRuleSup == 7) {
|
if (this.dayRuleSup == 7) {
|
||||||
this.dayRuleSup = 0;
|
this.dayRuleSup = 0
|
||||||
}
|
}
|
||||||
} else if (rule !== '*' && rule !== '?') {
|
} else if (rule !== '*' && rule !== '?') {
|
||||||
this.dayRule = 'weekDay';
|
this.dayRule = 'weekDay'
|
||||||
this.dayRuleSup = this.getAssignArr(rule)
|
this.dayRuleSup = this.getAssignArr(rule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 获取"日"数组-少量为日期规则
|
// 获取"日"数组-少量为日期规则
|
||||||
getDayArr(rule) {
|
getDayArr(rule) {
|
||||||
this.dateArr[3] = this.getOrderArr(1, 31);
|
this.dateArr[3] = this.getOrderArr(1, 31)
|
||||||
this.dayRule = '';
|
this.dayRule = ''
|
||||||
this.dayRuleSup = '';
|
this.dayRuleSup = ''
|
||||||
if (rule.indexOf('-') >= 0) {
|
if (rule.indexOf('-') >= 0) {
|
||||||
this.dateArr[3] = this.getCycleArr(rule, 31, false)
|
this.dateArr[3] = this.getCycleArr(rule, 31, false)
|
||||||
this.dayRuleSup = 'null';
|
this.dayRuleSup = 'null'
|
||||||
} else if (rule.indexOf('/') >= 0) {
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
this.dateArr[3] = this.getAverageArr(rule, 31)
|
this.dateArr[3] = this.getAverageArr(rule, 31)
|
||||||
this.dayRuleSup = 'null';
|
this.dayRuleSup = 'null'
|
||||||
} else if (rule.indexOf('W') >= 0) {
|
} else if (rule.indexOf('W') >= 0) {
|
||||||
this.dayRule = 'workDay';
|
this.dayRule = 'workDay'
|
||||||
this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
|
this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0])
|
||||||
this.dateArr[3] = [this.dayRuleSup];
|
this.dateArr[3] = [this.dayRuleSup]
|
||||||
} else if (rule.indexOf('L') >= 0) {
|
} else if (rule.indexOf('L') >= 0) {
|
||||||
this.dayRule = 'lastDay';
|
this.dayRule = 'lastDay'
|
||||||
this.dayRuleSup = 'null';
|
this.dayRuleSup = 'null'
|
||||||
this.dateArr[3] = [31];
|
this.dateArr[3] = [31]
|
||||||
} else if (rule !== '*' && rule !== '?') {
|
} else if (rule !== '*' && rule !== '?') {
|
||||||
this.dateArr[3] = this.getAssignArr(rule)
|
this.dateArr[3] = this.getAssignArr(rule)
|
||||||
this.dayRuleSup = 'null';
|
this.dayRuleSup = 'null'
|
||||||
} else if (rule == '*') {
|
} else if (rule == '*') {
|
||||||
this.dayRuleSup = 'null';
|
this.dayRuleSup = 'null'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 获取"时"数组
|
// 获取"时"数组
|
||||||
getHourArr(rule) {
|
getHourArr(rule) {
|
||||||
this.dateArr[2] = this.getOrderArr(0, 23);
|
this.dateArr[2] = this.getOrderArr(0, 23)
|
||||||
if (rule.indexOf('-') >= 0) {
|
if (rule.indexOf('-') >= 0) {
|
||||||
this.dateArr[2] = this.getCycleArr(rule, 24, true)
|
this.dateArr[2] = this.getCycleArr(rule, 24, true)
|
||||||
} else if (rule.indexOf('/') >= 0) {
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
@ -442,7 +441,7 @@ export default {
|
|||||||
},
|
},
|
||||||
// 获取"分"数组
|
// 获取"分"数组
|
||||||
getMinArr(rule) {
|
getMinArr(rule) {
|
||||||
this.dateArr[1] = this.getOrderArr(0, 59);
|
this.dateArr[1] = this.getOrderArr(0, 59)
|
||||||
if (rule.indexOf('-') >= 0) {
|
if (rule.indexOf('-') >= 0) {
|
||||||
this.dateArr[1] = this.getCycleArr(rule, 60, true)
|
this.dateArr[1] = this.getCycleArr(rule, 60, true)
|
||||||
} else if (rule.indexOf('/') >= 0) {
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
@ -453,7 +452,7 @@ export default {
|
|||||||
},
|
},
|
||||||
// 获取"秒"数组
|
// 获取"秒"数组
|
||||||
getSecondArr(rule) {
|
getSecondArr(rule) {
|
||||||
this.dateArr[0] = this.getOrderArr(0, 59);
|
this.dateArr[0] = this.getOrderArr(0, 59)
|
||||||
if (rule.indexOf('-') >= 0) {
|
if (rule.indexOf('-') >= 0) {
|
||||||
this.dateArr[0] = this.getCycleArr(rule, 60, true)
|
this.dateArr[0] = this.getCycleArr(rule, 60, true)
|
||||||
} else if (rule.indexOf('/') >= 0) {
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
@ -464,86 +463,86 @@ export default {
|
|||||||
},
|
},
|
||||||
// 根据传进来的min-max返回一个顺序的数组
|
// 根据传进来的min-max返回一个顺序的数组
|
||||||
getOrderArr(min, max) {
|
getOrderArr(min, max) {
|
||||||
let arr = [];
|
let arr = []
|
||||||
for (let i = min; i <= max; i++) {
|
for (let i = min; i <= max; i++) {
|
||||||
arr.push(i);
|
arr.push(i)
|
||||||
}
|
}
|
||||||
return arr;
|
return arr
|
||||||
},
|
},
|
||||||
// 根据规则中指定的零散值返回一个数组
|
// 根据规则中指定的零散值返回一个数组
|
||||||
getAssignArr(rule) {
|
getAssignArr(rule) {
|
||||||
let arr = [];
|
let arr = []
|
||||||
let assiginArr = rule.split(',');
|
let assiginArr = rule.split(',')
|
||||||
for (let i = 0; i < assiginArr.length; i++) {
|
for (let i = 0; i < assiginArr.length; i++) {
|
||||||
arr[i] = Number(assiginArr[i])
|
arr[i] = Number(assiginArr[i])
|
||||||
}
|
}
|
||||||
arr.sort(this.compare)
|
arr.sort(this.compare)
|
||||||
return arr;
|
return arr
|
||||||
},
|
},
|
||||||
// 根据一定算术规则计算返回一个数组
|
// 根据一定算术规则计算返回一个数组
|
||||||
getAverageArr(rule, limit) {
|
getAverageArr(rule, limit) {
|
||||||
let arr = [];
|
let arr = []
|
||||||
let agArr = rule.split('/');
|
let agArr = rule.split('/')
|
||||||
let min = Number(agArr[0]);
|
let min = Number(agArr[0])
|
||||||
let step = Number(agArr[1]);
|
let step = Number(agArr[1])
|
||||||
while (min <= limit) {
|
while (min <= limit) {
|
||||||
arr.push(min);
|
arr.push(min)
|
||||||
min += step;
|
min += step
|
||||||
}
|
}
|
||||||
return arr;
|
return arr
|
||||||
},
|
},
|
||||||
// 根据规则返回一个具有周期性的数组
|
// 根据规则返回一个具有周期性的数组
|
||||||
getCycleArr(rule, limit, status) {
|
getCycleArr(rule, limit, status) {
|
||||||
// status--表示是否从0开始(则从1开始)
|
// status--表示是否从0开始(则从1开始)
|
||||||
let arr = [];
|
let arr = []
|
||||||
let cycleArr = rule.split('-');
|
let cycleArr = rule.split('-')
|
||||||
let min = Number(cycleArr[0]);
|
let min = Number(cycleArr[0])
|
||||||
let max = Number(cycleArr[1]);
|
let max = Number(cycleArr[1])
|
||||||
if (min > max) {
|
if (min > max) {
|
||||||
max += limit;
|
max += limit
|
||||||
}
|
}
|
||||||
for (let i = min; i <= max; i++) {
|
for (let i = min; i <= max; i++) {
|
||||||
let add = 0;
|
let add = 0
|
||||||
if (status == false && i % limit == 0) {
|
if (status == false && i % limit == 0) {
|
||||||
add = limit;
|
add = limit
|
||||||
}
|
}
|
||||||
arr.push(Math.round(i % limit + add))
|
arr.push(Math.round(i % limit + add))
|
||||||
}
|
}
|
||||||
arr.sort(this.compare)
|
arr.sort(this.compare)
|
||||||
return arr;
|
return arr
|
||||||
},
|
},
|
||||||
// 比较数字大小(用于Array.sort)
|
// 比较数字大小(用于Array.sort)
|
||||||
compare(value1, value2) {
|
compare(value1, value2) {
|
||||||
if (value2 - value1 > 0) {
|
if (value2 - value1 > 0) {
|
||||||
return -1;
|
return -1
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 格式化日期格式如:2017-9-19 18:04:33
|
// 格式化日期格式如:2017-9-19 18:04:33
|
||||||
formatDate(value, type) {
|
formatDate(value, type) {
|
||||||
// 计算日期相关值
|
// 计算日期相关值
|
||||||
let time = typeof value == 'number' ? new Date(value) : value;
|
let time = typeof value == 'number' ? new Date(value) : value
|
||||||
let Y = time.getFullYear();
|
let Y = time.getFullYear()
|
||||||
let M = time.getMonth() + 1;
|
let M = time.getMonth() + 1
|
||||||
let D = time.getDate();
|
let D = time.getDate()
|
||||||
let h = time.getHours();
|
let h = time.getHours()
|
||||||
let m = time.getMinutes();
|
let m = time.getMinutes()
|
||||||
let s = time.getSeconds();
|
let s = time.getSeconds()
|
||||||
let week = time.getDay();
|
let week = time.getDay()
|
||||||
// 如果传递了type的话
|
// 如果传递了type的话
|
||||||
if (type == undefined) {
|
if (type == undefined) {
|
||||||
return Y + '-' + (M < 10 ? '0' + M : M) + '-' + (D < 10 ? '0' + D : D) + ' ' + (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
return Y + '-' + (M < 10 ? '0' + M : M) + '-' + (D < 10 ? '0' + D : D) + ' ' + (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s)
|
||||||
} else if (type == 'week') {
|
} else if (type == 'week') {
|
||||||
// 在quartz中 1为星期日
|
// 在quartz中 1为星期日
|
||||||
return week + 1;
|
return week + 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 检查日期是否存在
|
// 检查日期是否存在
|
||||||
checkDate(value) {
|
checkDate(value) {
|
||||||
let time = new Date(value);
|
let time = new Date(value)
|
||||||
let format = this.formatDate(time)
|
let format = this.formatDate(time)
|
||||||
return value === format;
|
return value === format
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -552,7 +551,7 @@ export default {
|
|||||||
props: ['ex'],
|
props: ['ex'],
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
// 初始化 获取一次结果
|
// 初始化 获取一次结果
|
||||||
this.expressionChange();
|
this.expressionChange()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -53,35 +53,35 @@ export default {
|
|||||||
radioChange() {
|
radioChange() {
|
||||||
switch (this.radioValue) {
|
switch (this.radioValue) {
|
||||||
case 1:
|
case 1:
|
||||||
this.$emit('update', 'second', '*', 'second');
|
this.$emit('update', 'second', '*', 'second')
|
||||||
break;
|
break
|
||||||
case 2:
|
case 2:
|
||||||
this.$emit('update', 'second', this.cycleTotal);
|
this.$emit('update', 'second', this.cycleTotal)
|
||||||
break;
|
break
|
||||||
case 3:
|
case 3:
|
||||||
this.$emit('update', 'second', this.averageTotal);
|
this.$emit('update', 'second', this.averageTotal)
|
||||||
break;
|
break
|
||||||
case 4:
|
case 4:
|
||||||
this.$emit('update', 'second', this.checkboxString);
|
this.$emit('update', 'second', this.checkboxString)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 周期两个值变化时
|
// 周期两个值变化时
|
||||||
cycleChange() {
|
cycleChange() {
|
||||||
if (this.radioValue == '2') {
|
if (this.radioValue == '2') {
|
||||||
this.$emit('update', 'second', this.cycleTotal);
|
this.$emit('update', 'second', this.cycleTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 平均两个值变化时
|
// 平均两个值变化时
|
||||||
averageChange() {
|
averageChange() {
|
||||||
if (this.radioValue == '3') {
|
if (this.radioValue == '3') {
|
||||||
this.$emit('update', 'second', this.averageTotal);
|
this.$emit('update', 'second', this.averageTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// checkbox值变化时
|
// checkbox值变化时
|
||||||
checkboxChange() {
|
checkboxChange() {
|
||||||
if (this.radioValue == '4') {
|
if (this.radioValue == '4') {
|
||||||
this.$emit('update', 'second', this.checkboxString);
|
this.$emit('update', 'second', this.checkboxString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -99,18 +99,18 @@ export default {
|
|||||||
cycleTotal: function () {
|
cycleTotal: function () {
|
||||||
const cycle01 = this.checkNum(this.cycle01, 0, 58)
|
const cycle01 = this.checkNum(this.cycle01, 0, 58)
|
||||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
|
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
|
||||||
return cycle01 + '-' + cycle02;
|
return cycle01 + '-' + cycle02
|
||||||
},
|
},
|
||||||
// 计算平均用到的值
|
// 计算平均用到的值
|
||||||
averageTotal: function () {
|
averageTotal: function () {
|
||||||
const average01 = this.checkNum(this.average01, 0, 58)
|
const average01 = this.checkNum(this.average01, 0, 58)
|
||||||
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
|
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
|
||||||
return average01 + '/' + average02;
|
return average01 + '/' + average02
|
||||||
},
|
},
|
||||||
// 计算勾选的checkbox值合集
|
// 计算勾选的checkbox值合集
|
||||||
checkboxString: function () {
|
checkboxString: function () {
|
||||||
let str = this.checkboxList.join();
|
let str = this.checkboxList.join()
|
||||||
return str == '' ? '*' : str;
|
return str == '' ? '*' : str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,52 +118,52 @@ export default {
|
|||||||
// 单选按钮值变化时
|
// 单选按钮值变化时
|
||||||
radioChange() {
|
radioChange() {
|
||||||
if (this.radioValue !== 2 && this.cron.day !== '?') {
|
if (this.radioValue !== 2 && this.cron.day !== '?') {
|
||||||
this.$emit('update', 'day', '?', 'week');
|
this.$emit('update', 'day', '?', 'week')
|
||||||
}
|
}
|
||||||
switch (this.radioValue) {
|
switch (this.radioValue) {
|
||||||
case 1:
|
case 1:
|
||||||
this.$emit('update', 'week', '*');
|
this.$emit('update', 'week', '*')
|
||||||
break;
|
break
|
||||||
case 2:
|
case 2:
|
||||||
this.$emit('update', 'week', '?');
|
this.$emit('update', 'week', '?')
|
||||||
break;
|
break
|
||||||
case 3:
|
case 3:
|
||||||
this.$emit('update', 'week', this.cycleTotal);
|
this.$emit('update', 'week', this.cycleTotal)
|
||||||
break;
|
break
|
||||||
case 4:
|
case 4:
|
||||||
this.$emit('update', 'week', this.averageTotal);
|
this.$emit('update', 'week', this.averageTotal)
|
||||||
break;
|
break
|
||||||
case 5:
|
case 5:
|
||||||
this.$emit('update', 'week', this.weekdayCheck + 'L');
|
this.$emit('update', 'week', this.weekdayCheck + 'L')
|
||||||
break;
|
break
|
||||||
case 6:
|
case 6:
|
||||||
this.$emit('update', 'week', this.checkboxString);
|
this.$emit('update', 'week', this.checkboxString)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 周期两个值变化时
|
// 周期两个值变化时
|
||||||
cycleChange() {
|
cycleChange() {
|
||||||
if (this.radioValue == '3') {
|
if (this.radioValue == '3') {
|
||||||
this.$emit('update', 'week', this.cycleTotal);
|
this.$emit('update', 'week', this.cycleTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 平均两个值变化时
|
// 平均两个值变化时
|
||||||
averageChange() {
|
averageChange() {
|
||||||
if (this.radioValue == '4') {
|
if (this.radioValue == '4') {
|
||||||
this.$emit('update', 'week', this.averageTotal);
|
this.$emit('update', 'week', this.averageTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 最近工作日值变化时
|
// 最近工作日值变化时
|
||||||
weekdayChange() {
|
weekdayChange() {
|
||||||
if (this.radioValue == '5') {
|
if (this.radioValue == '5') {
|
||||||
this.$emit('update', 'week', this.weekday + 'L');
|
this.$emit('update', 'week', this.weekday + 'L')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// checkbox值变化时
|
// checkbox值变化时
|
||||||
checkboxChange() {
|
checkboxChange() {
|
||||||
if (this.radioValue == '6') {
|
if (this.radioValue == '6') {
|
||||||
this.$emit('update', 'week', this.checkboxString);
|
this.$emit('update', 'week', this.checkboxString)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -179,23 +179,23 @@ export default {
|
|||||||
cycleTotal: function () {
|
cycleTotal: function () {
|
||||||
this.cycle01 = this.checkNum(this.cycle01, 1, 7)
|
this.cycle01 = this.checkNum(this.cycle01, 1, 7)
|
||||||
this.cycle02 = this.checkNum(this.cycle02, 1, 7)
|
this.cycle02 = this.checkNum(this.cycle02, 1, 7)
|
||||||
return this.cycle01 + '-' + this.cycle02;
|
return this.cycle01 + '-' + this.cycle02
|
||||||
},
|
},
|
||||||
// 计算平均用到的值
|
// 计算平均用到的值
|
||||||
averageTotal: function () {
|
averageTotal: function () {
|
||||||
this.average01 = this.checkNum(this.average01, 1, 4)
|
this.average01 = this.checkNum(this.average01, 1, 4)
|
||||||
this.average02 = this.checkNum(this.average02, 1, 7)
|
this.average02 = this.checkNum(this.average02, 1, 7)
|
||||||
return this.average02 + '#' + this.average01;
|
return this.average02 + '#' + this.average01
|
||||||
},
|
},
|
||||||
// 最近的工作日(格式)
|
// 最近的工作日(格式)
|
||||||
weekdayCheck: function () {
|
weekdayCheck: function () {
|
||||||
this.weekday = this.checkNum(this.weekday, 1, 7)
|
this.weekday = this.checkNum(this.weekday, 1, 7)
|
||||||
return this.weekday;
|
return this.weekday
|
||||||
},
|
},
|
||||||
// 计算勾选的checkbox值合集
|
// 计算勾选的checkbox值合集
|
||||||
checkboxString: function () {
|
checkboxString: function () {
|
||||||
let str = this.checkboxList.join();
|
let str = this.checkboxList.join()
|
||||||
return str == '' ? '*' : str;
|
return str == '' ? '*' : str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,38 +61,38 @@ export default {
|
|||||||
radioChange() {
|
radioChange() {
|
||||||
switch (this.radioValue) {
|
switch (this.radioValue) {
|
||||||
case 1:
|
case 1:
|
||||||
this.$emit('update', 'year', '');
|
this.$emit('update', 'year', '')
|
||||||
break;
|
break
|
||||||
case 2:
|
case 2:
|
||||||
this.$emit('update', 'year', '*');
|
this.$emit('update', 'year', '*')
|
||||||
break;
|
break
|
||||||
case 3:
|
case 3:
|
||||||
this.$emit('update', 'year', this.cycleTotal);
|
this.$emit('update', 'year', this.cycleTotal)
|
||||||
break;
|
break
|
||||||
case 4:
|
case 4:
|
||||||
this.$emit('update', 'year', this.averageTotal);
|
this.$emit('update', 'year', this.averageTotal)
|
||||||
break;
|
break
|
||||||
case 5:
|
case 5:
|
||||||
this.$emit('update', 'year', this.checkboxString);
|
this.$emit('update', 'year', this.checkboxString)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 周期两个值变化时
|
// 周期两个值变化时
|
||||||
cycleChange() {
|
cycleChange() {
|
||||||
if (this.radioValue == '3') {
|
if (this.radioValue == '3') {
|
||||||
this.$emit('update', 'year', this.cycleTotal);
|
this.$emit('update', 'year', this.cycleTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 平均两个值变化时
|
// 平均两个值变化时
|
||||||
averageChange() {
|
averageChange() {
|
||||||
if (this.radioValue == '4') {
|
if (this.radioValue == '4') {
|
||||||
this.$emit('update', 'year', this.averageTotal);
|
this.$emit('update', 'year', this.averageTotal)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// checkbox值变化时
|
// checkbox值变化时
|
||||||
checkboxChange() {
|
checkboxChange() {
|
||||||
if (this.radioValue == '5') {
|
if (this.radioValue == '5') {
|
||||||
this.$emit('update', 'year', this.checkboxString);
|
this.$emit('update', 'year', this.checkboxString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -107,23 +107,23 @@ export default {
|
|||||||
cycleTotal: function () {
|
cycleTotal: function () {
|
||||||
const cycle01 = this.checkNum(this.cycle01, this.fullYear, 2098)
|
const cycle01 = this.checkNum(this.cycle01, this.fullYear, 2098)
|
||||||
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : this.fullYear + 1, 2099)
|
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : this.fullYear + 1, 2099)
|
||||||
return cycle01 + '-' + cycle02;
|
return cycle01 + '-' + cycle02
|
||||||
},
|
},
|
||||||
// 计算平均用到的值
|
// 计算平均用到的值
|
||||||
averageTotal: function () {
|
averageTotal: function () {
|
||||||
const average01 = this.checkNum(this.average01, this.fullYear, 2098)
|
const average01 = this.checkNum(this.average01, this.fullYear, 2098)
|
||||||
const average02 = this.checkNum(this.average02, 1, 2099 - average01 || this.fullYear)
|
const average02 = this.checkNum(this.average02, 1, 2099 - average01 || this.fullYear)
|
||||||
return average01 + '/' + average02;
|
return average01 + '/' + average02
|
||||||
},
|
},
|
||||||
// 计算勾选的checkbox值合集
|
// 计算勾选的checkbox值合集
|
||||||
checkboxString: function () {
|
checkboxString: function () {
|
||||||
let str = this.checkboxList.join();
|
let str = this.checkboxList.join()
|
||||||
return str;
|
return str
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
// 仅获取当前年份
|
// 仅获取当前年份
|
||||||
this.fullYear = Number(new Date().getFullYear());
|
this.fullYear = Number(new Date().getFullYear())
|
||||||
this.cycle01 = this.fullYear
|
this.cycle01 = this.fullYear
|
||||||
this.average01 = this.fullYear
|
this.average01 = this.fullYear
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,13 +74,13 @@ export default {
|
|||||||
},
|
},
|
||||||
filters: {
|
filters: {
|
||||||
handleArray(array) {
|
handleArray(array) {
|
||||||
if (array.length === 0) return '';
|
if (array.length === 0) return ''
|
||||||
return array.reduce((pre, cur) => {
|
return array.reduce((pre, cur) => {
|
||||||
return pre + ' ' + cur;
|
return pre + ' ' + cur
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.el-tag + .el-tag {
|
.el-tag + .el-tag {
|
||||||
|
|||||||
@ -18,11 +18,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Quill from "quill";
|
import axios from "axios"
|
||||||
import "quill/dist/quill.core.css";
|
import Quill from "quill"
|
||||||
import "quill/dist/quill.snow.css";
|
import "quill/dist/quill.core.css"
|
||||||
import "quill/dist/quill.bubble.css";
|
import "quill/dist/quill.snow.css"
|
||||||
import { getToken } from "@/utils/auth";
|
import "quill/dist/quill.bubble.css"
|
||||||
|
import { getToken } from "@/utils/auth"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Editor",
|
name: "Editor",
|
||||||
@ -88,27 +89,27 @@ export default {
|
|||||||
placeholder: "请输入内容",
|
placeholder: "请输入内容",
|
||||||
readOnly: this.readOnly,
|
readOnly: this.readOnly,
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
styles() {
|
styles() {
|
||||||
let style = {};
|
let style = {}
|
||||||
if (this.minHeight) {
|
if (this.minHeight) {
|
||||||
style.minHeight = `${this.minHeight}px`;
|
style.minHeight = `${this.minHeight}px`
|
||||||
}
|
}
|
||||||
if (this.height) {
|
if (this.height) {
|
||||||
style.height = `${this.height}px`;
|
style.height = `${this.height}px`
|
||||||
}
|
}
|
||||||
return style;
|
return style
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value: {
|
value: {
|
||||||
handler(val) {
|
handler(val) {
|
||||||
if (val !== this.currentValue) {
|
if (val !== this.currentValue) {
|
||||||
this.currentValue = val === null ? "" : val;
|
this.currentValue = val === null ? "" : val
|
||||||
if (this.Quill) {
|
if (this.Quill) {
|
||||||
this.Quill.clipboard.dangerouslyPasteHTML(this.currentValue);
|
this.Quill.clipboard.dangerouslyPasteHTML(this.currentValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -116,84 +117,106 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.init();
|
this.init()
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.Quill = null;
|
this.Quill = null
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init() {
|
init() {
|
||||||
const editor = this.$refs.editor;
|
const editor = this.$refs.editor
|
||||||
this.Quill = new Quill(editor, this.options);
|
this.Quill = new Quill(editor, this.options)
|
||||||
// 如果设置了上传地址则自定义图片上传事件
|
// 如果设置了上传地址则自定义图片上传事件
|
||||||
if (this.type == 'url') {
|
if (this.type == 'url') {
|
||||||
let toolbar = this.Quill.getModule("toolbar");
|
let toolbar = this.Quill.getModule("toolbar")
|
||||||
toolbar.addHandler("image", (value) => {
|
toolbar.addHandler("image", (value) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
this.$refs.upload.$children[0].$refs.input.click();
|
this.$refs.upload.$children[0].$refs.input.click()
|
||||||
} else {
|
} else {
|
||||||
this.quill.format("image", false);
|
this.quill.format("image", false)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
this.Quill.root.addEventListener('paste', this.handlePasteCapture, true)
|
||||||
}
|
}
|
||||||
this.Quill.clipboard.dangerouslyPasteHTML(this.currentValue);
|
this.Quill.clipboard.dangerouslyPasteHTML(this.currentValue)
|
||||||
this.Quill.on("text-change", (delta, oldDelta, source) => {
|
this.Quill.on("text-change", (delta, oldDelta, source) => {
|
||||||
const html = this.$refs.editor.children[0].innerHTML;
|
const html = this.$refs.editor.children[0].innerHTML
|
||||||
const text = this.Quill.getText();
|
const text = this.Quill.getText()
|
||||||
const quill = this.Quill;
|
const quill = this.Quill
|
||||||
this.currentValue = html;
|
this.currentValue = html
|
||||||
this.$emit("input", html);
|
this.$emit("input", html)
|
||||||
this.$emit("on-change", { html, text, quill });
|
this.$emit("on-change", { html, text, quill })
|
||||||
});
|
})
|
||||||
this.Quill.on("text-change", (delta, oldDelta, source) => {
|
this.Quill.on("text-change", (delta, oldDelta, source) => {
|
||||||
this.$emit("on-text-change", delta, oldDelta, source);
|
this.$emit("on-text-change", delta, oldDelta, source)
|
||||||
});
|
})
|
||||||
this.Quill.on("selection-change", (range, oldRange, source) => {
|
this.Quill.on("selection-change", (range, oldRange, source) => {
|
||||||
this.$emit("on-selection-change", range, oldRange, source);
|
this.$emit("on-selection-change", range, oldRange, source)
|
||||||
});
|
})
|
||||||
this.Quill.on("editor-change", (eventName, ...args) => {
|
this.Quill.on("editor-change", (eventName, ...args) => {
|
||||||
this.$emit("on-editor-change", eventName, ...args);
|
this.$emit("on-editor-change", eventName, ...args)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// 上传前校检格式和大小
|
// 上传前校检格式和大小
|
||||||
handleBeforeUpload(file) {
|
handleBeforeUpload(file) {
|
||||||
const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"];
|
const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"]
|
||||||
const isJPG = type.includes(file.type);
|
const isJPG = type.includes(file.type)
|
||||||
// 检验文件格式
|
// 检验文件格式
|
||||||
if (!isJPG) {
|
if (!isJPG) {
|
||||||
this.$message.error(`图片格式错误!`);
|
this.$message.error(`图片格式错误!`)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
// 校检文件大小
|
// 校检文件大小
|
||||||
if (this.fileSize) {
|
if (this.fileSize) {
|
||||||
const isLt = file.size / 1024 / 1024 < this.fileSize;
|
const isLt = file.size / 1024 / 1024 < this.fileSize
|
||||||
if (!isLt) {
|
if (!isLt) {
|
||||||
this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
|
this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true
|
||||||
},
|
},
|
||||||
handleUploadSuccess(res, file) {
|
handleUploadSuccess(res, file) {
|
||||||
// 如果上传成功
|
// 如果上传成功
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
// 获取富文本组件实例
|
// 获取富文本组件实例
|
||||||
let quill = this.Quill;
|
let quill = this.Quill
|
||||||
// 获取光标所在位置
|
// 获取光标所在位置
|
||||||
let length = quill.getSelection().index;
|
let length = quill.getSelection().index
|
||||||
// 插入图片 res.url为服务器返回的图片地址
|
// 插入图片 res.url为服务器返回的图片地址
|
||||||
quill.insertEmbed(length, "image", process.env.VUE_APP_BASE_API + res.fileName);
|
quill.insertEmbed(length, "image", process.env.VUE_APP_BASE_API + res.fileName)
|
||||||
// 调整光标到最后
|
// 调整光标到最后
|
||||||
quill.setSelection(length + 1);
|
quill.setSelection(length + 1)
|
||||||
} else {
|
} else {
|
||||||
this.$message.error("图片插入失败");
|
this.$message.error("图片插入失败")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleUploadError() {
|
handleUploadError() {
|
||||||
this.$message.error("图片插入失败");
|
this.$message.error("图片插入失败")
|
||||||
},
|
},
|
||||||
},
|
// 复制粘贴图片处理
|
||||||
};
|
handlePasteCapture(e) {
|
||||||
|
const clipboard = e.clipboardData || window.clipboardData
|
||||||
|
if (clipboard && clipboard.items) {
|
||||||
|
for (let i = 0; i < clipboard.items.length; i++) {
|
||||||
|
const item = clipboard.items[i]
|
||||||
|
if (item.type.indexOf('image') !== -1) {
|
||||||
|
e.preventDefault()
|
||||||
|
const file = item.getAsFile()
|
||||||
|
this.insertImage(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
insertImage(file) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append("file", file)
|
||||||
|
axios.post(this.uploadUrl, formData, { headers: { "Content-Type": "multipart/form-data", Authorization: this.headers.Authorization } }).then(res => {
|
||||||
|
this.handleUploadSuccess(res.data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
:action="uploadFileUrl"
|
:action="uploadFileUrl"
|
||||||
:before-upload="handleBeforeUpload"
|
:before-upload="handleBeforeUpload"
|
||||||
:file-list="fileList"
|
:file-list="fileList"
|
||||||
|
:data="data"
|
||||||
:limit="limit"
|
:limit="limit"
|
||||||
:on-error="handleUploadError"
|
:on-error="handleUploadError"
|
||||||
:on-exceed="handleExceed"
|
:on-exceed="handleExceed"
|
||||||
@ -13,6 +14,7 @@
|
|||||||
:headers="headers"
|
:headers="headers"
|
||||||
class="upload-file-uploader"
|
class="upload-file-uploader"
|
||||||
ref="fileUpload"
|
ref="fileUpload"
|
||||||
|
v-if="!disabled"
|
||||||
>
|
>
|
||||||
<!-- 上传按钮 -->
|
<!-- 上传按钮 -->
|
||||||
<el-button size="mini" type="primary">选取文件</el-button>
|
<el-button size="mini" type="primary">选取文件</el-button>
|
||||||
@ -26,13 +28,13 @@
|
|||||||
</el-upload>
|
</el-upload>
|
||||||
|
|
||||||
<!-- 文件列表 -->
|
<!-- 文件列表 -->
|
||||||
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
|
<transition-group ref="uploadFileList" class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
|
||||||
<li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
|
<li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
|
||||||
<el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
|
<el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
|
||||||
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
||||||
</el-link>
|
</el-link>
|
||||||
<div class="ele-upload-list__item-content-action">
|
<div class="ele-upload-list__item-content-action">
|
||||||
<el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
|
<el-link :underline="false" @click="handleDelete(index)" type="danger" v-if="!disabled">删除</el-link>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
@ -40,32 +42,52 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getToken } from "@/utils/auth";
|
import { getToken } from "@/utils/auth"
|
||||||
|
import Sortable from 'sortablejs'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FileUpload",
|
name: "FileUpload",
|
||||||
props: {
|
props: {
|
||||||
// 值
|
// 值
|
||||||
value: [String, Object, Array],
|
value: [String, Object, Array],
|
||||||
|
// 上传接口地址
|
||||||
|
action: {
|
||||||
|
type: String,
|
||||||
|
default: "/common/upload"
|
||||||
|
},
|
||||||
|
// 上传携带的参数
|
||||||
|
data: {
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
// 数量限制
|
// 数量限制
|
||||||
limit: {
|
limit: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 5,
|
default: 5
|
||||||
},
|
},
|
||||||
// 大小限制(MB)
|
// 大小限制(MB)
|
||||||
fileSize: {
|
fileSize: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 5,
|
default: 5
|
||||||
},
|
},
|
||||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||||
fileType: {
|
fileType: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => ["doc", "xls", "ppt", "txt", "pdf"],
|
default: () => ["doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "pdf"]
|
||||||
},
|
},
|
||||||
// 是否显示提示
|
// 是否显示提示
|
||||||
isShowTip: {
|
isShowTip: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
// 禁用组件(仅查看文件)
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 拖动排序
|
||||||
|
drag: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@ -73,31 +95,46 @@ export default {
|
|||||||
number: 0,
|
number: 0,
|
||||||
uploadList: [],
|
uploadList: [],
|
||||||
baseUrl: process.env.VUE_APP_BASE_API,
|
baseUrl: process.env.VUE_APP_BASE_API,
|
||||||
uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传文件服务器地址
|
uploadFileUrl: process.env.VUE_APP_BASE_API + this.action, // 上传文件服务器地址
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: "Bearer " + getToken(),
|
Authorization: "Bearer " + getToken(),
|
||||||
},
|
},
|
||||||
fileList: [],
|
fileList: []
|
||||||
};
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.drag && !this.disabled) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const element = this.$refs.uploadFileList?.$el || this.$refs.uploadFileList
|
||||||
|
Sortable.create(element, {
|
||||||
|
ghostClass: 'file-upload-darg',
|
||||||
|
onEnd: (evt) => {
|
||||||
|
const movedItem = this.fileList.splice(evt.oldIndex, 1)[0]
|
||||||
|
this.fileList.splice(evt.newIndex, 0, movedItem)
|
||||||
|
this.$emit("input", this.listToString(this.fileList))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value: {
|
value: {
|
||||||
handler(val) {
|
handler(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
let temp = 1;
|
let temp = 1
|
||||||
// 首先将值转为数组
|
// 首先将值转为数组
|
||||||
const list = Array.isArray(val) ? val : this.value.split(',');
|
const list = Array.isArray(val) ? val : this.value.split(',')
|
||||||
// 然后将数组转为对象数组
|
// 然后将数组转为对象数组
|
||||||
this.fileList = list.map(item => {
|
this.fileList = list.map(item => {
|
||||||
if (typeof item === "string") {
|
if (typeof item === "string") {
|
||||||
item = { name: item, url: item };
|
item = { name: item, url: item }
|
||||||
}
|
}
|
||||||
item.uid = item.uid || new Date().getTime() + temp++;
|
item.uid = item.uid || new Date().getTime() + temp++
|
||||||
return item;
|
return item
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
this.fileList = [];
|
this.fileList = []
|
||||||
return [];
|
return []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
@ -107,7 +144,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
// 是否显示提示
|
// 是否显示提示
|
||||||
showTip() {
|
showTip() {
|
||||||
return this.isShowTip && (this.fileType || this.fileSize);
|
return this.isShowTip && (this.fileType || this.fileSize)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -115,91 +152,95 @@ export default {
|
|||||||
handleBeforeUpload(file) {
|
handleBeforeUpload(file) {
|
||||||
// 校检文件类型
|
// 校检文件类型
|
||||||
if (this.fileType) {
|
if (this.fileType) {
|
||||||
const fileName = file.name.split('.');
|
const fileName = file.name.split('.')
|
||||||
const fileExt = fileName[fileName.length - 1];
|
const fileExt = fileName[fileName.length - 1]
|
||||||
const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
|
const isTypeOk = this.fileType.indexOf(fileExt) >= 0
|
||||||
if (!isTypeOk) {
|
if (!isTypeOk) {
|
||||||
this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}格式文件!`);
|
this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}格式文件!`)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 校检文件名是否包含特殊字符
|
// 校检文件名是否包含特殊字符
|
||||||
if (file.name.includes(',')) {
|
if (file.name.includes(',')) {
|
||||||
this.$modal.msgError('文件名不正确,不能包含英文逗号!');
|
this.$modal.msgError('文件名不正确,不能包含英文逗号!')
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
// 校检文件大小
|
// 校检文件大小
|
||||||
if (this.fileSize) {
|
if (this.fileSize) {
|
||||||
const isLt = file.size / 1024 / 1024 < this.fileSize;
|
const isLt = file.size / 1024 / 1024 < this.fileSize
|
||||||
if (!isLt) {
|
if (!isLt) {
|
||||||
this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
|
this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$modal.loading("正在上传文件,请稍候...");
|
this.$modal.loading("正在上传文件,请稍候...")
|
||||||
this.number++;
|
this.number++
|
||||||
return true;
|
return true
|
||||||
},
|
},
|
||||||
// 文件个数超出
|
// 文件个数超出
|
||||||
handleExceed() {
|
handleExceed() {
|
||||||
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
|
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`)
|
||||||
},
|
},
|
||||||
// 上传失败
|
// 上传失败
|
||||||
handleUploadError(err) {
|
handleUploadError(err) {
|
||||||
this.$modal.msgError("上传文件失败,请重试");
|
this.$modal.msgError("上传文件失败,请重试")
|
||||||
this.$modal.closeLoading();
|
this.$modal.closeLoading()
|
||||||
},
|
},
|
||||||
// 上传成功回调
|
// 上传成功回调
|
||||||
handleUploadSuccess(res, file) {
|
handleUploadSuccess(res, file) {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.uploadList.push({ name: res.fileName, url: res.fileName });
|
this.uploadList.push({ name: res.fileName, url: res.fileName })
|
||||||
this.uploadedSuccessfully();
|
this.uploadedSuccessfully()
|
||||||
} else {
|
} else {
|
||||||
this.number--;
|
this.number--
|
||||||
this.$modal.closeLoading();
|
this.$modal.closeLoading()
|
||||||
this.$modal.msgError(res.msg);
|
this.$modal.msgError(res.msg)
|
||||||
this.$refs.fileUpload.handleRemove(file);
|
this.$refs.fileUpload.handleRemove(file)
|
||||||
this.uploadedSuccessfully();
|
this.uploadedSuccessfully()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 删除文件
|
// 删除文件
|
||||||
handleDelete(index) {
|
handleDelete(index) {
|
||||||
this.fileList.splice(index, 1);
|
this.fileList.splice(index, 1)
|
||||||
this.$emit("input", this.listToString(this.fileList));
|
this.$emit("input", this.listToString(this.fileList))
|
||||||
},
|
},
|
||||||
// 上传结束处理
|
// 上传结束处理
|
||||||
uploadedSuccessfully() {
|
uploadedSuccessfully() {
|
||||||
if (this.number > 0 && this.uploadList.length === this.number) {
|
if (this.number > 0 && this.uploadList.length === this.number) {
|
||||||
this.fileList = this.fileList.concat(this.uploadList);
|
this.fileList = this.fileList.concat(this.uploadList)
|
||||||
this.uploadList = [];
|
this.uploadList = []
|
||||||
this.number = 0;
|
this.number = 0
|
||||||
this.$emit("input", this.listToString(this.fileList));
|
this.$emit("input", this.listToString(this.fileList))
|
||||||
this.$modal.closeLoading();
|
this.$modal.closeLoading()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 获取文件名称
|
// 获取文件名称
|
||||||
getFileName(name) {
|
getFileName(name) {
|
||||||
// 如果是url那么取最后的名字 如果不是直接返回
|
// 如果是url那么取最后的名字 如果不是直接返回
|
||||||
if (name.lastIndexOf("/") > -1) {
|
if (name.lastIndexOf("/") > -1) {
|
||||||
return name.slice(name.lastIndexOf("/") + 1);
|
return name.slice(name.lastIndexOf("/") + 1)
|
||||||
} else {
|
} else {
|
||||||
return name;
|
return name
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 对象转成指定字符串分隔
|
// 对象转成指定字符串分隔
|
||||||
listToString(list, separator) {
|
listToString(list, separator) {
|
||||||
let strs = "";
|
let strs = ""
|
||||||
separator = separator || ",";
|
separator = separator || ","
|
||||||
for (let i in list) {
|
for (let i in list) {
|
||||||
strs += list[i].url + separator;
|
strs += list[i].url + separator
|
||||||
}
|
}
|
||||||
return strs != '' ? strs.substr(0, strs.length - 1) : '';
|
return strs != '' ? strs.substr(0, strs.length - 1) : ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.file-upload-darg {
|
||||||
|
opacity: 0.5;
|
||||||
|
background: #c8ebfb;
|
||||||
|
}
|
||||||
.upload-file-uploader {
|
.upload-file-uploader {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +1,49 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="{'show':show}" class="header-search">
|
<div class="header-search">
|
||||||
<svg-icon class-name="search-icon" icon-class="search" @click.stop="click" />
|
<svg-icon class-name="search-icon" icon-class="search" @click.stop="click" />
|
||||||
<el-select
|
<el-dialog
|
||||||
ref="headerSearchSelect"
|
:visible.sync="show"
|
||||||
v-model="search"
|
width="600px"
|
||||||
:remote-method="querySearch"
|
@close="close"
|
||||||
filterable
|
:show-close="false"
|
||||||
default-first-option
|
append-to-body
|
||||||
remote
|
|
||||||
placeholder="Search"
|
|
||||||
class="header-search-select"
|
|
||||||
@change="change"
|
|
||||||
>
|
>
|
||||||
<el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" />
|
<el-input
|
||||||
</el-select>
|
v-model="search"
|
||||||
|
ref="headerSearchSelectRef"
|
||||||
|
size="large"
|
||||||
|
@input="querySearch"
|
||||||
|
prefix-icon="el-icon-search"
|
||||||
|
placeholder="菜单搜索,支持标题、URL模糊查询"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="selectActiveResult"
|
||||||
|
@keydown.up.native="navigateResult('up')"
|
||||||
|
@keydown.down.native="navigateResult('down')"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
<el-scrollbar wrap-class="right-scrollbar-wrapper">
|
||||||
|
<div class="result-wrap">
|
||||||
|
<div class="search-item" v-for="(item, index) in options" :key="item.path" :style="activeStyle(index)" @mouseenter="activeIndex = index" @mouseleave="activeIndex = -1">
|
||||||
|
<div class="left">
|
||||||
|
<svg-icon class="menu-icon" :icon-class="item.icon" />
|
||||||
|
</div>
|
||||||
|
<div class="search-info" @click="change(item)">
|
||||||
|
<div class="menu-title">
|
||||||
|
{{ item.title.join(" / ") }}
|
||||||
|
</div>
|
||||||
|
<div class="menu-path">
|
||||||
|
{{ item.path }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<svg-icon icon-class="enter" v-show="index === activeIndex"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-scrollbar>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// fuse is a lightweight fuzzy-search module
|
|
||||||
// make search results more in line with expectations
|
|
||||||
import Fuse from 'fuse.js/dist/fuse.min.js'
|
import Fuse from 'fuse.js/dist/fuse.min.js'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { isHttp } from '@/utils/validate'
|
import { isHttp } from '@/utils/validate'
|
||||||
@ -31,13 +55,17 @@ export default {
|
|||||||
search: '',
|
search: '',
|
||||||
options: [],
|
options: [],
|
||||||
searchPool: [],
|
searchPool: [],
|
||||||
|
activeIndex: -1,
|
||||||
show: false,
|
show: false,
|
||||||
fuse: undefined
|
fuse: undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
theme() {
|
||||||
|
return this.$store.state.settings.theme
|
||||||
|
},
|
||||||
routes() {
|
routes() {
|
||||||
return this.$store.getters.permission_routes
|
return this.$store.getters.defaultRoutes
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -46,13 +74,6 @@ export default {
|
|||||||
},
|
},
|
||||||
searchPool(list) {
|
searchPool(list) {
|
||||||
this.initFuse(list)
|
this.initFuse(list)
|
||||||
},
|
|
||||||
show(value) {
|
|
||||||
if (value) {
|
|
||||||
document.body.addEventListener('click', this.close)
|
|
||||||
} else {
|
|
||||||
document.body.removeEventListener('click', this.close)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -63,23 +84,26 @@ export default {
|
|||||||
this.show = !this.show
|
this.show = !this.show
|
||||||
if (this.show) {
|
if (this.show) {
|
||||||
this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus()
|
this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus()
|
||||||
|
this.options = this.searchPool
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.blur()
|
this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.blur()
|
||||||
|
this.search = ''
|
||||||
this.options = []
|
this.options = []
|
||||||
this.show = false
|
this.show = false
|
||||||
|
this.activeIndex = -1
|
||||||
},
|
},
|
||||||
change(val) {
|
change(val) {
|
||||||
const path = val.path;
|
const path = val.path
|
||||||
const query = val.query;
|
const query = val.query
|
||||||
if(isHttp(val.path)) {
|
if(isHttp(val.path)) {
|
||||||
// http(s):// 路径新窗口打开
|
// http(s):// 路径新窗口打开
|
||||||
const pindex = path.indexOf("http");
|
const pindex = path.indexOf("http")
|
||||||
window.open(path.substr(pindex, path.length), "_blank");
|
window.open(path.substr(pindex, path.length), "_blank")
|
||||||
} else {
|
} else {
|
||||||
if (query) {
|
if (query) {
|
||||||
this.$router.push({ path: path, query: JSON.parse(query) });
|
this.$router.push({ path: path, query: JSON.parse(query) })
|
||||||
} else {
|
} else {
|
||||||
this.$router.push(path)
|
this.$router.push(path)
|
||||||
}
|
}
|
||||||
@ -117,11 +141,13 @@ export default {
|
|||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
path: !isHttp(router.path) ? path.resolve(basePath, router.path) : router.path,
|
path: !isHttp(router.path) ? path.resolve(basePath, router.path) : router.path,
|
||||||
title: [...prefixTitle]
|
title: [...prefixTitle],
|
||||||
|
icon: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
if (router.meta && router.meta.title) {
|
if (router.meta && router.meta.title) {
|
||||||
data.title = [...data.title, router.meta.title]
|
data.title = [...data.title, router.meta.title]
|
||||||
|
data.icon = router.meta.icon
|
||||||
|
|
||||||
if (router.redirect !== 'noRedirect') {
|
if (router.redirect !== 'noRedirect') {
|
||||||
// only push the routes with title
|
// only push the routes with title
|
||||||
@ -145,52 +171,94 @@ export default {
|
|||||||
return res
|
return res
|
||||||
},
|
},
|
||||||
querySearch(query) {
|
querySearch(query) {
|
||||||
|
this.activeIndex = -1
|
||||||
if (query !== '') {
|
if (query !== '') {
|
||||||
this.options = this.fuse.search(query)
|
this.options = this.fuse.search(query).map((item) => item.item) ?? this.searchPool
|
||||||
} else {
|
} else {
|
||||||
this.options = []
|
this.options = this.searchPool
|
||||||
|
}
|
||||||
|
},
|
||||||
|
activeStyle(index) {
|
||||||
|
if (index !== this.activeIndex) return {}
|
||||||
|
return {
|
||||||
|
"background-color": this.theme,
|
||||||
|
"color": "#fff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
navigateResult(direction) {
|
||||||
|
if (direction === "up") {
|
||||||
|
this.activeIndex = this.activeIndex <= 0 ? this.options.length - 1 : this.activeIndex - 1
|
||||||
|
} else if (direction === "down") {
|
||||||
|
this.activeIndex = this.activeIndex >= this.options.length - 1 ? 0 : this.activeIndex + 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectActiveResult() {
|
||||||
|
if (this.options.length > 0 && this.activeIndex >= 0) {
|
||||||
|
this.change(this.options[this.activeIndex])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang='scss' scoped>
|
||||||
.header-search {
|
::v-deep {
|
||||||
font-size: 0 !important;
|
.el-dialog__header {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-search {
|
||||||
.search-icon {
|
.search-icon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.header-search-select {
|
.result-wrap {
|
||||||
font-size: 18px;
|
height: 280px;
|
||||||
transition: width 0.2s;
|
margin: 6px 0;
|
||||||
width: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
background: transparent;
|
|
||||||
border-radius: 0;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
|
|
||||||
::v-deep .el-input__inner {
|
.search-item {
|
||||||
border-radius: 0;
|
display: flex;
|
||||||
border: 0;
|
height: 48px;
|
||||||
padding-left: 0;
|
align-items: center;
|
||||||
padding-right: 0;
|
padding-right: 10px;
|
||||||
box-shadow: none !important;
|
|
||||||
border-bottom: 1px solid #d9d9d9;
|
.left {
|
||||||
vertical-align: middle;
|
width: 60px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-info {
|
||||||
|
padding-left: 5px;
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.menu-title,
|
||||||
|
.menu-path {
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
.menu-path {
|
||||||
|
color: #ccc;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.show {
|
.search-item:hover {
|
||||||
.header-search-select {
|
cursor: pointer;
|
||||||
width: 210px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { isExternal } from "@/utils/validate";
|
import { isExternal } from "@/utils/validate"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ImagePreview",
|
name: "ImagePreview",
|
||||||
@ -33,36 +33,36 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
realSrc() {
|
realSrc() {
|
||||||
if (!this.src) {
|
if (!this.src) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
let real_src = this.src.split(",")[0];
|
let real_src = this.src.split(",")[0]
|
||||||
if (isExternal(real_src)) {
|
if (isExternal(real_src)) {
|
||||||
return real_src;
|
return real_src
|
||||||
}
|
}
|
||||||
return process.env.VUE_APP_BASE_API + real_src;
|
return process.env.VUE_APP_BASE_API + real_src
|
||||||
},
|
},
|
||||||
realSrcList() {
|
realSrcList() {
|
||||||
if (!this.src) {
|
if (!this.src) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
let real_src_list = this.src.split(",");
|
let real_src_list = this.src.split(",")
|
||||||
let srcList = [];
|
let srcList = []
|
||||||
real_src_list.forEach(item => {
|
real_src_list.forEach(item => {
|
||||||
if (isExternal(item)) {
|
if (isExternal(item)) {
|
||||||
return srcList.push(item);
|
return srcList.push(item)
|
||||||
}
|
}
|
||||||
return srcList.push(process.env.VUE_APP_BASE_API + item);
|
return srcList.push(process.env.VUE_APP_BASE_API + item)
|
||||||
});
|
})
|
||||||
return srcList;
|
return srcList
|
||||||
},
|
},
|
||||||
realWidth() {
|
realWidth() {
|
||||||
return typeof this.width == "string" ? this.width : `${this.width}px`;
|
return typeof this.width == "string" ? this.width : `${this.width}px`
|
||||||
},
|
},
|
||||||
realHeight() {
|
realHeight() {
|
||||||
return typeof this.height == "string" ? this.height : `${this.height}px`;
|
return typeof this.height == "string" ? this.height : `${this.height}px`
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -2,10 +2,12 @@
|
|||||||
<div class="component-upload-image">
|
<div class="component-upload-image">
|
||||||
<el-upload
|
<el-upload
|
||||||
multiple
|
multiple
|
||||||
|
:disabled="disabled"
|
||||||
:action="uploadImgUrl"
|
:action="uploadImgUrl"
|
||||||
list-type="picture-card"
|
list-type="picture-card"
|
||||||
:on-success="handleUploadSuccess"
|
:on-success="handleUploadSuccess"
|
||||||
:before-upload="handleBeforeUpload"
|
:before-upload="handleBeforeUpload"
|
||||||
|
:data="data"
|
||||||
:limit="limit"
|
:limit="limit"
|
||||||
:on-error="handleUploadError"
|
:on-error="handleUploadError"
|
||||||
:on-exceed="handleExceed"
|
:on-exceed="handleExceed"
|
||||||
@ -21,7 +23,7 @@
|
|||||||
</el-upload>
|
</el-upload>
|
||||||
|
|
||||||
<!-- 上传提示 -->
|
<!-- 上传提示 -->
|
||||||
<div class="el-upload__tip" slot="tip" v-if="showTip">
|
<div class="el-upload__tip" slot="tip" v-if="showTip && !disabled">
|
||||||
请上传
|
请上传
|
||||||
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
|
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
|
||||||
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
|
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
|
||||||
@ -43,31 +45,51 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getToken } from "@/utils/auth";
|
import { getToken } from "@/utils/auth"
|
||||||
import { isExternal } from "@/utils/validate";
|
import { isExternal } from "@/utils/validate"
|
||||||
|
import Sortable from 'sortablejs'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
value: [String, Object, Array],
|
value: [String, Object, Array],
|
||||||
|
// 上传接口地址
|
||||||
|
action: {
|
||||||
|
type: String,
|
||||||
|
default: "/common/upload"
|
||||||
|
},
|
||||||
|
// 上传携带的参数
|
||||||
|
data: {
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
// 图片数量限制
|
// 图片数量限制
|
||||||
limit: {
|
limit: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 5,
|
default: 5
|
||||||
},
|
},
|
||||||
// 大小限制(MB)
|
// 大小限制(MB)
|
||||||
fileSize: {
|
fileSize: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 5,
|
default: 5
|
||||||
},
|
},
|
||||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||||
fileType: {
|
fileType: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => ["png", "jpg", "jpeg"],
|
default: () => ["png", "jpg", "jpeg"]
|
||||||
},
|
},
|
||||||
// 是否显示提示
|
// 是否显示提示
|
||||||
isShowTip: {
|
isShowTip: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
// 禁用组件(仅查看图片)
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 拖动排序
|
||||||
|
drag: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@ -78,33 +100,47 @@ export default {
|
|||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
hideUpload: false,
|
hideUpload: false,
|
||||||
baseUrl: process.env.VUE_APP_BASE_API,
|
baseUrl: process.env.VUE_APP_BASE_API,
|
||||||
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
uploadImgUrl: process.env.VUE_APP_BASE_API + this.action, // 上传的图片服务器地址
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: "Bearer " + getToken(),
|
Authorization: "Bearer " + getToken(),
|
||||||
},
|
},
|
||||||
fileList: []
|
fileList: []
|
||||||
};
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.drag && !this.disabled) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const element = this.$refs.imageUpload?.$el?.querySelector('.el-upload-list')
|
||||||
|
Sortable.create(element, {
|
||||||
|
onEnd: (evt) => {
|
||||||
|
const movedItem = this.fileList.splice(evt.oldIndex, 1)[0]
|
||||||
|
this.fileList.splice(evt.newIndex, 0, movedItem)
|
||||||
|
this.$emit("input", this.listToString(this.fileList))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value: {
|
value: {
|
||||||
handler(val) {
|
handler(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
// 首先将值转为数组
|
// 首先将值转为数组
|
||||||
const list = Array.isArray(val) ? val : this.value.split(',');
|
const list = Array.isArray(val) ? val : this.value.split(',')
|
||||||
// 然后将数组转为对象数组
|
// 然后将数组转为对象数组
|
||||||
this.fileList = list.map(item => {
|
this.fileList = list.map(item => {
|
||||||
if (typeof item === "string") {
|
if (typeof item === "string") {
|
||||||
if (item.indexOf(this.baseUrl) === -1 && !isExternal(item)) {
|
if (item.indexOf(this.baseUrl) === -1 && !isExternal(item)) {
|
||||||
item = { name: this.baseUrl + item, url: this.baseUrl + item };
|
item = { name: this.baseUrl + item, url: this.baseUrl + item }
|
||||||
} else {
|
} else {
|
||||||
item = { name: item, url: item };
|
item = { name: item, url: item }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return item;
|
return item
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
this.fileList = [];
|
this.fileList = []
|
||||||
return [];
|
return []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
@ -114,113 +150,118 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
// 是否显示提示
|
// 是否显示提示
|
||||||
showTip() {
|
showTip() {
|
||||||
return this.isShowTip && (this.fileType || this.fileSize);
|
return this.isShowTip && (this.fileType || this.fileSize)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 上传前loading加载
|
// 上传前loading加载
|
||||||
handleBeforeUpload(file) {
|
handleBeforeUpload(file) {
|
||||||
let isImg = false;
|
let isImg = false
|
||||||
if (this.fileType.length) {
|
if (this.fileType.length) {
|
||||||
let fileExtension = "";
|
let fileExtension = ""
|
||||||
if (file.name.lastIndexOf(".") > -1) {
|
if (file.name.lastIndexOf(".") > -1) {
|
||||||
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
|
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1)
|
||||||
}
|
}
|
||||||
isImg = this.fileType.some(type => {
|
isImg = this.fileType.some(type => {
|
||||||
if (file.type.indexOf(type) > -1) return true;
|
if (file.type.indexOf(type) > -1) return true
|
||||||
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
|
if (fileExtension && fileExtension.indexOf(type) > -1) return true
|
||||||
return false;
|
return false
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
isImg = file.type.indexOf("image") > -1;
|
isImg = file.type.indexOf("image") > -1
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isImg) {
|
if (!isImg) {
|
||||||
this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}图片格式文件!`);
|
this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}图片格式文件!`)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
if (file.name.includes(',')) {
|
if (file.name.includes(',')) {
|
||||||
this.$modal.msgError('文件名不正确,不能包含英文逗号!');
|
this.$modal.msgError('文件名不正确,不能包含英文逗号!')
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
if (this.fileSize) {
|
if (this.fileSize) {
|
||||||
const isLt = file.size / 1024 / 1024 < this.fileSize;
|
const isLt = file.size / 1024 / 1024 < this.fileSize
|
||||||
if (!isLt) {
|
if (!isLt) {
|
||||||
this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
|
this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$modal.loading("正在上传图片,请稍候...");
|
this.$modal.loading("正在上传图片,请稍候...")
|
||||||
this.number++;
|
this.number++
|
||||||
},
|
},
|
||||||
// 文件个数超出
|
// 文件个数超出
|
||||||
handleExceed() {
|
handleExceed() {
|
||||||
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
|
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`)
|
||||||
},
|
},
|
||||||
// 上传成功回调
|
// 上传成功回调
|
||||||
handleUploadSuccess(res, file) {
|
handleUploadSuccess(res, file) {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.uploadList.push({ name: res.fileName, url: res.fileName });
|
this.uploadList.push({ name: res.fileName, url: res.fileName })
|
||||||
this.uploadedSuccessfully();
|
this.uploadedSuccessfully()
|
||||||
} else {
|
} else {
|
||||||
this.number--;
|
this.number--
|
||||||
this.$modal.closeLoading();
|
this.$modal.closeLoading()
|
||||||
this.$modal.msgError(res.msg);
|
this.$modal.msgError(res.msg)
|
||||||
this.$refs.imageUpload.handleRemove(file);
|
this.$refs.imageUpload.handleRemove(file)
|
||||||
this.uploadedSuccessfully();
|
this.uploadedSuccessfully()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 删除图片
|
// 删除图片
|
||||||
handleDelete(file) {
|
handleDelete(file) {
|
||||||
const findex = this.fileList.map(f => f.name).indexOf(file.name);
|
const findex = this.fileList.map(f => f.name).indexOf(file.name)
|
||||||
if (findex > -1) {
|
if (findex > -1) {
|
||||||
this.fileList.splice(findex, 1);
|
this.fileList.splice(findex, 1)
|
||||||
this.$emit("input", this.listToString(this.fileList));
|
this.$emit("input", this.listToString(this.fileList))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 上传失败
|
// 上传失败
|
||||||
handleUploadError() {
|
handleUploadError() {
|
||||||
this.$modal.msgError("上传图片失败,请重试");
|
this.$modal.msgError("上传图片失败,请重试")
|
||||||
this.$modal.closeLoading();
|
this.$modal.closeLoading()
|
||||||
},
|
},
|
||||||
// 上传结束处理
|
// 上传结束处理
|
||||||
uploadedSuccessfully() {
|
uploadedSuccessfully() {
|
||||||
if (this.number > 0 && this.uploadList.length === this.number) {
|
if (this.number > 0 && this.uploadList.length === this.number) {
|
||||||
this.fileList = this.fileList.concat(this.uploadList);
|
this.fileList = this.fileList.concat(this.uploadList)
|
||||||
this.uploadList = [];
|
this.uploadList = []
|
||||||
this.number = 0;
|
this.number = 0
|
||||||
this.$emit("input", this.listToString(this.fileList));
|
this.$emit("input", this.listToString(this.fileList))
|
||||||
this.$modal.closeLoading();
|
this.$modal.closeLoading()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 预览
|
// 预览
|
||||||
handlePictureCardPreview(file) {
|
handlePictureCardPreview(file) {
|
||||||
this.dialogImageUrl = file.url;
|
this.dialogImageUrl = file.url
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true
|
||||||
},
|
},
|
||||||
// 对象转成指定字符串分隔
|
// 对象转成指定字符串分隔
|
||||||
listToString(list, separator) {
|
listToString(list, separator) {
|
||||||
let strs = "";
|
let strs = ""
|
||||||
separator = separator || ",";
|
separator = separator || ","
|
||||||
for (let i in list) {
|
for (let i in list) {
|
||||||
if (list[i].url) {
|
if (list[i].url) {
|
||||||
strs += list[i].url.replace(this.baseUrl, "") + separator;
|
strs += list[i].url.replace(this.baseUrl, "") + separator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strs != '' ? strs.substr(0, strs.length - 1) : '';
|
return strs != '' ? strs.substr(0, strs.length - 1) : ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
// .el-upload--picture-card 控制加号部分
|
// .el-upload--picture-card 控制加号部分
|
||||||
::v-deep.hide .el-upload--picture-card {
|
::v-deep.hide .el-upload--picture-card {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::v-deep .el-upload-list--picture-card.is-disabled + .el-upload--picture-card {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
// 去掉动画效果
|
// 去掉动画效果
|
||||||
::v-deep .el-list-enter-active,
|
::v-deep .el-list-enter-active,
|
||||||
::v-deep .el-list-leave-active {
|
::v-deep .el-list-leave-active {
|
||||||
transition: all 0s;
|
transition: all 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .el-list-enter, .el-list-leave-active {
|
::v-deep .el-list-enter, .el-list-leave-active {
|
||||||
|
|||||||
@ -63,7 +63,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
currentPage: {
|
currentPage: {
|
||||||
@ -106,7 +106,6 @@ export default {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.pagination-container {
|
.pagination-container {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 32px 16px;
|
|
||||||
}
|
}
|
||||||
.pagination-container.hidden {
|
.pagination-container.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- eslint-disable-next-line -->
|
|
||||||
<div :style="{backgroundImage: `url(${image})`}" class="pan-thumb"></div>
|
<div :style="{backgroundImage: `url(${image})`}" class="pan-thumb"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,106 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div ref="rightPanel" class="rightPanel-container">
|
|
||||||
<div class="rightPanel-background" />
|
|
||||||
<div class="rightPanel">
|
|
||||||
<div class="rightPanel-items">
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'RightPanel',
|
|
||||||
props: {
|
|
||||||
clickNotClose: {
|
|
||||||
default: false,
|
|
||||||
type: Boolean
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
show: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.showSettings
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'showSettings',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
show(value) {
|
|
||||||
if (value && !this.clickNotClose) {
|
|
||||||
this.addEventClick()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.addEventClick()
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
const elx = this.$refs.rightPanel
|
|
||||||
elx.remove()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
addEventClick() {
|
|
||||||
window.addEventListener('click', this.closeSidebar)
|
|
||||||
},
|
|
||||||
closeSidebar(evt) {
|
|
||||||
const parent = evt.target.closest('.el-drawer__body')
|
|
||||||
if (!parent) {
|
|
||||||
this.show = false
|
|
||||||
window.removeEventListener('click', this.closeSidebar)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.rightPanel-background {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity .3s cubic-bezier(.7, .3, .1, 1);
|
|
||||||
background: rgba(0, 0, 0, .2);
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightPanel {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 260px;
|
|
||||||
height: 100vh;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
|
|
||||||
transition: all .25s cubic-bezier(.7, .3, .1, 1);
|
|
||||||
transform: translate(100%);
|
|
||||||
background: #fff;
|
|
||||||
z-index: 40000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.handle-button {
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
position: absolute;
|
|
||||||
left: -48px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24px;
|
|
||||||
border-radius: 6px 0 0 6px !important;
|
|
||||||
z-index: 0;
|
|
||||||
pointer-events: auto;
|
|
||||||
cursor: pointer;
|
|
||||||
color: #fff;
|
|
||||||
line-height: 48px;
|
|
||||||
i {
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 48px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -7,14 +7,19 @@
|
|||||||
<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-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="Object.keys(columns).length > 0">
|
||||||
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/>
|
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/>
|
||||||
<el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'">
|
<el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'">
|
||||||
<el-button size="mini" circle icon="el-icon-menu" />
|
<el-button size="mini" circle icon="el-icon-menu" />
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<template v-for="item in columns">
|
<!-- 全选/反选 按钮 -->
|
||||||
<el-dropdown-item :key="item.key">
|
<el-dropdown-item>
|
||||||
<el-checkbox :checked="item.visible" @change="checkboxChange($event, item.label)" :label="item.label" />
|
<el-checkbox :indeterminate="isIndeterminate" v-model="isChecked" @change="toggleCheckAll"> 列展示 </el-checkbox>
|
||||||
|
</el-dropdown-item>
|
||||||
|
<div class="check-line"></div>
|
||||||
|
<template v-for="(item, key) in columns">
|
||||||
|
<el-dropdown-item :key="key">
|
||||||
|
<el-checkbox v-model="item.visible" @change="checkboxChange($event, key)" :label="item.label" />
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
@ -25,12 +30,13 @@
|
|||||||
<el-transfer
|
<el-transfer
|
||||||
:titles="['显示', '隐藏']"
|
:titles="['显示', '隐藏']"
|
||||||
v-model="value"
|
v-model="value"
|
||||||
:data="columns"
|
:data="transferData"
|
||||||
@change="dataChange"
|
@change="dataChange"
|
||||||
></el-transfer>
|
></el-transfer>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "RightToolbar",
|
name: "RightToolbar",
|
||||||
@ -41,81 +47,126 @@ export default {
|
|||||||
// 弹出层标题
|
// 弹出层标题
|
||||||
title: "显示/隐藏",
|
title: "显示/隐藏",
|
||||||
// 是否显示弹出层
|
// 是否显示弹出层
|
||||||
open: false,
|
open: false
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
/* 是否显示检索条件 */
|
/* 是否显示检索条件 */
|
||||||
showSearch: {
|
showSearch: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true
|
||||||
},
|
},
|
||||||
/* 显隐列信息 */
|
/* 显隐列信息(数组格式、对象格式) */
|
||||||
columns: {
|
columns: {
|
||||||
type: Array,
|
type: [Array, Object],
|
||||||
|
default: () => ({})
|
||||||
},
|
},
|
||||||
/* 是否显示检索图标 */
|
/* 是否显示检索图标 */
|
||||||
search: {
|
search: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true
|
||||||
},
|
},
|
||||||
/* 显隐列类型(transfer穿梭框、checkbox复选框) */
|
/* 显隐列类型(transfer穿梭框、checkbox复选框) */
|
||||||
showColumnsType: {
|
showColumnsType: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "checkbox",
|
default: "checkbox"
|
||||||
},
|
},
|
||||||
/* 右外边距 */
|
/* 右外边距 */
|
||||||
gutter: {
|
gutter: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 10,
|
default: 10
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
style() {
|
style() {
|
||||||
const ret = {};
|
const ret = {}
|
||||||
if (this.gutter) {
|
if (this.gutter) {
|
||||||
ret.marginRight = `${this.gutter / 2}px`;
|
ret.marginRight = `${this.gutter / 2}px`
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
},
|
||||||
|
isChecked: {
|
||||||
|
get() {
|
||||||
|
return Array.isArray(this.columns) ? this.columns.every((col) => col.visible) : Object.values(this.columns).every((col) => col.visible)
|
||||||
|
},
|
||||||
|
set() {}
|
||||||
|
},
|
||||||
|
isIndeterminate() {
|
||||||
|
return Array.isArray(this.columns) ? this.columns.some((col) => col.visible) && !this.isChecked : Object.values(this.columns).some((col) => col.visible) && !this.isChecked
|
||||||
|
},
|
||||||
|
transferData() {
|
||||||
|
if (Array.isArray(this.columns)) {
|
||||||
|
return this.columns.map((item, index) => ({ key: index, label: item.label }))
|
||||||
|
} else {
|
||||||
|
return Object.keys(this.columns).map((key, index) => ({ key: index, label: this.columns[key].label }))
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.showColumnsType == 'transfer') {
|
if (this.showColumnsType == 'transfer') {
|
||||||
// 显隐列初始默认隐藏列
|
// transfer穿梭显隐列初始默认隐藏列
|
||||||
for (let item in this.columns) {
|
if (Array.isArray(this.columns)) {
|
||||||
if (this.columns[item].visible === false) {
|
for (let item in this.columns) {
|
||||||
this.value.push(parseInt(item));
|
if (this.columns[item].visible === false) {
|
||||||
|
this.value.push(parseInt(item))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Object.keys(this.columns).forEach((key, index) => {
|
||||||
|
if (this.columns[key].visible === false) {
|
||||||
|
this.value.push(index)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
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) {
|
dataChange(data) {
|
||||||
for (let item in this.columns) {
|
if (Array.isArray(this.columns)) {
|
||||||
const key = this.columns[item].key;
|
for (let item in this.columns) {
|
||||||
this.columns[item].visible = !data.includes(key);
|
const key = this.columns[item].key
|
||||||
|
this.columns[item].visible = !data.includes(key)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Object.keys(this.columns).forEach((key, index) => {
|
||||||
|
this.columns[key].visible = !data.includes(index)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 打开显隐列dialog
|
// 打开显隐列dialog
|
||||||
showColumn() {
|
showColumn() {
|
||||||
this.open = true;
|
this.open = true
|
||||||
},
|
},
|
||||||
// 勾选
|
// 单勾选
|
||||||
checkboxChange(event, label) {
|
checkboxChange(event, key) {
|
||||||
this.columns.filter(item => item.label == label)[0].visible = event;
|
if (Array.isArray(this.columns)) {
|
||||||
|
this.columns.filter(item => item.key == key)[0].visible = event
|
||||||
|
} else {
|
||||||
|
this.columns[key].visible = event
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 切换全选/反选
|
||||||
|
toggleCheckAll() {
|
||||||
|
const newValue = !this.isChecked
|
||||||
|
if (Array.isArray(this.columns)) {
|
||||||
|
this.columns.forEach((col) => (col.visible = newValue))
|
||||||
|
} else {
|
||||||
|
Object.values(this.columns).forEach((col) => (col.visible = newValue))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
::v-deep .el-transfer__button {
|
::v-deep .el-transfer__button {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@ -126,4 +177,10 @@ export default {
|
|||||||
::v-deep .el-transfer__button:first-child {
|
::v-deep .el-transfer__button:first-child {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
.check-line {
|
||||||
|
width: 90%;
|
||||||
|
height: 1px;
|
||||||
|
background-color: #ccc;
|
||||||
|
margin: 3px auto;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -51,6 +51,5 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -32,11 +32,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { constantRoutes } from "@/router";
|
import { constantRoutes } from "@/router"
|
||||||
import { isHttp } from "@/utils/validate";
|
import { isHttp } from "@/utils/validate"
|
||||||
|
|
||||||
// 隐藏侧边栏路由
|
// 隐藏侧边栏路由
|
||||||
const hideList = ['/index', '/user/profile'];
|
const hideList = ['/index', '/user/profile']
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@ -45,67 +45,67 @@ export default {
|
|||||||
visibleNumber: 5,
|
visibleNumber: 5,
|
||||||
// 当前激活菜单的 index
|
// 当前激活菜单的 index
|
||||||
currentIndex: undefined
|
currentIndex: undefined
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
theme() {
|
theme() {
|
||||||
return this.$store.state.settings.theme;
|
return this.$store.state.settings.theme
|
||||||
},
|
},
|
||||||
// 顶部显示菜单
|
// 顶部显示菜单
|
||||||
topMenus() {
|
topMenus() {
|
||||||
let topMenus = [];
|
let topMenus = []
|
||||||
this.routers.map((menu) => {
|
this.routers.map((menu) => {
|
||||||
if (menu.hidden !== true) {
|
if (menu.hidden !== true) {
|
||||||
// 兼容顶部栏一级菜单内部跳转
|
// 兼容顶部栏一级菜单内部跳转
|
||||||
if (menu.path === "/") {
|
if (menu.path === '/' && menu.children) {
|
||||||
topMenus.push(menu.children[0]);
|
topMenus.push(menu.children[0])
|
||||||
} else {
|
} else {
|
||||||
topMenus.push(menu);
|
topMenus.push(menu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
return topMenus;
|
return topMenus
|
||||||
},
|
},
|
||||||
// 所有的路由信息
|
// 所有的路由信息
|
||||||
routers() {
|
routers() {
|
||||||
return this.$store.state.permission.topbarRouters;
|
return this.$store.state.permission.topbarRouters
|
||||||
},
|
},
|
||||||
// 设置子路由
|
// 设置子路由
|
||||||
childrenMenus() {
|
childrenMenus() {
|
||||||
var childrenMenus = [];
|
var childrenMenus = []
|
||||||
this.routers.map((router) => {
|
this.routers.map((router) => {
|
||||||
for (var item in router.children) {
|
for (var item in router.children) {
|
||||||
if (router.children[item].parentPath === undefined) {
|
if (router.children[item].parentPath === undefined) {
|
||||||
if(router.path === "/") {
|
if(router.path === "/") {
|
||||||
router.children[item].path = "/" + router.children[item].path;
|
router.children[item].path = "/" + router.children[item].path
|
||||||
} else {
|
} else {
|
||||||
if(!isHttp(router.children[item].path)) {
|
if(!isHttp(router.children[item].path)) {
|
||||||
router.children[item].path = router.path + "/" + router.children[item].path;
|
router.children[item].path = router.path + "/" + router.children[item].path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
router.children[item].parentPath = router.path;
|
router.children[item].parentPath = router.path
|
||||||
}
|
}
|
||||||
childrenMenus.push(router.children[item]);
|
childrenMenus.push(router.children[item])
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
return constantRoutes.concat(childrenMenus);
|
return constantRoutes.concat(childrenMenus)
|
||||||
},
|
},
|
||||||
// 默认激活的菜单
|
// 默认激活的菜单
|
||||||
activeMenu() {
|
activeMenu() {
|
||||||
const path = this.$route.path;
|
const path = this.$route.path
|
||||||
let activePath = path;
|
let activePath = path
|
||||||
if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) {
|
if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) {
|
||||||
const tmpPath = path.substring(1, path.length);
|
const tmpPath = path.substring(1, path.length)
|
||||||
if (!this.$route.meta.link) {
|
if (!this.$route.meta.link) {
|
||||||
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"));
|
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"))
|
||||||
this.$store.dispatch('app/toggleSideBarHide', false);
|
this.$store.dispatch('app/toggleSideBarHide', false)
|
||||||
}
|
}
|
||||||
} else if(!this.$route.children) {
|
} else if(!this.$route.children) {
|
||||||
activePath = path;
|
activePath = path
|
||||||
this.$store.dispatch('app/toggleSideBarHide', true);
|
this.$store.dispatch('app/toggleSideBarHide', true)
|
||||||
}
|
}
|
||||||
this.activeRoutes(activePath);
|
this.activeRoutes(activePath)
|
||||||
return activePath;
|
return activePath
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
@ -115,55 +115,55 @@ export default {
|
|||||||
window.removeEventListener('resize', this.setVisibleNumber)
|
window.removeEventListener('resize', this.setVisibleNumber)
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.setVisibleNumber();
|
this.setVisibleNumber()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 根据宽度计算设置显示栏数
|
// 根据宽度计算设置显示栏数
|
||||||
setVisibleNumber() {
|
setVisibleNumber() {
|
||||||
const width = document.body.getBoundingClientRect().width / 3;
|
const width = document.body.getBoundingClientRect().width / 3
|
||||||
this.visibleNumber = parseInt(width / 85);
|
this.visibleNumber = parseInt(width / 85)
|
||||||
},
|
},
|
||||||
// 菜单选择事件
|
// 菜单选择事件
|
||||||
handleSelect(key, keyPath) {
|
handleSelect(key, keyPath) {
|
||||||
this.currentIndex = key;
|
this.currentIndex = key
|
||||||
const route = this.routers.find(item => item.path === key);
|
const route = this.routers.find(item => item.path === key)
|
||||||
if (isHttp(key)) {
|
if (isHttp(key)) {
|
||||||
// http(s):// 路径新窗口打开
|
// http(s):// 路径新窗口打开
|
||||||
window.open(key, "_blank");
|
window.open(key, "_blank")
|
||||||
} else if (!route || !route.children) {
|
} else if (!route || !route.children) {
|
||||||
// 没有子路由路径内部打开
|
// 没有子路由路径内部打开
|
||||||
const routeMenu = this.childrenMenus.find(item => item.path === key);
|
const routeMenu = this.childrenMenus.find(item => item.path === key)
|
||||||
if (routeMenu && routeMenu.query) {
|
if (routeMenu && routeMenu.query) {
|
||||||
let query = JSON.parse(routeMenu.query);
|
let query = JSON.parse(routeMenu.query)
|
||||||
this.$router.push({ path: key, query: query });
|
this.$router.push({ path: key, query: query })
|
||||||
} else {
|
} else {
|
||||||
this.$router.push({ path: key });
|
this.$router.push({ path: key })
|
||||||
}
|
}
|
||||||
this.$store.dispatch('app/toggleSideBarHide', true);
|
this.$store.dispatch('app/toggleSideBarHide', true)
|
||||||
} else {
|
} else {
|
||||||
// 显示左侧联动菜单
|
// 显示左侧联动菜单
|
||||||
this.activeRoutes(key);
|
this.activeRoutes(key)
|
||||||
this.$store.dispatch('app/toggleSideBarHide', false);
|
this.$store.dispatch('app/toggleSideBarHide', false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 当前激活的路由
|
// 当前激活的路由
|
||||||
activeRoutes(key) {
|
activeRoutes(key) {
|
||||||
var routes = [];
|
var routes = []
|
||||||
if (this.childrenMenus && this.childrenMenus.length > 0) {
|
if (this.childrenMenus && this.childrenMenus.length > 0) {
|
||||||
this.childrenMenus.map((item) => {
|
this.childrenMenus.map((item) => {
|
||||||
if (key == item.parentPath || (key == "index" && "" == item.path)) {
|
if (key == item.parentPath || (key == "index" && "" == item.path)) {
|
||||||
routes.push(item);
|
routes.push(item)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
if(routes.length > 0) {
|
if(routes.length > 0) {
|
||||||
this.$store.commit("SET_SIDEBAR_ROUTERS", routes);
|
this.$store.commit("SET_SIDEBAR_ROUTERS", routes)
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('app/toggleSideBarHide', true);
|
this.$store.dispatch('app/toggleSideBarHide', true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@ -21,16 +21,16 @@ export default {
|
|||||||
height: document.documentElement.clientHeight - 94.5 + "px;",
|
height: document.documentElement.clientHeight - 94.5 + "px;",
|
||||||
loading: true,
|
loading: true,
|
||||||
url: this.src
|
url: this.src
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
}, 300);
|
}, 300)
|
||||||
const that = this;
|
const that = this
|
||||||
window.onresize = function temp() {
|
window.onresize = function temp() {
|
||||||
that.height = document.documentElement.clientHeight - 94.5 + "px;";
|
that.height = document.documentElement.clientHeight - 94.5 + "px;"
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -8,57 +8,57 @@ export default {
|
|||||||
const value = binding.value
|
const value = binding.value
|
||||||
if (value == false) return
|
if (value == false) return
|
||||||
// 获取拖拽内容头部
|
// 获取拖拽内容头部
|
||||||
const dialogHeaderEl = el.querySelector('.el-dialog__header');
|
const dialogHeaderEl = el.querySelector('.el-dialog__header')
|
||||||
const dragDom = el.querySelector('.el-dialog');
|
const dragDom = el.querySelector('.el-dialog')
|
||||||
dialogHeaderEl.style.cursor = 'move';
|
dialogHeaderEl.style.cursor = 'move'
|
||||||
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
|
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null)
|
||||||
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
|
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)
|
||||||
dragDom.style.position = 'absolute';
|
dragDom.style.position = 'absolute'
|
||||||
dragDom.style.marginTop = 0;
|
dragDom.style.marginTop = 0
|
||||||
let width = dragDom.style.width;
|
let width = dragDom.style.width
|
||||||
if (width.includes('%')) {
|
if (width.includes('%')) {
|
||||||
width = +document.body.clientWidth * (+width.replace(/\%/g, '') / 100);
|
width = +document.body.clientWidth * (+width.replace(/\%/g, '') / 100)
|
||||||
} else {
|
} else {
|
||||||
width = +width.replace(/\px/g, '');
|
width = +width.replace(/\px/g, '')
|
||||||
}
|
}
|
||||||
dragDom.style.left = `${(document.body.clientWidth - width) / 2}px`;
|
dragDom.style.left = `${(document.body.clientWidth - width) / 2}px`
|
||||||
// 鼠标按下事件
|
// 鼠标按下事件
|
||||||
dialogHeaderEl.onmousedown = (e) => {
|
dialogHeaderEl.onmousedown = (e) => {
|
||||||
// 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离)
|
// 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离)
|
||||||
const disX = e.clientX - dialogHeaderEl.offsetLeft;
|
const disX = e.clientX - dialogHeaderEl.offsetLeft
|
||||||
const disY = e.clientY - dialogHeaderEl.offsetTop;
|
const disY = e.clientY - dialogHeaderEl.offsetTop
|
||||||
|
|
||||||
// 获取到的值带px 正则匹配替换
|
// 获取到的值带px 正则匹配替换
|
||||||
let styL, styT;
|
let styL, styT
|
||||||
|
|
||||||
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
|
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
|
||||||
if (sty.left.includes('%')) {
|
if (sty.left.includes('%')) {
|
||||||
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100);
|
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)
|
||||||
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100);
|
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)
|
||||||
} else {
|
} else {
|
||||||
styL = +sty.left.replace(/\px/g, '');
|
styL = +sty.left.replace(/\px/g, '')
|
||||||
styT = +sty.top.replace(/\px/g, '');
|
styT = +sty.top.replace(/\px/g, '')
|
||||||
};
|
}
|
||||||
|
|
||||||
// 鼠标拖拽事件
|
// 鼠标拖拽事件
|
||||||
document.onmousemove = function (e) {
|
document.onmousemove = function (e) {
|
||||||
// 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
|
// 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
|
||||||
const l = e.clientX - disX;
|
const l = e.clientX - disX
|
||||||
const t = e.clientY - disY;
|
const t = e.clientY - disY
|
||||||
|
|
||||||
let finallyL = l + styL
|
let finallyL = l + styL
|
||||||
let finallyT = t + styT
|
let finallyT = t + styT
|
||||||
|
|
||||||
// 移动当前元素
|
// 移动当前元素
|
||||||
dragDom.style.left = `${finallyL}px`;
|
dragDom.style.left = `${finallyL}px`
|
||||||
dragDom.style.top = `${finallyT}px`;
|
dragDom.style.top = `${finallyT}px`
|
||||||
|
|
||||||
};
|
}
|
||||||
|
|
||||||
document.onmouseup = function (e) {
|
document.onmouseup = function (e) {
|
||||||
document.onmousemove = null;
|
document.onmousemove = null
|
||||||
document.onmouseup = null;
|
document.onmouseup = null
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
@ -5,30 +5,30 @@
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
bind(el) {
|
bind(el) {
|
||||||
const dragDom = el.querySelector('.el-dialog');
|
const dragDom = el.querySelector('.el-dialog')
|
||||||
const lineEl = document.createElement('div');
|
const lineEl = document.createElement('div')
|
||||||
lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
|
lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;'
|
||||||
lineEl.addEventListener('mousedown',
|
lineEl.addEventListener('mousedown',
|
||||||
function(e) {
|
function(e) {
|
||||||
// 鼠标按下,计算当前元素距离可视区的距离
|
// 鼠标按下,计算当前元素距离可视区的距离
|
||||||
const disX = e.clientX - el.offsetLeft;
|
const disX = e.clientX - el.offsetLeft
|
||||||
const disY = e.clientY - el.offsetTop;
|
const disY = e.clientY - el.offsetTop
|
||||||
// 当前宽度 高度
|
// 当前宽度 高度
|
||||||
const curWidth = dragDom.offsetWidth;
|
const curWidth = dragDom.offsetWidth
|
||||||
const curHeight = dragDom.offsetHeight;
|
const curHeight = dragDom.offsetHeight
|
||||||
document.onmousemove = function(e) {
|
document.onmousemove = function(e) {
|
||||||
e.preventDefault(); // 移动时禁用默认事件
|
e.preventDefault() // 移动时禁用默认事件
|
||||||
// 通过事件委托,计算移动的距离
|
// 通过事件委托,计算移动的距离
|
||||||
const xl = e.clientX - disX;
|
const xl = e.clientX - disX
|
||||||
const yl = e.clientY - disY
|
const yl = e.clientY - disY
|
||||||
dragDom.style.width = `${curWidth + xl}px`;
|
dragDom.style.width = `${curWidth + xl}px`
|
||||||
dragDom.style.height = `${curHeight + yl}px`;
|
dragDom.style.height = `${curHeight + yl}px`
|
||||||
};
|
}
|
||||||
document.onmouseup = function(e) {
|
document.onmouseup = function(e) {
|
||||||
document.onmousemove = null;
|
document.onmousemove = null
|
||||||
document.onmouseup = null;
|
document.onmouseup = null
|
||||||
};
|
}
|
||||||
}, false);
|
}, false)
|
||||||
dragDom.appendChild(lineEl);
|
dragDom.appendChild(lineEl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,26 +5,26 @@
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
bind(el) {
|
bind(el) {
|
||||||
const dragDom = el.querySelector('.el-dialog');
|
const dragDom = el.querySelector('.el-dialog')
|
||||||
const lineEl = document.createElement('div');
|
const lineEl = document.createElement('div')
|
||||||
lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
|
lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;'
|
||||||
lineEl.addEventListener('mousedown',
|
lineEl.addEventListener('mousedown',
|
||||||
function (e) {
|
function (e) {
|
||||||
// 鼠标按下,计算当前元素距离可视区的距离
|
// 鼠标按下,计算当前元素距离可视区的距离
|
||||||
const disX = e.clientX - el.offsetLeft;
|
const disX = e.clientX - el.offsetLeft
|
||||||
// 当前宽度
|
// 当前宽度
|
||||||
const curWidth = dragDom.offsetWidth;
|
const curWidth = dragDom.offsetWidth
|
||||||
document.onmousemove = function (e) {
|
document.onmousemove = function (e) {
|
||||||
e.preventDefault(); // 移动时禁用默认事件
|
e.preventDefault() // 移动时禁用默认事件
|
||||||
// 通过事件委托,计算移动的距离
|
// 通过事件委托,计算移动的距离
|
||||||
const l = e.clientX - disX;
|
const l = e.clientX - disX
|
||||||
dragDom.style.width = `${curWidth + l}px`;
|
dragDom.style.width = `${curWidth + l}px`
|
||||||
};
|
}
|
||||||
document.onmouseup = function (e) {
|
document.onmouseup = function (e) {
|
||||||
document.onmousemove = null;
|
document.onmousemove = null
|
||||||
document.onmouseup = null;
|
document.onmouseup = null
|
||||||
};
|
}
|
||||||
}, false);
|
}, false)
|
||||||
dragDom.appendChild(lineEl);
|
dragDom.appendChild(lineEl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const install = function(Vue) {
|
|||||||
if (window.Vue) {
|
if (window.Vue) {
|
||||||
window['hasRole'] = hasRole
|
window['hasRole'] = hasRole
|
||||||
window['hasPermi'] = hasPermi
|
window['hasPermi'] = hasPermi
|
||||||
Vue.use(install); // eslint-disable-line
|
Vue.use(install)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default install
|
export default install
|
||||||
|
|||||||
@ -8,47 +8,47 @@ export default {
|
|||||||
bind(el, binding, vnode) {
|
bind(el, binding, vnode) {
|
||||||
switch (binding.arg) {
|
switch (binding.arg) {
|
||||||
case 'success':
|
case 'success':
|
||||||
el._vClipBoard_success = binding.value;
|
el._vClipBoard_success = binding.value
|
||||||
break;
|
break
|
||||||
case 'error':
|
case 'error':
|
||||||
el._vClipBoard_error = binding.value;
|
el._vClipBoard_error = binding.value
|
||||||
break;
|
break
|
||||||
default: {
|
default: {
|
||||||
const clipboard = new Clipboard(el, {
|
const clipboard = new Clipboard(el, {
|
||||||
text: () => binding.value,
|
text: () => binding.value,
|
||||||
action: () => binding.arg === 'cut' ? 'cut' : 'copy'
|
action: () => binding.arg === 'cut' ? 'cut' : 'copy'
|
||||||
});
|
})
|
||||||
clipboard.on('success', e => {
|
clipboard.on('success', e => {
|
||||||
const callback = el._vClipBoard_success;
|
const callback = el._vClipBoard_success
|
||||||
callback && callback(e);
|
callback && callback(e)
|
||||||
});
|
})
|
||||||
clipboard.on('error', e => {
|
clipboard.on('error', e => {
|
||||||
const callback = el._vClipBoard_error;
|
const callback = el._vClipBoard_error
|
||||||
callback && callback(e);
|
callback && callback(e)
|
||||||
});
|
})
|
||||||
el._vClipBoard = clipboard;
|
el._vClipBoard = clipboard
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update(el, binding) {
|
update(el, binding) {
|
||||||
if (binding.arg === 'success') {
|
if (binding.arg === 'success') {
|
||||||
el._vClipBoard_success = binding.value;
|
el._vClipBoard_success = binding.value
|
||||||
} else if (binding.arg === 'error') {
|
} else if (binding.arg === 'error') {
|
||||||
el._vClipBoard_error = binding.value;
|
el._vClipBoard_error = binding.value
|
||||||
} else {
|
} else {
|
||||||
el._vClipBoard.text = function () { return binding.value; };
|
el._vClipBoard.text = function () { return binding.value }
|
||||||
el._vClipBoard.action = () => binding.arg === 'cut' ? 'cut' : 'copy';
|
el._vClipBoard.action = () => binding.arg === 'cut' ? 'cut' : 'copy'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
unbind(el, binding) {
|
unbind(el, binding) {
|
||||||
if (!el._vClipboard) return
|
if (!el._vClipboard) return
|
||||||
if (binding.arg === 'success') {
|
if (binding.arg === 'success') {
|
||||||
delete el._vClipBoard_success;
|
delete el._vClipBoard_success
|
||||||
} else if (binding.arg === 'error') {
|
} else if (binding.arg === 'error') {
|
||||||
delete el._vClipBoard_error;
|
delete el._vClipBoard_error
|
||||||
} else {
|
} else {
|
||||||
el._vClipBoard.destroy();
|
el._vClipBoard.destroy()
|
||||||
delete el._vClipBoard;
|
delete el._vClipBoard
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import store from '@/store'
|
|||||||
export default {
|
export default {
|
||||||
inserted(el, binding, vnode) {
|
inserted(el, binding, vnode) {
|
||||||
const { value } = binding
|
const { value } = binding
|
||||||
const all_permission = "*:*:*";
|
const all_permission = "*:*:*"
|
||||||
const permissions = store.getters && store.getters.permissions
|
const permissions = store.getters && store.getters.permissions
|
||||||
|
|
||||||
if (value && value instanceof Array && value.length > 0) {
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import store from '@/store'
|
|||||||
export default {
|
export default {
|
||||||
inserted(el, binding, vnode) {
|
inserted(el, binding, vnode) {
|
||||||
const { value } = binding
|
const { value } = binding
|
||||||
const super_admin = "admin";
|
const super_admin = "admin"
|
||||||
const roles = store.getters && store.getters.roles
|
const roles = store.getters && store.getters.roles
|
||||||
|
|
||||||
if (value && value instanceof Array && value.length > 0) {
|
if (value && value instanceof Array && value.length > 0) {
|
||||||
|
|||||||
@ -6,15 +6,17 @@
|
|||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
<iframe-toggle />
|
<iframe-toggle />
|
||||||
|
<copyright />
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import copyright from "./Copyright/index"
|
||||||
import iframeToggle from "./IframeToggle/index"
|
import iframeToggle from "./IframeToggle/index"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AppMain',
|
name: 'AppMain',
|
||||||
components: { iframeToggle },
|
components: { iframeToggle, copyright },
|
||||||
computed: {
|
computed: {
|
||||||
cachedViews() {
|
cachedViews() {
|
||||||
return this.$store.state.tagsView.cachedViews
|
return this.$store.state.tagsView.cachedViews
|
||||||
@ -33,7 +35,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addIframe() {
|
addIframe() {
|
||||||
const {name} = this.$route
|
const { name } = this.$route
|
||||||
if (name && this.$route.meta.link) {
|
if (name && this.$route.meta.link) {
|
||||||
this.$store.dispatch('tagsView/addIframeView', this.$route)
|
this.$store.dispatch('tagsView/addIframeView', this.$route)
|
||||||
}
|
}
|
||||||
@ -52,7 +54,18 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.fixed-header + .app-main {
|
.fixed-header + .app-main {
|
||||||
padding-top: 50px;
|
overflow-y: auto;
|
||||||
|
scrollbar-gutter: auto;
|
||||||
|
height: calc(100vh - 50px);
|
||||||
|
min-height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-main:has(.copyright) {
|
||||||
|
padding-bottom: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-header + .app-main {
|
||||||
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hasTagsView {
|
.hasTagsView {
|
||||||
@ -62,19 +75,14 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.fixed-header + .app-main {
|
.fixed-header + .app-main {
|
||||||
padding-top: 84px;
|
margin-top: 84px;
|
||||||
|
height: calc(100vh - 84px);
|
||||||
|
min-height: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
// fix css style bug in open el-dialog
|
|
||||||
.el-popup-parent--hidden {
|
|
||||||
.fixed-header {
|
|
||||||
padding-right: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 6px;
|
width: 6px;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
|
|||||||
35
ruoyi-ui/src/layout/components/Copyright/index.vue
Normal file
35
ruoyi-ui/src/layout/components/Copyright/index.vue
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<footer v-if="visible" class="copyright">
|
||||||
|
<span>{{ content }}</span>
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
visible() {
|
||||||
|
return this.$store.state.settings.footerVisible
|
||||||
|
},
|
||||||
|
content() {
|
||||||
|
return this.$store.state.settings.footerContent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.copyright {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 36px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
text-align: right;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
border-top: 1px solid #e7e7e7;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -11,22 +11,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import InnerLink from "../InnerLink/index";
|
import InnerLink from "../InnerLink/index"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { InnerLink },
|
components: { InnerLink },
|
||||||
computed: {
|
computed: {
|
||||||
iframeViews() {
|
iframeViews() {
|
||||||
return this.$store.state.tagsView.iframeViews;
|
return this.$store.state.tagsView.iframeViews
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
iframeUrl(url, query) {
|
iframeUrl(url, query) {
|
||||||
if (Object.keys(query).length > 0) {
|
if (Object.keys(query).length > 0) {
|
||||||
let params = Object.keys(query).map((key) => key + "=" + query[key]).join("&");
|
let params = Object.keys(query).map((key) => key + "=" + query[key]).join("&")
|
||||||
return url + "?" + params;
|
return url + "?" + params
|
||||||
}
|
}
|
||||||
return url;
|
return url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,24 +24,24 @@ export default {
|
|||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
height: document.documentElement.clientHeight - 94.5 + "px;"
|
height: document.documentElement.clientHeight - 94.5 + "px;"
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
var _this = this;
|
var _this = this
|
||||||
const iframeId = ("#" + this.iframeId).replace(/\//g, "\\/");
|
const iframeId = ("#" + this.iframeId).replace(/\//g, "\\/")
|
||||||
const iframe = document.querySelector(iframeId);
|
const iframe = document.querySelector(iframeId)
|
||||||
// iframe页面loading控制
|
// iframe页面loading控制
|
||||||
if (iframe.attachEvent) {
|
if (iframe.attachEvent) {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
iframe.attachEvent("onload", function () {
|
iframe.attachEvent("onload", function () {
|
||||||
_this.loading = false;
|
_this.loading = false
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
iframe.onload = function () {
|
iframe.onload = function () {
|
||||||
_this.loading = false;
|
_this.loading = false
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
<div class="navbar">
|
<div class="navbar">
|
||||||
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
||||||
|
|
||||||
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
|
<breadcrumb v-if="!topNav" id="breadcrumb-container" class="breadcrumb-container" />
|
||||||
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/>
|
<top-nav v-if="topNav" id="topmenu-container" class="topmenu-container" />
|
||||||
|
|
||||||
<div class="right-menu">
|
<div class="right-menu">
|
||||||
<template v-if="device!=='mobile'">
|
<template v-if="device!=='mobile'">
|
||||||
@ -25,16 +25,16 @@
|
|||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
|
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="hover">
|
||||||
<div class="avatar-wrapper">
|
<div class="avatar-wrapper">
|
||||||
<img :src="avatar" class="user-avatar">
|
<img :src="avatar" class="user-avatar">
|
||||||
<i class="el-icon-caret-bottom" />
|
<span class="user-nickname"> {{ nickName }} </span>
|
||||||
</div>
|
</div>
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<router-link to="/user/profile">
|
<router-link to="/user/profile">
|
||||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||||
</router-link>
|
</router-link>
|
||||||
<el-dropdown-item @click.native="setting = true">
|
<el-dropdown-item @click.native="setLayout" v-if="setting">
|
||||||
<span>布局设置</span>
|
<span>布局设置</span>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item divided @click.native="logout">
|
<el-dropdown-item divided @click.native="logout">
|
||||||
@ -58,6 +58,7 @@ import RuoYiGit from '@/components/RuoYi/Git'
|
|||||||
import RuoYiDoc from '@/components/RuoYi/Doc'
|
import RuoYiDoc from '@/components/RuoYi/Doc'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
emits: ['setLayout'],
|
||||||
components: {
|
components: {
|
||||||
Breadcrumb,
|
Breadcrumb,
|
||||||
TopNav,
|
TopNav,
|
||||||
@ -72,17 +73,12 @@ export default {
|
|||||||
...mapGetters([
|
...mapGetters([
|
||||||
'sidebar',
|
'sidebar',
|
||||||
'avatar',
|
'avatar',
|
||||||
'device'
|
'device',
|
||||||
|
'nickName'
|
||||||
]),
|
]),
|
||||||
setting: {
|
setting: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.settings.showSettings
|
return this.$store.state.settings.showSettings
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
|
||||||
key: 'showSettings',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
topNav: {
|
topNav: {
|
||||||
@ -95,16 +91,19 @@ export default {
|
|||||||
toggleSideBar() {
|
toggleSideBar() {
|
||||||
this.$store.dispatch('app/toggleSideBar')
|
this.$store.dispatch('app/toggleSideBar')
|
||||||
},
|
},
|
||||||
async logout() {
|
setLayout(event) {
|
||||||
|
this.$emit('setLayout')
|
||||||
|
},
|
||||||
|
logout() {
|
||||||
this.$confirm('确定注销并退出系统吗?', '提示', {
|
this.$confirm('确定注销并退出系统吗?', '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$store.dispatch('LogOut').then(() => {
|
this.$store.dispatch('LogOut').then(() => {
|
||||||
location.href = '/index';
|
location.href = '/index'
|
||||||
})
|
})
|
||||||
}).catch(() => {});
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,17 +172,27 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.avatar-container {
|
.avatar-container {
|
||||||
margin-right: 30px;
|
margin-right: 0px;
|
||||||
|
padding-right: 0px;
|
||||||
|
|
||||||
.avatar-wrapper {
|
.avatar-wrapper {
|
||||||
margin-top: 5px;
|
margin-top: 10px;
|
||||||
|
right: 8px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.user-avatar {
|
.user-avatar {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 40px;
|
width: 30px;
|
||||||
height: 40px;
|
height: 30px;
|
||||||
border-radius: 10px;
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-nickname{
|
||||||
|
position: relative;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 2px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-icon-caret-bottom {
|
.el-icon-caret-bottom {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer size="280px" :visible="visible" :with-header="false" :append-to-body="true" :show-close="false">
|
<el-drawer size="280px" :visible="showSettings" :with-header="false" :append-to-body="true" :before-close="closeSetting" :lock-scroll="false">
|
||||||
<div class="drawer-container">
|
<div class="drawer-container">
|
||||||
<div>
|
<div>
|
||||||
<div class="setting-drawer-content">
|
<div class="setting-drawer-content">
|
||||||
@ -49,6 +49,11 @@
|
|||||||
<el-switch v-model="tagsView" class="drawer-switch" />
|
<el-switch v-model="tagsView" class="drawer-switch" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="drawer-item">
|
||||||
|
<span>显示页签图标</span>
|
||||||
|
<el-switch v-model="tagsIcon" :disabled="!tagsView" class="drawer-switch" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="drawer-item">
|
<div class="drawer-item">
|
||||||
<span>固定 Header</span>
|
<span>固定 Header</span>
|
||||||
<el-switch v-model="fixedHeader" class="drawer-switch" />
|
<el-switch v-model="fixedHeader" class="drawer-switch" />
|
||||||
@ -64,6 +69,11 @@
|
|||||||
<el-switch v-model="dynamicTitle" class="drawer-switch" />
|
<el-switch v-model="dynamicTitle" class="drawer-switch" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="drawer-item">
|
||||||
|
<span>底部版权</span>
|
||||||
|
<el-switch v-model="footerVisible" class="drawer-switch" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-divider/>
|
<el-divider/>
|
||||||
|
|
||||||
<el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">保存配置</el-button>
|
<el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">保存配置</el-button>
|
||||||
@ -78,18 +88,15 @@ import ThemePicker from '@/components/ThemePicker'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ThemePicker },
|
components: { ThemePicker },
|
||||||
|
expose: ['openSetting'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
theme: this.$store.state.settings.theme,
|
theme: this.$store.state.settings.theme,
|
||||||
sideTheme: this.$store.state.settings.sideTheme
|
sideTheme: this.$store.state.settings.sideTheme,
|
||||||
};
|
showSettings: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
visible: {
|
|
||||||
get() {
|
|
||||||
return this.$store.state.settings.showSettings
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fixedHeader: {
|
fixedHeader: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.settings.fixedHeader
|
return this.$store.state.settings.fixedHeader
|
||||||
@ -111,8 +118,8 @@ export default {
|
|||||||
value: val
|
value: val
|
||||||
})
|
})
|
||||||
if (!val) {
|
if (!val) {
|
||||||
this.$store.dispatch('app/toggleSideBarHide', false);
|
this.$store.dispatch('app/toggleSideBarHide', false)
|
||||||
this.$store.commit("SET_SIDEBAR_ROUTERS", this.$store.state.permission.defaultRoutes);
|
this.$store.commit("SET_SIDEBAR_ROUTERS", this.$store.state.permission.defaultRoutes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -127,6 +134,17 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
tagsIcon: {
|
||||||
|
get() {
|
||||||
|
return this.$store.state.settings.tagsIcon
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$store.dispatch('settings/changeSetting', {
|
||||||
|
key: 'tagsIcon',
|
||||||
|
value: val
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
sidebarLogo: {
|
sidebarLogo: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.settings.sidebarLogo
|
return this.$store.state.settings.sidebarLogo
|
||||||
@ -147,8 +165,20 @@ export default {
|
|||||||
key: 'dynamicTitle',
|
key: 'dynamicTitle',
|
||||||
value: val
|
value: val
|
||||||
})
|
})
|
||||||
|
this.$store.dispatch('settings/setTitle', this.$store.state.settings.title)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
footerVisible: {
|
||||||
|
get() {
|
||||||
|
return this.$store.state.settings.footerVisible
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$store.dispatch('settings/changeSetting', {
|
||||||
|
key: 'footerVisible',
|
||||||
|
value: val
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
themeChange(val) {
|
themeChange(val) {
|
||||||
@ -156,33 +186,41 @@ export default {
|
|||||||
key: 'theme',
|
key: 'theme',
|
||||||
value: val
|
value: val
|
||||||
})
|
})
|
||||||
this.theme = val;
|
this.theme = val
|
||||||
},
|
},
|
||||||
handleTheme(val) {
|
handleTheme(val) {
|
||||||
this.$store.dispatch('settings/changeSetting', {
|
this.$store.dispatch('settings/changeSetting', {
|
||||||
key: 'sideTheme',
|
key: 'sideTheme',
|
||||||
value: val
|
value: val
|
||||||
})
|
})
|
||||||
this.sideTheme = val;
|
this.sideTheme = val
|
||||||
|
},
|
||||||
|
openSetting() {
|
||||||
|
this.showSettings = true
|
||||||
|
},
|
||||||
|
closeSetting(){
|
||||||
|
this.showSettings = false
|
||||||
},
|
},
|
||||||
saveSetting() {
|
saveSetting() {
|
||||||
this.$modal.loading("正在保存到本地,请稍候...");
|
this.$modal.loading("正在保存到本地,请稍候...")
|
||||||
this.$cache.local.set(
|
this.$cache.local.set(
|
||||||
"layout-setting",
|
"layout-setting",
|
||||||
`{
|
`{
|
||||||
"topNav":${this.topNav},
|
"topNav":${this.topNav},
|
||||||
"tagsView":${this.tagsView},
|
"tagsView":${this.tagsView},
|
||||||
|
"tagsIcon":${this.tagsIcon},
|
||||||
"fixedHeader":${this.fixedHeader},
|
"fixedHeader":${this.fixedHeader},
|
||||||
"sidebarLogo":${this.sidebarLogo},
|
"sidebarLogo":${this.sidebarLogo},
|
||||||
"dynamicTitle":${this.dynamicTitle},
|
"dynamicTitle":${this.dynamicTitle},
|
||||||
|
"footerVisible":${this.footerVisible},
|
||||||
"sideTheme":"${this.sideTheme}",
|
"sideTheme":"${this.sideTheme}",
|
||||||
"theme":"${this.theme}"
|
"theme":"${this.theme}"
|
||||||
}`
|
}`
|
||||||
);
|
)
|
||||||
setTimeout(this.$modal.closeLoading(), 1000)
|
setTimeout(this.$modal.closeLoading(), 1000)
|
||||||
},
|
},
|
||||||
resetSetting() {
|
resetSetting() {
|
||||||
this.$modal.loading("正在清除设置缓存并刷新,请稍候...");
|
this.$modal.loading("正在清除设置缓存并刷新,请稍候...")
|
||||||
this.$cache.local.remove("layout-setting")
|
this.$cache.local.remove("layout-setting")
|
||||||
setTimeout("window.location.reload()", 1000)
|
setTimeout("window.location.reload()", 1000)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
variables() {
|
variables() {
|
||||||
return variables;
|
return variables
|
||||||
},
|
},
|
||||||
sideTheme() {
|
sideTheme() {
|
||||||
return this.$store.state.settings.sideTheme
|
return this.$store.state.settings.sideTheme
|
||||||
|
|||||||
@ -57,7 +57,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
hasOneShowingChild(children = [], parent) {
|
hasOneShowingChild(children = [], parent) {
|
||||||
if (!children) {
|
if (!children) {
|
||||||
children = [];
|
children = []
|
||||||
}
|
}
|
||||||
const showingChildren = children.filter(item => {
|
const showingChildren = children.filter(item => {
|
||||||
if (item.hidden) {
|
if (item.hidden) {
|
||||||
@ -89,7 +89,7 @@ export default {
|
|||||||
return this.basePath
|
return this.basePath
|
||||||
}
|
}
|
||||||
if (routeQuery) {
|
if (routeQuery) {
|
||||||
let query = JSON.parse(routeQuery);
|
let query = JSON.parse(routeQuery)
|
||||||
return { path: path.resolve(this.basePath, routePath), query: query }
|
return { path: path.resolve(this.basePath, routePath), query: query }
|
||||||
}
|
}
|
||||||
return path.resolve(this.basePath, routePath)
|
return path.resolve(this.basePath, routePath)
|
||||||
|
|||||||
@ -24,10 +24,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapState } from "vuex";
|
import { mapGetters, mapState } from "vuex"
|
||||||
import Logo from "./Logo";
|
import Logo from "./Logo"
|
||||||
import SidebarItem from "./SidebarItem";
|
import SidebarItem from "./SidebarItem"
|
||||||
import variables from "@/assets/styles/variables.scss";
|
import variables from "@/assets/styles/variables.scss"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { SidebarItem, Logo },
|
components: { SidebarItem, Logo },
|
||||||
@ -35,23 +35,23 @@ export default {
|
|||||||
...mapState(["settings"]),
|
...mapState(["settings"]),
|
||||||
...mapGetters(["sidebarRouters", "sidebar"]),
|
...mapGetters(["sidebarRouters", "sidebar"]),
|
||||||
activeMenu() {
|
activeMenu() {
|
||||||
const route = this.$route;
|
const route = this.$route
|
||||||
const { meta, path } = route;
|
const { meta, path } = route
|
||||||
// if set path, the sidebar will highlight the path you set
|
// if set path, the sidebar will highlight the path you set
|
||||||
if (meta.activeMenu) {
|
if (meta.activeMenu) {
|
||||||
return meta.activeMenu;
|
return meta.activeMenu
|
||||||
}
|
}
|
||||||
return path;
|
return path
|
||||||
},
|
},
|
||||||
showLogo() {
|
showLogo() {
|
||||||
return this.$store.state.settings.sidebarLogo;
|
return this.$store.state.settings.sidebarLogo
|
||||||
},
|
},
|
||||||
variables() {
|
variables() {
|
||||||
return variables;
|
return variables
|
||||||
},
|
},
|
||||||
isCollapse() {
|
isCollapse() {
|
||||||
return !this.sidebar.opened;
|
return !this.sidebar.opened
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
v-for="tag in visitedViews"
|
v-for="tag in visitedViews"
|
||||||
ref="tag"
|
ref="tag"
|
||||||
:key="tag.path"
|
:key="tag.path"
|
||||||
:class="isActive(tag)?'active':''"
|
:class="{ 'active': isActive(tag), 'has-icon': tagsIcon }"
|
||||||
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||||
tag="span"
|
tag="span"
|
||||||
class="tags-view-item"
|
class="tags-view-item"
|
||||||
@ -13,6 +13,7 @@
|
|||||||
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
|
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
|
||||||
@contextmenu.prevent.native="openMenu(tag,$event)"
|
@contextmenu.prevent.native="openMenu(tag,$event)"
|
||||||
>
|
>
|
||||||
|
<svg-icon v-if="tagsIcon && tag.meta && tag.meta.icon && tag.meta.icon !== '#'" :icon-class="tag.meta.icon" />
|
||||||
{{ tag.title }}
|
{{ tag.title }}
|
||||||
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
||||||
</router-link>
|
</router-link>
|
||||||
@ -51,7 +52,10 @@ export default {
|
|||||||
return this.$store.state.permission.routes
|
return this.$store.state.permission.routes
|
||||||
},
|
},
|
||||||
theme() {
|
theme() {
|
||||||
return this.$store.state.settings.theme;
|
return this.$store.state.settings.theme
|
||||||
|
},
|
||||||
|
tagsIcon() {
|
||||||
|
return this.$store.state.settings.tagsIcon
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -76,11 +80,11 @@ export default {
|
|||||||
return route.path === this.$route.path
|
return route.path === this.$route.path
|
||||||
},
|
},
|
||||||
activeStyle(tag) {
|
activeStyle(tag) {
|
||||||
if (!this.isActive(tag)) return {};
|
if (!this.isActive(tag)) return {}
|
||||||
return {
|
return {
|
||||||
"background-color": this.theme,
|
"background-color": this.theme,
|
||||||
"border-color": this.theme
|
"border-color": this.theme
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
isAffix(tag) {
|
isAffix(tag) {
|
||||||
return tag.meta && tag.meta.affix
|
return tag.meta && tag.meta.affix
|
||||||
@ -151,7 +155,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
refreshSelectedTag(view) {
|
refreshSelectedTag(view) {
|
||||||
this.$tab.refreshPage(view);
|
this.$tab.refreshPage(view)
|
||||||
if (this.$route.meta.link) {
|
if (this.$route.meta.link) {
|
||||||
this.$store.dispatch('tagsView/delIframeView', this.$route)
|
this.$store.dispatch('tagsView/delIframeView', this.$route)
|
||||||
}
|
}
|
||||||
@ -178,7 +182,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
closeOthersTags() {
|
closeOthersTags() {
|
||||||
this.$router.push(this.selectedTag.fullPath).catch(()=>{});
|
this.$router.push(this.selectedTag.fullPath).catch(()=>{})
|
||||||
this.$tab.closeOtherPage(this.selectedTag).then(() => {
|
this.$tab.closeOtherPage(this.selectedTag).then(() => {
|
||||||
this.moveToCurrentTag()
|
this.moveToCurrentTag()
|
||||||
})
|
})
|
||||||
@ -277,6 +281,11 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tags-view-item.active.has-icon::before {
|
||||||
|
content: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.contextmenu {
|
.contextmenu {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|||||||
@ -4,19 +4,16 @@
|
|||||||
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
||||||
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
|
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
|
||||||
<div :class="{'fixed-header':fixedHeader}">
|
<div :class="{'fixed-header':fixedHeader}">
|
||||||
<navbar/>
|
<navbar @setLayout="setLayout"/>
|
||||||
<tags-view v-if="needTagsView"/>
|
<tags-view v-if="needTagsView"/>
|
||||||
</div>
|
</div>
|
||||||
<app-main/>
|
<app-main/>
|
||||||
<right-panel>
|
<settings ref="settingRef"/>
|
||||||
<settings/>
|
|
||||||
</right-panel>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
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'
|
||||||
@ -27,7 +24,6 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
AppMain,
|
AppMain,
|
||||||
Navbar,
|
Navbar,
|
||||||
RightPanel,
|
|
||||||
Settings,
|
Settings,
|
||||||
Sidebar,
|
Sidebar,
|
||||||
TagsView
|
TagsView
|
||||||
@ -51,12 +47,15 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
variables() {
|
variables() {
|
||||||
return variables;
|
return variables
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClickOutside() {
|
handleClickOutside() {
|
||||||
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
|
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
|
||||||
|
},
|
||||||
|
setLayout() {
|
||||||
|
this.$refs.settingRef.openSetting()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,6 +77,11 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-container:has(.fixed-header) {
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.drawer-bg {
|
.drawer-bg {
|
||||||
background: #000;
|
background: #000;
|
||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user