feat: 文件导入配置
This commit is contained in:
parent
499876773f
commit
a351191b4c
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -55,5 +55,5 @@ public interface DeptService extends IService<Dept> {
|
|||
*
|
||||
* @return 所有部门列表
|
||||
*/
|
||||
List<DeptVo> getAllDeptList();
|
||||
List<DeptVo> allDeptList();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -126,13 +126,6 @@ public interface UserService extends IService<AdminUser> {
|
|||
*/
|
||||
void updateUserStatusByAdmin(AdminUserUpdateUserStatusDto dto);
|
||||
|
||||
/**
|
||||
* * 获取本地登录用户信息
|
||||
*
|
||||
* @return 用户信息
|
||||
*/
|
||||
LoginVo getUserinfo();
|
||||
|
||||
/**
|
||||
* * 更新本地用户信息
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加角色
|
||||
*
|
||||
|
|
|
@ -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 管理路由权限
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
* * 更新本地用户信息
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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("*::*::*", "*::*", "*");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue