Compare commits
No commits in common. "94e0d7f264c140f2322b417ff397683aff60499d" and "3dd368140dadeb580791e589c4a028b6c22536aa" have entirely different histories.
94e0d7f264
...
3dd368140d
|
@ -26,7 +26,6 @@ ENTRYPOINT ["java","-jar","/home/server/app.jar"]
|
||||||
|
|
||||||
#暴露 8000 端口
|
#暴露 8000 端口
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
EXPOSE 7070
|
|
||||||
|
|
||||||
# 生产环境
|
# 生产环境
|
||||||
# mvn clean package -Pprod -DskipTests
|
# mvn clean package -Pprod -DskipTests
|
||||||
|
|
|
@ -3,7 +3,7 @@ package cn.bunny.services.controller.configuration;
|
||||||
import cn.bunny.services.domain.system.configuration.dto.WebConfigurationDto;
|
import cn.bunny.services.domain.system.configuration.dto.WebConfigurationDto;
|
||||||
import cn.bunny.services.domain.system.configuration.entity.WebConfiguration;
|
import cn.bunny.services.domain.system.configuration.entity.WebConfiguration;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.configuration.ConfigurationService;
|
import cn.bunny.services.service.configuration.ConfigurationService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package cn.bunny.services.controller.configuration;
|
package cn.bunny.services.controller.configuration;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
|
||||||
import cn.bunny.services.domain.system.email.dto.EmailTemplateAddDto;
|
import cn.bunny.services.domain.system.email.dto.EmailTemplateAddDto;
|
||||||
import cn.bunny.services.domain.system.email.dto.EmailTemplateDto;
|
import cn.bunny.services.domain.system.email.dto.EmailTemplateDto;
|
||||||
import cn.bunny.services.domain.system.email.dto.EmailTemplateUpdateDto;
|
import cn.bunny.services.domain.system.email.dto.EmailTemplateUpdateDto;
|
||||||
import cn.bunny.services.domain.system.email.entity.EmailTemplate;
|
import cn.bunny.services.domain.system.email.entity.EmailTemplate;
|
||||||
import cn.bunny.services.domain.system.email.vo.EmailTemplateVo;
|
import cn.bunny.services.domain.system.email.vo.EmailTemplateVo;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.configuration.EmailTemplateService;
|
import cn.bunny.services.service.configuration.EmailTemplateService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
@ -71,7 +71,7 @@ public class EmailTemplateController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "全部邮件类型列表", description = "获取全部邮件类型列表", tags = "emailTemplate::query")
|
@Operation(summary = "全部邮件类型列表", description = "获取全部邮件类型列表", tags = "emailTemplate::query")
|
||||||
@GetMapping("private")
|
@GetMapping("public")
|
||||||
public Result<List<Map<String, String>>> getEmailTypeList() {
|
public Result<List<Map<String, String>>> getEmailTypeList() {
|
||||||
List<Map<String, String>> list = emailTemplateService.getEmailTypeList();
|
List<Map<String, String>> list = emailTemplateService.getEmailTypeList();
|
||||||
return Result.success(list);
|
return Result.success(list);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.email.entity.EmailUsers;
|
||||||
import cn.bunny.services.domain.system.email.vo.EmailUsersVo;
|
import cn.bunny.services.domain.system.email.vo.EmailUsersVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.configuration.EmailUsersService;
|
import cn.bunny.services.service.configuration.EmailUsersService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import cn.bunny.services.domain.system.i18n.entity.I18n;
|
||||||
import cn.bunny.services.domain.system.i18n.vo.I18nVo;
|
import cn.bunny.services.domain.system.i18n.vo.I18nVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.configuration.I18nService;
|
import cn.bunny.services.service.configuration.I18nService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import cn.bunny.services.domain.system.i18n.dto.I18nTypeDto;
|
||||||
import cn.bunny.services.domain.system.i18n.dto.I18nTypeUpdateDto;
|
import cn.bunny.services.domain.system.i18n.dto.I18nTypeUpdateDto;
|
||||||
import cn.bunny.services.domain.system.i18n.vo.I18nTypeVo;
|
import cn.bunny.services.domain.system.i18n.vo.I18nTypeVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.configuration.I18nTypeService;
|
import cn.bunny.services.service.configuration.I18nTypeService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.menuIcon.entity.MenuIcon;
|
||||||
import cn.bunny.services.domain.system.menuIcon.vo.MenuIconVo;
|
import cn.bunny.services.domain.system.menuIcon.vo.MenuIconVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.configuration.MenuIconService;
|
import cn.bunny.services.service.configuration.MenuIconService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import cn.bunny.services.domain.system.log.entity.ScheduleExecuteLog;
|
||||||
import cn.bunny.services.domain.system.log.vo.ScheduleExecuteLogVo;
|
import cn.bunny.services.domain.system.log.vo.ScheduleExecuteLogVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.log.ScheduleExecuteLogService;
|
import cn.bunny.services.service.log.ScheduleExecuteLogService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import cn.bunny.services.domain.system.log.vo.UserLoginLogLocalVo;
|
||||||
import cn.bunny.services.domain.system.log.vo.UserLoginLogVo;
|
import cn.bunny.services.domain.system.log.vo.UserLoginLogVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.log.UserLoginLogService;
|
import cn.bunny.services.service.log.UserLoginLogService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import cn.bunny.services.domain.system.message.vo.MessageReceivedWithUserVo;
|
||||||
import cn.bunny.services.domain.system.message.vo.MessageVo;
|
import cn.bunny.services.domain.system.message.vo.MessageVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.message.MessageService;
|
import cn.bunny.services.service.message.MessageService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import cn.bunny.services.domain.system.message.vo.MessageReceivedWithMessageVo;
|
||||||
import cn.bunny.services.domain.system.message.vo.MessageUserVo;
|
import cn.bunny.services.domain.system.message.vo.MessageUserVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.message.MessageReceivedService;
|
import cn.bunny.services.service.message.MessageReceivedService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.message.entity.MessageType;
|
||||||
import cn.bunny.services.domain.system.message.vo.MessageTypeVo;
|
import cn.bunny.services.domain.system.message.vo.MessageTypeVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.message.MessageTypeService;
|
import cn.bunny.services.service.message.MessageTypeService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package cn.bunny.services.controller.schedule;
|
||||||
import cn.bunny.services.aop.scanner.QuartzSchedulersScanner;
|
import cn.bunny.services.aop.scanner.QuartzSchedulersScanner;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.quartz.dto.SchedulersAddDto;
|
import cn.bunny.services.domain.system.quartz.dto.SchedulersAddDto;
|
||||||
import cn.bunny.services.domain.system.quartz.dto.SchedulersDto;
|
import cn.bunny.services.domain.system.quartz.dto.SchedulersDto;
|
||||||
import cn.bunny.services.domain.system.quartz.dto.SchedulersUpdateDto;
|
import cn.bunny.services.domain.system.quartz.dto.SchedulersUpdateDto;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.quartz.entity.SchedulersGroup;
|
||||||
import cn.bunny.services.domain.system.quartz.vo.SchedulersGroupVo;
|
import cn.bunny.services.domain.system.quartz.vo.SchedulersGroupVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.schedule.SchedulersGroupService;
|
import cn.bunny.services.service.schedule.SchedulersGroupService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.system.entity.Dept;
|
||||||
import cn.bunny.services.domain.system.system.vo.DeptVo;
|
import cn.bunny.services.domain.system.system.vo.DeptVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.system.DeptService;
|
import cn.bunny.services.service.system.DeptService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -10,7 +10,7 @@ import cn.bunny.services.domain.system.files.vo.FileInfoVo;
|
||||||
import cn.bunny.services.domain.system.files.vo.FilesVo;
|
import cn.bunny.services.domain.system.files.vo.FilesVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.system.FilesService;
|
import cn.bunny.services.service.system.FilesService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import cn.bunny.services.aop.scanner.ControllerApiPermissionScanner;
|
||||||
import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo;
|
import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.system.dto.power.PermissionAddDto;
|
import cn.bunny.services.domain.system.system.dto.power.PermissionAddDto;
|
||||||
import cn.bunny.services.domain.system.system.dto.power.PermissionDto;
|
import cn.bunny.services.domain.system.system.dto.power.PermissionDto;
|
||||||
import cn.bunny.services.domain.system.system.dto.power.PermissionUpdateBatchByParentIdDto;
|
import cn.bunny.services.domain.system.system.dto.power.PermissionUpdateBatchByParentIdDto;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.system.entity.Role;
|
||||||
import cn.bunny.services.domain.system.system.vo.RoleVo;
|
import cn.bunny.services.domain.system.system.vo.RoleVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.system.RoleService;
|
import cn.bunny.services.service.system.RoleService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import cn.bunny.services.domain.system.system.dto.router.RouterUpdateDto;
|
||||||
import cn.bunny.services.domain.system.system.vo.router.RouterManageVo;
|
import cn.bunny.services.domain.system.system.vo.router.RouterManageVo;
|
||||||
import cn.bunny.services.domain.system.system.vo.router.WebUserRouterVo;
|
import cn.bunny.services.domain.system.system.vo.router.WebUserRouterVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.service.system.RouterService;
|
import cn.bunny.services.service.system.RouterService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package cn.bunny.services.controller.system;
|
package cn.bunny.services.controller.system;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.LoginVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.system.dto.user.AdminUserAddDto;
|
import cn.bunny.services.domain.system.system.dto.user.AdminUserAddDto;
|
||||||
import cn.bunny.services.domain.system.system.dto.user.AdminUserDto;
|
import cn.bunny.services.domain.system.system.dto.user.AdminUserDto;
|
||||||
import cn.bunny.services.domain.system.system.dto.user.AdminUserUpdateDto;
|
import cn.bunny.services.domain.system.system.dto.user.AdminUserUpdateDto;
|
||||||
|
@ -90,13 +91,13 @@ public class UserController {
|
||||||
|
|
||||||
@Operation(summary = "已登录用户", description = "查询缓存中已登录用户", tags = "user::query")
|
@Operation(summary = "已登录用户", description = "查询缓存中已登录用户", tags = "user::query")
|
||||||
@GetMapping("getCacheUserPage/{page}/{limit}")
|
@GetMapping("getCacheUserPage/{page}/{limit}")
|
||||||
public Result<PageResult<UserVo>> getCacheUserPage(
|
public Result<PageResult<LoginVo>> getCacheUserPage(
|
||||||
@Parameter(name = "page", description = "当前页", required = true)
|
@Parameter(name = "page", description = "当前页", required = true)
|
||||||
@PathVariable("page") Integer page,
|
@PathVariable("page") Integer page,
|
||||||
@Parameter(name = "limit", description = "每页记录数", required = true)
|
@Parameter(name = "limit", description = "每页记录数", required = true)
|
||||||
@PathVariable("limit") Integer limit) {
|
@PathVariable("limit") Integer limit) {
|
||||||
Page<AdminUser> pageParams = new Page<>(page, limit);
|
Page<AdminUser> pageParams = new Page<>(page, limit);
|
||||||
PageResult<UserVo> pageResult = userService.getCacheUserPage(pageParams);
|
PageResult<LoginVo> pageResult = userService.getCacheUserPage(pageParams);
|
||||||
return Result.success(pageResult);
|
return Result.success(pageResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ package cn.bunny.services.controller.system;
|
||||||
import cn.bunny.services.context.BaseContext;
|
import cn.bunny.services.context.BaseContext;
|
||||||
import cn.bunny.services.domain.common.model.vo.LoginVo;
|
import cn.bunny.services.domain.common.model.vo.LoginVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.system.dto.user.AdminUserUpdateByLocalUserDto;
|
import cn.bunny.services.domain.system.system.dto.user.AdminUserUpdateByLocalUserDto;
|
||||||
import cn.bunny.services.domain.system.system.dto.user.LoginDto;
|
import cn.bunny.services.domain.system.system.dto.user.LoginDto;
|
||||||
import cn.bunny.services.domain.system.system.dto.user.RefreshTokenDto;
|
import cn.bunny.services.domain.system.system.dto.user.RefreshTokenDto;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
server:
|
server:
|
||||||
port: 8000
|
port: 8000
|
||||||
tomcat:
|
|
||||||
threads:
|
|
||||||
max: 1000
|
|
||||||
spring:
|
spring:
|
||||||
profiles:
|
profiles:
|
||||||
active: @profiles.active@
|
active: @profiles.active@
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
public abstract class AbstractPermissionCheckHandler {
|
||||||
|
|
||||||
|
private AbstractPermissionCheckHandler abstractPermissionCheckHandler;
|
||||||
|
|
||||||
|
public AbstractPermissionCheckHandler(AbstractPermissionCheckHandler abstractPermissionCheckHandler) {
|
||||||
|
this.abstractPermissionCheckHandler = abstractPermissionCheckHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected void checkPermission(String requestUrl);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package cn.bunny.services.config;
|
||||||
|
|
||||||
|
import cn.bunny.services.utils.TokenUtilsTest;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.test.context.TestConfiguration;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
// @TestConfiguration
|
||||||
|
// public class WebConfig {
|
||||||
|
// @Value("${server.port}")
|
||||||
|
// private String port;
|
||||||
|
//
|
||||||
|
// @Autowired
|
||||||
|
// private TokenUtilsTest tokenUtils;
|
||||||
|
//
|
||||||
|
// @Bean
|
||||||
|
// public RestTemplate restTemplate(RestTemplateBuilder builder) {
|
||||||
|
// String token = tokenUtils.getToken();
|
||||||
|
// return builder.rootUri("http://localhost:" + port)
|
||||||
|
// .defaultHeader("token", token)
|
||||||
|
// .defaultHeader("Content-Type", "application/json")
|
||||||
|
// .build();
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -0,0 +1,37 @@
|
||||||
|
package cn.bunny.services.controller;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.openqa.selenium.chrome.ChromeDriver;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
public class LoginTest {
|
||||||
|
private ChromeDriver chromeDriver;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUpMockMvc() {
|
||||||
|
chromeDriver = new ChromeDriver();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
chromeDriver.quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试登录页面
|
||||||
|
@Test
|
||||||
|
// @WithMockUser(username = "Administrator", password = "admin123", roles = "admin")
|
||||||
|
// @WithUserDetails("Administrator")
|
||||||
|
void testLogin() throws InterruptedException {
|
||||||
|
chromeDriver.get("http://localhost:7000/");
|
||||||
|
TimeUnit.MINUTES.sleep(100);
|
||||||
|
chromeDriver.manage().timeouts().implicitlyWait(Duration.of(1000L, TimeUnit.SECONDS.toChronoUnit()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package cn.bunny.services.controller;
|
||||||
|
|
||||||
|
import cn.bunny.services.aop.scanner.ControllerApiPermissionScanner;
|
||||||
|
import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo;
|
||||||
|
import cn.bunny.services.domain.system.system.entity.Permission;
|
||||||
|
import cn.bunny.services.service.system.PermissionService;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class TestControllerTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PermissionService permissionService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test1() {
|
||||||
|
List<ScannerControllerInfoVo> list = ControllerApiPermissionScanner.getSystemApiInfoList();
|
||||||
|
list.forEach(parent -> {
|
||||||
|
String parentPath = parent.getPath();
|
||||||
|
String powerCode = parentPath.replace("/api/", "").replace("/**", "");
|
||||||
|
powerCode = "user::" + powerCode;
|
||||||
|
|
||||||
|
Permission permission = new Permission();
|
||||||
|
permission.setParentId(0L);
|
||||||
|
permission.setPowerCode(powerCode);
|
||||||
|
permission.setPowerName(parent.getSummary());
|
||||||
|
permission.setRequestUrl(parentPath);
|
||||||
|
permissionService.saveOrUpdate(permission);
|
||||||
|
// System.out.println(permission);
|
||||||
|
|
||||||
|
List<Permission> permissionList = parent.getChildren().stream()
|
||||||
|
.map(children -> {
|
||||||
|
Permission childrenPermission = new Permission();
|
||||||
|
childrenPermission.setParentId(permission.getId());
|
||||||
|
childrenPermission.setPowerName(children.getSummary());
|
||||||
|
if (!children.getPowerCodes().isEmpty()) {
|
||||||
|
String ChildrenPowerCode = children.getPowerCodes().get(0);
|
||||||
|
childrenPermission.setPowerCode(ChildrenPowerCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
String childrenPath = children.getPath();
|
||||||
|
childrenPermission.setRequestUrl(childrenPath);
|
||||||
|
childrenPermission.setRequestMethod(children.getHttpMethod());
|
||||||
|
|
||||||
|
return childrenPermission;
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
// System.out.println(JSON.toJSONString(permissionList));
|
||||||
|
permissionService.saveOrUpdateBatch(permissionList);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
package cn.bunny.services.controller.configuration;
|
||||||
|
|
||||||
|
import cn.bunny.services.domain.system.configuration.dto.WebConfigurationDto;
|
||||||
|
import cn.bunny.services.domain.system.configuration.entity.WebConfiguration;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
|
import cn.bunny.services.utils.TokenUtilsTest;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.TypeReference;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@WebAppConfiguration
|
||||||
|
class ConfigurationControllerTest {
|
||||||
|
private static final String prefix = "/api/config";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebApplicationContext webApplicationContext;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenUtilsTest tokenUtils;
|
||||||
|
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUpMockMvc() {
|
||||||
|
token = tokenUtils.getToken();
|
||||||
|
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
|
||||||
|
.apply(SecurityMockMvcConfigurers.springSecurity())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void webConfig() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.get(prefix + "/noAuth/webConfig")
|
||||||
|
.header("token", token))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
MockHttpServletResponse response = result.getResponse();
|
||||||
|
String contentAsString = response.getContentAsString();
|
||||||
|
|
||||||
|
WebConfiguration webConfiguration = JSON.parseObject(contentAsString, WebConfiguration.class);
|
||||||
|
|
||||||
|
if (!webConfiguration.getTitle().equals("BunnyAdmin")) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(webConfiguration);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getWebConfig() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.request(HttpMethod.GET, prefix + "/getWebConfig")
|
||||||
|
.header("token", token))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
MockHttpServletResponse response = result.getResponse();
|
||||||
|
String contentAsString = response.getContentAsString();
|
||||||
|
|
||||||
|
Result<WebConfiguration> webConfigurationResult = JSON.parseObject(contentAsString, new TypeReference<>() {
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!webConfigurationResult.getCode().equals(200)) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!webConfigurationResult.getData().getShowModel().equals("smart")) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
System.out.println(contentAsString);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void updateWebConfiguration() throws Exception {
|
||||||
|
AtomicReference<WebConfigurationDto> webConfigurationDto = new AtomicReference<>();
|
||||||
|
String testTitle = "修改的之";
|
||||||
|
|
||||||
|
// 获取原本的配置信息
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.request(HttpMethod.GET, prefix + "/getWebConfig")
|
||||||
|
.header("token", token))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
MockHttpServletResponse response = result.getResponse();
|
||||||
|
String contentAsString = response.getContentAsString();
|
||||||
|
|
||||||
|
System.out.println(contentAsString);
|
||||||
|
|
||||||
|
Result<WebConfiguration> webConfigurationResult = JSON.parseObject(contentAsString, new TypeReference<>() {
|
||||||
|
});
|
||||||
|
|
||||||
|
WebConfigurationDto dto = new WebConfigurationDto();
|
||||||
|
BeanUtils.copyProperties(webConfigurationResult.getData(), dto);
|
||||||
|
|
||||||
|
webConfigurationDto.set(dto);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 修改原本的测试内容
|
||||||
|
webConfigurationDto.get().setTitle(testTitle);
|
||||||
|
|
||||||
|
// 测试修改方法
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.put(prefix + "/updateWebConfiguration")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(JSON.toJSONString(webConfigurationDto.get()))
|
||||||
|
.header("token", token))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
String contentAsString = result.getResponse().getContentAsString();
|
||||||
|
|
||||||
|
System.out.println(contentAsString);
|
||||||
|
|
||||||
|
Result<String> stringResult = JSON.parseObject(contentAsString, new TypeReference<>() {
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!stringResult.getCode().equals(200)) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 验证是否修改成功
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.request(HttpMethod.GET, prefix + "/getWebConfig")
|
||||||
|
.header("token", token))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
MockHttpServletResponse response = result.getResponse();
|
||||||
|
String contentAsString = response.getContentAsString();
|
||||||
|
|
||||||
|
Result<WebConfiguration> webConfigurationResult = JSON.parseObject(contentAsString, new TypeReference<>() {
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!webConfigurationResult.getCode().equals(200)) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!webConfigurationResult.getData().getTitle().equals(testTitle)) {
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
System.out.println(contentAsString);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
package cn.bunny.services.controller.configuration;
|
||||||
|
|
||||||
|
import cn.bunny.services.domain.system.email.dto.EmailTemplateAddDto;
|
||||||
|
import cn.bunny.services.domain.system.email.dto.EmailTemplateUpdateDto;
|
||||||
|
import cn.bunny.services.domain.system.email.vo.EmailTemplateVo;
|
||||||
|
import cn.bunny.services.domain.common.enums.EmailTemplateEnums;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
|
import cn.bunny.services.utils.TokenUtilsTest;
|
||||||
|
import cn.hutool.crypto.digest.MD5;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.alibaba.fastjson2.TypeReference;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@WebAppConfiguration
|
||||||
|
class EmailTemplateControllerTest {
|
||||||
|
private static final String prefix = "/api/emailTemplate";
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebApplicationContext webApplicationContext;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenUtilsTest tokenUtilsTest;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
token = tokenUtilsTest.getToken();
|
||||||
|
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
|
||||||
|
.apply(SecurityMockMvcConfigurers.springSecurity())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getEmailTemplatePage() throws Exception {
|
||||||
|
String api = prefix + "/getEmailTemplateList/1/10";
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.get(api)
|
||||||
|
.header("token", token)
|
||||||
|
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
|
.param("type", "code"))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
String contentAsString = result.getResponse().getContentAsString();
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(contentAsString);
|
||||||
|
|
||||||
|
if (jsonObject == null) {
|
||||||
|
throw new Exception(contentAsString);
|
||||||
|
}
|
||||||
|
System.out.println(jsonObject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getEmailTypeList() throws Exception {
|
||||||
|
String api = prefix + "/getEmailTypes";
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get(api).header("token", token))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
String contentAsString = result.getResponse().getContentAsString();
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(contentAsString);
|
||||||
|
|
||||||
|
if (jsonObject == null) {
|
||||||
|
throw new Exception(contentAsString);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(jsonObject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void addEmailTemplate() throws Exception {
|
||||||
|
String api = prefix + "/addEmailTemplate";
|
||||||
|
|
||||||
|
EmailTemplateAddDto dto = EmailTemplateAddDto.builder()
|
||||||
|
.emailUser(2L)
|
||||||
|
.body("哈哈哈")
|
||||||
|
.templateName("测试")
|
||||||
|
.subject("test")
|
||||||
|
.type(EmailTemplateEnums.NOTIFICATION.getType())
|
||||||
|
.isDefault(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.post(api)
|
||||||
|
.header("token", token)
|
||||||
|
.content(JSONObject.toJSONString(dto))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
String contentAsString = result.getResponse().getContentAsString();
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(contentAsString);
|
||||||
|
|
||||||
|
System.out.println(jsonObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
getEmailTemplatePage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void updateEmailTemplate() throws Exception {
|
||||||
|
String api = prefix + "/updateEmailTemplate";
|
||||||
|
String restTemplateApi = prefix + "/getEmailTemplateList/1/10";
|
||||||
|
|
||||||
|
String url = UriComponentsBuilder.fromUriString(restTemplateApi)
|
||||||
|
.queryParam("subject", "test")
|
||||||
|
.build()
|
||||||
|
.toUriString();
|
||||||
|
|
||||||
|
Result<PageResult<EmailTemplateVo>> result = restTemplate.exchange(
|
||||||
|
url,
|
||||||
|
HttpMethod.GET,
|
||||||
|
new HttpEntity<>(null),
|
||||||
|
new ParameterizedTypeReference<Result<PageResult<EmailTemplateVo>>>() {
|
||||||
|
}
|
||||||
|
).getBody();
|
||||||
|
|
||||||
|
if (result == null) throw new Exception();
|
||||||
|
if (!result.getCode().equals(200)) throw new Exception(result.getMessage());
|
||||||
|
if (result.getData().getList().isEmpty()) throw new Exception("没有测试数据");
|
||||||
|
|
||||||
|
EmailTemplateVo emailTemplateVo = result.getData().getList().get(0);
|
||||||
|
EmailTemplateUpdateDto emailTemplateUpdateDto = new EmailTemplateUpdateDto();
|
||||||
|
BeanUtils.copyProperties(emailTemplateVo, emailTemplateUpdateDto);
|
||||||
|
|
||||||
|
System.out.println(emailTemplateUpdateDto);
|
||||||
|
|
||||||
|
emailTemplateUpdateDto.setBody(MD5.create().digestHex16(LocalDateTime.now().toString()));
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.put(api)
|
||||||
|
.header("token", token)
|
||||||
|
.content(JSON.toJSONString(emailTemplateUpdateDto))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
)
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result1 -> {
|
||||||
|
String contentAsString = result1.getResponse().getContentAsString();
|
||||||
|
var pageResultResult = JSONObject.parseObject(contentAsString, new TypeReference<Result<PageResult<EmailTemplateVo>>>() {
|
||||||
|
});
|
||||||
|
if (pageResultResult == null) throw new Exception(contentAsString);
|
||||||
|
if (!pageResultResult.getCode().equals(200)) throw new Exception(pageResultResult.getMessage());
|
||||||
|
|
||||||
|
System.out.println(pageResultResult);
|
||||||
|
});
|
||||||
|
|
||||||
|
result = restTemplate.exchange(
|
||||||
|
url,
|
||||||
|
HttpMethod.GET,
|
||||||
|
new HttpEntity<>(null),
|
||||||
|
new ParameterizedTypeReference<Result<PageResult<EmailTemplateVo>>>() {
|
||||||
|
}
|
||||||
|
).getBody();
|
||||||
|
|
||||||
|
if (result == null) throw new Exception();
|
||||||
|
if (!result.getCode().equals(200)) throw new Exception(result.getMessage());
|
||||||
|
emailTemplateVo = result.getData().getList().get(0);
|
||||||
|
if (!emailTemplateVo.getBody().equals(emailTemplateUpdateDto.getBody())) {
|
||||||
|
throw new Exception(emailTemplateUpdateDto.getBody());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deleteEmailTemplate() throws Exception {
|
||||||
|
String api = prefix + "/deleteEmailTemplate";
|
||||||
|
List<Long> ids = new ArrayList<>();
|
||||||
|
ids.add(1905180657917157378L);
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.delete(api)
|
||||||
|
.header("token", token)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(JSON.toJSONString(ids)))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
String contentAsString = result.getResponse().getContentAsString();
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(contentAsString);
|
||||||
|
System.out.println(jsonObject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,179 @@
|
||||||
|
package cn.bunny.services.controller.log;
|
||||||
|
|
||||||
|
import cn.bunny.services.domain.system.log.dto.UserLoginLogDto;
|
||||||
|
import cn.bunny.services.domain.system.log.entity.UserLoginLog;
|
||||||
|
import cn.bunny.services.domain.system.log.vo.UserLoginLogLocalVo;
|
||||||
|
import cn.bunny.services.domain.system.log.vo.UserLoginLogVo;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
|
import cn.bunny.services.service.log.UserLoginLogService;
|
||||||
|
import cn.bunny.services.utils.TokenUtilsTest;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.TypeReference;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@SpringBootTest
|
||||||
|
@WebAppConfiguration
|
||||||
|
class UserLoginLogControllerTest {
|
||||||
|
private static final String prefix = "/api/userLoginLog";
|
||||||
|
|
||||||
|
private WebTestClient testClient;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebApplicationContext webApplicationContext;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserLoginLogService userLoginLogService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenUtilsTest tokenUtils;
|
||||||
|
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
token = tokenUtils.getToken();
|
||||||
|
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
|
||||||
|
.apply(SecurityMockMvcConfigurers.springSecurity())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
testClient = WebTestClient.bindToController(new UserLoginLogController()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getUserLoginLogPage() throws Exception {
|
||||||
|
UserLoginLogDto dto = UserLoginLogDto.builder()
|
||||||
|
.username("bunny")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get(prefix + "/getUserLoginLogList/1/10")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(JSON.toJSONString(dto))
|
||||||
|
.header("token", token))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
MockHttpServletResponse response = result.getResponse();
|
||||||
|
String contentAsString = response.getContentAsString();
|
||||||
|
|
||||||
|
System.out.println(contentAsString);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getUserLoginLogPage2() {
|
||||||
|
UserLoginLogDto dto = UserLoginLogDto.builder()
|
||||||
|
.username("bunny")
|
||||||
|
.build();
|
||||||
|
Map<String, String> params = JSON.parseObject(JSON.toJSONString(dto), new TypeReference<>() {
|
||||||
|
});
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
ResponseEntity<Result<PageResult<UserLoginLogVo>>> response = restTemplate.exchange(
|
||||||
|
prefix + "/getUserLoginLogList/1/10",
|
||||||
|
HttpMethod.GET,
|
||||||
|
new HttpEntity<>(params),
|
||||||
|
new ParameterizedTypeReference<>() {
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Result<PageResult<UserLoginLogVo>> body = response.getBody();
|
||||||
|
System.out.println(JSON.toJSONString(body));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getUserLoginLogPageByUser() throws Exception {
|
||||||
|
String api = prefix + "/noManage/getUserLoginLogListByLocalUser/1/10";
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.get(api)
|
||||||
|
.header("token", token))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
MockHttpServletResponse response = result.getResponse();
|
||||||
|
String contentAsString = response.getContentAsString();
|
||||||
|
|
||||||
|
System.out.println(contentAsString);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getUserLoginLogPageByUser2() {
|
||||||
|
String api = prefix + "/noManage/getUserLoginLogListByLocalUser/1/10";
|
||||||
|
|
||||||
|
testClient.get()
|
||||||
|
.uri(api)
|
||||||
|
.header("token", token)
|
||||||
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isOk()
|
||||||
|
.expectBody(new ParameterizedTypeReference<Result<PageResult<UserLoginLogLocalVo>>>() {
|
||||||
|
})
|
||||||
|
.consumeWith(result -> {
|
||||||
|
Result<PageResult<UserLoginLogLocalVo>> responseBody = result.getResponseBody();
|
||||||
|
System.out.println(JSON.toJSONString(responseBody));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deleteUserLoginLog() throws Exception {
|
||||||
|
String api = prefix + "/deleteUserLoginLog";
|
||||||
|
|
||||||
|
Page<UserLoginLog> page = new Page<>(1, 10);
|
||||||
|
List<UserLoginLog> deleteBeforeList = userLoginLogService.list(page);
|
||||||
|
List<Long> ids = deleteBeforeList.stream().map(UserLoginLog::getId).limit(4).toList();
|
||||||
|
List<Long> deleteBeforeIds = deleteBeforeList.stream().map(UserLoginLog::getId).toList();
|
||||||
|
|
||||||
|
log.info("要删除的ids: {}", ids);
|
||||||
|
log.info("删除前ids数据:{}", deleteBeforeIds);
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.delete(api)
|
||||||
|
.header("token", token)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(JSON.toJSONString(ids)))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(result -> {
|
||||||
|
MockHttpServletResponse response = result.getResponse();
|
||||||
|
String contentAsString = response.getContentAsString();
|
||||||
|
System.out.println(contentAsString);
|
||||||
|
});
|
||||||
|
|
||||||
|
deleteBeforeList = userLoginLogService.list(page);
|
||||||
|
deleteBeforeIds = deleteBeforeList.stream().map(UserLoginLog::getId).toList();
|
||||||
|
log.info("要删除的ids: {}", ids);
|
||||||
|
log.info("删除前ids数据:{}", deleteBeforeIds);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package cn.bunny.services.controller.system;
|
||||||
|
|
||||||
|
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.data.redis.core.Cursor;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.ScanOptions;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class UserControllerTest {
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test() {
|
||||||
|
// Set<String> keys = redisTemplate.keys("admin::login_info::*");
|
||||||
|
// for (String key : keys) {
|
||||||
|
// System.out.println(key);
|
||||||
|
// }
|
||||||
|
|
||||||
|
Map<String, Object> adminLoginInfoWithScan = getAdminLoginInfoWithScan();
|
||||||
|
JSONObject adminLoginInfo = new JSONObject(adminLoginInfoWithScan);
|
||||||
|
System.out.println(adminLoginInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getAdminLoginInfoWithScan() {
|
||||||
|
String pattern = "admin::login_info::*";
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
// 使用scan命令迭代查找
|
||||||
|
ScanOptions options = ScanOptions.scanOptions().match(pattern).count(100).build();
|
||||||
|
Cursor<String> cursor = redisTemplate.scan(options);
|
||||||
|
|
||||||
|
while (cursor.hasNext()) {
|
||||||
|
String key = cursor.next();
|
||||||
|
Object value = redisTemplate.opsForValue().get(key);
|
||||||
|
result.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
cursor.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 处理异常
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package cn.bunny.services.utils;
|
||||||
|
|
||||||
|
import cn.bunny.services.domain.common.model.vo.LoginVo;
|
||||||
|
import cn.bunny.services.domain.system.system.entity.AdminUser;
|
||||||
|
import cn.bunny.services.mapper.system.UserMapper;
|
||||||
|
import cn.bunny.services.service.system.helper.UserLoginHelper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class TokenUtilsTest {
|
||||||
|
@Autowired
|
||||||
|
private UserLoginHelper userUtil;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserMapper userMapper;
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
AdminUser adminUser = userMapper.selectOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getUsername, "Administrator"));
|
||||||
|
adminUser.setPassword("admin123");
|
||||||
|
LoginVo loginVo = userUtil.buildLoginUserVo(adminUser, 7);
|
||||||
|
return loginVo.getToken();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package impl;
|
||||||
|
|
||||||
|
import cn.bunny.services.domain.common.model.dto.excel.I18nExcel;
|
||||||
|
import cn.bunny.services.domain.system.i18n.entity.I18n;
|
||||||
|
import cn.bunny.services.mapper.configuration.I18nMapper;
|
||||||
|
import com.alibaba.excel.EasyExcel;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
public class I18nServiceImplTest extends ServiceImpl<I18nMapper, I18n> {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void downloadI18nByExcel() {
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) {
|
||||||
|
// 查找默认语言内容
|
||||||
|
List<I18n> i18nList = list();
|
||||||
|
Map<String, List<I18nExcel>> hashMap = i18nList.stream()
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
I18n::getTypeName,
|
||||||
|
Collectors.mapping((I18n i18n) -> {
|
||||||
|
String keyName = i18n.getKeyName();
|
||||||
|
String translation = i18n.getTranslation();
|
||||||
|
return I18nExcel.builder().keyName(keyName).translation(translation).build();
|
||||||
|
}, Collectors.toList())
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
hashMap.forEach((key, value) -> {
|
||||||
|
// EasyExcel.write(key + ".xlsx", I18nExcel.class).sheet(key).doWrite(value);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ZipEntry zipEntry = new ZipEntry(key + ".xlsx");
|
||||||
|
zipOutputStream.putNextEntry(zipEntry);
|
||||||
|
|
||||||
|
// 直接写入到ZipOutputStream
|
||||||
|
EasyExcel.write(zipOutputStream, I18nExcel.class).sheet(key).doWrite(value);
|
||||||
|
zipOutputStream.closeEntry();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,38 +0,0 @@
|
||||||
package impl;
|
|
||||||
|
|
||||||
import cn.bunny.services.AuthServiceApplication;
|
|
||||||
import cn.bunny.services.core.template.PermissionTreeProcessor;
|
|
||||||
import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel;
|
|
||||||
import cn.bunny.services.domain.system.system.entity.Permission;
|
|
||||||
import cn.bunny.services.mapper.system.PermissionMapper;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@SpringBootTest(classes = AuthServiceApplication.class)
|
|
||||||
class PermissionServiceImplTest {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PermissionMapper permissionMapper;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void exportPermission() {
|
|
||||||
|
|
||||||
List<Permission> permissionList = permissionMapper.selectList(null);
|
|
||||||
List<PermissionExcel> permissionExcelList = permissionList.stream().map(permission -> {
|
|
||||||
PermissionExcel permissionExcel = new PermissionExcel();
|
|
||||||
BeanUtils.copyProperties(permission, permissionExcel);
|
|
||||||
|
|
||||||
return permissionExcel;
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
PermissionTreeProcessor permissionTreeProcessor = new PermissionTreeProcessor();
|
|
||||||
List<PermissionExcel> buildTree = permissionTreeProcessor.process(permissionExcelList);
|
|
||||||
|
|
||||||
System.out.println(JSON.toJSONString(buildTree));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package system;
|
||||||
|
|
||||||
|
import cn.bunny.services.controller.system.UserController;
|
||||||
|
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
||||||
|
import cn.bunny.services.service.system.impl.UserServiceImpl;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.data.redis.core.RedisConnectionUtils;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
@SpringBootTest(classes = UserServiceImpl.class)
|
||||||
|
class UserServiceTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test() {
|
||||||
|
String prefix = RedisUserConstant.getAdminUserEmailCodePrefix("");
|
||||||
|
Set<String> keys = redisTemplate.keys(prefix);
|
||||||
|
for (String key : keys) {
|
||||||
|
System.out.println(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -127,11 +127,5 @@
|
||||||
<artifactId>ip2region</artifactId>
|
<artifactId>ip2region</artifactId>
|
||||||
<version>2.6.5</version>
|
<version>2.6.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
|
||||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.springframework.data.redis.cache.RedisCacheManager;
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
|
@ -41,14 +42,13 @@ public class RedisConfiguration {
|
||||||
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
|
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
|
||||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||||
redisTemplate.setConnectionFactory(connectionFactory);
|
redisTemplate.setConnectionFactory(connectionFactory);
|
||||||
|
|
||||||
// 设置key序列化为string
|
// 设置key序列化为string
|
||||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
|
||||||
|
|
||||||
// 设置value序列化为JSON,使用GenericJackson2JsonRedisSerializer替换默认序列化
|
// 设置value序列化为JSON,使用GenericJackson2JsonRedisSerializer替换默认序列化
|
||||||
redisTemplate.setValueSerializer(jsonRedisSerializer());
|
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
|
||||||
redisTemplate.setHashValueSerializer(jsonRedisSerializer());
|
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||||
|
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
|
||||||
|
|
||||||
// 开启Redis事务
|
// 开启Redis事务
|
||||||
redisTemplate.setEnableTransactionSupport(true);
|
redisTemplate.setEnableTransactionSupport(true);
|
||||||
|
|
|
@ -12,57 +12,15 @@ public class RedisUserConstant {
|
||||||
public static final Integer Cookie_EXPIRATION_TIME = 5 * 60 * 60;// cookies 过期时间 5 分钟
|
public static final Integer Cookie_EXPIRATION_TIME = 5 * 60 * 60;// cookies 过期时间 5 分钟
|
||||||
public static final String WEB_CONFIG_KEY = "webConfig::platformConfig";// web配置
|
public static final String WEB_CONFIG_KEY = "webConfig::platformConfig";// web配置
|
||||||
|
|
||||||
/* 用户登录前缀 */
|
private static final String ADMIN_LOGIN_INFO_PREFIX = "admin::login_info::";
|
||||||
private static final String USER_LOGIN_INFO_PREFIX = "user::login_info::";
|
private static final String ADMIN_EMAIL_CODE_PREFIX = "admin::email_code::";
|
||||||
|
|
||||||
/* 用户邮箱验证码前缀 */
|
|
||||||
private static final String USER_EMAIL_CODE_PREFIX = "user::email_code::";
|
|
||||||
|
|
||||||
/* 用户角色前缀 */
|
|
||||||
private static final String USER_ROLES_CODE_PREFIX = "user::roles::";
|
|
||||||
|
|
||||||
/* 用户权限前缀 */
|
|
||||||
private static final String USER_PERMISSION_CODE_PREFIX = "user::permission::";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户登录前缀
|
|
||||||
*
|
|
||||||
* @param user 用户名信息
|
|
||||||
* @return 格式化后缓存前缀
|
|
||||||
*/
|
|
||||||
public static String getUserLoginInfoPrefix(String user) {
|
|
||||||
return USER_LOGIN_INFO_PREFIX + user;
|
|
||||||
|
|
||||||
|
public static String getAdminLoginInfoPrefix(String adminUser) {
|
||||||
|
return ADMIN_LOGIN_INFO_PREFIX + adminUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static String getAdminUserEmailCodePrefix(String adminUser) {
|
||||||
* 用户邮箱前缀
|
return ADMIN_EMAIL_CODE_PREFIX + adminUser;
|
||||||
*
|
|
||||||
* @param user 用户信息
|
|
||||||
* @return 邮箱验证码前缀
|
|
||||||
*/
|
|
||||||
public static String getUserEmailCodePrefix(String user) {
|
|
||||||
return USER_EMAIL_CODE_PREFIX + user;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户角色前缀
|
|
||||||
*
|
|
||||||
* @param user 用户信息
|
|
||||||
* @return 格式化后用户角色前缀
|
|
||||||
*/
|
|
||||||
public static String getUserRolesCodePrefix(String user) {
|
|
||||||
return USER_ROLES_CODE_PREFIX + user;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户权限前缀
|
|
||||||
*
|
|
||||||
* @param user 用户信息
|
|
||||||
* @return 格式化后用户权限前缀
|
|
||||||
*/
|
|
||||||
public static String getUserPermissionCodePrefix(String user) {
|
|
||||||
return USER_PERMISSION_CODE_PREFIX + user;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.bunny.services.domain.common.model.vo.result;
|
package cn.bunny.services.domain.common.model.vo.result;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.services.domain.common.enums;
|
package cn.bunny.services.domain.common.model.vo.result;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -53,8 +53,7 @@ public enum ResultCodeEnum {
|
||||||
LOGIN_AUTH(208, "请先登陆"),
|
LOGIN_AUTH(208, "请先登陆"),
|
||||||
AUTHENTICATION_EXPIRED(208, "身份验证过期"),
|
AUTHENTICATION_EXPIRED(208, "身份验证过期"),
|
||||||
SESSION_EXPIRATION(208, "会话过期"),
|
SESSION_EXPIRATION(208, "会话过期"),
|
||||||
FAIL_NO_ACCESS_DENIED_USER_LOCKED(208, "该账户已封禁"),
|
|
||||||
|
|
||||||
// 209
|
// 209
|
||||||
THE_SAME_USER_HAS_LOGGED_IN(209, "相同用户已登录"),
|
THE_SAME_USER_HAS_LOGGED_IN(209, "相同用户已登录"),
|
||||||
|
|
||||||
|
@ -72,6 +71,7 @@ public enum ResultCodeEnum {
|
||||||
FAIL_NO_ACCESS_DENIED(403, "无权访问"),
|
FAIL_NO_ACCESS_DENIED(403, "无权访问"),
|
||||||
FAIL_NO_ACCESS_DENIED_USER_OFFLINE(403, "用户强制下线"),
|
FAIL_NO_ACCESS_DENIED_USER_OFFLINE(403, "用户强制下线"),
|
||||||
TOKEN_PARSING_FAILED(403, "token解析失败"),
|
TOKEN_PARSING_FAILED(403, "token解析失败"),
|
||||||
|
FAIL_NO_ACCESS_DENIED_USER_LOCKED(403, "该账户已封禁"),
|
||||||
|
|
||||||
// 系统错误 500
|
// 系统错误 500
|
||||||
UNKNOWN_EXCEPTION(500, "服务异常"),
|
UNKNOWN_EXCEPTION(500, "服务异常"),
|
|
@ -1,6 +1,6 @@
|
||||||
package cn.bunny.services.exception;
|
package cn.bunny.services.exception;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
|
@ -2,7 +2,7 @@ package cn.bunny.services.exception;
|
||||||
|
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.context.BaseContext;
|
import cn.bunny.services.context.BaseContext;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.mybatis.spring.MyBatisSystemException;
|
import org.mybatis.spring.MyBatisSystemException;
|
||||||
|
|
|
@ -2,7 +2,7 @@ package cn.bunny.services.minio;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.constant.MinioConstant;
|
import cn.bunny.services.domain.common.constant.MinioConstant;
|
||||||
import cn.bunny.services.domain.common.model.dto.minio.MinioUploadFileInfo;
|
import cn.bunny.services.domain.common.model.dto.minio.MinioUploadFileInfo;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
||||||
import io.minio.*;
|
import io.minio.*;
|
||||||
import io.minio.messages.DeleteError;
|
import io.minio.messages.DeleteError;
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
package cn.bunny.services.processor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/* 构建树型结构模板处理器 */
|
|
||||||
public abstract class TreeProcessor<T> {
|
|
||||||
public final List<T> process(List<T> list) {
|
|
||||||
List<T> roots = findRoots(list);
|
|
||||||
for (T root : roots) {
|
|
||||||
buildChildren(root, list);
|
|
||||||
}
|
|
||||||
return roots;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract List<T> findRoots(List<T> list);
|
|
||||||
|
|
||||||
protected abstract void buildChildren(T parent, List<T> list);
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.services.core.cache;
|
package cn.bunny.services.redis;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
@ -26,7 +26,7 @@ public class RedisService {
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<String> scannerRedisKeyByPage(long pageNum, long pageSize) {
|
public List<String> scannerRedisKeyByPage(long pageNum, long pageSize) {
|
||||||
String prefix = RedisUserConstant.getUserLoginInfoPrefix("*");
|
String prefix = RedisUserConstant.getAdminLoginInfoPrefix("*");
|
||||||
|
|
||||||
List<String> keys = new ArrayList<>();
|
List<String> keys = new ArrayList<>();
|
||||||
ScanOptions scanOptions = ScanOptions.scanOptions()
|
ScanOptions scanOptions = ScanOptions.scanOptions()
|
|
@ -1,6 +1,6 @@
|
||||||
package cn.bunny.services.utils;
|
package cn.bunny.services.utils;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.Jws;
|
import io.jsonwebtoken.Jws;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class MinioTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test() {
|
||||||
|
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM-dd");
|
||||||
|
String date = formatter.format(new Date());
|
||||||
|
System.out.println(date);
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,9 +21,9 @@ public interface RolePermissionMapper extends BaseMapper<RolePermission> {
|
||||||
/**
|
/**
|
||||||
* * 根据权限id列表删除角色权限相关
|
* * 根据权限id列表删除角色权限相关
|
||||||
*
|
*
|
||||||
* @param permissionIds 权限id列表
|
* @param powerIds 权限id列表
|
||||||
*/
|
*/
|
||||||
void deleteBatchPowerIds(List<Long> permissionIds);
|
void deleteBatchPowerIds(List<Long> powerIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 根据角色id删除角色权限
|
* * 根据角色id删除角色权限
|
||||||
|
@ -38,7 +38,7 @@ public interface RolePermissionMapper extends BaseMapper<RolePermission> {
|
||||||
* @param roleId 角色id
|
* @param roleId 角色id
|
||||||
* @return 已选择的权限列表
|
* @return 已选择的权限列表
|
||||||
*/
|
*/
|
||||||
List<RolePermission> selectRolePermissionListByRoleId(Long roleId);
|
List<RolePermission> selectPowerListByRoleId(Long roleId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查看所有角色关联的权限
|
* 查看所有角色关联的权限
|
||||||
|
@ -46,12 +46,4 @@ public interface RolePermissionMapper extends BaseMapper<RolePermission> {
|
||||||
* @return 角色权限关系视图
|
* @return 角色权限关系视图
|
||||||
*/
|
*/
|
||||||
List<ViewRolePermission> viewRolePowerWithAll();
|
List<ViewRolePermission> viewRolePowerWithAll();
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据权限id列表查询角色和权限
|
|
||||||
*
|
|
||||||
* @param permissionIds 权限id列表
|
|
||||||
* @return List<RolePermission>
|
|
||||||
*/
|
|
||||||
List<RolePermission> selectRolePermissionListByPermissionIds(List<Long> permissionIds);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,4 @@ public interface UserRoleMapper extends BaseMapper<UserRole> {
|
||||||
*/
|
*/
|
||||||
void deleteBatchIdsByRoleIds(List<Long> roleIds);
|
void deleteBatchIdsByRoleIds(List<Long> roleIds);
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据角色id列表查询
|
|
||||||
*
|
|
||||||
* @param ids 角色id列表
|
|
||||||
* @return {@link List<UserRole>}
|
|
||||||
*/
|
|
||||||
List<UserRole> selectListByRoleIds(List<Long> ids);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,11 +53,15 @@
|
||||||
<!-- 根据用户id查询当前用户所有权限 -->
|
<!-- 根据用户id查询当前用户所有权限 -->
|
||||||
<select id="selectListByUserId" resultType="cn.bunny.services.domain.system.system.entity.Permission">
|
<select id="selectListByUserId" resultType="cn.bunny.services.domain.system.system.entity.Permission">
|
||||||
SELECT p.*
|
SELECT p.*
|
||||||
FROM sys_permission p
|
FROM sys_user u,
|
||||||
INNER JOIN sys_role_permission rp ON p.id = rp.power_id
|
sys_user_role ur,
|
||||||
INNER JOIN sys_user_role ur ON rp.role_id = ur.role_id
|
sys_role_permission rp,
|
||||||
INNER JOIN sys_user u ON ur.user_id = u.id AND u.is_deleted = 0
|
sys_permission p
|
||||||
WHERE u.id = #{userId}
|
WHERE u.id = ur.user_id
|
||||||
|
AND u.is_deleted = 0
|
||||||
|
AND ur.role_id = rp.role_id
|
||||||
|
AND rp.power_id = p.id
|
||||||
|
AND u.id = #{userId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
@ -43,10 +43,12 @@
|
||||||
<!-- 根据用户id查询当前用户所有角色 -->
|
<!-- 根据用户id查询当前用户所有角色 -->
|
||||||
<select id="selectListByUserId" resultType="cn.bunny.services.domain.system.system.entity.Role">
|
<select id="selectListByUserId" resultType="cn.bunny.services.domain.system.system.entity.Role">
|
||||||
SELECT r.*
|
SELECT r.*
|
||||||
FROM sys_user u
|
FROM sys_user u,
|
||||||
INNER JOIN sys_user_role ur ON u.id = ur.user_id
|
sys_role r,
|
||||||
INNER JOIN sys_role r ON r.id = ur.role_id
|
sys_user_role ur
|
||||||
WHERE u.is_deleted = 0
|
WHERE u.id = ur.user_id
|
||||||
|
AND u.is_deleted = 0
|
||||||
|
AND r.id = ur.role_id
|
||||||
AND ur.user_id = #{userId}
|
AND ur.user_id = #{userId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
delete
|
delete
|
||||||
from sys_role_permission
|
from sys_role_permission
|
||||||
where power_id in
|
where power_id in
|
||||||
<foreach collection="permissionIds" item="id" open="(" close=")" separator=",">
|
<foreach collection="powerIds" item="id" open="(" close=")" separator=",">
|
||||||
#{id}
|
#{id}
|
||||||
</foreach>
|
</foreach>
|
||||||
</delete>
|
</delete>
|
||||||
|
@ -40,8 +40,7 @@
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
<!-- 根据角色id获取权限内容 -->
|
<!-- 根据角色id获取权限内容 -->
|
||||||
<select id="selectRolePermissionListByRoleId"
|
<select id="selectPowerListByRoleId" resultType="cn.bunny.services.domain.system.system.entity.RolePermission">
|
||||||
resultType="cn.bunny.services.domain.system.system.entity.RolePermission">
|
|
||||||
select *
|
select *
|
||||||
from sys_role_permission
|
from sys_role_permission
|
||||||
where role_id = #{roleId}
|
where role_id = #{roleId}
|
||||||
|
@ -62,14 +61,4 @@
|
||||||
LEFT JOIN sys_permission permission ON rp.power_id = permission.id
|
LEFT JOIN sys_permission permission ON rp.power_id = permission.id
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- 根据权限id列表查询角色和权限 -->
|
|
||||||
<select id="selectRolePermissionListByPermissionIds"
|
|
||||||
resultType="cn.bunny.services.domain.system.system.entity.RolePermission">
|
|
||||||
SELECT * FROM
|
|
||||||
sys_role_permission WHERE power_id IN
|
|
||||||
<foreach collection="permissionIds" item="id" separator="," open="(" close=")">
|
|
||||||
#{id}
|
|
||||||
</foreach>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
@ -39,12 +39,4 @@
|
||||||
</foreach>
|
</foreach>
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
<!-- 根据角色id列表查询 -->
|
|
||||||
<select id="selectListByRoleIds" resultType="cn.bunny.services.domain.system.system.entity.UserRole">
|
|
||||||
SELECT * FROM sys_user_role WHERE role_id IN
|
|
||||||
<foreach collection="ids" item="id" open="(" close=")" separator=",">
|
|
||||||
#{id}
|
|
||||||
</foreach>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
package cn.bunny;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.bunny.core.TypeConvertCore;
|
||||||
|
import cn.bunny.dao.entity.ColumnMetaData;
|
||||||
|
import cn.bunny.dao.entity.TableMetaData;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
public class JDBCTest {
|
||||||
|
|
||||||
|
DatabaseMetaData metaData;
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
public JDBCTest(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
metaData = connection.getMetaData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testComment() throws SQLException {
|
||||||
|
String tableName = "sys_i18n";
|
||||||
|
TableMetaData tableMetaData;
|
||||||
|
ResultSet tables = metaData.getTables(null, null, tableName, new String[]{"TABLE"});
|
||||||
|
|
||||||
|
// 获取表的注释信息
|
||||||
|
if (tables.next()) {
|
||||||
|
String remarks = tables.getString("REMARKS");
|
||||||
|
String tableCat = tables.getString("TABLE_CAT");
|
||||||
|
|
||||||
|
tableMetaData = TableMetaData.builder()
|
||||||
|
.tableName(tableName)
|
||||||
|
.comment(remarks)
|
||||||
|
.tableCat(tableCat)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
System.out.println(tableMetaData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAllTableComment() throws SQLException {
|
||||||
|
ResultSet tables = metaData.getTables(null, null, "%", new String[]{"TABLE"});
|
||||||
|
List<TableMetaData> list = new ArrayList<>();
|
||||||
|
|
||||||
|
while (tables.next()) {
|
||||||
|
String tableName = tables.getString("TABLE_NAME");
|
||||||
|
String remarks = tables.getString("REMARKS");
|
||||||
|
String tableCat = tables.getString("TABLE_CAT");
|
||||||
|
|
||||||
|
TableMetaData tableMetaData = TableMetaData.builder()
|
||||||
|
.tableName(tableName).comment(remarks)
|
||||||
|
.tableCat(tableCat)
|
||||||
|
.build();
|
||||||
|
list.add(tableMetaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testColumnInfo() throws SQLException {
|
||||||
|
List<ColumnMetaData> columns = new ArrayList<>();
|
||||||
|
|
||||||
|
try (ResultSet columnsRs = metaData.getColumns(null, null, "sys_i18n", null)) {
|
||||||
|
while (columnsRs.next()) {
|
||||||
|
ColumnMetaData column = new ColumnMetaData();
|
||||||
|
column.setColumnName(columnsRs.getString("COLUMN_NAME"));
|
||||||
|
column.setLowercaseName(TypeConvertCore.convertToCamelCase(column.getColumnName()));
|
||||||
|
column.setJdbcType(columnsRs.getString("TYPE_NAME"));
|
||||||
|
column.setJavaType(TypeConvertCore.convertToJavaType(column.getJdbcType()));
|
||||||
|
column.setComment(columnsRs.getString("REMARKS"));
|
||||||
|
|
||||||
|
columns.add(column);
|
||||||
|
System.out.println(column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(columns);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package cn.bunny;
|
||||||
|
|
||||||
|
import cn.bunny.core.TypeConvertCore;
|
||||||
|
import cn.bunny.dao.entity.ColumnMetaData;
|
||||||
|
import cn.bunny.dao.entity.TableMetaData;
|
||||||
|
import net.sf.jsqlparser.JSQLParserException;
|
||||||
|
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||||
|
import net.sf.jsqlparser.statement.Statement;
|
||||||
|
import net.sf.jsqlparser.statement.create.table.CreateTable;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class SqlParserTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws JSQLParserException {
|
||||||
|
String sql = """
|
||||||
|
CREATE TABLE `sys_files` (
|
||||||
|
`id` bigint NOT NULL COMMENT '文件的唯一标识符,自动递增',
|
||||||
|
`filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '文件的名称',
|
||||||
|
`filepath` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '文件在服务器上的存储路径',
|
||||||
|
`file_size` int NOT NULL COMMENT '文件的大小,以字节为单位',
|
||||||
|
`file_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '文件的MIME类型',
|
||||||
|
`download_count` int NULL DEFAULT 0 COMMENT '下载数量',
|
||||||
|
`create_user` bigint NOT NULL COMMENT '创建用户',
|
||||||
|
`update_user` bigint NULL DEFAULT NULL COMMENT '操作用户',
|
||||||
|
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录文件最后修改的时间戳',
|
||||||
|
`is_deleted` tinyint(1) UNSIGNED ZEROFILL NOT NULL DEFAULT 0 COMMENT '文件是否被删除',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
INDEX `idx_filename`(`filename` ASC) USING BTREE COMMENT '索引文件名',
|
||||||
|
INDEX `idx_filepath`(`filepath` ASC) USING BTREE COMMENT '索引文件路径',
|
||||||
|
INDEX `idx_file_type`(`file_type` ASC) USING BTREE COMMENT '索引文件类型',
|
||||||
|
INDEX `idx_update_user`(`update_user` ASC) USING BTREE COMMENT '索引创更新用户',
|
||||||
|
INDEX `idx_create_user`(`create_user` ASC) USING BTREE COMMENT '索引创建用户',
|
||||||
|
INDEX `idx_user`(`update_user` ASC, `create_user` ASC) USING BTREE COMMENT '索引创建用户和更新用户',
|
||||||
|
INDEX `idx_time`(`update_time` ASC, `create_time` ASC) USING BTREE COMMENT '索引创建时间和更新时间'
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统文件表' ROW_FORMAT = DYNAMIC;
|
||||||
|
""";
|
||||||
|
|
||||||
|
TableMetaData tableInfo = new TableMetaData();
|
||||||
|
|
||||||
|
// 解析sql
|
||||||
|
Statement statement = CCJSqlParserUtil.parse(sql);
|
||||||
|
if (!(statement instanceof CreateTable createTable)) {
|
||||||
|
throw new IllegalArgumentException("Not a CREATE TABLE statement");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置表基本信息
|
||||||
|
tableInfo.setTableName(createTable.getTable().getName());
|
||||||
|
tableInfo.setTableType("TABLE");
|
||||||
|
String tableOptionsStrings = String.join(" ", createTable.getTableOptionsStrings());
|
||||||
|
|
||||||
|
// 注释信息
|
||||||
|
Pattern pattern = Pattern.compile("COMMENT\\s*=\\s*'(.*?)'", Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher matcher = pattern.matcher(tableOptionsStrings);
|
||||||
|
if (matcher.find()) {
|
||||||
|
tableInfo.setComment(matcher.group(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析列信息
|
||||||
|
List<ColumnMetaData> columnMetaData = createTable.getColumnDefinitions()
|
||||||
|
.stream().map(column -> {
|
||||||
|
// 列信息
|
||||||
|
ColumnMetaData columnInfo = new ColumnMetaData();
|
||||||
|
|
||||||
|
// 列名称
|
||||||
|
columnInfo.setColumnName(column.getColumnName());
|
||||||
|
|
||||||
|
// 设置 JDBC 类型
|
||||||
|
String dataType = column.getColDataType().getDataType();
|
||||||
|
columnInfo.setJdbcType(dataType);
|
||||||
|
|
||||||
|
// 设置 Java 类型
|
||||||
|
String javaType = TypeConvertCore.convertToJavaType(dataType.contains("varchar") ? "varchar" : dataType);
|
||||||
|
columnInfo.setJavaType(javaType);
|
||||||
|
|
||||||
|
// 设置 JavaScript 类型
|
||||||
|
columnInfo.setJavascriptType(StringUtils.uncapitalize(javaType));
|
||||||
|
|
||||||
|
// 列字段转成 下划线 -> 小驼峰
|
||||||
|
columnInfo.setLowercaseName(TypeConvertCore.convertToCamelCase(column.getColumnName()));
|
||||||
|
// 列字段转成 下划线 -> 大驼峰名称
|
||||||
|
columnInfo.setUppercaseName(TypeConvertCore.convertToCamelCase(column.getColumnName(), true));
|
||||||
|
|
||||||
|
// 解析注释
|
||||||
|
List<String> columnSpecs = column.getColumnSpecs();
|
||||||
|
String columnSpecsString = String.join(" ", columnSpecs);
|
||||||
|
Matcher columnSpecsStringMatcher = Pattern.compile("COMMENT\\s*'(.*?)'", Pattern.CASE_INSENSITIVE).matcher(columnSpecsString);
|
||||||
|
if (columnSpecsStringMatcher.find()) {
|
||||||
|
columnInfo.setComment(columnSpecsStringMatcher.group(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return columnInfo;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
System.out.println(tableInfo);
|
||||||
|
System.out.println("----------------------------------------------------------------------------------------");
|
||||||
|
System.out.println(columnMetaData);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package cn.bunny;
|
||||||
|
|
||||||
|
import cn.bunny.core.TypeConvertCore;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.assertj.core.util.introspection.CaseFormatUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class StringFormatTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test1() {
|
||||||
|
System.out.println(CaseFormatUtils.toCamelCase("user_login" ));
|
||||||
|
System.out.println(CaseFormatUtils.toCamelCase("userLogin" ));
|
||||||
|
System.out.println(CaseFormatUtils.toCamelCase("UserLogin" ));
|
||||||
|
|
||||||
|
System.out.println("--------------------------------" );
|
||||||
|
|
||||||
|
System.out.println(StringUtils.lowerCase("user_login" ));
|
||||||
|
System.out.println(StringUtils.lowerCase("userLogin" ));
|
||||||
|
System.out.println(StringUtils.lowerCase("UserLogin" ));
|
||||||
|
|
||||||
|
System.out.println("--------------------------------" );
|
||||||
|
|
||||||
|
System.out.println(StringUtils.upperCase("user_login" ));
|
||||||
|
System.out.println(StringUtils.upperCase("userLogin" ));
|
||||||
|
System.out.println(StringUtils.upperCase("UserLogin" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test2() {
|
||||||
|
System.out.println(TypeConvertCore.convertToCamelCase("user_login_A" ));
|
||||||
|
System.out.println(TypeConvertCore.convertToCamelCase("User_Login_A" ));
|
||||||
|
System.out.println(TypeConvertCore.convertToCamelCase("userLoginA" ));
|
||||||
|
System.out.println(TypeConvertCore.convertToCamelCase("UserLoginA" ));
|
||||||
|
|
||||||
|
System.out.println("--------------------------------" );
|
||||||
|
|
||||||
|
System.out.println(TypeConvertCore.convertToCamelCase("i18n_type_A" , true));
|
||||||
|
System.out.println(TypeConvertCore.convertToCamelCase("User_Login_A" , true));
|
||||||
|
System.out.println(TypeConvertCore.convertToCamelCase("userLoginA" , true));
|
||||||
|
System.out.println(TypeConvertCore.convertToCamelCase("UserLoginA" , true));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package cn.bunny;
|
||||||
|
|
||||||
|
import cn.hutool.crypto.digest.MD5;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class TimeTest {
|
||||||
|
@Test
|
||||||
|
void timeTest() {
|
||||||
|
long currentTimeMillis = System.currentTimeMillis();
|
||||||
|
String digestHex = MD5.create().digestHex(currentTimeMillis + "");
|
||||||
|
System.out.println(currentTimeMillis);
|
||||||
|
System.out.println(digestHex);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package cn.bunny.service.impl;
|
||||||
|
|
||||||
|
import cn.bunny.core.ResourceFileCore;
|
||||||
|
import cn.bunny.dao.vo.VmsPathVo;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
class VmsServiceImplTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void vmsResourcePathList() throws IOException, URISyntaxException {
|
||||||
|
List<String> vmsFiles = ResourceFileCore.getAbsoluteFiles("vms");
|
||||||
|
System.out.println(vmsFiles);
|
||||||
|
|
||||||
|
System.out.println("--------------------------------------------------------------");
|
||||||
|
|
||||||
|
List<String> vmsRelativeFiles = ResourceFileCore.getRelativeFiles("vms");
|
||||||
|
System.out.println(vmsRelativeFiles);
|
||||||
|
|
||||||
|
System.out.println("--------------------------集合对象模式------------------------------------");
|
||||||
|
|
||||||
|
Map<String, List<VmsPathVo>> map = vmsRelativeFiles.stream().map(vmFile -> {
|
||||||
|
String[] filepathList = vmFile.split("/");
|
||||||
|
String filename = filepathList[filepathList.length - 1].replace(".vm", "");
|
||||||
|
|
||||||
|
return VmsPathVo.builder().name(vmFile).label(filename).type(filepathList[0]).build();
|
||||||
|
}).collect(Collectors.groupingBy(VmsPathVo::getType));
|
||||||
|
|
||||||
|
System.out.println(JSON.toJSONString(map));
|
||||||
|
|
||||||
|
System.out.println("----------------------------二维数组格式----------------------------------");
|
||||||
|
List<List<VmsPathVo>> listMap = vmsRelativeFiles.stream().map(vmFile -> {
|
||||||
|
String[] filepathList = vmFile.split("/");
|
||||||
|
String filename = filepathList[filepathList.length - 1].replace(".vm", "");
|
||||||
|
|
||||||
|
return VmsPathVo.builder().name(vmFile).label(filename).type(filepathList[0]).build();
|
||||||
|
})
|
||||||
|
.collect(Collectors.groupingBy(VmsPathVo::getType))
|
||||||
|
.values().stream().toList();
|
||||||
|
|
||||||
|
System.out.println(JSON.toJSONString(listMap));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package cn.bunny.utils;
|
||||||
|
|
||||||
|
import cn.bunny.dao.entity.TableMetaData;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class DatabaseInfoCoreTest {
|
||||||
|
|
||||||
|
String tableName = "sys_i18n";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTableInfoMetaData() {
|
||||||
|
TableMetaData tableMetaData;
|
||||||
|
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
DatabaseMetaData metaData = connection.getMetaData();
|
||||||
|
ResultSet tables = metaData.getTables(null, null, tableName, new String[]{"TABLE"});
|
||||||
|
|
||||||
|
// 获取表的注释信息
|
||||||
|
if (tables.next()) {
|
||||||
|
String remarks = tables.getString("REMARKS");
|
||||||
|
String tableCat = tables.getString("TABLE_CAT");
|
||||||
|
String tableType = tables.getString("TABLE_TYPE");
|
||||||
|
|
||||||
|
tableMetaData = TableMetaData.builder()
|
||||||
|
.tableName(tableName)
|
||||||
|
.comment(remarks)
|
||||||
|
.tableCat(tableCat)
|
||||||
|
.tableType(tableType)
|
||||||
|
.build();
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("数据表不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(tableMetaData);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Test
|
||||||
|
void getDbTableList() {
|
||||||
|
String dbName = "auth_admin";
|
||||||
|
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
DatabaseMetaData metaData = connection.getMetaData();
|
||||||
|
ResultSet tables = metaData.getTables(dbName, null, "%", new String[]{"TABLE"});
|
||||||
|
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
|
||||||
|
while (tables.next()) {
|
||||||
|
dbName = tables.getString("TABLE_NAME");
|
||||||
|
list.add(dbName);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
pom.xml
2
pom.xml
|
@ -43,7 +43,7 @@
|
||||||
<velocity-tools.version>3.1</velocity-tools.version>
|
<velocity-tools.version>3.1</velocity-tools.version>
|
||||||
<HikariCP.version>6.2.1</HikariCP.version>
|
<HikariCP.version>6.2.1</HikariCP.version>
|
||||||
<dynamic.datasource.version>4.3.1</dynamic.datasource.version>
|
<dynamic.datasource.version>4.3.1</dynamic.datasource.version>
|
||||||
<jackson-dataType.version>2.19.0</jackson-dataType.version>
|
<jackson-dataType.version>2.12.3</jackson-dataType.version>
|
||||||
<quartz-scheduler.version>2.3.2</quartz-scheduler.version>
|
<quartz-scheduler.version>2.3.2</quartz-scheduler.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -91,5 +91,10 @@
|
||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-j</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package cn.bunny.services.aop.scanner;
|
package cn.bunny.services.aop.scanner;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
package cn.bunny.services.core.cache;
|
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class EmailCacheService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存储邮箱验证码
|
|
||||||
*
|
|
||||||
* @param email 邮箱
|
|
||||||
* @param emailCode 邮箱验证码
|
|
||||||
*/
|
|
||||||
public void buildEmailCodeCache(@NotNull String email, String emailCode) {
|
|
||||||
// 在Redis中存储验证码
|
|
||||||
String emailCodePrefix = RedisUserConstant.getUserEmailCodePrefix(email);
|
|
||||||
redisTemplate.opsForValue().set(emailCodePrefix, emailCode, RedisUserConstant.REDIS_EXPIRATION_TIME, TimeUnit.MINUTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取邮箱验证码
|
|
||||||
*
|
|
||||||
* @param email 邮箱
|
|
||||||
* @return 邮箱验证码
|
|
||||||
*/
|
|
||||||
public String getEmailCode(@NotNull String email) {
|
|
||||||
String userEmailCodePrefix = RedisUserConstant.getUserEmailCodePrefix(email);
|
|
||||||
Object emailCode = redisTemplate.opsForValue().get(userEmailCodePrefix);
|
|
||||||
|
|
||||||
if (emailCode == null) {
|
|
||||||
throw new UsernameNotFoundException(ResultCodeEnum.EMAIL_CODE_EMPTY.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return emailCode.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清除邮箱验证码
|
|
||||||
*
|
|
||||||
* @param email 邮箱
|
|
||||||
*/
|
|
||||||
public void deleteEmailCodeCache(String email) {
|
|
||||||
String emailCodePrefix = RedisUserConstant.getUserEmailCodePrefix(email);
|
|
||||||
redisTemplate.delete(emailCodePrefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
package cn.bunny.services.core.cache;
|
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
|
||||||
import cn.bunny.services.domain.system.system.entity.Permission;
|
|
||||||
import cn.bunny.services.domain.system.system.entity.Role;
|
|
||||||
import cn.bunny.services.mapper.system.PermissionMapper;
|
|
||||||
import cn.bunny.services.mapper.system.RoleMapper;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import com.alibaba.fastjson2.TypeReference;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class UserAuthorizationCacheService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private PermissionMapper permissionMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RoleMapper roleMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据用户ID和用户名获取角色列表(缓存优先)
|
|
||||||
*
|
|
||||||
* <p><b>执行逻辑</b>:</p>
|
|
||||||
* <ol>
|
|
||||||
* <li>尝试从Redis缓存获取用户角色(使用用户名作为缓存key)</li>
|
|
||||||
* <li>若缓存未命中,则从数据库查询并写入缓存(有效期1天)</li>
|
|
||||||
* <li>若缓存命中,反序列化缓存数据返回</li>
|
|
||||||
* </ol>
|
|
||||||
*
|
|
||||||
* @param userId 用户ID(数据库查询用)
|
|
||||||
* @param username 用户名(缓存key生成用)
|
|
||||||
* @return 用户角色列表
|
|
||||||
*/
|
|
||||||
public List<Role> getRolesByUser(Long userId, String username) {
|
|
||||||
// 角色列表
|
|
||||||
List<Role> roleList;
|
|
||||||
|
|
||||||
// 尝试从缓存中获取当前用户角色
|
|
||||||
String userRolesCodePrefix = RedisUserConstant.getUserRolesCodePrefix(username);
|
|
||||||
Object object = redisTemplate.opsForValue().get(userRolesCodePrefix);
|
|
||||||
|
|
||||||
// 为空查询数据库,并将信息存入Redis
|
|
||||||
if (Objects.isNull(object)) {
|
|
||||||
roleList = roleMapper.selectListByUserId(userId);
|
|
||||||
redisTemplate.opsForValue().set(userRolesCodePrefix, roleList, 1, TimeUnit.DAYS);
|
|
||||||
}
|
|
||||||
// 从缓存中得到当前用户的角色列表
|
|
||||||
else {
|
|
||||||
String jsonString = JSON.toJSONString(object);
|
|
||||||
TypeReference<List<Role>> reference = new TypeReference<>() {
|
|
||||||
};
|
|
||||||
List<Role> list = JSON.parseObject(jsonString, reference);
|
|
||||||
// 防止 list 为空报错
|
|
||||||
roleList = list != null ? list : new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return roleList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据用户ID和用户名获取权限列表(缓存优先)
|
|
||||||
*
|
|
||||||
* <p><b>执行逻辑</b>:</p>
|
|
||||||
* <ol>
|
|
||||||
* <li>尝试从Redis缓存获取用户权限(使用用户名作为缓存key)</li>
|
|
||||||
* <li>若缓存未命中,则从数据库查询并写入缓存(有效期1天)</li>
|
|
||||||
* <li>若缓存命中,反序列化缓存数据返回</li>
|
|
||||||
* </ol>
|
|
||||||
*
|
|
||||||
* @param userId 用户ID(数据库查询用)
|
|
||||||
* @param username 用户名(缓存key生成用)
|
|
||||||
* @return 用户权限列表
|
|
||||||
*/
|
|
||||||
public List<Permission> getPermissionsByUser(Long userId, String username) {
|
|
||||||
// 权限列表
|
|
||||||
List<Permission> permissionList;
|
|
||||||
|
|
||||||
// 获取缓存中的用户权限
|
|
||||||
String userPermissionCodePrefix = RedisUserConstant.getUserPermissionCodePrefix(username);
|
|
||||||
Object object = redisTemplate.opsForValue().get(userPermissionCodePrefix);
|
|
||||||
|
|
||||||
// 为空查询数据库,并将用户权限放在Redis中
|
|
||||||
if (Objects.isNull(object)) {
|
|
||||||
permissionList = permissionMapper.selectListByUserId(userId);
|
|
||||||
redisTemplate.opsForValue().set(userPermissionCodePrefix, permissionList, 1, TimeUnit.DAYS);
|
|
||||||
}
|
|
||||||
// 从缓存中得到当前用户权限
|
|
||||||
else {
|
|
||||||
String jsonString = JSON.toJSONString(object);
|
|
||||||
TypeReference<List<Permission>> reference = new TypeReference<>() {
|
|
||||||
};
|
|
||||||
List<Permission> list = JSON.parseObject(jsonString, reference);
|
|
||||||
// 防止 list 为空报错
|
|
||||||
permissionList = list != null ? list : new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return permissionList;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package cn.bunny.services.core.cache;
|
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class UserCacheCleaner {
|
|
||||||
@Resource
|
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
|
||||||
|
|
||||||
public void cleanUserLoginCache(String username) {
|
|
||||||
String key = RedisUserConstant.getUserLoginInfoPrefix(username);
|
|
||||||
redisTemplate.delete(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cleanUserRoleCache(String username) {
|
|
||||||
String key = RedisUserConstant.getUserRolesCodePrefix(username);
|
|
||||||
redisTemplate.delete(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cleanUserPermissionCache(String username) {
|
|
||||||
String key = RedisUserConstant.getUserPermissionCodePrefix(username);
|
|
||||||
redisTemplate.delete(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cleanAllUserCache(String username) {
|
|
||||||
cleanUserLoginCache(username);
|
|
||||||
cleanUserRoleCache(username);
|
|
||||||
cleanUserPermissionCache(username);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
package cn.bunny.services.core.cache;
|
|
||||||
|
|
||||||
import cn.bunny.services.core.utils.RoleHelper;
|
|
||||||
import cn.bunny.services.domain.common.constant.LocalDateTimeConstant;
|
|
||||||
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
|
||||||
import cn.bunny.services.domain.common.model.vo.LoginVo;
|
|
||||||
import cn.bunny.services.domain.system.system.entity.AdminUser;
|
|
||||||
import cn.bunny.services.domain.system.system.entity.Permission;
|
|
||||||
import cn.bunny.services.domain.system.system.entity.Role;
|
|
||||||
import cn.bunny.services.mapper.system.PermissionMapper;
|
|
||||||
import cn.bunny.services.mapper.system.RoleMapper;
|
|
||||||
import cn.bunny.services.minio.MinioHelper;
|
|
||||||
import cn.bunny.services.utils.JwtTokenUtil;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import lombok.Value;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class UserLoginVoBuilderCacheService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private MinioHelper minioHelper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RoleMapper roleMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private PermissionMapper permissionMapper;
|
|
||||||
|
|
||||||
public LoginVo buildLoginUserVo(AdminUser user, long readMeDay) {
|
|
||||||
String username = user.getUsername();
|
|
||||||
Long userId = user.getId();
|
|
||||||
|
|
||||||
UserAuthInfo authInfo = getAuthInfo(userId, user);
|
|
||||||
|
|
||||||
// 设置用户返回对象
|
|
||||||
LoginVo loginVo = new LoginVo();
|
|
||||||
BeanUtils.copyProperties(user, loginVo);
|
|
||||||
loginVo.setPersonDescription(user.getSummary());
|
|
||||||
loginVo.setRoles(authInfo.getRoles());
|
|
||||||
loginVo.setPermissions(authInfo.getPermissions());
|
|
||||||
|
|
||||||
// 使用用户名创建token
|
|
||||||
String token = JwtTokenUtil.createToken(userId, username, (int) readMeDay);
|
|
||||||
loginVo.setToken(token);
|
|
||||||
loginVo.setRefreshToken(token);
|
|
||||||
loginVo.setReadMeDay(readMeDay);
|
|
||||||
|
|
||||||
// 计算过期时间,并格式化返回
|
|
||||||
String expires = calculateExpires(readMeDay);
|
|
||||||
loginVo.setExpires(expires);
|
|
||||||
|
|
||||||
// 设置用户头像
|
|
||||||
String userAvatar = minioHelper.getUserAvatar(user.getAvatar());
|
|
||||||
loginVo.setAvatar(userAvatar);
|
|
||||||
|
|
||||||
String loginInfoPrefix = RedisUserConstant.getUserLoginInfoPrefix(username);
|
|
||||||
redisTemplate.opsForValue().set(loginInfoPrefix, loginVo, readMeDay, TimeUnit.DAYS);
|
|
||||||
return loginVo;
|
|
||||||
}
|
|
||||||
|
|
||||||
private UserAuthInfo getAuthInfo(Long userId, AdminUser user) {
|
|
||||||
// 用户角色
|
|
||||||
List<String> roles = new ArrayList<>(roleMapper.selectListByUserId(userId).stream().map(Role::getRoleCode).toList());
|
|
||||||
|
|
||||||
// 判断是否是 admin 如果是admin 赋予所有权限
|
|
||||||
List<String> permissions = new ArrayList<>();
|
|
||||||
boolean isAdmin = RoleHelper.checkAdmin(roles, permissions, user);
|
|
||||||
if (!isAdmin) {
|
|
||||||
permissions = permissionMapper.selectListByUserId(userId).stream()
|
|
||||||
.map(Permission::getPowerCode)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 为这两个去重,在判断 checkAdmin 会重新赋值
|
|
||||||
permissions = permissions.stream().distinct().toList();
|
|
||||||
roles = roles.stream().distinct().toList();
|
|
||||||
|
|
||||||
return new UserAuthInfo(roles, permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String calculateExpires(long readMeDay) {
|
|
||||||
LocalDateTime localDateTime = LocalDateTime.now();
|
|
||||||
LocalDateTime plusDay = localDateTime.plusDays(readMeDay);
|
|
||||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS_SLASH);
|
|
||||||
return plusDay.format(dateTimeFormatter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Value
|
|
||||||
private static class UserAuthInfo {
|
|
||||||
List<String> roles;
|
|
||||||
List<String> permissions;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package cn.bunny.services.core.event.event;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.springframework.context.ApplicationEvent;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class ClearAllUserCacheEvent extends ApplicationEvent {
|
|
||||||
private final String key;
|
|
||||||
|
|
||||||
public ClearAllUserCacheEvent(Object source, String key) {
|
|
||||||
super(source);
|
|
||||||
this.key = key;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package cn.bunny.services.core.event.event;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.springframework.context.ApplicationEvent;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class UpdateUserinfoByPermissionIdsEvent extends ApplicationEvent {
|
|
||||||
private final List<Long> permissionIds;
|
|
||||||
|
|
||||||
public UpdateUserinfoByPermissionIdsEvent(Object source, List<Long> permissionIds) {
|
|
||||||
super(source);
|
|
||||||
this.permissionIds = permissionIds;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package cn.bunny.services.core.event.event;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.springframework.context.ApplicationEvent;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class UpdateUserinfoByRoleIdsEvent extends ApplicationEvent {
|
|
||||||
private final List<Long> roleIds;
|
|
||||||
|
|
||||||
public UpdateUserinfoByRoleIdsEvent(Object source, List<Long> roleIds) {
|
|
||||||
super(source);
|
|
||||||
this.roleIds = roleIds;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package cn.bunny.services.core.event.event;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.springframework.context.ApplicationEvent;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class UpdateUserinfoByUserIdsEvent extends ApplicationEvent {
|
|
||||||
private final List<Long> userIds;
|
|
||||||
|
|
||||||
public UpdateUserinfoByUserIdsEvent(Object source, List<Long> userIds) {
|
|
||||||
super(source);
|
|
||||||
this.userIds = userIds;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
package cn.bunny.services.core.event.listener.user;
|
|
||||||
|
|
||||||
import cn.bunny.services.core.cache.UserCacheCleaner;
|
|
||||||
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
|
||||||
import cn.bunny.services.domain.system.system.entity.AdminUser;
|
|
||||||
import cn.bunny.services.mapper.system.UserMapper;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
@Component("AbstractUserInfoUpdateHandler")
|
|
||||||
public abstract class AbstractUserInfoUpdateHandler {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
protected UserMapper userMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
protected UserCacheCleaner userCacheCleaner;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
|
||||||
|
|
||||||
public void processUserUpdate(List<Long> userIds, Consumer<AdminUser> postProcess) {
|
|
||||||
if (userIds.isEmpty()) return;
|
|
||||||
|
|
||||||
List<AdminUser> adminUsers = userMapper.selectBatchIds(userIds);
|
|
||||||
adminUsers.stream()
|
|
||||||
.filter(user -> redisTemplate.hasKey(RedisUserConstant.getUserLoginInfoPrefix(user.getUsername())))
|
|
||||||
.forEach(postProcess);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
package cn.bunny.services.core.event.listener.user;
|
|
||||||
|
|
||||||
import cn.bunny.services.core.cache.UserLoginVoBuilderCacheService;
|
|
||||||
import cn.bunny.services.core.event.event.ClearAllUserCacheEvent;
|
|
||||||
import cn.bunny.services.core.event.event.UpdateUserinfoByPermissionIdsEvent;
|
|
||||||
import cn.bunny.services.core.event.event.UpdateUserinfoByRoleIdsEvent;
|
|
||||||
import cn.bunny.services.core.event.event.UpdateUserinfoByUserIdsEvent;
|
|
||||||
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
|
||||||
import cn.bunny.services.domain.system.system.entity.RolePermission;
|
|
||||||
import cn.bunny.services.domain.system.system.entity.UserRole;
|
|
||||||
import cn.bunny.services.mapper.system.RolePermissionMapper;
|
|
||||||
import cn.bunny.services.mapper.system.UserRoleMapper;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.context.event.EventListener;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Component("UserinfoUpdateListener")
|
|
||||||
public class UserinfoUpdateListener extends AbstractUserInfoUpdateHandler {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private UserLoginVoBuilderCacheService userLoginVoBuilderCacheService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private UserRoleMapper userRoleMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RolePermissionMapper rolePermissionMapper;
|
|
||||||
|
|
||||||
/* 根据用户id更新用户信息,重新生成LoginVo对象 */
|
|
||||||
@EventListener
|
|
||||||
public void handlerUpdateUserinfoByUserIds(UpdateUserinfoByUserIdsEvent event) {
|
|
||||||
List<Long> userIds = event.getUserIds();
|
|
||||||
processUserUpdate(userIds, user -> {
|
|
||||||
userCacheCleaner.cleanAllUserCache(user.getUsername());
|
|
||||||
userLoginVoBuilderCacheService.buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 根据角色id更新用户信息,重新生成LoginVo对象 */
|
|
||||||
@EventListener
|
|
||||||
public void handlerUserinfoUpdateByRoleId(UpdateUserinfoByRoleIdsEvent event) {
|
|
||||||
List<Long> roleIds = event.getRoleIds();
|
|
||||||
List<UserRole> userRoles = userRoleMapper.selectListByRoleIds(roleIds);
|
|
||||||
List<Long> userIds = userRoles.stream().map(UserRole::getUserId).toList();
|
|
||||||
|
|
||||||
UpdateUserinfoByUserIdsEvent userIdsEvent = new UpdateUserinfoByUserIdsEvent(event.getSource(), userIds);
|
|
||||||
handlerUpdateUserinfoByUserIds(userIdsEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 根据角色id更新用户信息,重新生成LoginVo对象 */
|
|
||||||
@EventListener
|
|
||||||
public void handlerUserinfoUpdateByPermissionId(UpdateUserinfoByPermissionIdsEvent event) {
|
|
||||||
List<Long> permissionIds = event.getPermissionIds();
|
|
||||||
List<RolePermission> rolePermissions = rolePermissionMapper.selectRolePermissionListByPermissionIds(permissionIds);
|
|
||||||
List<Long> roleIds = rolePermissions.stream().map(RolePermission::getRoleId).toList();
|
|
||||||
|
|
||||||
UpdateUserinfoByRoleIdsEvent roleIdsEvent = new UpdateUserinfoByRoleIdsEvent(event.getSource(), roleIds);
|
|
||||||
handlerUserinfoUpdateByRoleId(roleIdsEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 清除用户登录、角色、权限所有缓存 */
|
|
||||||
@EventListener
|
|
||||||
public void handlerDeleteAllUserCache(ClearAllUserCacheEvent event) {
|
|
||||||
userCacheCleaner.cleanAllUserCache(event.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package cn.bunny.services.core.strategy.export;
|
|
||||||
|
|
||||||
import com.alibaba.excel.EasyExcel;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
public class ExcelExportStrategy implements ExportStrategy<List<?>> {
|
|
||||||
|
|
||||||
private final Class<?> clazz;
|
|
||||||
private final String sheetName;
|
|
||||||
|
|
||||||
public ExcelExportStrategy(Class<?> clazz, String sheetName) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
this.sheetName = sheetName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void export(List<?> data, ZipOutputStream zipOutputStream, String filename) {
|
|
||||||
try {
|
|
||||||
ByteArrayOutputStream excelOutputStream = new ByteArrayOutputStream();
|
|
||||||
EasyExcel.write(excelOutputStream, clazz).sheet(sheetName).doWrite(data);
|
|
||||||
|
|
||||||
// 将Excel写入到Zip中
|
|
||||||
ZipEntry zipEntry = new ZipEntry(filename);
|
|
||||||
zipOutputStream.putNextEntry(zipEntry);
|
|
||||||
zipOutputStream.write(excelOutputStream.toByteArray());
|
|
||||||
zipOutputStream.closeEntry();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package cn.bunny.services.core.strategy.export;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
public interface ExportStrategy<T> {
|
|
||||||
void export(T data, ZipOutputStream zipOutputStream, String filename) throws IOException;
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package cn.bunny.services.core.strategy.export;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
public class JsonExportStrategy implements ExportStrategy<Object> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void export(Object data, ZipOutputStream zipOutputStream, String filename) {
|
|
||||||
try {
|
|
||||||
ZipEntry zipEntry = new ZipEntry(filename);
|
|
||||||
zipOutputStream.putNextEntry(zipEntry);
|
|
||||||
zipOutputStream.write(JSON.toJSONString(data).getBytes(StandardCharsets.UTF_8));
|
|
||||||
zipOutputStream.closeEntry();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package cn.bunny.services.core.template;
|
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel;
|
|
||||||
import cn.bunny.services.processor.TreeProcessor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class PermissionTreeProcessor extends TreeProcessor<PermissionExcel> {
|
|
||||||
@Override
|
|
||||||
public List<PermissionExcel> findRoots(List<PermissionExcel> list) {
|
|
||||||
return list.stream()
|
|
||||||
.filter(p -> p.getParentId() == null || p.getParentId() == 0)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void buildChildren(PermissionExcel parent, List<PermissionExcel> list) {
|
|
||||||
List<PermissionExcel> children = list.stream()
|
|
||||||
.filter(p -> parent.getId().equals(p.getParentId()))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
if (!children.isEmpty()) {
|
|
||||||
parent.setChildren(children);
|
|
||||||
children.forEach(child -> buildChildren(child, list));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.services.core.event.listener.excel;
|
package cn.bunny.services.excel;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.model.dto.excel.I18nExcel;
|
import cn.bunny.services.domain.common.model.dto.excel.I18nExcel;
|
||||||
import cn.bunny.services.domain.system.i18n.entity.I18n;
|
import cn.bunny.services.domain.system.i18n.entity.I18n;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.services.core.event.listener.excel;
|
package cn.bunny.services.excel;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel;
|
import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel;
|
||||||
import cn.bunny.services.domain.system.system.entity.Permission;
|
import cn.bunny.services.domain.system.system.entity.Permission;
|
|
@ -1,7 +1,7 @@
|
||||||
package cn.bunny.services.core.event.listener.excel;
|
package cn.bunny.services.excel;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
|
||||||
import cn.bunny.services.domain.common.model.dto.excel.RoleExcel;
|
import cn.bunny.services.domain.common.model.dto.excel.RoleExcel;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.system.entity.Role;
|
import cn.bunny.services.domain.system.system.entity.Role;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
||||||
import cn.bunny.services.service.system.RoleService;
|
import cn.bunny.services.service.system.RoleService;
|
|
@ -1,6 +1,6 @@
|
||||||
package cn.bunny.services.security.config;
|
package cn.bunny.services.security.config;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.system.entity.AdminUser;
|
import cn.bunny.services.domain.system.system.entity.AdminUser;
|
||||||
import cn.bunny.services.mapper.system.UserMapper;
|
import cn.bunny.services.mapper.system.UserMapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package cn.bunny.services.security.exception;
|
package cn.bunny.services.security.exception;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cn.bunny.services.security.handelr;
|
package cn.bunny.services.security.handelr;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cn.bunny.services.security.handelr;
|
package cn.bunny.services.security.handelr;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.model.vo.result.Result;
|
import cn.bunny.services.domain.common.model.vo.result.Result;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.security.exception.CustomAuthenticationException;
|
import cn.bunny.services.security.exception.CustomAuthenticationException;
|
||||||
import cn.bunny.services.utils.ResponseUtil;
|
import cn.bunny.services.utils.ResponseUtil;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package cn.bunny.services.security.service;
|
||||||
import cn.bunny.services.context.BaseContext;
|
import cn.bunny.services.context.BaseContext;
|
||||||
import cn.bunny.services.domain.common.model.dto.security.TokenInfo;
|
import cn.bunny.services.domain.common.model.dto.security.TokenInfo;
|
||||||
import cn.bunny.services.domain.common.model.vo.LoginVo;
|
import cn.bunny.services.domain.common.model.vo.LoginVo;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.security.exception.CustomAuthenticationException;
|
import cn.bunny.services.security.exception.CustomAuthenticationException;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package cn.bunny.services.security.service;
|
package cn.bunny.services.security.service;
|
||||||
|
|
||||||
import cn.bunny.services.context.BaseContext;
|
import cn.bunny.services.context.BaseContext;
|
||||||
import cn.bunny.services.core.cache.UserAuthorizationCacheService;
|
|
||||||
import cn.bunny.services.core.utils.RoleHelper;
|
|
||||||
import cn.bunny.services.domain.system.system.entity.Permission;
|
import cn.bunny.services.domain.system.system.entity.Permission;
|
||||||
import cn.bunny.services.domain.system.system.entity.Role;
|
import cn.bunny.services.domain.system.system.entity.Role;
|
||||||
|
import cn.bunny.services.mapper.system.PermissionMapper;
|
||||||
|
import cn.bunny.services.mapper.system.RoleMapper;
|
||||||
import cn.bunny.services.security.config.WebSecurityConfig;
|
import cn.bunny.services.security.config.WebSecurityConfig;
|
||||||
|
import cn.bunny.services.service.system.helper.role.RoleHelper;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
@ -22,7 +23,10 @@ import java.util.Objects;
|
||||||
public class PermissionCheckService {
|
public class PermissionCheckService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private UserAuthorizationCacheService authorizationCacheService;
|
private PermissionMapper permissionMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RoleMapper roleMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询用户所属的角色信息
|
* 查询用户所属的角色信息
|
||||||
|
@ -34,9 +38,7 @@ public class PermissionCheckService {
|
||||||
|
|
||||||
// 根据用户ID查询角色数据
|
// 根据用户ID查询角色数据
|
||||||
Long userId = BaseContext.getUserId();
|
Long userId = BaseContext.getUserId();
|
||||||
String username = BaseContext.getUsername();
|
List<Role> roleList = roleMapper.selectListByUserId(userId);
|
||||||
// List<Role> roleList = roleMapper.selectListByUserId(userId);
|
|
||||||
List<Role> roleList = authorizationCacheService.getRolesByUser(userId, username);
|
|
||||||
|
|
||||||
// 角色代码
|
// 角色代码
|
||||||
List<String> roleCodeList = roleList.stream().map(Role::getRoleCode).toList();
|
List<String> roleCodeList = roleList.stream().map(Role::getRoleCode).toList();
|
||||||
|
@ -52,8 +54,7 @@ public class PermissionCheckService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据角色列表查询权限信息
|
// 根据角色列表查询权限信息
|
||||||
// List<Permission> permissionList = permissionMapper.selectListByUserId(userId);
|
List<Permission> permissionList = permissionMapper.selectListByUserId(userId);
|
||||||
List<Permission> permissionList = authorizationCacheService.getPermissionsByUser(userId, username);
|
|
||||||
|
|
||||||
// 判断是否与请求路径匹配
|
// 判断是否与请求路径匹配
|
||||||
return permissionList.stream()
|
return permissionList.stream()
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
package cn.bunny.services.security.service;
|
package cn.bunny.services.security.service;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
|
||||||
import cn.bunny.services.domain.common.model.dto.security.TokenInfo;
|
import cn.bunny.services.domain.common.model.dto.security.TokenInfo;
|
||||||
import cn.bunny.services.domain.common.model.vo.LoginVo;
|
import cn.bunny.services.domain.common.model.vo.LoginVo;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.security.exception.CustomAuthenticationException;
|
import cn.bunny.services.security.exception.CustomAuthenticationException;
|
||||||
import cn.bunny.services.utils.JwtTokenUtil;
|
import cn.bunny.services.utils.JwtTokenUtil;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理Token相关逻辑
|
* 处理Token相关逻辑
|
||||||
*/
|
*/
|
||||||
@Service
|
@Component
|
||||||
public class TokenValidationService {
|
public class TokenValidationService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -39,7 +39,7 @@ public class TokenValidationService {
|
||||||
Long userId = JwtTokenUtil.getUserId(token);
|
Long userId = JwtTokenUtil.getUserId(token);
|
||||||
|
|
||||||
// 查找 Redis
|
// 查找 Redis
|
||||||
Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getUserLoginInfoPrefix(username));
|
Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getAdminLoginInfoPrefix(username));
|
||||||
LoginVo loginVo = JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class);
|
LoginVo loginVo = JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class);
|
||||||
|
|
||||||
return TokenInfo.builder().userId(userId).username(username).token(token).loginVo(loginVo).build();
|
return TokenInfo.builder().userId(userId).username(username).token(token).loginVo(loginVo).build();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package cn.bunny.services.core.template.email;
|
package cn.bunny.services.service.configuration.helper.email;
|
||||||
|
|
||||||
import cn.bunny.services.config.mail.MailSenderConfiguration;
|
import cn.bunny.services.config.mail.MailSenderConfiguration;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
|
||||||
import cn.bunny.services.domain.common.model.dto.email.EmailSend;
|
import cn.bunny.services.domain.common.model.dto.email.EmailSend;
|
||||||
import cn.bunny.services.domain.common.model.dto.email.EmailSendInit;
|
import cn.bunny.services.domain.common.model.dto.email.EmailSendInit;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.email.entity.EmailTemplate;
|
import cn.bunny.services.domain.system.email.entity.EmailTemplate;
|
||||||
import cn.bunny.services.domain.system.email.entity.EmailUsers;
|
import cn.bunny.services.domain.system.email.entity.EmailUsers;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.services.core.template.email;
|
package cn.bunny.services.service.configuration.helper.email;
|
||||||
|
|
||||||
import cn.bunny.services.domain.system.email.entity.EmailTemplate;
|
import cn.bunny.services.domain.system.email.entity.EmailTemplate;
|
||||||
import cn.bunny.services.mapper.configuration.EmailTemplateMapper;
|
import cn.bunny.services.mapper.configuration.EmailTemplateMapper;
|
|
@ -0,0 +1,122 @@
|
||||||
|
package cn.bunny.services.service.configuration.helper.i18n;
|
||||||
|
|
||||||
|
import cn.bunny.services.domain.common.model.dto.excel.I18nExcel;
|
||||||
|
import cn.bunny.services.domain.system.i18n.entity.I18n;
|
||||||
|
import cn.bunny.services.service.configuration.impl.I18nServiceImpl;
|
||||||
|
import com.alibaba.excel.EasyExcel;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
public class I18nHelper {
|
||||||
|
/**
|
||||||
|
* 将国际化资源列表写入Excel并打包到ZIP输出流
|
||||||
|
*
|
||||||
|
* <p>处理流程:</p>
|
||||||
|
* <ol>
|
||||||
|
* <li>按资源类型(typeName)分组 --- 多语言的类型,英文?中文?</li>
|
||||||
|
* <li>每组数据生成单独多语言 key的Excel工作表</li>
|
||||||
|
* <li>将Excel文件写入ZIP输出流</li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* @param i18nList 国际化资源列表,包含key-value对和类型信息
|
||||||
|
* @param zipOutputStream ZIP输出流,用于写入打包后的Excel文件
|
||||||
|
* @throws RuntimeException 当IO操作失败时抛出
|
||||||
|
*/
|
||||||
|
public static void writeExcel(List<I18n> i18nList, ZipOutputStream zipOutputStream) {
|
||||||
|
Map<String, List<I18nExcel>> hashMap = i18nList.stream()
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
I18n::getTypeName,
|
||||||
|
Collectors.mapping((I18n i18n) -> {
|
||||||
|
String keyName = i18n.getKeyName();
|
||||||
|
String translation = i18n.getTranslation();
|
||||||
|
return I18nExcel.builder().keyName(keyName).translation(translation).build();
|
||||||
|
}, Collectors.toList())
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
hashMap.forEach((key, value) -> {
|
||||||
|
try {
|
||||||
|
// 创建临时ByteArrayOutputStream
|
||||||
|
ByteArrayOutputStream excelOutputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
ZipEntry zipEntry = new ZipEntry(key + ".xlsx");
|
||||||
|
zipOutputStream.putNextEntry(zipEntry);
|
||||||
|
|
||||||
|
// 先写入到临时流
|
||||||
|
EasyExcel.write(excelOutputStream, I18nExcel.class).sheet(key).doWrite(value);
|
||||||
|
zipOutputStream.write(excelOutputStream.toByteArray());
|
||||||
|
zipOutputStream.closeEntry();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将国际化资源列表写入JSON并打包到ZIP输出流
|
||||||
|
*
|
||||||
|
* <p>处理流程:</p>
|
||||||
|
* <ol>
|
||||||
|
* <li>按资源类型(typeName)分组 --- 多语言的类型,英文?中文?</li>
|
||||||
|
* <li>每组数据生成单独多语言 key的Excel工作表</li>
|
||||||
|
* <li>将JSON文件写入ZIP输出流</li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* @param i18nList 国际化资源列表
|
||||||
|
* @param zipOutputStream ZIP输出流
|
||||||
|
* @throws RuntimeException 当IO操作失败时抛出
|
||||||
|
*/
|
||||||
|
public static void writeJson(List<I18n> i18nList, ZipOutputStream zipOutputStream) {
|
||||||
|
HashMap<String, Object> hashMap = getMapByI18nList(i18nList);
|
||||||
|
|
||||||
|
hashMap.forEach((k, v) -> {
|
||||||
|
try {
|
||||||
|
ZipEntry zipEntry = new ZipEntry(k + ".json");
|
||||||
|
zipOutputStream.putNextEntry(zipEntry);
|
||||||
|
|
||||||
|
zipOutputStream.write(JSON.toJSONString(v).getBytes(StandardCharsets.UTF_8));
|
||||||
|
zipOutputStream.closeEntry();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将国际化资源列表转换为结构化Map
|
||||||
|
*
|
||||||
|
* <p>转换规则:</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>外层Key: 资源类型(typeName)</li>
|
||||||
|
* <li>内层Key: 资源键名(keyName)</li>
|
||||||
|
* <li>值: 翻译文本(translation)</li>
|
||||||
|
* </ul>
|
||||||
|
* <p>详细结构和结果示例看前端传递的 {@link I18nServiceImpl#getI18nMap} 控制器</p>
|
||||||
|
* <p>/api/i18n/public</p>
|
||||||
|
*
|
||||||
|
* @param i18nList 国际化资源列表
|
||||||
|
* @return 结构化Map {typeName: {keyName: translation}}
|
||||||
|
* @throws IllegalArgumentException 当参数为null时抛出
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static HashMap<String, Object> getMapByI18nList(@NotNull List<I18n> i18nList) {
|
||||||
|
// 整理集合
|
||||||
|
Map<String, Map<String, String>> map = i18nList.stream()
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
I18n::getTypeName,
|
||||||
|
Collectors.toMap(I18n::getKeyName, I18n::getTranslation)));
|
||||||
|
|
||||||
|
// 返回集合
|
||||||
|
return new HashMap<>(map);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ package cn.bunny.services.service.configuration.impl;
|
||||||
import cn.bunny.services.domain.system.configuration.dto.WebConfigurationDto;
|
import cn.bunny.services.domain.system.configuration.dto.WebConfigurationDto;
|
||||||
import cn.bunny.services.domain.system.configuration.entity.WebConfiguration;
|
import cn.bunny.services.domain.system.configuration.entity.WebConfiguration;
|
||||||
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
import cn.bunny.services.domain.common.constant.RedisUserConstant;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
||||||
import cn.bunny.services.service.configuration.ConfigurationService;
|
import cn.bunny.services.service.configuration.ConfigurationService;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.email.entity.EmailTemplate;
|
||||||
import cn.bunny.services.domain.system.email.vo.EmailTemplateVo;
|
import cn.bunny.services.domain.system.email.vo.EmailTemplateVo;
|
||||||
import cn.bunny.services.domain.common.enums.EmailTemplateEnums;
|
import cn.bunny.services.domain.common.enums.EmailTemplateEnums;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
||||||
import cn.bunny.services.mapper.configuration.EmailTemplateMapper;
|
import cn.bunny.services.mapper.configuration.EmailTemplateMapper;
|
||||||
import cn.bunny.services.service.configuration.EmailTemplateService;
|
import cn.bunny.services.service.configuration.EmailTemplateService;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import cn.bunny.services.domain.system.email.dto.EmailUsersUpdateDto;
|
||||||
import cn.bunny.services.domain.system.email.entity.EmailUsers;
|
import cn.bunny.services.domain.system.email.entity.EmailUsers;
|
||||||
import cn.bunny.services.domain.system.email.vo.EmailUsersVo;
|
import cn.bunny.services.domain.system.email.vo.EmailUsersVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
||||||
import cn.bunny.services.mapper.configuration.EmailUsersMapper;
|
import cn.bunny.services.mapper.configuration.EmailUsersMapper;
|
||||||
import cn.bunny.services.service.configuration.EmailUsersService;
|
import cn.bunny.services.service.configuration.EmailUsersService;
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
package cn.bunny.services.service.configuration.impl;
|
package cn.bunny.services.service.configuration.impl;
|
||||||
|
|
||||||
import cn.bunny.services.core.event.listener.excel.I18nExcelListener;
|
|
||||||
import cn.bunny.services.core.strategy.export.ExcelExportStrategy;
|
|
||||||
import cn.bunny.services.core.strategy.export.JsonExportStrategy;
|
|
||||||
import cn.bunny.services.domain.common.constant.FileType;
|
import cn.bunny.services.domain.common.constant.FileType;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
|
||||||
import cn.bunny.services.domain.common.model.dto.excel.I18nExcel;
|
import cn.bunny.services.domain.common.model.dto.excel.I18nExcel;
|
||||||
import cn.bunny.services.domain.common.model.entity.BaseEntity;
|
import cn.bunny.services.domain.common.model.entity.BaseEntity;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.i18n.dto.I18nAddDto;
|
import cn.bunny.services.domain.system.i18n.dto.I18nAddDto;
|
||||||
import cn.bunny.services.domain.system.i18n.dto.I18nDto;
|
import cn.bunny.services.domain.system.i18n.dto.I18nDto;
|
||||||
import cn.bunny.services.domain.system.i18n.dto.I18nUpdateByFileDto;
|
import cn.bunny.services.domain.system.i18n.dto.I18nUpdateByFileDto;
|
||||||
|
@ -15,10 +12,12 @@ import cn.bunny.services.domain.system.i18n.dto.I18nUpdateDto;
|
||||||
import cn.bunny.services.domain.system.i18n.entity.I18n;
|
import cn.bunny.services.domain.system.i18n.entity.I18n;
|
||||||
import cn.bunny.services.domain.system.i18n.entity.I18nType;
|
import cn.bunny.services.domain.system.i18n.entity.I18nType;
|
||||||
import cn.bunny.services.domain.system.i18n.vo.I18nVo;
|
import cn.bunny.services.domain.system.i18n.vo.I18nVo;
|
||||||
|
import cn.bunny.services.excel.I18nExcelListener;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
||||||
import cn.bunny.services.mapper.configuration.I18nMapper;
|
import cn.bunny.services.mapper.configuration.I18nMapper;
|
||||||
import cn.bunny.services.mapper.configuration.I18nTypeMapper;
|
import cn.bunny.services.mapper.configuration.I18nTypeMapper;
|
||||||
import cn.bunny.services.service.configuration.I18nService;
|
import cn.bunny.services.service.configuration.I18nService;
|
||||||
|
import cn.bunny.services.service.configuration.helper.i18n.I18nHelper;
|
||||||
import cn.bunny.services.utils.FileUtil;
|
import cn.bunny.services.utils.FileUtil;
|
||||||
import com.alibaba.excel.EasyExcel;
|
import com.alibaba.excel.EasyExcel;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
@ -30,7 +29,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
|
@ -49,7 +47,6 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,7 +60,6 @@ import java.util.zip.ZipOutputStream;
|
||||||
@Service
|
@Service
|
||||||
@Transactional
|
@Transactional
|
||||||
public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I18nService {
|
public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I18nService {
|
||||||
private static final String CACHE_NAMES = "i18n";
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private I18nTypeMapper i18nTypeMapper;
|
private I18nTypeMapper i18nTypeMapper;
|
||||||
|
@ -74,13 +70,13 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
|
||||||
* @return 多语言返回内容
|
* @return 多语言返回内容
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(cacheNames = CACHE_NAMES, key = "'i18nMap'", cacheManager = "cacheManagerWithMouth")
|
@Cacheable(cacheNames = "i18n", key = "'i18n'", cacheManager = "cacheManagerWithMouth")
|
||||||
public HashMap<String, Object> getI18nMap() {
|
public HashMap<String, Object> getI18nMap() {
|
||||||
// 查找默认语言内容
|
// 查找默认语言内容
|
||||||
I18nType i18nType = i18nTypeMapper.selectOne(Wrappers.<I18nType>lambdaQuery().eq(I18nType::getIsDefault, true));
|
I18nType i18nType = i18nTypeMapper.selectOne(Wrappers.<I18nType>lambdaQuery().eq(I18nType::getIsDefault, true));
|
||||||
List<I18n> i18nList = list();
|
List<I18n> i18nList = list();
|
||||||
|
|
||||||
HashMap<String, Object> hashMap = getMapByI18nList(i18nList);
|
HashMap<String, Object> hashMap = I18nHelper.getMapByI18nList(i18nList);
|
||||||
hashMap.put("local", Objects.requireNonNull(i18nType.getTypeName(), "zh"));
|
hashMap.put("local", Objects.requireNonNull(i18nType.getTypeName(), "zh"));
|
||||||
|
|
||||||
return hashMap;
|
return hashMap;
|
||||||
|
@ -109,7 +105,7 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
|
||||||
* @param dto 添加表单
|
* @param dto 添加表单
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true)
|
@CacheEvict(cacheNames = "i18n", key = "'i18n'", beforeInvocation = true)
|
||||||
public void addI18n(@Valid I18nAddDto dto) {
|
public void addI18n(@Valid I18nAddDto dto) {
|
||||||
String keyName = dto.getKeyName();
|
String keyName = dto.getKeyName();
|
||||||
String typeName = dto.getTypeName();
|
String typeName = dto.getTypeName();
|
||||||
|
@ -130,7 +126,7 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
|
||||||
* @param dto 更新表单
|
* @param dto 更新表单
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true)
|
@CacheEvict(cacheNames = "i18n", key = "'i18n'", beforeInvocation = true)
|
||||||
public void updateI18n(@Valid I18nUpdateDto dto) {
|
public void updateI18n(@Valid I18nUpdateDto dto) {
|
||||||
Long id = dto.getId();
|
Long id = dto.getId();
|
||||||
|
|
||||||
|
@ -150,7 +146,7 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
|
||||||
* @param ids 删除id列表
|
* @param ids 删除id列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true)
|
@CacheEvict(cacheNames = "i18n", key = "'i18n'", beforeInvocation = true)
|
||||||
public void deleteI18n(List<Long> ids) {
|
public void deleteI18n(List<Long> ids) {
|
||||||
// 判断数据请求是否为空
|
// 判断数据请求是否为空
|
||||||
if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY);
|
if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY);
|
||||||
|
@ -167,35 +163,18 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<byte[]> downloadI18n(String type) {
|
public ResponseEntity<byte[]> downloadI18n(String type) {
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) {
|
try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) {
|
||||||
|
|
||||||
// 查找默认语言内容
|
// 查找默认语言内容
|
||||||
List<I18n> i18nList = list();
|
List<I18n> i18nList = list();
|
||||||
|
|
||||||
// 类型是Excel写入Excel
|
// 类型是Excel写入Excel
|
||||||
if (type.equals(FileType.EXCEL)) {
|
if (type.equals(FileType.EXCEL)) {
|
||||||
i18nList.stream()
|
I18nHelper.writeExcel(i18nList, zipOutputStream);
|
||||||
.collect(Collectors.groupingBy(
|
|
||||||
I18n::getTypeName,
|
|
||||||
Collectors.mapping((I18n i18n) -> {
|
|
||||||
String keyName = i18n.getKeyName();
|
|
||||||
String translation = i18n.getTranslation();
|
|
||||||
return I18nExcel.builder().keyName(keyName).translation(translation).build();
|
|
||||||
}, Collectors.toList())
|
|
||||||
))
|
|
||||||
.forEach((key, value) -> {
|
|
||||||
ExcelExportStrategy excelExportStrategy = new ExcelExportStrategy(I18nExcel.class, key);
|
|
||||||
excelExportStrategy.export(value, zipOutputStream, key + ".xlsx");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// 其他格式写入JSON
|
// 其他格式写入JSON
|
||||||
else {
|
else {
|
||||||
HashMap<String, Object> hashMap = getMapByI18nList(i18nList);
|
I18nHelper.writeJson(i18nList, zipOutputStream);
|
||||||
|
|
||||||
hashMap.forEach((k, v) -> {
|
|
||||||
JsonExportStrategy jsonExportStrategy = new JsonExportStrategy();
|
|
||||||
jsonExportStrategy.export(v, zipOutputStream, k + ".json");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置响应头
|
// 设置响应头
|
||||||
|
@ -214,7 +193,7 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
|
||||||
* @param dto 文件更新对象
|
* @param dto 文件更新对象
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true)
|
@CacheEvict(cacheNames = "i18n", key = "'i18n'", beforeInvocation = true)
|
||||||
public void uploadI18nFile(I18nUpdateByFileDto dto) {
|
public void uploadI18nFile(I18nUpdateByFileDto dto) {
|
||||||
String type = dto.getType();
|
String type = dto.getType();
|
||||||
MultipartFile file = dto.getFile();
|
MultipartFile file = dto.getFile();
|
||||||
|
@ -261,32 +240,4 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 将国际化资源列表转换为结构化Map
|
|
||||||
*
|
|
||||||
* <p>转换规则:</p>
|
|
||||||
* <ul>
|
|
||||||
* <li>外层Key: 资源类型(typeName)</li>
|
|
||||||
* <li>内层Key: 资源键名(keyName)</li>
|
|
||||||
* <li>值: 翻译文本(translation)</li>
|
|
||||||
* </ul>
|
|
||||||
* <p>详细结构和结果示例看前端传递的 {@link I18nServiceImpl#getI18nMap} 控制器</p>
|
|
||||||
* <p>/api/i18n/public</p>
|
|
||||||
*
|
|
||||||
* @param i18nList 国际化资源列表
|
|
||||||
* @return 结构化Map {typeName: {keyName: translation}}
|
|
||||||
* @throws IllegalArgumentException 当参数为null时抛出
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
public HashMap<String, Object> getMapByI18nList(@NotNull List<I18n> i18nList) {
|
|
||||||
// 整理集合
|
|
||||||
Map<String, Map<String, String>> map = i18nList.stream()
|
|
||||||
.collect(Collectors.groupingBy(
|
|
||||||
I18n::getTypeName,
|
|
||||||
Collectors.toMap(I18n::getKeyName, I18n::getTranslation)));
|
|
||||||
|
|
||||||
// 返回集合
|
|
||||||
return new HashMap<>(map);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,17 @@
|
||||||
package cn.bunny.services.service.configuration.impl;
|
package cn.bunny.services.service.configuration.impl;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
|
||||||
import cn.bunny.services.domain.system.i18n.dto.I18nTypeAddDto;
|
import cn.bunny.services.domain.system.i18n.dto.I18nTypeAddDto;
|
||||||
import cn.bunny.services.domain.system.i18n.dto.I18nTypeDto;
|
import cn.bunny.services.domain.system.i18n.dto.I18nTypeDto;
|
||||||
import cn.bunny.services.domain.system.i18n.dto.I18nTypeUpdateDto;
|
import cn.bunny.services.domain.system.i18n.dto.I18nTypeUpdateDto;
|
||||||
import cn.bunny.services.domain.system.i18n.entity.I18nType;
|
import cn.bunny.services.domain.system.i18n.entity.I18nType;
|
||||||
import cn.bunny.services.domain.system.i18n.vo.I18nTypeVo;
|
import cn.bunny.services.domain.system.i18n.vo.I18nTypeVo;
|
||||||
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
||||||
import cn.bunny.services.mapper.configuration.I18nTypeMapper;
|
import cn.bunny.services.mapper.configuration.I18nTypeMapper;
|
||||||
import cn.bunny.services.service.configuration.I18nTypeService;
|
import cn.bunny.services.service.configuration.I18nTypeService;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
|
||||||
import org.springframework.cache.annotation.Caching;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@ -31,7 +28,6 @@ import java.util.List;
|
||||||
@Service
|
@Service
|
||||||
@Transactional
|
@Transactional
|
||||||
public class I18nTypeServiceImpl extends ServiceImpl<I18nTypeMapper, I18nType> implements I18nTypeService {
|
public class I18nTypeServiceImpl extends ServiceImpl<I18nTypeMapper, I18nType> implements I18nTypeService {
|
||||||
private static final String CACHE_NAMES = "i18n";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取多语言类型
|
* 获取多语言类型
|
||||||
|
@ -39,7 +35,6 @@ public class I18nTypeServiceImpl extends ServiceImpl<I18nTypeMapper, I18nType> i
|
||||||
* @return 多语言类型列表
|
* @return 多语言类型列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(cacheNames = CACHE_NAMES, key = "'i18nTypeList'", cacheManager = "cacheManagerWithMouth")
|
|
||||||
public List<I18nTypeVo> getI18nTypeList(I18nTypeDto dto) {
|
public List<I18nTypeVo> getI18nTypeList(I18nTypeDto dto) {
|
||||||
List<I18nType> i18nTypeList = baseMapper.selectListByPage(dto);
|
List<I18nType> i18nTypeList = baseMapper.selectListByPage(dto);
|
||||||
return i18nTypeList.stream().map(i18nType -> {
|
return i18nTypeList.stream().map(i18nType -> {
|
||||||
|
@ -55,10 +50,6 @@ public class I18nTypeServiceImpl extends ServiceImpl<I18nTypeMapper, I18nType> i
|
||||||
* @param dto 多语言类型添加
|
* @param dto 多语言类型添加
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Caching(evict = {
|
|
||||||
@CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true),
|
|
||||||
@CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nTypeList'", beforeInvocation = true),
|
|
||||||
})
|
|
||||||
public void addI18nType(I18nTypeAddDto dto) {
|
public void addI18nType(I18nTypeAddDto dto) {
|
||||||
String typeName = dto.getTypeName();
|
String typeName = dto.getTypeName();
|
||||||
Boolean isDefault = dto.getIsDefault();
|
Boolean isDefault = dto.getIsDefault();
|
||||||
|
@ -86,18 +77,14 @@ public class I18nTypeServiceImpl extends ServiceImpl<I18nTypeMapper, I18nType> i
|
||||||
* @param dto 多语言类型更新
|
* @param dto 多语言类型更新
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Caching(evict = {
|
|
||||||
@CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true),
|
|
||||||
@CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nTypeList'", beforeInvocation = true),
|
|
||||||
})
|
|
||||||
public void updateI18nType(I18nTypeUpdateDto dto) {
|
public void updateI18nType(I18nTypeUpdateDto dto) {
|
||||||
Long id = dto.getId();
|
Long id = dto.getId();
|
||||||
Boolean isDefault = dto.getIsDefault();
|
Boolean isDefault = dto.getIsDefault();
|
||||||
I18nType i18nType = new I18nType();
|
I18nType i18nType = new I18nType();
|
||||||
|
|
||||||
// 查询更新的内容是否存在
|
// 查询更新的内容是否存在
|
||||||
I18nType dbI18nType = getOne(Wrappers.<I18nType>lambdaQuery().eq(I18nType::getId, id));
|
List<I18nType> i18nTypeList = list(Wrappers.<I18nType>lambdaQuery().eq(I18nType::getId, id));
|
||||||
if (dbI18nType == null) throw new AuthCustomerException(ResultCodeEnum.DATA_NOT_EXIST);
|
if (i18nTypeList.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.DATA_NOT_EXIST);
|
||||||
|
|
||||||
// 如果是默认,将其它内容设为false
|
// 如果是默认,将其它内容设为false
|
||||||
if (isDefault) {
|
if (isDefault) {
|
||||||
|
@ -117,10 +104,6 @@ public class I18nTypeServiceImpl extends ServiceImpl<I18nTypeMapper, I18nType> i
|
||||||
* @param ids 删除id列表
|
* @param ids 删除id列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Caching(evict = {
|
|
||||||
@CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true),
|
|
||||||
@CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nTypeList'", beforeInvocation = true),
|
|
||||||
})
|
|
||||||
public void deleteI18nType(List<Long> ids) {
|
public void deleteI18nType(List<Long> ids) {
|
||||||
// 判断数据请求是否为空
|
// 判断数据请求是否为空
|
||||||
if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY);
|
if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY);
|
||||||
|
|
|
@ -6,7 +6,7 @@ import cn.bunny.services.domain.system.menuIcon.dto.MenuIconUpdateDto;
|
||||||
import cn.bunny.services.domain.system.menuIcon.entity.MenuIcon;
|
import cn.bunny.services.domain.system.menuIcon.entity.MenuIcon;
|
||||||
import cn.bunny.services.domain.system.menuIcon.vo.MenuIconVo;
|
import cn.bunny.services.domain.system.menuIcon.vo.MenuIconVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.exception.AuthCustomerException;
|
import cn.bunny.services.exception.AuthCustomerException;
|
||||||
import cn.bunny.services.mapper.configuration.MenuIconMapper;
|
import cn.bunny.services.mapper.configuration.MenuIconMapper;
|
||||||
import cn.bunny.services.service.configuration.MenuIconService;
|
import cn.bunny.services.service.configuration.MenuIconService;
|
||||||
|
|
|
@ -2,7 +2,7 @@ package cn.bunny.services.service.message.impl;
|
||||||
|
|
||||||
import cn.bunny.services.context.BaseContext;
|
import cn.bunny.services.context.BaseContext;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.message.dto.MessageReceivedDto;
|
import cn.bunny.services.domain.system.message.dto.MessageReceivedDto;
|
||||||
import cn.bunny.services.domain.system.message.dto.MessageReceivedUpdateDto;
|
import cn.bunny.services.domain.system.message.dto.MessageReceivedUpdateDto;
|
||||||
import cn.bunny.services.domain.system.message.dto.MessageUserDto;
|
import cn.bunny.services.domain.system.message.dto.MessageUserDto;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package cn.bunny.services.service.message.impl;
|
||||||
import cn.bunny.services.context.BaseContext;
|
import cn.bunny.services.context.BaseContext;
|
||||||
import cn.bunny.services.domain.common.model.entity.BaseEntity;
|
import cn.bunny.services.domain.common.model.entity.BaseEntity;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.message.dto.MessageAddDto;
|
import cn.bunny.services.domain.system.message.dto.MessageAddDto;
|
||||||
import cn.bunny.services.domain.system.message.dto.MessageDto;
|
import cn.bunny.services.domain.system.message.dto.MessageDto;
|
||||||
import cn.bunny.services.domain.system.message.dto.MessageUpdateDto;
|
import cn.bunny.services.domain.system.message.dto.MessageUpdateDto;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cn.bunny.services.service.schedule.impl;
|
package cn.bunny.services.service.schedule.impl;
|
||||||
|
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.common.enums.ResultCodeEnum;
|
import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.services.domain.system.quartz.dto.SchedulersAddDto;
|
import cn.bunny.services.domain.system.quartz.dto.SchedulersAddDto;
|
||||||
import cn.bunny.services.domain.system.quartz.dto.SchedulersDto;
|
import cn.bunny.services.domain.system.quartz.dto.SchedulersDto;
|
||||||
import cn.bunny.services.domain.system.quartz.dto.SchedulersUpdateDto;
|
import cn.bunny.services.domain.system.quartz.dto.SchedulersUpdateDto;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import cn.bunny.services.domain.system.system.dto.user.RefreshTokenDto;
|
||||||
import cn.bunny.services.domain.system.system.entity.AdminUser;
|
import cn.bunny.services.domain.system.system.entity.AdminUser;
|
||||||
import cn.bunny.services.domain.system.system.vo.user.RefreshTokenVo;
|
import cn.bunny.services.domain.system.system.vo.user.RefreshTokenVo;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public interface UserLoginService extends IService<AdminUser> {
|
public interface UserLoginService extends IService<AdminUser> {
|
||||||
|
@ -52,6 +53,6 @@ public interface UserLoginService extends IService<AdminUser> {
|
||||||
*
|
*
|
||||||
* @param password 更新本地用户密码
|
* @param password 更新本地用户密码
|
||||||
*/
|
*/
|
||||||
void updateUserPasswordByLocalUser(String password);
|
void updateUserPasswordByLocalUser(@Valid String password);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.bunny.services.service.system;
|
package cn.bunny.services.service.system;
|
||||||
|
|
||||||
|
import cn.bunny.services.domain.common.model.vo.LoginVo;
|
||||||
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
import cn.bunny.services.domain.common.model.vo.result.PageResult;
|
||||||
import cn.bunny.services.domain.system.system.dto.user.AdminUserAddDto;
|
import cn.bunny.services.domain.system.system.dto.user.AdminUserAddDto;
|
||||||
import cn.bunny.services.domain.system.system.dto.user.AdminUserDto;
|
import cn.bunny.services.domain.system.system.dto.user.AdminUserDto;
|
||||||
|
@ -80,5 +81,5 @@ public interface UserService extends IService<AdminUser> {
|
||||||
* @param pageParams 分页查询
|
* @param pageParams 分页查询
|
||||||
* @return 分页查询结果
|
* @return 分页查询结果
|
||||||
*/
|
*/
|
||||||
PageResult<UserVo> getCacheUserPage(Page<AdminUser> pageParams);
|
PageResult<LoginVo> getCacheUserPage(Page<AdminUser> pageParams);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
package cn.bunny.services.service.system.helper;
|
||||||
|
|
||||||
|
import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel;
|
||||||
|
import com.alibaba.excel.EasyExcel;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限数据处理工具类
|
||||||
|
*
|
||||||
|
* <p>提供权限数据的树形结构处理、扁平化处理以及导出功能</p>
|
||||||
|
*/
|
||||||
|
public class PermissionHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将树形结构权限数据扁平化为列表
|
||||||
|
*
|
||||||
|
* <p>使用递归处理树形结构</p>
|
||||||
|
*
|
||||||
|
* @param list 树形结构的权限列表,每个节点可能包含children子节点
|
||||||
|
* @return 扁平化后的权限列表(
|
||||||
|
*/
|
||||||
|
public static List<PermissionExcel> flattenTree(List<PermissionExcel> list) {
|
||||||
|
List<PermissionExcel> result = new ArrayList<>();
|
||||||
|
|
||||||
|
for (PermissionExcel node : list) {
|
||||||
|
result.add(node);
|
||||||
|
if (node.getChildren() != null && !node.getChildren().isEmpty()) {
|
||||||
|
result.addAll(flattenTree(node.getChildren()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归设置子节点(内部方法)
|
||||||
|
*
|
||||||
|
* <p>为父节点查找并设置所有子节点,递归处理子节点的子节点</p>
|
||||||
|
*
|
||||||
|
* @param parent 当前父节点
|
||||||
|
* @param list 完整的权限数据列表
|
||||||
|
*/
|
||||||
|
private static void setChildren(PermissionExcel parent, List<PermissionExcel> list) {
|
||||||
|
List<PermissionExcel> children = list.stream()
|
||||||
|
.filter(p -> parent.getId().equals(p.getParentId()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (!children.isEmpty()) {
|
||||||
|
parent.setChildren(children);
|
||||||
|
|
||||||
|
for (PermissionExcel child : children) {
|
||||||
|
setChildren(child, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建权限树形结构
|
||||||
|
*
|
||||||
|
* <p>从扁平列表中构建树形结构,根节点的判断条件为parentId为null或0</p>
|
||||||
|
*
|
||||||
|
* @param list 扁平化的权限数据列表
|
||||||
|
* @return 构建完成的树形结构列表(只包含根节点)
|
||||||
|
*/
|
||||||
|
public static List<PermissionExcel> buildTree(List<PermissionExcel> list) {
|
||||||
|
List<PermissionExcel> permissionExcels = list.stream()
|
||||||
|
.filter(permissionExcel -> permissionExcel.getParentId() == null || permissionExcel.getParentId() == 0)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (PermissionExcel permission : permissionExcels) {
|
||||||
|
setChildren(permission, list);
|
||||||
|
}
|
||||||
|
return permissionExcels;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将权限数据写入JSON格式到ZIP压缩包
|
||||||
|
*
|
||||||
|
* @param list 要导出的权限数据列表
|
||||||
|
* @param zipOutputStream ZIP输出流
|
||||||
|
* @param zipName 在ZIP包中的文件名
|
||||||
|
*/
|
||||||
|
public static void writeJson(List<PermissionExcel> list, ZipOutputStream zipOutputStream, String zipName) {
|
||||||
|
try {
|
||||||
|
ZipEntry zipEntry = new ZipEntry(zipName);
|
||||||
|
zipOutputStream.putNextEntry(zipEntry);
|
||||||
|
zipOutputStream.write(JSON.toJSONString(list).getBytes(StandardCharsets.UTF_8));
|
||||||
|
zipOutputStream.closeEntry();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将权限数据写入Excel格式到ZIP压缩包
|
||||||
|
*
|
||||||
|
* @param list 要导出的权限数据列表
|
||||||
|
* @param zipOutputStream ZIP输出流
|
||||||
|
* @param zipName 在ZIP包中的文件名(需包含.xlsx后缀)
|
||||||
|
*/
|
||||||
|
public static void writExcel(List<PermissionExcel> list, ZipOutputStream zipOutputStream, String zipName) {
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream excelOutputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
EasyExcel.write(excelOutputStream, PermissionExcel.class).sheet("permission").doWrite(list);
|
||||||
|
|
||||||
|
// 将Excel写入到Zip中
|
||||||
|
ZipEntry zipEntry = new ZipEntry(zipName);
|
||||||
|
zipOutputStream.putNextEntry(zipEntry);
|
||||||
|
zipOutputStream.write(excelOutputStream.toByteArray());
|
||||||
|
zipOutputStream.closeEntry();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue