feat: 文件导入配置

This commit is contained in:
bunny 2025-04-25 23:49:22 +08:00
parent 499876773f
commit a351191b4c
27 changed files with 419 additions and 165 deletions

View File

@ -24,7 +24,7 @@ public class WebSecurityConfig {
"/media.ico", "/favicon.ico", "/webjars/**", "/v3/api-docs/**", "/swagger-ui/**",
"/*/*/login",
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
"/*/i18n/getI18n",
"/*/i18n/getI18n"
};
@Resource

View File

@ -49,9 +49,9 @@ public class DeptController {
}
@Operation(summary = "获取所有部门", description = "获取所有部门")
@GetMapping("noManage/getAllDeptList")
public Result<List<DeptVo>> getAllDeptList() {
List<DeptVo> voList = deptService.getAllDeptList();
@GetMapping("noManage/allDeptList")
public Result<List<DeptVo>> allDeptList() {
List<DeptVo> voList = deptService.allDeptList();
return Result.success(voList);
}

View File

@ -82,15 +82,6 @@ public class FilesController {
return filesService.downloadFilesByFilepath(filepath);
}
// // 无法做权限校验
// @Operation(summary = "根据文件名访问resource下图片文件", description = "根据文件名访问resource下文件")
// @GetMapping("noAuth/getResourceImagesByFilename/{filename}")
// public ResponseEntity<Resource> getResourceImagesByFilename(@PathVariable String filename) {
// Resource file = new ClassPathResource("static/images/" + filename);
// if (!file.exists()) throw new BunnyException(ResultCodeEnum.FILE_NOT_EXIST);
// return ResponseEntity.ok().body(file);
// }
@Operation(summary = "更新系统文件", description = "更新系统文件")
@PutMapping("updateFiles")
public Result<String> updateFiles(@Valid FilesUpdateDto dto) {

View File

@ -28,7 +28,7 @@ import java.util.List;
* @author Bunny
* @since 2024-10-03 16:00:52
*/
@Tag(name = "权限", description = "权限相关接口")
@Tag(name = "系统权限", description = "权限相关接口")
@RestController
@RequestMapping("api/power")
public class PowerController {

View File

@ -1,13 +1,14 @@
package cn.bunny.services.controller.system;
import cn.bunny.domain.system.entity.Role;
import cn.bunny.domain.system.dto.role.RoleAddDto;
import cn.bunny.domain.system.dto.role.RoleDto;
import cn.bunny.domain.system.dto.role.RoleUpdateDto;
import cn.bunny.domain.system.entity.Role;
import cn.bunny.domain.system.vo.RoleVo;
import cn.bunny.domain.vo.result.PageResult;
import cn.bunny.domain.vo.result.Result;
import cn.bunny.domain.vo.result.ResultCodeEnum;
import cn.bunny.services.exception.AuthCustomerException;
import cn.bunny.services.service.system.RoleService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
@ -15,7 +16,9 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@ -27,7 +30,7 @@ import java.util.List;
* @author Bunny
* @since 2024-10-03 14:26:24
*/
@Tag(name = "角色", description = "角色相关接口")
@Tag(name = "系统角色", description = "角色相关接口")
@RestController
@RequestMapping("api/role")
public class RoleController {
@ -49,12 +52,28 @@ public class RoleController {
}
@Operation(summary = "获取所有角色", description = "获取所有角色")
@GetMapping("noManage/getAllRoles")
public Result<List<RoleVo>> getAllRoles() {
List<RoleVo> roleVoList = roleService.getAllRoles();
@GetMapping("noManage/allRoles")
public Result<List<RoleVo>> allRoles() {
List<RoleVo> roleVoList = roleService.allRoles();
return Result.success(roleVoList);
}
@Operation(summary = "导出角色列表", description = "使用Excel导出导出角色列表")
@GetMapping("exportByExcel")
public ResponseEntity<byte[]> exportByExcel() {
return roleService.exportByExcel();
}
@Operation(summary = "更新角色列表", description = "使用Excel更新角色列表")
@PutMapping("update/roleByFile")
public Result<String> updateRoleByFile(MultipartFile file) {
if (file == null) {
throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY);
}
roleService.updateRoleByFile(file);
return Result.success();
}
@Operation(summary = "添加角色", description = "添加角色")
@PostMapping("addRole")
public Result<Object> addRole(@Valid @RequestBody RoleAddDto dto) {

View File

@ -19,7 +19,7 @@ import java.util.List;
* @author Bunny
* @since 2024-09-26
*/
@Tag(name = "角色和权限", description = "角色和权限相关接口")
@Tag(name = "系统角色和权限", description = "角色和权限相关接口")
@RestController
@RequestMapping("api/rolePower")
public class RolePowerController {

View File

@ -10,6 +10,7 @@ import cn.bunny.domain.vo.LoginVo;
import cn.bunny.domain.vo.result.PageResult;
import cn.bunny.domain.vo.result.Result;
import cn.bunny.domain.vo.result.ResultCodeEnum;
import cn.bunny.services.context.BaseContext;
import cn.bunny.services.service.system.UserService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
@ -44,9 +45,9 @@ public class UserController {
}
@Operation(summary = "获取本地登录用户信息", description = "获取用户信息从Redis中获取")
@GetMapping("noManage/getUserinfo")
public Result<LoginVo> getUserinfo() {
LoginVo vo = userService.getUserinfo();
@GetMapping("noManage/userinfo")
public Result<LoginVo> userinfo() {
LoginVo vo = BaseContext.getLoginVo();
return Result.success(vo);
}

View File

@ -0,0 +1,46 @@
package cn.bunny.domain.i18n.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.*;
import com.alibaba.excel.enums.BooleanEnum;
import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
// fontHeightInPoints字体大小颜色color 绿色
@HeadFontStyle(fontHeightInPoints = 30, color = 14, bold = BooleanEnum.TRUE)
// fillForegroundColor 将背景填充为白色
@HeadStyle(fillForegroundColor = 9, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND)
@HeadRowHeight(30)
public class RoleExcel {
@Schema(name = "id", title = "唯一标识")
@ExcelProperty({"修改时不要修改id列如需更新不填写此列", "id/唯一标识(添加不填写)"})
@ColumnWidth(66)
// 字体颜色红色
@ContentFontStyle(fontHeightInPoints = 14, color = 10, bold = BooleanEnum.TRUE)
private String id;
@Schema(name = "roleCode", title = "角色代码")
@ExcelProperty({"修改时不要修改id列如需更新不填写此列", "roleCode/角色代码"})
// 列宽
@ColumnWidth(66)
// fontHeightInPoints字体大小颜色color 绿色
@ContentFontStyle(fontHeightInPoints = 14, color = 17, bold = BooleanEnum.TRUE)
private String roleCode;
@Schema(name = "description", title = "描述")
@ExcelProperty({"修改时不要修改id列如需更新不填写此列", "description/描述"})
@ColumnWidth(66)
// fontHeightInPoints字体大小颜色color 天蓝色
@ContentFontStyle(fontHeightInPoints = 14, color = 40, bold = BooleanEnum.TRUE)
private String description;
}

View File

@ -1,7 +1,7 @@
package cn.bunny.services.mapper.system;
import cn.bunny.domain.system.entity.Role;
import cn.bunny.domain.system.dto.role.RoleDto;
import cn.bunny.domain.system.entity.Role;
import cn.bunny.domain.system.vo.RoleVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

View File

@ -0,0 +1,62 @@
package cn.bunny.services.excel;
import cn.bunny.domain.i18n.excel.RoleExcel;
import cn.bunny.domain.system.entity.Role;
import cn.bunny.domain.vo.result.ResultCodeEnum;
import cn.bunny.services.exception.AuthCustomerException;
import cn.bunny.services.service.system.RoleService;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import java.util.List;
@Slf4j
public class RoleExcelListener implements ReadListener<RoleExcel> {
private static final int BATCH_COUNT = 100;
private final RoleService roleService;
private List<RoleExcel> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
public RoleExcelListener(RoleService roleService) {
this.roleService = roleService;
}
@Override
public void invoke(RoleExcel roleExcel, AnalysisContext analysisContext) {
cachedDataList.add(roleExcel);
// 达到BATCH_COUNT了需要去存储一次数据库防止数据几万条数据在内存容易OOM
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();
}
private void saveData() {
List<Role> roleList = cachedDataList.stream().map(item -> {
Role role = new Role();
BeanUtils.copyProperties(item, role);
// id 不为空设置
String id = item.getId();
if (!StringUtils.isEmpty(id)) {
role.setId(Long.valueOf(id));
}
return role;
}).toList();
if (roleList.isEmpty()) {
throw new AuthCustomerException(ResultCodeEnum.DATA_TOO_LARGE);
}
roleService.saveOrUpdateBatch(roleList, BATCH_COUNT);
}
}

View File

@ -17,6 +17,7 @@ import cn.bunny.services.exception.AuthCustomerException;
import cn.bunny.services.mapper.configuration.I18nMapper;
import cn.bunny.services.mapper.configuration.I18nTypeMapper;
import cn.bunny.services.service.configuration.I18nService;
import cn.bunny.services.utils.FileUtil;
import cn.bunny.services.utils.i8n.I18nUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSON;
@ -178,11 +179,7 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
}
// 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=" + "i18n.zip");
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
HttpHeaders headers = FileUtil.buildHttpHeadersByBinary("i18n-configuration.zip");
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
return new ResponseEntity<>(byteArrayInputStream.readAllBytes(), headers, HttpStatus.OK);

View File

@ -55,5 +55,5 @@ public interface DeptService extends IService<Dept> {
*
* @return 所有部门列表
*/
List<DeptVo> getAllDeptList();
List<DeptVo> allDeptList();
}

View File

@ -1,14 +1,16 @@
package cn.bunny.services.service.system;
import cn.bunny.domain.system.entity.Role;
import cn.bunny.domain.system.dto.role.RoleAddDto;
import cn.bunny.domain.system.dto.role.RoleDto;
import cn.bunny.domain.system.dto.role.RoleUpdateDto;
import cn.bunny.domain.system.entity.Role;
import cn.bunny.domain.system.vo.RoleVo;
import cn.bunny.domain.vo.result.PageResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@ -55,5 +57,19 @@ public interface RoleService extends IService<Role> {
*
* @return 所有角色列表
*/
List<RoleVo> getAllRoles();
List<RoleVo> allRoles();
/**
* 使用Excel导出导出角色列表
*
* @return Excel
*/
ResponseEntity<byte[]> exportByExcel();
/**
* 使用Excel更新角色列表
*
* @param file Excel文件
*/
void updateRoleByFile(MultipartFile file);
}

View File

@ -126,13 +126,6 @@ public interface UserService extends IService<AdminUser> {
*/
void updateUserStatusByAdmin(AdminUserUpdateUserStatusDto dto);
/**
* * 获取本地登录用户信息
*
* @return 用户信息
*/
LoginVo getUserinfo();
/**
* * 更新本地用户信息
*

View File

@ -65,7 +65,7 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements De
*/
@Override
@Cacheable(cacheNames = "dept", key = "'allDept'", cacheManager = "cacheManagerWithMouth")
public List<DeptVo> getAllDeptList() {
public List<DeptVo> allDeptList() {
return list().stream().map(dept -> {
DeptVo deptVo = new DeptVo();
BeanUtils.copyProperties(dept, deptVo);

View File

@ -14,9 +14,9 @@ import cn.bunny.services.context.BaseContext;
import cn.bunny.services.exception.AuthCustomerException;
import cn.bunny.services.mapper.system.FilesMapper;
import cn.bunny.services.service.system.FilesService;
import cn.bunny.services.utils.FileUtil;
import cn.bunny.services.utils.minio.MinioProperties;
import cn.bunny.services.utils.minio.MinioUtil;
import cn.bunny.services.utils.system.FileUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

View File

@ -1,5 +1,6 @@
package cn.bunny.services.service.system.impl;
import cn.bunny.domain.i18n.excel.RoleExcel;
import cn.bunny.domain.system.dto.role.RoleAddDto;
import cn.bunny.domain.system.dto.role.RoleDto;
import cn.bunny.domain.system.dto.role.RoleUpdateDto;
@ -8,13 +9,16 @@ import cn.bunny.domain.system.entity.UserRole;
import cn.bunny.domain.system.vo.RoleVo;
import cn.bunny.domain.vo.result.PageResult;
import cn.bunny.domain.vo.result.ResultCodeEnum;
import cn.bunny.services.excel.RoleExcelListener;
import cn.bunny.services.exception.AuthCustomerException;
import cn.bunny.services.mapper.system.RoleMapper;
import cn.bunny.services.mapper.system.RolePermissionMapper;
import cn.bunny.services.mapper.system.RouterRoleMapper;
import cn.bunny.services.mapper.system.UserRoleMapper;
import cn.bunny.services.service.system.RoleService;
import cn.bunny.services.utils.FileUtil;
import cn.bunny.services.utils.system.RoleUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -24,9 +28,19 @@ import jakarta.validation.Valid;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* <p>
@ -77,7 +91,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
*/
@Override
@Cacheable(cacheNames = "role", key = "'allRole'", cacheManager = "cacheManagerWithMouth")
public List<RoleVo> getAllRoles() {
public List<RoleVo> allRoles() {
return list().stream().map(role -> {
RoleVo roleVo = new RoleVo();
BeanUtils.copyProperties(role, roleVo);
@ -85,6 +99,65 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
}).toList();
}
/**
* 使用Excel导出导出角色列表
*
* @return Excel
*/
@Override
public ResponseEntity<byte[]> exportByExcel() {
String filename = FileUtil.buildFilenameBefore("role-");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) {
List<RoleExcel> list = list().stream().map(role -> {
RoleExcel roleExcel = new RoleExcel();
BeanUtils.copyProperties(role, roleExcel);
roleExcel.setId(role.getId().toString());
return roleExcel;
}).toList();
// 创建临时ByteArrayOutputStream
ByteArrayOutputStream excelOutputStream = new ByteArrayOutputStream();
ZipEntry zipEntry = new ZipEntry(filename + ".xlsx");
zipOutputStream.putNextEntry(zipEntry);
// 先写入到临时流
EasyExcel.write(excelOutputStream, RoleExcel.class).sheet("role").doWrite(list);
zipOutputStream.write(excelOutputStream.toByteArray());
zipOutputStream.closeEntry();
} catch (IOException e) {
throw new RuntimeException(e);
}
// 设置响应头
HttpHeaders headers = FileUtil.buildHttpHeadersByBinary(filename + ".zip");
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
return new ResponseEntity<>(byteArrayInputStream.readAllBytes(), headers, HttpStatus.OK);
}
/**
* 使用Excel更新角色列表
*
* @param file Excel文件
*/
@Override
@CacheEvict(cacheNames = "role", key = "'allRole'", beforeInvocation = true)
public void updateRoleByFile(MultipartFile file) {
InputStream fileInputStream;
try {
fileInputStream = file.getInputStream();
EasyExcel.read(fileInputStream, RoleExcel.class, new RoleExcelListener(this)).sheet().doRead();
} catch (IOException e) {
throw new AuthCustomerException(ResultCodeEnum.UPLOAD_ERROR);
}
}
/**
* 添加角色
*

View File

@ -65,7 +65,7 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
// 当前的所有的路由列表
List<Router> routerList = list();
// 查询路由角色列表
Map<Long, List<ViewRouterRole>> routerRoleList = routerRoleMapper.selectRouterRoleList().stream()
.collect(Collectors.groupingBy(ViewRouterRole::getRouterId, Collectors.toList()));
@ -74,7 +74,7 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
Map<Long, List<ViewRolePermission>> rolePermissionList = rolePermissionMapper.viewRolePowerWithAll().stream()
.collect(Collectors.groupingBy(ViewRolePermission::getRoleId, Collectors.toList()));
// 整理web用户所能看到的路由列表
// 整理web用户所能看到的路由列表并检查当前用户是否是admin
List<WebUserRouterVo> webUserRouterVoList = routerUtil.getWebUserRouterVos(routerList, routerRoleList, rolePermissionList);
// 添加 admin 管理路由权限

View File

@ -334,11 +334,12 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
@Override
public List<SearchUserinfoVo> queryUser(String keyword) {
if (!StringUtils.hasText(keyword)) {
return list(Page.of(1, 20), Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getStatus, false)).stream().map(adminUser -> {
SearchUserinfoVo adminUserVo = new SearchUserinfoVo();
BeanUtils.copyProperties(adminUser, adminUserVo);
return adminUserVo;
}).toList();
return list(Page.of(1, 20), Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getStatus, false)).stream()
.map(adminUser -> {
SearchUserinfoVo adminUserVo = new SearchUserinfoVo();
BeanUtils.copyProperties(adminUser, adminUserVo);
return adminUserVo;
}).toList();
}
List<AdminUser> list = baseMapper.queryUser(keyword);
@ -371,16 +372,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
}
}
/**
* * 获取本地登录用户信息
*
* @return 用户信息
*/
@Override
public LoginVo getUserinfo() {
return BaseContext.getLoginVo();
}
/**
* * 更新本地用户信息
*

View File

@ -1,36 +0,0 @@
package cn.bunny.services.utils.system;
/*
* 文件工具类
* 格式化字节大小
*/
public class FileUtil {
/**
* 获取文件大小字符串
*
* @param fileSize 文件大小
* @return 格式化后文件大小
*/
public static String getSize(Long fileSize) {
double fileSizeInKB = fileSize / 1024.00;
double fileSizeInMB = fileSizeInKB / 1024;
double fileSizeInGB = fileSizeInMB / 1024;
String size;
if (fileSizeInGB >= 1) {
fileSizeInGB = Double.parseDouble(String.format("%.2f", fileSizeInGB));
size = fileSizeInGB + "GB";
} else if (fileSizeInMB >= 1) {
fileSizeInMB = Double.parseDouble(String.format("%.2f", fileSizeInMB));
size = fileSizeInMB + "MB";
} else if (fileSizeInKB >= 1) {
fileSizeInKB = Double.parseDouble(String.format("%.2f", fileSizeInKB));
size = fileSizeInKB + "KB";
} else {
size = fileSize + "B";
}
return size;
}
}

View File

@ -6,7 +6,7 @@ import cn.bunny.domain.system.entity.AdminUser;
import cn.bunny.services.context.BaseContext;
import cn.bunny.services.mapper.system.UserMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@ -15,13 +15,13 @@ import java.util.List;
@Component
public class RoleUtil {
@Autowired
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Autowired
@Resource
private UserMapper userMapper;
@Autowired
@Resource
private UserUtil userUtil;
/**

View File

@ -6,24 +6,21 @@ import cn.bunny.domain.system.entity.RouterRole;
import cn.bunny.domain.system.views.ViewRolePermission;
import cn.bunny.domain.system.views.ViewRouterRole;
import cn.bunny.domain.system.vo.router.WebUserRouterVo;
import cn.bunny.services.context.BaseContext;
import cn.bunny.services.service.system.RouterRoleService;
import com.alibaba.fastjson2.JSON;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static cn.bunny.domain.constant.UserConstant.allAuths;
import java.util.*;
@Slf4j
@Component
public class RouterUtil {
@Resource
private RouterRoleService routerRoleService;
@ -75,72 +72,78 @@ public class RouterUtil {
*/
@NotNull
public List<WebUserRouterVo> getWebUserRouterVos(List<Router> routerList, Map<Long, List<ViewRouterRole>> routerRoleList, Map<Long, List<ViewRolePermission>> rolePermissionList) {
// 检查当前是否是 admin 用户
List<String> roles = BaseContext.getLoginVo().getRoles();
List<String> allAuths = !RoleUtil.checkAdmin(roles) ? new ArrayList<>() : List.of("*:*:*", "*:*", "*", "admin");
// 查询路由所有数据整理前端需要的路和角色权限
return routerList.stream().map(view -> {
// 前端需要的格式路由
WebUserRouterVo webUserRouterVo = new WebUserRouterVo();
// 前端需要的格式路由
WebUserRouterVo webUserRouterVo = new WebUserRouterVo();
// 复制数据库中信息到新路由中
BeanUtils.copyProperties(view, webUserRouterVo);
// 复制数据库中信息到新路由中
BeanUtils.copyProperties(view, webUserRouterVo);
// 整理前端需要格式的路由 meta
String meta = view.getMeta();
RouterMeta routerMeta;
// 整理前端需要格式的路由 meta
String meta = view.getMeta();
RouterMeta routerMeta;
// 如果么meta存在将其转成 RouterMeta 而不是 JSON/字符串
if (StringUtils.hasText(meta)) {
routerMeta = JSON.parseObject(meta, RouterMeta.class);
webUserRouterVo.setMeta(routerMeta);
} else {
// 不存在时不能为 null 将路由名称设置为title
routerMeta = new RouterMeta();
routerMeta.setTitle(view.getRouteName());
webUserRouterVo.setMeta(routerMeta);
}
// 如果么meta存在将其转成 RouterMeta 而不是 JSON/字符串
if (StringUtils.hasText(meta)) {
routerMeta = JSON.parseObject(meta, RouterMeta.class);
webUserRouterVo.setMeta(routerMeta);
} else {
// 不存在时不能为 null 将路由名称设置为title
routerMeta = new RouterMeta();
routerMeta.setTitle(view.getRouteName());
webUserRouterVo.setMeta(routerMeta);
}
// 路由路由和橘色 设置角色信息防止为空报错最后添加 roles
List<String> roleCodeList = new ArrayList<>(allAuths);
if (!routerRoleList.isEmpty()) {
// 找到当前路由下的角色信息
List<String> list = routerRoleList.getOrDefault(view.getId(), Collections.emptyList()).stream()
.map(ViewRouterRole::getRoleCode).toList();
// 路由路由和橘色 设置角色信息防止为空报错最后添加 roles
List<String> roleCodeList = new ArrayList<>(allAuths);
if (!routerRoleList.isEmpty()) {
// 找到当前路由下的角色信息
List<String> list = routerRoleList.getOrDefault(view.getId(), Collections.emptyList()).stream()
.map(ViewRouterRole::getRoleCode).toList();
// 将角色码添加到角色列表
roleCodeList.addAll(list);
}
webUserRouterVo.getMeta().setRoles(roleCodeList);
// 将角色码添加到角色列表
roleCodeList.addAll(list);
}
webUserRouterVo.getMeta().setRoles(roleCodeList);
// 角色和权限 设置权限信息最后添加权限信息 auth/permission
List<String> permissionList = new ArrayList<>(allAuths);
if (!rolePermissionList.isEmpty()) {
// 找到当前路由下所有的角色id之后根据 角色和权限查找 角色对应的权限
List<Long> roleIds = routerRoleList.getOrDefault(view.getId(), Collections.emptyList()).stream()
.map(ViewRouterRole::getRoleId).toList();
// 角色和权限 设置权限信息最后添加权限信息 auth/permission
List<String> permissionList = new ArrayList<>(allAuths);
if (!rolePermissionList.isEmpty()) {
// 找到当前路由下所有的角色id之后根据 角色和权限查找 角色对应的权限
List<Long> roleIds = routerRoleList.getOrDefault(view.getId(), Collections.emptyList()).stream()
.map(ViewRouterRole::getRoleId).toList();
// 根据角色id找到所有权限
List<String> list = roleIds.stream()
.map(roleId -> {
List<ViewRolePermission> viewRolePermissions = rolePermissionList.get(roleId);
// 根据角色id找到所有权限
List<String> list = roleIds.stream()
.map(roleId -> {
List<ViewRolePermission> viewRolePermissions = rolePermissionList.get(roleId);
// 根据角色id查找权限且角色和权限存在
if (roleId != null && viewRolePermissions != null && !viewRolePermissions.isEmpty()) {
return viewRolePermissions.stream().map(ViewRolePermission::getPowerCode).toList();
}
// 根据角色id查找权限且角色和权限存在
if (roleId != null && viewRolePermissions != null && !viewRolePermissions.isEmpty()) {
return viewRolePermissions.stream().map(ViewRolePermission::getPowerCode).toList();
}
// 未找到返回 空字符串
return List.of("");
})
// 将二维数组转成一维数组
.flatMap(List::stream)
// 过滤掉为空的字符串
.filter(StringUtils::hasText)
.distinct()
.toList();
permissionList.addAll(list);
}
webUserRouterVo.getMeta().setAuths(permissionList);
// 未找到返回 空字符串
return List.of("");
})
// 将二维数组转成一维数组
.flatMap(List::stream)
// 过滤掉为空的字符串
.filter(StringUtils::hasText)
.distinct()
.toList();
permissionList.addAll(list);
}
webUserRouterVo.getMeta().setAuths(permissionList);
return webUserRouterVo;
}).toList();
return webUserRouterVo;
})
.sorted(Comparator.comparing(routerVo -> routerVo.getMeta().getRank()))
.toList();
}
}

View File

@ -24,6 +24,10 @@
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

View File

@ -0,0 +1,17 @@
package cn.bunny.services.config;
import cn.bunny.services.context.BaseContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
@Component
public class ThreadLocalCleanupInterceptor implements HandlerInterceptor {
/* 请求完成后清理 */
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
BaseContext.removeUser();
}
}

View File

@ -1,11 +1,23 @@
package cn.bunny.services.config;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig {
public class WebConfig implements WebMvcConfigurer {
@Resource
private ThreadLocalCleanupInterceptor interceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();

View File

@ -0,0 +1,68 @@
package cn.bunny.services.utils;
import cn.hutool.crypto.digest.MD5;
import org.springframework.http.HttpHeaders;
/*
* 文件工具类
* 格式化字节大小
*/
public class FileUtil {
/**
* 获取文件大小字符串
*
* @param fileSize 文件大小
* @return 格式化后文件大小
*/
public static String getSize(Long fileSize) {
double fileSizeInKB = fileSize / 1024.00;
double fileSizeInMB = fileSizeInKB / 1024;
double fileSizeInGB = fileSizeInMB / 1024;
String size;
if (fileSizeInGB >= 1) {
fileSizeInGB = Double.parseDouble(String.format("%.2f", fileSizeInGB));
size = fileSizeInGB + "GB";
} else if (fileSizeInMB >= 1) {
fileSizeInMB = Double.parseDouble(String.format("%.2f", fileSizeInMB));
size = fileSizeInMB + "MB";
} else if (fileSizeInKB >= 1) {
fileSizeInKB = Double.parseDouble(String.format("%.2f", fileSizeInKB));
size = fileSizeInKB + "KB";
} else {
size = fileSize + "B";
}
return size;
}
/**
* 构建二进制文件响应头
*
* @param filename 文件名
* @return HttpHeaders
*/
public static HttpHeaders buildHttpHeadersByBinary(String filename) {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=" + filename);
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
return headers;
}
/* 文件名在前面 */
public static String buildFilenameBefore(String filename) {
long currentTimeMillis = System.currentTimeMillis();
String digestHex = MD5.create().digestHex(currentTimeMillis + "");
return filename + digestHex;
}
/* 文件名在后面 */
public static String buildFilenameAfter(String filename) {
long currentTimeMillis = System.currentTimeMillis();
String digestHex = MD5.create().digestHex(currentTimeMillis + "");
return digestHex + filename;
}
}

View File

@ -2,11 +2,8 @@ package cn.bunny.domain.constant;
import lombok.Data;
import java.util.List;
@Data
public class UserConstant {
public static final String USER_AVATAR = "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132";
public static final String PERSON_DESCRIPTION = "这个人很懒没有介绍...";
public static final List<String> allAuths = List.of("*::*::*", "*::*", "*");
}