From ccf84377f8609d6f867a556d2802c57a497232ec Mon Sep 17 00:00:00 2001 From: RuoYi Date: Sun, 27 Mar 2022 15:34:13 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AF=BC=E5=87=BAexcel?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E9=AA=8C=E8=AF=81,=E5=8C=85?= =?UTF-8?q?=E5=90=AB=E5=8F=98=E6=9B=B4=E4=B8=BA=E5=BC=80=E5=A4=B4.?= =?UTF-8?q?=E9=98=B2=E6=AD=A2=E6=AD=A3=E5=B8=B8=E5=86=85=E5=AE=B9=E8=A2=AB?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/ruoyi/common/core/utils/poi/ExcelUtil.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java index aa475e35..1650f4df 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/poi/ExcelUtil.java @@ -18,6 +18,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.RegExUtils; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; @@ -65,6 +66,8 @@ public class ExcelUtil { private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; + public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; /** @@ -595,9 +598,9 @@ public class ExcelUtil { String cellValue = Convert.toStr(value); // 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。 - if (StringUtils.containsAny(cellValue, FORMULA_STR)) + if (StringUtils.startsWithAny(cellValue, FORMULA_STR)) { - cellValue = StringUtils.replaceEach(cellValue, FORMULA_STR, new String[] { "\t=", "\t-", "\t+", "\t@" }); + cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); } cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); } From e5c938c64a8620aef716882d4527498174ace558 Mon Sep 17 00:00:00 2001 From: RuoYi Date: Sun, 27 Mar 2022 15:35:20 +0800 Subject: [PATCH 02/17] =?UTF-8?q?=E4=BC=98=E5=8C=96IP=E5=9C=B0=E5=9D=80?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=88=B0=E5=A4=9A=E4=B8=AA=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/common/core/utils/ip/IpUtils.java | 121 +++++++++++++----- 1 file changed, 88 insertions(+), 33 deletions(-) diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java index 767cab7c..78186aca 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java @@ -12,58 +12,62 @@ import com.ruoyi.common.core.utils.StringUtils; */ public class IpUtils { + /** + * 获取客户端IP + * + * @param request 请求对象 + * @return IP地址 + */ public static String getIpAddr(HttpServletRequest request) { if (request == null) { - return null; + return "unknown"; } - - String ip = null; - - // X-Forwarded-For:Squid 服务代理 - String ipAddresses = request.getHeader("X-Forwarded-For"); - if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - // Proxy-Client-IP:apache 服务代理 - ipAddresses = request.getHeader("Proxy-Client-IP"); + ip = request.getHeader("Proxy-Client-IP"); } - if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - // WL-Proxy-Client-IP:weblogic 服务代理 - ipAddresses = request.getHeader("WL-Proxy-Client-IP"); + ip = request.getHeader("X-Forwarded-For"); } - if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - // HTTP_CLIENT_IP:有些代理服务器 - ipAddresses = request.getHeader("HTTP_CLIENT_IP"); + ip = request.getHeader("WL-Proxy-Client-IP"); } - if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - // X-Real-IP:nginx服务代理 - ipAddresses = request.getHeader("X-Real-IP"); + ip = request.getHeader("X-Real-IP"); } - // 有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP - if (ipAddresses != null && ipAddresses.length() != 0) - { - ip = ipAddresses.split(",")[0]; - } - - // 还是不能获取到,最后再通过request.getRemoteAddr();获取 - if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } - return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip; + + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip); } + /** + * 检查是否为内部IP地址 + * + * @param ip IP地址 + * @return 结果 + */ public static boolean internalIp(String ip) { byte[] addr = textToNumericFormatV4(ip); return internalIp(addr) || "127.0.0.1".equals(ip); } + /** + * 检查是否为内部IP地址 + * + * @param addr byte地址 + * @return 结果 + */ private static boolean internalIp(byte[] addr) { if (StringUtils.isNull(addr) || addr.length < 2) @@ -124,7 +128,8 @@ public class IpUtils { case 1: l = Long.parseLong(elements[0]); - if ((l < 0L) || (l > 4294967295L)){ + if ((l < 0L) || (l > 4294967295L)) + { return null; } bytes[0] = (byte) (int) (l >> 24 & 0xFF); @@ -134,12 +139,14 @@ public class IpUtils break; case 2: l = Integer.parseInt(elements[0]); - if ((l < 0L) || (l > 255L)) { + if ((l < 0L) || (l > 255L)) + { return null; } bytes[0] = (byte) (int) (l & 0xFF); l = Integer.parseInt(elements[1]); - if ((l < 0L) || (l > 16777215L)) { + if ((l < 0L) || (l > 16777215L)) + { return null; } bytes[1] = (byte) (int) (l >> 16 & 0xFF); @@ -150,13 +157,15 @@ public class IpUtils for (i = 0; i < 2; ++i) { l = Integer.parseInt(elements[i]); - if ((l < 0L) || (l > 255L)) { + if ((l < 0L) || (l > 255L)) + { return null; } bytes[i] = (byte) (int) (l & 0xFF); } l = Integer.parseInt(elements[2]); - if ((l < 0L) || (l > 65535L)) { + if ((l < 0L) || (l > 65535L)) + { return null; } bytes[2] = (byte) (int) (l >> 8 & 0xFF); @@ -166,7 +175,8 @@ public class IpUtils for (i = 0; i < 4; ++i) { l = Integer.parseInt(elements[i]); - if ((l < 0L) || (l > 255L)) { + if ((l < 0L) || (l > 255L)) + { return null; } bytes[i] = (byte) (int) (l & 0xFF); @@ -183,6 +193,11 @@ public class IpUtils return bytes; } + /** + * 获取IP地址 + * + * @return 本地IP地址 + */ public static String getHostIp() { try @@ -195,6 +210,11 @@ public class IpUtils return "127.0.0.1"; } + /** + * 获取主机名 + * + * @return 本地主机名 + */ public static String getHostName() { try @@ -206,4 +226,39 @@ public class IpUtils } return "未知"; } + + /** + * 从多级反向代理中获得第一个非unknown IP地址 + * + * @param ip 获得的IP地址 + * @return 第一个非unknown IP地址 + */ + public static String getMultistageReverseProxyIp(String ip) + { + // 多级反向代理检测 + if (ip != null && ip.indexOf(",") > 0) + { + final String[] ips = ip.trim().split(","); + for (String subIp : ips) + { + if (false == isUnknown(subIp)) + { + ip = subIp; + break; + } + } + } + return ip; + } + + /** + * 检测给定字符串是否为未知,多用于检测HTTP请求相关 + * + * @param checkString 被检测的字符串 + * @return 是否未知 + */ + public static boolean isUnknown(String checkString) + { + return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); + } } \ No newline at end of file From a70d5ee2ab94d2796c27964093a49ff7b57ba0d9 Mon Sep 17 00:00:00 2001 From: RuoYi Date: Wed, 30 Mar 2022 10:21:28 +0800 Subject: [PATCH 03/17] =?UTF-8?q?topNav=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E9=9A=90=E8=97=8F=E4=BE=A7=E8=BE=B9=E6=A0=8F=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-ui/src/components/TopNav/index.vue | 14 ++++---------- ruoyi-ui/src/layout/index.vue | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/ruoyi-ui/src/components/TopNav/index.vue b/ruoyi-ui/src/components/TopNav/index.vue index cabb2582..0cc24dba 100644 --- a/ruoyi-ui/src/components/TopNav/index.vue +++ b/ruoyi-ui/src/components/TopNav/index.vue @@ -30,13 +30,14 @@