1、同步ruoyi-vue-plus的2023-10-25至2023-11-14的更新
1)update 优化 排除powerjob无用的依赖 减少打包30M体积 2)fix 修复 代码生成 是否必填与数据库不匹配问题 3)update 优化 补全操作日志部门数据 4)update 优化 AddressUtils 兼容linux系统本地ip 5)fix 修复 普通角色编辑使用内置管理员code越权问题 6)update 优化 补全代码生成 columnList 接口参数注解缺失 7)fix 修复 外链带端口出现的异常 8)update 优化 更改默认日志等级为info 避免日志过多(按需开启debug) 2、同步RuoYi-Vue的2023-10-24到2023-12-5的更新: 1)update ruoyi-ui/src/permission.js 2)优化数字金额大写转换精度丢失问题 3)修复字典表详情页面搜索bug 4)修复五级路由缓存无效问题 5)优化缓存监控图表支持跟随屏幕大小自适应调整 6)update fastjson2 7)升级oshi到最新版本6.4.8
This commit is contained in:
parent
47ed943d61
commit
83d968e621
@ -21,6 +21,8 @@ router.beforeEach((to, from, next) => {
|
||||
if (to.path === '/login') {
|
||||
next({ path: '/' })
|
||||
NProgress.done()
|
||||
} else if (whiteList.indexOf(to.path) !== -1) {
|
||||
next()
|
||||
} else {
|
||||
if (useUserStore().roles.length === 0) {
|
||||
isRelogin.show = true
|
||||
|
@ -102,6 +102,10 @@ function filterChildren(childrenMap, lastRouter = false) {
|
||||
}
|
||||
if (lastRouter) {
|
||||
el.path = lastRouter.path + '/' + el.path
|
||||
if (el.children && el.children.length) {
|
||||
children = children.concat(filterChildren(el.children, el))
|
||||
return
|
||||
}
|
||||
}
|
||||
children = children.concat(el)
|
||||
})
|
||||
|
6
flex-ui/src/views/monitor/cache/index.vue
vendored
6
flex-ui/src/views/monitor/cache/index.vue
vendored
@ -123,7 +123,11 @@ function getList() {
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
});
|
||||
window.addEventListener("resize", () => {
|
||||
commandstatsIntance.resize();
|
||||
usedmemoryInstance.resize();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -195,8 +195,8 @@ const data = reactive({
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
dictName: undefined,
|
||||
dictType: undefined,
|
||||
dictLabel: undefined,
|
||||
status: undefined
|
||||
},
|
||||
rules: {
|
||||
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
15
pom.xml
15
pom.xml
@ -26,8 +26,8 @@
|
||||
<bitwalker.version>1.21</bitwalker.version>
|
||||
<kaptcha.version>2.3.3</kaptcha.version>
|
||||
<pagehelper.version>5.3.3</pagehelper.version>
|
||||
<fastjson.version>2.0.41</fastjson.version>
|
||||
<oshi.version>6.4.6</oshi.version>
|
||||
<fastjson.version>2.0.43</fastjson.version>
|
||||
<oshi.version>6.4.8</oshi.version>
|
||||
<commons.collections.version>3.2.2</commons.collections.version>
|
||||
<poi.version>5.2.3</poi.version>
|
||||
<easyexcel.version>3.3.2</easyexcel.version>
|
||||
@ -49,6 +49,8 @@
|
||||
<alibaba-ttl.version>2.14.3</alibaba-ttl.version>
|
||||
<spring-boot-admin.version>3.1.6</spring-boot-admin.version>
|
||||
<powerjob.version>4.3.6</powerjob.version>
|
||||
<!-- 离线IP地址定位库 -->
|
||||
<ip2region.version>2.7.0</ip2region.version>
|
||||
<!-- OSS 配置 -->
|
||||
<aws-java-sdk-s3.version>1.12.540</aws-java-sdk-s3.version>
|
||||
|
||||
@ -66,7 +68,7 @@
|
||||
<properties>
|
||||
<!-- 环境标识,需要与配置文件的名称相对应 -->
|
||||
<profiles.active>dev</profiles.active>
|
||||
<logging.level>debug</logging.level>
|
||||
<logging.level>info</logging.level>
|
||||
</properties>
|
||||
<activation>
|
||||
<!-- 默认环境 -->
|
||||
@ -323,6 +325,13 @@
|
||||
<version>${lock4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 离线IP地址定位库 ip2region -->
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
<artifactId>ip2region</artifactId>
|
||||
<version>${ip2region.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- OSS 配置 -->
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
|
@ -1,4 +1,4 @@
|
||||
restart.include.json=/com.alibaba.fastjson.*.jar
|
||||
restart.include.json=/com.alibaba.fastjson2.*.jar
|
||||
restart.include.mapper=/mapper-[\\w-\\.].jar
|
||||
restart.include.pagehelper=/pagehelper-[\\w-\\.].jar
|
||||
restart.include.mybatis-flex=/mybatis-flex-[\\w-\\.]+jar
|
||||
|
@ -60,12 +60,6 @@
|
||||
<artifactId>fastjson2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- io常用工具类 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>commons-io</groupId>-->
|
||||
<!-- <artifactId>commons-io</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- excel工具 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
@ -149,6 +143,12 @@
|
||||
<artifactId>pagehelper</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 离线IP地址定位库 -->
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
<artifactId>ip2region</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.ruoyi.common.core.core.text;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.NumberFormat;
|
||||
@ -977,7 +978,12 @@ public class Convert
|
||||
String s = "";
|
||||
for (int i = 0; i < fraction.length; i++)
|
||||
{
|
||||
s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
|
||||
// 优化double计算精度丢失问题
|
||||
BigDecimal nNum = new BigDecimal(n);
|
||||
BigDecimal decimal = new BigDecimal(10);
|
||||
BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN);
|
||||
double d = scale.doubleValue();
|
||||
s += (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
|
||||
}
|
||||
if (s.length() < 1)
|
||||
{
|
||||
|
@ -1,56 +1,33 @@
|
||||
package com.ruoyi.common.core.utils.ip;
|
||||
|
||||
import cn.hutool.core.net.NetUtil;
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.common.core.config.RuoYiConfig;
|
||||
import com.ruoyi.common.core.constant.Constants;
|
||||
import com.ruoyi.common.core.utils.http.HttpUtils;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 获取地址类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Slf4j
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class AddressUtils
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
|
||||
|
||||
// IP地址查询
|
||||
public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
|
||||
|
||||
// 未知地址
|
||||
public static final String UNKNOWN = "XX XX";
|
||||
|
||||
public static String getRealAddressByIP(String ip)
|
||||
{
|
||||
public static String getRealAddressByIP(String ip) {
|
||||
if (StringUtils.isBlank(ip)) {
|
||||
return UNKNOWN;
|
||||
}
|
||||
// 内网不查询
|
||||
if (IpUtils.internalIp(ip))
|
||||
{
|
||||
ip = StringUtils.contains(ip, "0:0:0:0:0:0:0:1") ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
|
||||
if (NetUtil.isInnerIP(ip)) {
|
||||
return "内网IP";
|
||||
}
|
||||
if (RuoYiConfig.isAddressEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
String rspStr = HttpUtils.sendGet(IP_URL, "ip=" + ip + "&json=true", Constants.GBK);
|
||||
if (StringUtils.isEmpty(rspStr))
|
||||
{
|
||||
log.error("获取地理位置异常 {}", ip);
|
||||
return UNKNOWN;
|
||||
}
|
||||
JSONObject obj = JSON.parseObject(rspStr);
|
||||
String region = obj.getString("pro");
|
||||
String city = obj.getString("city");
|
||||
return String.format("%s %s", region, city);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("获取地理位置异常 {}", ip);
|
||||
}
|
||||
}
|
||||
return UNKNOWN;
|
||||
return RegionUtils.getCityInfo(ip);
|
||||
}
|
||||
}
|
||||
|
@ -1,383 +0,0 @@
|
||||
package com.ruoyi.common.core.utils.ip;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import com.ruoyi.common.core.utils.ServletUtils;
|
||||
|
||||
/**
|
||||
* 获取IP方法
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class IpUtils
|
||||
{
|
||||
public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
|
||||
// 匹配 ip
|
||||
public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")";
|
||||
public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))";
|
||||
// 匹配网段
|
||||
public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")";
|
||||
|
||||
/**
|
||||
* 获取客户端IP
|
||||
*
|
||||
* @return IP地址
|
||||
*/
|
||||
public static String getIpAddr()
|
||||
{
|
||||
return getIpAddr(ServletUtils.getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端IP
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return IP地址
|
||||
*/
|
||||
public static String getIpAddr(HttpServletRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
|
||||
{
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
|
||||
{
|
||||
ip = request.getHeader("X-Forwarded-For");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
|
||||
{
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
|
||||
{
|
||||
ip = request.getHeader("X-Real-IP");
|
||||
}
|
||||
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
|
||||
{
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
final byte b0 = addr[0];
|
||||
final byte b1 = addr[1];
|
||||
// 10.x.x.x/8
|
||||
final byte SECTION_1 = 0x0A;
|
||||
// 172.16.x.x/12
|
||||
final byte SECTION_2 = (byte) 0xAC;
|
||||
final byte SECTION_3 = (byte) 0x10;
|
||||
final byte SECTION_4 = (byte) 0x1F;
|
||||
// 192.168.x.x/16
|
||||
final byte SECTION_5 = (byte) 0xC0;
|
||||
final byte SECTION_6 = (byte) 0xA8;
|
||||
switch (b0)
|
||||
{
|
||||
case SECTION_1:
|
||||
return true;
|
||||
case SECTION_2:
|
||||
if (b1 >= SECTION_3 && b1 <= SECTION_4)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
case SECTION_5:
|
||||
switch (b1)
|
||||
{
|
||||
case SECTION_6:
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将IPv4地址转换成字节
|
||||
*
|
||||
* @param text IPv4地址
|
||||
* @return byte 字节
|
||||
*/
|
||||
public static byte[] textToNumericFormatV4(String text)
|
||||
{
|
||||
if (text.length() == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[4];
|
||||
String[] elements = text.split("\\.", -1);
|
||||
try
|
||||
{
|
||||
long l;
|
||||
int i;
|
||||
switch (elements.length)
|
||||
{
|
||||
case 1:
|
||||
l = Long.parseLong(elements[0]);
|
||||
if ((l < 0L) || (l > 4294967295L))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
|
||||
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
|
||||
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
|
||||
bytes[3] = (byte) (int) (l & 0xFF);
|
||||
break;
|
||||
case 2:
|
||||
l = Integer.parseInt(elements[0]);
|
||||
if ((l < 0L) || (l > 255L))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
bytes[0] = (byte) (int) (l & 0xFF);
|
||||
l = Integer.parseInt(elements[1]);
|
||||
if ((l < 0L) || (l > 16777215L))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
|
||||
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
|
||||
bytes[3] = (byte) (int) (l & 0xFF);
|
||||
break;
|
||||
case 3:
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
l = Integer.parseInt(elements[i]);
|
||||
if ((l < 0L) || (l > 255L))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
bytes[i] = (byte) (int) (l & 0xFF);
|
||||
}
|
||||
l = Integer.parseInt(elements[2]);
|
||||
if ((l < 0L) || (l > 65535L))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
|
||||
bytes[3] = (byte) (int) (l & 0xFF);
|
||||
break;
|
||||
case 4:
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
l = Integer.parseInt(elements[i]);
|
||||
if ((l < 0L) || (l > 255L))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
bytes[i] = (byte) (int) (l & 0xFF);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取IP地址
|
||||
*
|
||||
* @return 本地IP地址
|
||||
*/
|
||||
public static String getHostIp()
|
||||
{
|
||||
try
|
||||
{
|
||||
return InetAddress.getLocalHost().getHostAddress();
|
||||
}
|
||||
catch (UnknownHostException e)
|
||||
{
|
||||
}
|
||||
return "127.0.0.1";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主机名
|
||||
*
|
||||
* @return 本地主机名
|
||||
*/
|
||||
public static String getHostName()
|
||||
{
|
||||
try
|
||||
{
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
}
|
||||
catch (UnknownHostException e)
|
||||
{
|
||||
}
|
||||
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 StringUtils.substring(ip, 0, 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测给定字符串是否为未知,多用于检测HTTP请求相关
|
||||
*
|
||||
* @param checkString 被检测的字符串
|
||||
* @return 是否未知
|
||||
*/
|
||||
public static boolean isUnknown(String checkString)
|
||||
{
|
||||
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为IP
|
||||
*/
|
||||
public static boolean isIP(String ip)
|
||||
{
|
||||
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为IP,或 *为间隔的通配符地址
|
||||
*/
|
||||
public static boolean isIpWildCard(String ip)
|
||||
{
|
||||
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测参数是否在ip通配符里
|
||||
*/
|
||||
public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip)
|
||||
{
|
||||
String[] s1 = ipWildCard.split("\\.");
|
||||
String[] s2 = ip.split("\\.");
|
||||
boolean isMatchedSeg = true;
|
||||
for (int i = 0; i < s1.length && !s1[i].equals("*"); i++)
|
||||
{
|
||||
if (!s1[i].equals(s2[i]))
|
||||
{
|
||||
isMatchedSeg = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isMatchedSeg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串
|
||||
*/
|
||||
public static boolean isIPSegment(String ipSeg)
|
||||
{
|
||||
return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断ip是否在指定网段中
|
||||
*/
|
||||
public static boolean ipIsInNetNoCheck(String iparea, String ip)
|
||||
{
|
||||
int idx = iparea.indexOf('-');
|
||||
String[] sips = iparea.substring(0, idx).split("\\.");
|
||||
String[] sipe = iparea.substring(idx + 1).split("\\.");
|
||||
String[] sipt = ip.split("\\.");
|
||||
long ips = 0L, ipe = 0L, ipt = 0L;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
ips = ips << 8 | Integer.parseInt(sips[i]);
|
||||
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
|
||||
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
|
||||
}
|
||||
if (ips > ipe)
|
||||
{
|
||||
long t = ips;
|
||||
ips = ipe;
|
||||
ipe = t;
|
||||
}
|
||||
return ips <= ipt && ipt <= ipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验ip是否符合过滤串规则
|
||||
*
|
||||
* @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99`
|
||||
* @param ip 校验IP地址
|
||||
* @return boolean 结果
|
||||
*/
|
||||
public static boolean isMatchedIp(String filter, String ip)
|
||||
{
|
||||
if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
String[] ips = filter.split(";");
|
||||
for (String iStr : ips)
|
||||
{
|
||||
if (isIP(iStr) && iStr.equals(ip))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.ruoyi.common.core.utils.ip;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.resource.ClassPathResource;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.ruoyi.common.core.exception.ServiceException;
|
||||
import com.ruoyi.common.core.utils.file.FileUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.lionsoul.ip2region.xdb.Searcher;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 根据ip地址定位工具类,离线方式
|
||||
* 参考地址:<a href="https://gitee.com/lionsoul/ip2region/tree/master/binding/java">集成 ip2region 实现离线IP地址定位库</a>
|
||||
*
|
||||
* @author lishuyan
|
||||
*/
|
||||
@Slf4j
|
||||
public class RegionUtils {
|
||||
|
||||
private static final Searcher SEARCHER;
|
||||
|
||||
static {
|
||||
String fileName = "/ip2region.xdb";
|
||||
File existFile = FileUtils.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
|
||||
if (!FileUtils.exist(existFile)) {
|
||||
ClassPathResource fileStream = new ClassPathResource(fileName);
|
||||
if (ObjectUtil.isEmpty(fileStream.getStream())) {
|
||||
throw new ServiceException("RegionUtils初始化失败,原因:IP地址库数据不存在!");
|
||||
}
|
||||
FileUtils.writeFromStream(fileStream.getStream(), existFile);
|
||||
}
|
||||
|
||||
String dbPath = existFile.getPath();
|
||||
|
||||
// 1、从 dbPath 加载整个 xdb 到内存。
|
||||
byte[] cBuff;
|
||||
try {
|
||||
cBuff = Searcher.loadContentFromFile(dbPath);
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("RegionUtils初始化失败,原因:从ip2region.xdb文件加载内容失败!" + e.getMessage());
|
||||
}
|
||||
// 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。
|
||||
try {
|
||||
SEARCHER = Searcher.newWithBuffer(cBuff);
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("RegionUtils初始化失败,原因:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据IP地址离线获取城市
|
||||
*/
|
||||
public static String getCityInfo(String ip) {
|
||||
try {
|
||||
ip = ip.trim();
|
||||
// 3、执行查询
|
||||
String region = SEARCHER.search(ip);
|
||||
return region.replace("0|", "").replace("|0", "");
|
||||
} catch (Exception e) {
|
||||
log.error("IP地址离线获取城市异常 {}", ip);
|
||||
return "未知";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -26,6 +26,12 @@
|
||||
<dependency>
|
||||
<groupId>tech.powerjob</groupId>
|
||||
<artifactId>powerjob-worker-spring-boot-starter</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>powerjob-remote-impl-akka</artifactId>
|
||||
<groupId>tech.powerjob</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>tech.powerjob</groupId>
|
||||
|
@ -5,6 +5,7 @@ import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
import com.ruoyi.common.core.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.core.utils.ServletUtils;
|
||||
import com.ruoyi.common.core.utils.SpringUtils;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
@ -94,7 +95,9 @@ public class LogAspect {
|
||||
String ip = ServletUtils.getClientIP();
|
||||
operLog.setOperIp(ip);
|
||||
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
|
||||
operLog.setOperName(LoginHelper.getUsername());
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
operLog.setOperName(loginUser.getUsername());
|
||||
operLog.setDeptName(loginUser.getDeptName());
|
||||
|
||||
if (e != null) {
|
||||
operLog.setStatus(BusinessStatus.FAIL.ordinal());
|
||||
|
@ -43,14 +43,14 @@ public class FlexWebInvokeTimeInterceptor implements HandlerInterceptor {
|
||||
BufferedReader reader = request.getReader();
|
||||
jsonParam = IoUtil.read(reader);
|
||||
}
|
||||
log.debug("[PLUS]开始请求 => URL[{}],参数类型[json],参数:[{}]", url, jsonParam);
|
||||
log.info("[Ruoyi-Flex]开始请求 => URL[{}],参数类型[json],参数:[{}]", url, jsonParam);
|
||||
} else {
|
||||
Map<String, String[]> parameterMap = request.getParameterMap();
|
||||
if (MapUtil.isNotEmpty(parameterMap)) {
|
||||
String parameters = JsonUtils.toJsonString(parameterMap);
|
||||
log.debug("[PLUS]开始请求 => URL[{}],参数类型[param],参数:[{}]", url, parameters);
|
||||
log.info("[Ruoyi-Flex]开始请求 => URL[{}],参数类型[param],参数:[{}]", url, parameters);
|
||||
} else {
|
||||
log.debug("[PLUS]开始请求 => URL[{}],无参数", url);
|
||||
log.info("[Ruoyi-Flex]开始请求 => URL[{}],无参数", url);
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ public class FlexWebInvokeTimeInterceptor implements HandlerInterceptor {
|
||||
if (!prodProfile.equals(SpringUtils.getActiveProfile())) {
|
||||
StopWatch stopWatch = invokeTimeTL.get();
|
||||
stopWatch.stop();
|
||||
log.debug("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime());
|
||||
log.info("[Ruoyi-Flex]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime());
|
||||
invokeTimeTL.remove();
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ public class GenController extends BaseController
|
||||
*/
|
||||
@SaCheckPermission("tool:gen:list")
|
||||
@GetMapping(value = "/column/{tableId}")
|
||||
public TableDataInfo columnList(Long tableId)
|
||||
public TableDataInfo columnList(@PathVariable("tableId") Long tableId)
|
||||
{
|
||||
TableDataInfo dataInfo = new TableDataInfo();
|
||||
List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(tableId);
|
||||
|
@ -40,7 +40,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</select>
|
||||
|
||||
<select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
|
||||
select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type
|
||||
select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else '0' end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type
|
||||
from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
|
||||
order by ordinal_position
|
||||
</select>
|
||||
|
@ -79,80 +79,80 @@ public class SysMenu extends BaseEntity
|
||||
/** 子菜单 */
|
||||
private List<SysMenu> children = new ArrayList<>();
|
||||
|
||||
// /**
|
||||
// * 获取路由名称
|
||||
// */
|
||||
// public String getRouteName() {
|
||||
// String routerName = StringUtils.capitalize(path);
|
||||
// // 非外链并且是一级目录(类型为目录)
|
||||
// if (isMenuFrame()) {
|
||||
// routerName = StringUtils.EMPTY;
|
||||
// }
|
||||
// return routerName;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取路由地址
|
||||
// */
|
||||
// public String getRouterPath() {
|
||||
// String routerPath = this.path;
|
||||
// // 内链打开外网方式
|
||||
// if (getParentId() != 0L && isInnerLink()) {
|
||||
// routerPath = innerLinkReplaceEach(routerPath);
|
||||
// }
|
||||
// // 非外链并且是一级目录(类型为目录)
|
||||
// if (0L == getParentId() && UserConstants.TYPE_DIR.equals(getMenuType())
|
||||
// && UserConstants.NO_FRAME.equals(getIsFrame())) {
|
||||
// routerPath = "/" + this.path;
|
||||
// }
|
||||
// // 非外链并且是一级目录(类型为菜单)
|
||||
// else if (isMenuFrame()) {
|
||||
// routerPath = "/";
|
||||
// }
|
||||
// return routerPath;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取组件信息
|
||||
// */
|
||||
// public String getComponentInfo() {
|
||||
// String component = UserConstants.LAYOUT;
|
||||
// if (StringUtils.isNotEmpty(this.component) && !isMenuFrame()) {
|
||||
// component = this.component;
|
||||
// } else if (StringUtils.isEmpty(this.component) && getParentId() != 0L && isInnerLink()) {
|
||||
// component = UserConstants.INNER_LINK;
|
||||
// } else if (StringUtils.isEmpty(this.component) && isParentView()) {
|
||||
// component = UserConstants.PARENT_VIEW;
|
||||
// }
|
||||
// return component;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 是否为菜单内部跳转
|
||||
// */
|
||||
// public boolean isMenuFrame() {
|
||||
// return getParentId() == 0L && UserConstants.TYPE_MENU.equals(menuType) && isFrame.equals(UserConstants.NO_FRAME);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 是否为内链组件
|
||||
// */
|
||||
// public boolean isInnerLink() {
|
||||
// return isFrame.equals(UserConstants.NO_FRAME) && StringUtils.ishttp(path);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 是否为parent_view组件
|
||||
// */
|
||||
// public boolean isParentView() {
|
||||
// return getParentId() != 0L && UserConstants.TYPE_DIR.equals(menuType);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 内链域名特殊字符替换
|
||||
// */
|
||||
// public static String innerLinkReplaceEach(String path) {
|
||||
// return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "."},
|
||||
// new String[]{"", "", "", "/"});
|
||||
// }
|
||||
/**
|
||||
* 获取路由名称
|
||||
*/
|
||||
public String getRouteName() {
|
||||
String routerName = StringUtils.capitalize(path);
|
||||
// 非外链并且是一级目录(类型为目录)
|
||||
if (isMenuFrame()) {
|
||||
routerName = StringUtils.EMPTY;
|
||||
}
|
||||
return routerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路由地址
|
||||
*/
|
||||
public String getRouterPath() {
|
||||
String routerPath = this.path;
|
||||
// 内链打开外网方式
|
||||
if (getParentId() != 0L && isInnerLink()) {
|
||||
routerPath = innerLinkReplaceEach(routerPath);
|
||||
}
|
||||
// 非外链并且是一级目录(类型为目录)
|
||||
if (0L == getParentId() && UserConstants.TYPE_DIR.equals(getMenuType())
|
||||
&& UserConstants.NO_FRAME.equals(getIsFrame())) {
|
||||
routerPath = "/" + this.path;
|
||||
}
|
||||
// 非外链并且是一级目录(类型为菜单)
|
||||
else if (isMenuFrame()) {
|
||||
routerPath = "/";
|
||||
}
|
||||
return routerPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组件信息
|
||||
*/
|
||||
public String getComponentInfo() {
|
||||
String component = UserConstants.LAYOUT;
|
||||
if (StringUtils.isNotEmpty(this.component) && !isMenuFrame()) {
|
||||
component = this.component;
|
||||
} else if (StringUtils.isEmpty(this.component) && getParentId() != 0L && isInnerLink()) {
|
||||
component = UserConstants.INNER_LINK;
|
||||
} else if (StringUtils.isEmpty(this.component) && isParentView()) {
|
||||
component = UserConstants.PARENT_VIEW;
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为菜单内部跳转
|
||||
*/
|
||||
public boolean isMenuFrame() {
|
||||
return getParentId() == 0L && UserConstants.TYPE_MENU.equals(menuType) && isFrame.equals(UserConstants.NO_FRAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为内链组件
|
||||
*/
|
||||
public boolean isInnerLink() {
|
||||
return isFrame.equals(UserConstants.NO_FRAME) && StringUtils.ishttp(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为parent_view组件
|
||||
*/
|
||||
public boolean isParentView() {
|
||||
return getParentId() != 0L && UserConstants.TYPE_DIR.equals(menuType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内链域名特殊字符替换
|
||||
*/
|
||||
public static String innerLinkReplaceEach(String path) {
|
||||
return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":"},
|
||||
new String[]{"", "", "", "/", "/"});
|
||||
}
|
||||
}
|
||||
|
@ -462,7 +462,7 @@ public class SysMenuServiceImpl extends BaseServiceImpl<SysMenuMapper,SysMenu> i
|
||||
* @return 替换后的内链域名
|
||||
*/
|
||||
public String innerLinkReplaceEach(String path) {
|
||||
return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "."},
|
||||
new String[]{"", "", "", "/"});
|
||||
return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":" },
|
||||
new String[] { "", "", "", "/", "/" });
|
||||
}
|
||||
}
|
||||
|
@ -308,20 +308,22 @@ public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleMapper, SysRole>
|
||||
if (ObjectUtil.isNotNull(roleBo.getRoleId()) && LoginHelper.isSuperAdmin(roleBo.getRoleId())) {
|
||||
throw new ServiceException("不允许操作超级管理员角色");
|
||||
}
|
||||
String[] keys = new String[]{TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.TENANT_ADMIN_ROLE_KEY};
|
||||
// 新增:不允许使用 管理员标识符
|
||||
if (ObjectUtil.isNull(roleBo.getRoleId())
|
||||
&& StringUtils.equalsAny(roleBo.getRoleKey(),
|
||||
TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.TENANT_ADMIN_ROLE_KEY)) {
|
||||
&& StringUtils.equalsAny(roleBo.getRoleKey(), keys)) {
|
||||
throw new ServiceException("不允许使用系统内置管理员角色标识符!");
|
||||
}
|
||||
// 修改:不允许修改 管理员标识符
|
||||
if (ObjectUtil.isNotNull(roleBo.getRoleId())) {
|
||||
SysRole sysRole = this.getById(roleBo.getRoleId());
|
||||
// 如果标识符不相等 判断为修改了管理员标识符
|
||||
if (!StringUtils.equals(sysRole.getRoleKey(), roleBo.getRoleKey())
|
||||
&& StringUtils.equalsAny(sysRole.getRoleKey(),
|
||||
TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.TENANT_ADMIN_ROLE_KEY)) {
|
||||
if (!StringUtils.equals(sysRole.getRoleKey(), roleBo.getRoleKey())) {
|
||||
if (StringUtils.equalsAny(sysRole.getRoleKey(), keys)) {
|
||||
throw new ServiceException("不允许修改系统内置管理员角色标识符!");
|
||||
} else if (StringUtils.equalsAny(roleBo.getRoleKey(), keys)) {
|
||||
throw new ServiceException("不允许使用系统内置管理员角色标识符!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user