2 Commits

Author SHA1 Message Date
死亡诗人
89bdfd0584 Pre Merge pull request !411 from 死亡诗人/master 2025-12-16 08:42:32 +00:00
adinlead
eeeaa00747 修复了由于Nacos2.2+镜像版本引起的无法启动NacosDocker问题 2025-05-27 15:57:51 +08:00
48 changed files with 114 additions and 258 deletions

View File

@@ -1,11 +1,11 @@
<p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-b99b286755aef70355a7084753f89cdb7c9.png">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.6.7</h1>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.6.6</h1>
<h4 align="center">基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构</h4>
<p align="center">
<a href="https://gitee.com/y_project/RuoYi-Cloud/stargazers"><img src="https://gitee.com/y_project/RuoYi-Cloud/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.6.7-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.6.6-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p>

View File

@@ -10,7 +10,7 @@ usage() {
# copy sql
echo "begin copy sql "
cp ../sql/ry_20250523.sql ./mysql/db
cp ../sql/ry_config_20250902.sql ./mysql/db
cp ../sql/ry_config_20250224.sql ./mysql/db
# copy html
echo "begin copy html "

View File

@@ -7,10 +7,16 @@ services:
context: ./nacos
environment:
- MODE=standalone
# Nacos 2.2+ 需要设置以下启动参数
- NACOS_AUTH_TOKEN=U2VjcmV0S2V5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5
- NACOS_AUTH_IDENTITY_KEY=serverIdentity
- NACOS_AUTH_IDENTITY_VALUE=security
volumes:
- ./nacos/logs/:/home/nacos/logs
- ./nacos/conf/application.properties:/home/nacos/conf/application.properties
ports:
# Nacos 2.0+ 默认管理端口
- "8864:8080"
- "8848:8848"
- "9848:9848"
- "9849:9849"

View File

@@ -22,11 +22,11 @@ nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/
nacos.core.auth.system.type=nacos
nacos.core.auth.enabled=false
nacos.core.auth.default.token.expire.seconds=18000
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
nacos.core.auth.plugin.nacos.token.expire.seconds=18000
nacos.core.auth.plugin.nacos.token.secret.key=U2VjcmV0S2V5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5
nacos.core.auth.caching.enabled=true
nacos.core.auth.enable.userAgentAuthWhite=false
nacos.core.auth.server.identity.key=serverIdentity
nacos.core.auth.server.identity.value=security
nacos.istio.mcp.server.enabled=false
nacos.istio.mcp.server.enabled=false

View File

@@ -6,14 +6,14 @@
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依微服务系统</description>
<properties>
<ruoyi.version>3.6.7</ruoyi.version>
<ruoyi.version>3.6.6</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -114,6 +114,11 @@ public class SysUser extends BaseEntity
}
public boolean isAdmin()
{
return isAdmin(this.userId);
}
public static boolean isAdmin(Long userId)
{
return UserConstants.isAdmin(userId);
}

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@ package com.ruoyi.common.core.exception.file;
import java.util.Arrays;
/**
* 文件上传无效扩展名异常类
* 文件上传异常类
*
* @author ruoyi
*/

View File

@@ -1003,7 +1003,7 @@ public class ExcelUtil<T>
String separator = attr.separator();
if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
{
cell.setCellStyle(createCellStyle(cell.getCellStyle(), dateFormat));
cell.getCellStyle().setDataFormat(this.wb.getCreationHelper().createDataFormat().getFormat(dateFormat));
cell.setCellValue(parseDateToStr(dateFormat, value));
}
else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
@@ -1033,21 +1033,6 @@ public class ExcelUtil<T>
return cell;
}
/**
* 使用自定义格式,同时避免样式污染
*
* @param cellStyle 从此样式复制
* @param format 格式匹配的字符串
* @return 格式化后CellStyle对象
*/
private CellStyle createCellStyle(CellStyle cellStyle, String format)
{
CellStyle style = wb.createCellStyle();
style.cloneStyleFrom(cellStyle);
style.setDataFormat(wb.getCreationHelper().createDataFormat().getFormat(format));
return style;
}
/**
* 设置 POI XSSFSheet 单元格提示或选择框
*

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,6 @@ import javax.servlet.http.HttpServletRequest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.constant.TokenConstants;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.context.SecurityContextHolder;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
@@ -80,16 +79,6 @@ public class SecurityUtils
return token;
}
/**
* 是否为管理员
*
* @return 结果
*/
public static boolean isAdmin()
{
return isAdmin(getUserId());
}
/**
* 是否为管理员
*
@@ -98,7 +87,7 @@ public class SecurityUtils
*/
public static boolean isAdmin(Long userId)
{
return UserConstants.isAdmin(userId);
return userId != null && 1L == userId;
}
/**

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -97,10 +97,6 @@ public class SysMenuController extends BaseController
{
return error("新增菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
}
else if (!menuService.checkRouteConfigUnique(menu))
{
return error("新增菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
}
menu.setCreateBy(SecurityUtils.getUsername());
return toAjax(menuService.insertMenu(menu));
}
@@ -125,10 +121,6 @@ public class SysMenuController extends BaseController
{
return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
}
else if (!menuService.checkRouteConfigUnique(menu))
{
return error("修改菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
}
menu.setUpdateBy(SecurityUtils.getUsername());
return toAjax(menuService.updateMenu(menu));
}

View File

@@ -235,7 +235,7 @@ public class SysUserController extends BaseController
ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
}
List<SysRole> roles = roleService.selectRoleAll();
ajax.put("roles", SecurityUtils.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
ajax.put("posts", postService.selectPostAll());
return ajax;
}
@@ -350,7 +350,7 @@ public class SysUserController extends BaseController
SysUser user = userService.selectUserById(userId);
List<SysRole> roles = roleService.selectRolesByUserId(userId);
ajax.put("user", user);
ajax.put("roles", SecurityUtils.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
return ajax;
}

View File

@@ -122,13 +122,4 @@ public interface SysMenuMapper
* @return 结果
*/
public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId);
/**
* 根据路由路径或名称查询菜单信息(用于唯一性校验)
*
* @param path 路由地址
* @param routeName 路由名称
* @return 匹配的菜单列表
*/
public List<SysMenu> selectMenusByPathOrRouteName(@Param("path") String path, @Param("routeName") String routeName);
}

View File

@@ -141,12 +141,4 @@ public interface ISysMenuService
* @return 结果
*/
public boolean checkMenuNameUnique(SysMenu menu);
/**
* 校验路由组合是否唯一
*
* @param menu 菜单信息
* @return 结果
*/
public boolean checkRouteConfigUnique(SysMenu menu);
}

View File

@@ -15,6 +15,7 @@ import com.ruoyi.common.datascope.annotation.DataScope;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysDept;
import com.ruoyi.system.api.domain.SysRole;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.domain.vo.TreeSelect;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
@@ -189,7 +190,7 @@ public class SysDeptServiceImpl implements ISysDeptService
@Override
public void checkDeptDataScope(Long deptId)
{
if (!SecurityUtils.isAdmin() && StringUtils.isNotNull(deptId))
if (!SysUser.isAdmin(SecurityUtils.getUserId()) && StringUtils.isNotNull(deptId))
{
SysDept dept = new SysDept();
dept.setDeptId(deptId);

View File

@@ -8,8 +8,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.constant.Constants;
@@ -17,6 +15,7 @@ import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysRole;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.domain.SysMenu;
import com.ruoyi.system.domain.vo.MetaVo;
import com.ruoyi.system.domain.vo.RouterVo;
@@ -34,12 +33,8 @@ import com.ruoyi.system.service.ISysMenuService;
@Service
public class SysMenuServiceImpl implements ISysMenuService
{
private static final Logger log = LoggerFactory.getLogger(SysMenuServiceImpl.class);
public static final String PREMISSION_STRING = "perms[\"{0}\"]";
public static final Long MENU_ROOT_ID = 0L;
@Autowired
private SysMenuMapper menuMapper;
@@ -72,7 +67,7 @@ public class SysMenuServiceImpl implements ISysMenuService
{
List<SysMenu> menuList = null;
// 管理员显示所有菜单信息
if (SecurityUtils.isAdmin(userId))
if (SysUser.isAdmin(userId))
{
menuList = menuMapper.selectMenuList(menu);
}
@@ -144,7 +139,7 @@ public class SysMenuServiceImpl implements ISysMenuService
{
menus = menuMapper.selectMenuTreeByUserId(userId);
}
return getChildPerms(menus, MENU_ROOT_ID);
return getChildPerms(menus, 0);
}
/**
@@ -199,7 +194,7 @@ public class SysMenuServiceImpl implements ISysMenuService
childrenList.add(children);
router.setChildren(childrenList);
}
else if (menu.getParentId().intValue() == MENU_ROOT_ID && isInnerLink(menu))
else if (menu.getParentId().intValue() == 0 && isInnerLink(menu))
{
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
router.setPath("/");
@@ -351,47 +346,6 @@ public class SysMenuServiceImpl implements ISysMenuService
return UserConstants.UNIQUE;
}
/**
* 校验路由名称是否唯一
*
* @param menu 菜单信息
* @return 结果
*/
@Override
public boolean checkRouteConfigUnique(SysMenu menu)
{
Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
Long parentId = menu.getParentId();
String path = menu.getPath();
String routeName = StringUtils.isEmpty(menu.getRouteName()) ? path : menu.getRouteName();
List<SysMenu> sysMenuList = menuMapper.selectMenusByPathOrRouteName(path, routeName);
for (SysMenu sysMenu : sysMenuList)
{
if (sysMenu.getMenuId().longValue() != menuId.longValue())
{
Long dbParentId = sysMenu.getParentId();
String dbPath = sysMenu.getPath();
String dbRouteName = StringUtils.isEmpty(sysMenu.getRouteName()) ? dbPath : sysMenu.getRouteName();
if (StringUtils.equalsAnyIgnoreCase(path, dbPath) && parentId.longValue() == dbParentId.longValue())
{
log.warn("[同级路由冲突] 同级下已存在相同路由路径 '{}',冲突菜单:{}", dbPath, sysMenu.getMenuName());
return UserConstants.NOT_UNIQUE;
}
else if (StringUtils.equalsAnyIgnoreCase(path, dbPath) && parentId.longValue() == MENU_ROOT_ID)
{
log.warn("[根目录路由冲突] 根目录下路由 '{}' 必须唯一,已被菜单 '{}' 占用", path, sysMenu.getMenuName());
return UserConstants.NOT_UNIQUE;
}
else if (StringUtils.equalsAnyIgnoreCase(routeName, dbRouteName))
{
log.warn("[路由名称冲突] 路由名称 '{}' 需全局唯一,已被菜单 '{}' 使用", routeName, sysMenu.getMenuName());
return UserConstants.NOT_UNIQUE;
}
}
}
return UserConstants.UNIQUE;
}
/**
* 获取路由名称
*
@@ -431,12 +385,12 @@ public class SysMenuServiceImpl implements ISysMenuService
{
String routerPath = menu.getPath();
// 内链打开外网方式
if (menu.getParentId().intValue() != MENU_ROOT_ID && isInnerLink(menu))
if (menu.getParentId().intValue() != 0 && isInnerLink(menu))
{
routerPath = innerLinkReplaceEach(routerPath);
}
// 非外链并且是一级目录(类型为目录)
if (MENU_ROOT_ID == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType())
if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType())
&& UserConstants.NO_FRAME.equals(menu.getIsFrame()))
{
routerPath = "/" + menu.getPath();
@@ -462,7 +416,7 @@ public class SysMenuServiceImpl implements ISysMenuService
{
component = menu.getComponent();
}
else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != MENU_ROOT_ID && isInnerLink(menu))
else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu))
{
component = UserConstants.INNER_LINK;
}
@@ -481,21 +435,10 @@ public class SysMenuServiceImpl implements ISysMenuService
*/
public boolean isMenuFrame(SysMenu menu)
{
return menu.getParentId().intValue() == MENU_ROOT_ID && UserConstants.TYPE_MENU.equals(menu.getMenuType())
return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType())
&& menu.getIsFrame().equals(UserConstants.NO_FRAME);
}
/**
* 是否为parent_view组件
*
* @param menu 菜单信息
* @return 结果
*/
public boolean isParentView(SysMenu menu)
{
return menu.getParentId().intValue() != MENU_ROOT_ID && UserConstants.TYPE_DIR.equals(menu.getMenuType());
}
/**
* 是否为内链组件
*
@@ -507,6 +450,17 @@ public class SysMenuServiceImpl implements ISysMenuService
return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath());
}
/**
* 是否为parent_view组件
*
* @param menu 菜单信息
* @return 结果
*/
public boolean isParentView(SysMenu menu)
{
return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType());
}
/**
* 根据父节点的ID获取所有子节点
*
@@ -514,7 +468,7 @@ public class SysMenuServiceImpl implements ISysMenuService
* @param parentId 传入的父节点ID
* @return String
*/
public List<SysMenu> getChildPerms(List<SysMenu> list, long parentId)
public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId)
{
List<SysMenu> returnList = new ArrayList<SysMenu>();
for (Iterator<SysMenu> iterator = list.iterator(); iterator.hasNext();)

View File

@@ -15,6 +15,7 @@ import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.datascope.annotation.DataScope;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysRole;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.domain.SysRoleDept;
import com.ruoyi.system.domain.SysRoleMenu;
import com.ruoyi.system.domain.SysUserRole;
@@ -196,7 +197,7 @@ public class SysRoleServiceImpl implements ISysRoleService
@Override
public void checkRoleDataScope(Long... roleIds)
{
if (!SecurityUtils.isAdmin())
if (!SysUser.isAdmin(SecurityUtils.getUserId()))
{
for (Long roleId : roleIds)
{

View File

@@ -238,7 +238,7 @@ public class SysUserServiceImpl implements ISysUserService
@Override
public void checkUserDataScope(Long userId)
{
if (!SecurityUtils.isAdmin())
if (!SysUser.isAdmin(SecurityUtils.getUserId()))
{
SysUser user = new SysUser();
user.setUserId(userId);

View File

@@ -130,12 +130,7 @@
<select id="checkMenuNameUnique" parameterType="SysMenu" resultMap="SysMenuResult">
<include refid="selectMenuVo"/>
where menu_name= #{menuName} and parent_id = #{parentId} limit 1
</select>
<select id="selectMenusByPathOrRouteName" parameterType="SysMenu" resultMap="SysMenuResult">
<include refid="selectMenuVo"/>
where menu_type in ('M', 'C') and (path = #{path} or path = #{routeName} or route_name = #{path} or route_name = #{routeName})
where menu_name=#{menuName} and parent_id = #{parentId} limit 1
</select>
<update id="updateMenu" parameterType="SysMenu">

View File

@@ -1,6 +1,6 @@
{
"name": "ruoyi",
"version": "3.6.7",
"version": "3.6.6",
"description": "若依管理系统",
"author": "若依",
"license": "MIT",

View File

@@ -130,10 +130,12 @@
border-radius: 4px;
}
/* horizontal el menu */
.el-menu--horizontal .el-menu-item .svg-icon + span,
.el-menu--horizontal .el-submenu__title .svg-icon + span {
margin-left: 3px;
/* el menu */
.el-menu-item,
.el-sub-menu {
.svg-icon + span {
margin-left: 5px;
}
}
.el-menu--horizontal .el-menu--popup {

View File

@@ -116,17 +116,15 @@
margin-left: 54px;
}
.el-menu:not(.el-menu--horizontal) {
.submenu-title-noDropdown {
.submenu-title-noDropdown {
padding: 0 !important;
position: relative;
.el-tooltip {
padding: 0 !important;
position: relative;
.el-tooltip {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
.svg-icon {
margin-left: 20px;
}
}
}

View File

@@ -80,39 +80,6 @@ export default {
min-height: 0px;
}
}
/* 移动端fixed-header优化 */
@media screen and (max-width: 991px) {
.fixed-header + .app-main {
padding-bottom: max(60px, calc(constant(safe-area-inset-bottom) + 40px));
padding-bottom: max(60px, calc(env(safe-area-inset-bottom) + 40px));
overscroll-behavior-y: none;
}
.hasTagsView .fixed-header + .app-main {
padding-bottom: max(60px, calc(constant(safe-area-inset-bottom) + 40px));
padding-bottom: max(60px, calc(env(safe-area-inset-bottom) + 40px));
overscroll-behavior-y: none;
}
}
@supports (-webkit-touch-callout: none) {
@media screen and (max-width: 991px) {
.fixed-header + .app-main {
padding-bottom: max(17px, calc(constant(safe-area-inset-bottom) + 10px));
padding-bottom: max(17px, calc(env(safe-area-inset-bottom) + 10px));
height: calc(100svh - 50px);
height: calc(100dvh - 50px);
}
.hasTagsView .fixed-header + .app-main {
padding-bottom: max(17px, calc(constant(safe-area-inset-bottom) + 10px));
padding-bottom: max(17px, calc(env(safe-area-inset-bottom) + 10px));
height: calc(100svh - 84px);
height: calc(100dvh - 84px);
}
}
}
</style>
<style lang="scss">

View File

@@ -60,22 +60,36 @@ export default {
</script>
<style lang="scss">
/* menu item */
.topbar-menu.el-menu--horizontal .el-submenu__title, .topbar-menu.el-menu--horizontal .el-menu-item {
padding: 0 10px !important;
.topbar-menu.el-menu--horizontal > .el-menu-item {
float: left;
height: 50px !important;
line-height: 50px !important;
color: #303133 !important;
padding: 0 5px !important;
margin: 0 10px !important;
}
.el-menu--horizontal .el-menu--popup .el-menu-item:hover {
background-color: #f5f7fa !important;
.el-menu-item.is-active .svg-icon + span, .el-submenu.is-active .svg-icon + span{
color: v-bind(theme);
}
.el-menu--horizontal .el-menu .el-menu-item, .el-menu--horizontal .el-menu .el-submenu__title {
color: #303133 !important;
}
/* submenu item */
.topbar-menu.el-menu--horizontal > .el-submenu .el-submenu__title {
float: left;
height: 47px !important;
height: 50px !important;
line-height: 50px !important;
color: #303133;
margin: 0 15px !important;
color: #303133 !important;
padding: 0 5px !important;
margin: 0 10px !important;
}
/* 图标右间距 */
.topbar-menu .svg-icon {
margin-right: 4px;
}
/* topbar more arrow */
@@ -89,10 +103,6 @@ export default {
/* menu__title el-menu-item */
.topbar-menu.el-menu--horizontal .el-submenu__title, .topbar-menu.el-menu--horizontal .el-menu-item {
height: 55px;
}
.el-menu--horizontal .el-menu .el-menu-item, .el-menu--horizontal .el-menu .el-submenu__title{
color: #303133;
padding: 0 15px;
}
</style>

View File

@@ -32,7 +32,7 @@ module.exports = {
/**
* 是否固定头部
*/
fixedHeader: true,
fixedHeader: false,
/**
* 是否显示logo
@@ -52,5 +52,5 @@ module.exports = {
/**
* 底部版权文本内容
*/
footerContent: 'Copyright © 2018-2026 RuoYi. All Rights Reserved.'
footerContent: 'Copyright © 2018-2025 RuoYi. All Rights Reserved.'
}

View File

@@ -26,8 +26,6 @@ service.interceptors.request.use(config => {
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
// 间隔时间(ms),小于此时间视为重复提交
const interval = (config.headers || {}).interval || 1000
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
@@ -57,6 +55,7 @@ service.interceptors.request.use(config => {
const s_url = sessionObj.url // 请求地址
const s_data = sessionObj.data // 请求数据
const s_time = sessionObj.time // 请求时间
const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
const message = '数据正在处理,请勿重复提交'
console.warn(`[${s_url}]: ` + message)
@@ -116,7 +115,7 @@ service.interceptors.response.use(res => {
} else if (message.includes("timeout")) {
message = "系统接口请求超时"
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.slice(-3) + "异常"
message = "系统接口" + message.substr(message.length - 3) + "异常"
}
Message({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)

View File

@@ -108,37 +108,6 @@
<span>更新日志</span>
</div>
<el-collapse accordion>
<el-collapse-item title="v3.6.7 - 2025-12-22">
<ol>
<li>支持防盗链功能</li>
<li>菜单导航设置支持纯顶部</li>
<li>用户头像更换后移除旧头像文件</li>
<li>支持Excel导出对象的多个子列表</li>
<li>升级druid到最新版本1.2.27</li>
<li>升级fastjson到最新版2.0.60</li>
<li>升级tomcat到最新版本9.0.112</li>
<li>升级commons.io到最新版本2.21.0</li>
<li>用户导入添加验证提示</li>
<li>显示列信息支持对象格式</li>
<li>网页标题设置新增SET_TITLE方法</li>
<li>自动识别json对象白名单配置范围缩小</li>
<li>登录/注册页面底部版权信息修改为读取配置</li>
<li>修复用户归属部门无法修改为空问题</li>
<li>修复固定头部时出现的导航栏偏移问题</li>
<li>修复v3时间控件between选择后清空报错问题</li>
<li>修复comboReadDict属性下多个sheet出现的报错</li>
<li>修复表单构建移除所有控件后切换路由回来空白问题</li>
<li>优化布局设置显示</li>
<li>优化字典组件值宽松匹配</li>
<li>优化生成代码下载的zip文件名</li>
<li>优化日志记录参数拼装提升效率</li>
<li>优化导入文件检查标题行不能为空</li>
<li>优化表单构建关闭页签销毁复制插件</li>
<li>优化Excel统计行数值的单元格样式显示</li>
<li>优化数据权限控制逻辑放开permission限制</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.6.6 - 2025-05-30">
<ol>
<li>优化菜单搜索查询页</li>
@@ -987,7 +956,7 @@ export default {
data() {
return {
// 版本号
version: "3.6.7"
version: "3.6.6"
}
},
methods: {

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-visual</artifactId>
<version>3.6.7</version>
<version>3.6.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -178,7 +178,7 @@ insert into sys_menu values('108', '日志管理', '1', '9', 'log',
insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单');
insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单');
insert into sys_menu values('111', 'Sentinel控制台', '2', '3', 'http://localhost:8718', '', '', '', 0, 0, 'C', '0', '0', 'monitor:sentinel:list', 'sentinel', 'admin', sysdate(), '', null, '流量控制菜单');
insert into sys_menu values('112', 'Nacos控制台', '2', '4', 'http://localhost:8848/nacos', '', '', '', 0, 0, 'C', '0', '0', 'monitor:nacos:list', 'nacos', 'admin', sysdate(), '', null, '服务治理菜单');
insert into sys_menu values('112', 'Nacos控制台', '2', '4', 'http://localhost:8864', '', '', '', 0, 0, 'C', '0', '0', 'monitor:nacos:list', 'nacos', 'admin', sysdate(), '', null, '服务治理菜单');
insert into sys_menu values('113', 'Admin控制台', '2', '5', 'http://localhost:9100/login', '', '', '', 0, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单');
insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', '', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单');
insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单');