diff --git a/continew-system/src/main/java/top/continew/admin/system/service/UserRoleService.java b/continew-system/src/main/java/top/continew/admin/system/service/UserRoleService.java
index f6289aa17..e756232e7 100644
--- a/continew-system/src/main/java/top/continew/admin/system/service/UserRoleService.java
+++ b/continew-system/src/main/java/top/continew/admin/system/service/UserRoleService.java
@@ -103,4 +103,18 @@ public interface UserRoleService {
* @return 是否已关联(true:已关联;false:未关联)
*/
boolean isRoleIdExists(List roleIds);
+
+ /**
+ * 检查系统内置用户是否在用户列表中,如果存在则抛出异常
+ *
+ * @param userIds 用户 ID 列表
+ */
+ void checkSystemUserAssignment(List userIds);
+
+ /**
+ * 检查系统内置用户是否在用户角色关联列表中,如果存在则抛出异常
+ *
+ * @param userRoleIds 用户角色关联 ID 列表
+ */
+ void checkSystemUserUnassignment(List userRoleIds);
}
\ No newline at end of file
diff --git a/continew-system/src/main/java/top/continew/admin/system/service/impl/FileServiceImpl.java b/continew-system/src/main/java/top/continew/admin/system/service/impl/FileServiceImpl.java
index e1504007b..85da45a4e 100644
--- a/continew-system/src/main/java/top/continew/admin/system/service/impl/FileServiceImpl.java
+++ b/continew-system/src/main/java/top/continew/admin/system/service/impl/FileServiceImpl.java
@@ -235,7 +235,8 @@ private FileInfo upload(Object file, String parentPath, String storageCode, Stri
// 生成唯一文件名(处理重名情况)
String originalFileName = getOriginalFileName(file);
- String uniqueFileName = FileNameGenerator.generateUniqueName(originalFileName, parentPath, storage.getId(), baseMapper);
+ String uniqueFileName = FileNameGenerator.generateUniqueName(originalFileName, parentPath, storage
+ .getId(), baseMapper);
UploadPretreatment uploadPretreatment = fileStorageService.of(file)
.setPlatform(storage.getCode())
diff --git a/continew-system/src/main/java/top/continew/admin/system/service/impl/MultipartUploadServiceImpl.java b/continew-system/src/main/java/top/continew/admin/system/service/impl/MultipartUploadServiceImpl.java
index ef6bb67a3..995cc9218 100644
--- a/continew-system/src/main/java/top/continew/admin/system/service/impl/MultipartUploadServiceImpl.java
+++ b/continew-system/src/main/java/top/continew/admin/system/service/impl/MultipartUploadServiceImpl.java
@@ -104,7 +104,8 @@ public MultipartUploadInitResp initMultipartUpload(MultipartUploadInitReq multiP
}
// 生成唯一文件名(处理重名情况)
- String uniqueFileName = FileNameGenerator.generateUniqueName(originalFileName, parentPath, storageDO.getId(), fileMapper);
+ String uniqueFileName = FileNameGenerator.generateUniqueName(originalFileName, parentPath, storageDO
+ .getId(), fileMapper);
multiPartUploadInitReq.setFileName(uniqueFileName);
StorageHandler storageHandler = storageHandlerFactory.createHandler(storageDO.getType());
diff --git a/continew-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java b/continew-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java
index 7ff97946b..8cc84375a 100644
--- a/continew-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java
+++ b/continew-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java
@@ -164,6 +164,10 @@ public void updatePermission(Long id, RolePermissionUpdateReq req) {
public void assignToUsers(Long id, List userIds) {
RoleDO role = super.getById(id);
CheckUtils.throwIf(Boolean.TRUE.equals(role.getIsSystem()), "[{}] 是系统内置角色,不允许分配角色给其他用户", role.getName());
+ // 防止将系统内置用户分配给非超级管理员角色
+ if (!SystemConstants.SUPER_ADMIN_ROLE_ID.equals(id)) {
+ userRoleService.checkSystemUserAssignment(userIds);
+ }
// 保存用户和角色关联
userRoleService.assignRoleToUsers(id, userIds);
// 更新用户上下文
diff --git a/continew-system/src/main/java/top/continew/admin/system/service/impl/UserRoleServiceImpl.java b/continew-system/src/main/java/top/continew/admin/system/service/impl/UserRoleServiceImpl.java
index 172e5d5d0..2d2ab50ee 100644
--- a/continew-system/src/main/java/top/continew/admin/system/service/impl/UserRoleServiceImpl.java
+++ b/continew-system/src/main/java/top/continew/admin/system/service/impl/UserRoleServiceImpl.java
@@ -120,6 +120,8 @@ public boolean assignRoleToUsers(Long roleId, List userIds) {
@Override
public void deleteByIds(List ids) {
+ // 检查是否包含系统内置用户的角色关联
+ this.checkSystemUserUnassignment(ids);
baseMapper.deleteByIds(ids);
}
@@ -165,4 +167,42 @@ public boolean isRoleIdExists(List roleIds) {
}
return baseMapper.lambdaQuery().in(UserRoleDO::getRoleId, roleIds).exists();
}
+
+ @Override
+ public void checkSystemUserAssignment(List userIds) {
+ if (CollUtil.isEmpty(userIds)) {
+ return;
+ }
+ // 查询用户列表中是否包含系统内置用户
+ List systemUsers = userService.lambdaQuery()
+ .select(UserDO::getId, UserDO::getNickname)
+ .in(UserDO::getId, userIds)
+ .eq(UserDO::getIsSystem, true)
+ .list();
+ CheckUtils.throwIfNotEmpty(systemUsers, "[{}] 是系统内置用户,不允许分配给非超级管理员角色", systemUsers.get(0).getNickname());
+ }
+
+ @Override
+ public void checkSystemUserUnassignment(List userRoleIds) {
+ if (CollUtil.isEmpty(userRoleIds)) {
+ return;
+ }
+ // 查询用户角色关联列表
+ List userRoleList = baseMapper.lambdaQuery()
+ .select(UserRoleDO::getUserId)
+ .in(UserRoleDO::getId, userRoleIds)
+ .list();
+ if (CollUtil.isEmpty(userRoleList)) {
+ return;
+ }
+ // 获取用户ID列表
+ List userIds = userRoleList.stream().map(UserRoleDO::getUserId).distinct().toList();
+ // 查询是否包含系统内置用户
+ List systemUsers = userService.lambdaQuery()
+ .select(UserDO::getId, UserDO::getNickname)
+ .in(UserDO::getId, userIds)
+ .eq(UserDO::getIsSystem, true)
+ .list();
+ CheckUtils.throwIfNotEmpty(systemUsers, "[{}] 是系统内置用户,不允许取消分配角色", systemUsers.get(0).getNickname());
+ }
}
diff --git a/continew-system/src/main/java/top/continew/admin/system/util/FileNameGenerator.java b/continew-system/src/main/java/top/continew/admin/system/util/FileNameGenerator.java
index 85a9004ce..29f6998ee 100644
--- a/continew-system/src/main/java/top/continew/admin/system/util/FileNameGenerator.java
+++ b/continew-system/src/main/java/top/continew/admin/system/util/FileNameGenerator.java
@@ -50,9 +50,9 @@ private FileNameGenerator() {
*
* 当目标目录存在同名文件时,自动添加序号后缀:
*
- * - file.txt → file(1).txt → file(2).txt → ...
- * - 无扩展名:README → README(1) → README(2) → ...
- * - 隐藏文件:.gitignore → .gitignore(1) → .gitignore(2) → ...
+ * - file.txt → file(1).txt → file(2).txt → ...
+ * - 无扩展名:README → README(1) → README(2) → ...
+ * - 隐藏文件:.gitignore → .gitignore(1) → .gitignore(2) → ...
*
*
*
@@ -90,7 +90,9 @@ public static String generateUniqueName(String fileName, String parentPath, Long
// 安全限制,防止无限循环
if (counter > 9999) {
log.warn("文件名重命名超过最大限制,使用当前时间戳: {}", fileName);
- return baseName + "_" + System.currentTimeMillis() + (StrUtil.isNotBlank(extension) ? "." + extension : "");
+ return baseName + "_" + System.currentTimeMillis() + (StrUtil.isNotBlank(extension)
+ ? "." + extension
+ : "");
}
}
}
@@ -102,10 +104,10 @@ public static String generateUniqueName(String fileName, String parentPath, Long
* 示例:
*
*
- * - "document.pdf" → ["document", "pdf"]
- * - "README" → ["README", ""]
- * - ".gitignore" → [".gitignore", ""]
- * - "archive.tar.gz" → ["archive.tar", "gz"]
+ * - "document.pdf" → ["document", "pdf"]
+ * - "README" → ["README", ""]
+ * - ".gitignore" → [".gitignore", ""]
+ * - "archive.tar.gz" → ["archive.tar", "gz"]
*
*
* @param fileName 文件名
@@ -113,7 +115,7 @@ public static String generateUniqueName(String fileName, String parentPath, Long
*/
public static String[] parseFileName(String fileName) {
if (StrUtil.isBlank(fileName)) {
- return new String[]{"", ""};
+ return new String[] {"", ""};
}
// 处理隐藏文件(以.开头)
@@ -122,7 +124,7 @@ public static String[] parseFileName(String fileName) {
// 处理空文件名(如只有"."的情况)
if (nameWithoutDot.isEmpty()) {
- return new String[]{fileName, ""};
+ return new String[] {fileName, ""};
}
// 查找最后一个点号位置
@@ -130,18 +132,20 @@ public static String[] parseFileName(String fileName) {
// 点号不存在或在开头(如 ".bashrc"),视为无扩展名
if (lastDotIndex <= 0) {
- return new String[]{fileName, ""};
+ return new String[] {fileName, ""};
}
- String baseName = isHidden ? "." + nameWithoutDot.substring(0, lastDotIndex) : nameWithoutDot.substring(0, lastDotIndex);
+ String baseName = isHidden
+ ? "." + nameWithoutDot.substring(0, lastDotIndex)
+ : nameWithoutDot.substring(0, lastDotIndex);
String extension = nameWithoutDot.substring(lastDotIndex + 1);
// 扩展名不应包含路径分隔符(安全检查)
if (extension.contains("/") || extension.contains("\\")) {
- return new String[]{fileName, ""};
+ return new String[] {fileName, ""};
}
- return new String[]{baseName, extension};
+ return new String[] {baseName, extension};
}
/**
@@ -194,7 +198,10 @@ private static boolean existsByName(String parentPath, Long storageId, String na
* @param fileMapper 文件Mapper
* @return 文件名列表
*/
- private static List selectNamesByParentPath(String parentPath, Long storageId, String namePrefix, FileMapper fileMapper) {
+ private static List selectNamesByParentPath(String parentPath,
+ Long storageId,
+ String namePrefix,
+ FileMapper fileMapper) {
var wrapper = fileMapper.lambdaQuery()
.eq(FileDO::getParentPath, parentPath)
.eq(FileDO::getStorageId, storageId)