Browse Source

first commit

master
fangyang2021 1 year ago
commit
1faf38893e
  1. 51
      .gitignore
  2. 90
      admin/pom.xml
  3. 17
      admin/src/main/java/com/yyy/Application.java
  4. 72
      admin/src/main/java/com/yyy/web/config/SwaggerConfig.java
  5. 154
      admin/src/main/java/com/yyy/web/controller/common/CommonController.java
  6. 88
      admin/src/main/java/com/yyy/web/controller/ums/OauthController.java
  7. 104
      admin/src/main/java/com/yyy/web/controller/ums/UmsMenuController.java
  8. 112
      admin/src/main/java/com/yyy/web/controller/ums/UmsOrganizationController.java
  9. 101
      admin/src/main/java/com/yyy/web/controller/ums/UmsRoleController.java
  10. 233
      admin/src/main/java/com/yyy/web/controller/ums/UmsUserController.java
  11. 69
      admin/src/main/resources/application-dev.yml
  12. 60
      admin/src/main/resources/application-prod.yml
  13. 54
      admin/src/main/resources/application.yml
  14. 22
      admin/src/main/resources/banner.txt
  15. 152
      admin/src/main/resources/logback-spring.xml
  16. 20
      admin/src/main/resources/mybatis/mybatis-config.xml
  17. 100
      common/pom.xml
  18. 188
      common/src/main/java/com/yyy/common/annotation/Excel.java
  19. 17
      common/src/main/java/com/yyy/common/annotation/Excels.java
  20. 102
      common/src/main/java/com/yyy/common/config/AppConfig.java
  21. 30
      common/src/main/java/com/yyy/common/config/QRConfig.java
  22. 33
      common/src/main/java/com/yyy/common/config/ServerConfig.java
  23. 146
      common/src/main/java/com/yyy/common/constant/Constants.java
  24. 77
      common/src/main/java/com/yyy/common/constant/ShiroConstants.java
  25. 249
      common/src/main/java/com/yyy/common/core/controller/BaseController.java
  26. 69
      common/src/main/java/com/yyy/common/core/domain/Result.java
  27. 32
      common/src/main/java/com/yyy/common/core/domain/ResultCode.java
  28. 34
      common/src/main/java/com/yyy/common/core/domain/dto/LoginDto.java
  29. 54
      common/src/main/java/com/yyy/common/core/domain/dto/UmsMenuDto.java
  30. 44
      common/src/main/java/com/yyy/common/core/domain/dto/UmsOrganizationDto.java
  31. 44
      common/src/main/java/com/yyy/common/core/domain/dto/UmsRoleDto.java
  32. 60
      common/src/main/java/com/yyy/common/core/domain/dto/UmsUserAddDto.java
  33. 33
      common/src/main/java/com/yyy/common/core/domain/dto/UmsUserPasswordDto.java
  34. 46
      common/src/main/java/com/yyy/common/core/domain/dto/UmsUserQueryDto.java
  35. 39
      common/src/main/java/com/yyy/common/core/domain/dto/UmsUserSelfDto.java
  36. 118
      common/src/main/java/com/yyy/common/core/domain/entity/UmsMenu.java
  37. 100
      common/src/main/java/com/yyy/common/core/domain/entity/UmsOrganization.java
  38. 104
      common/src/main/java/com/yyy/common/core/domain/entity/UmsRole.java
  39. 34
      common/src/main/java/com/yyy/common/core/domain/entity/UmsRoleMenu.java
  40. 177
      common/src/main/java/com/yyy/common/core/domain/entity/UmsUser.java
  41. 34
      common/src/main/java/com/yyy/common/core/domain/entity/UmsUserOrganization.java
  42. 34
      common/src/main/java/com/yyy/common/core/domain/entity/UmsUserRole.java
  43. 47
      common/src/main/java/com/yyy/common/core/domain/vo/LoginVo.java
  44. 68
      common/src/main/java/com/yyy/common/core/domain/vo/UmsMenuVo.java
  45. 52
      common/src/main/java/com/yyy/common/core/domain/vo/UmsOrganizationVo.java
  46. 60
      common/src/main/java/com/yyy/common/core/domain/vo/UmsRoleVo.java
  47. 69
      common/src/main/java/com/yyy/common/core/domain/vo/UmsUserVo.java
  48. 89
      common/src/main/java/com/yyy/common/core/page/PageDomain.java
  49. 85
      common/src/main/java/com/yyy/common/core/page/TableDataInfo.java
  50. 56
      common/src/main/java/com/yyy/common/core/page/TableSupport.java
  51. 118
      common/src/main/java/com/yyy/common/core/qr/PdfCellUtill.java
  52. 197
      common/src/main/java/com/yyy/common/core/qr/QrCodeManageAction.java
  53. 88
      common/src/main/java/com/yyy/common/core/text/CharsetKit.java
  54. 1007
      common/src/main/java/com/yyy/common/core/text/Convert.java
  55. 93
      common/src/main/java/com/yyy/common/core/text/StrFormatter.java
  56. 40
      common/src/main/java/com/yyy/common/enums/AssetStatusEnum.java
  57. 29
      common/src/main/java/com/yyy/common/enums/BusinessStatusEnum.java
  58. 23
      common/src/main/java/com/yyy/common/enums/ConfigEnum.java
  59. 37
      common/src/main/java/com/yyy/common/enums/DetectTypeEnum.java
  60. 43
      common/src/main/java/com/yyy/common/enums/EncodingEum.java
  61. 39
      common/src/main/java/com/yyy/common/enums/OrganizationTypeEnum.java
  62. 35
      common/src/main/java/com/yyy/common/enums/ScrapTypeEnum.java
  63. 29
      common/src/main/java/com/yyy/common/enums/SexEnum.java
  64. 28
      common/src/main/java/com/yyy/common/enums/StockTackingDetailStatusEnum.java
  65. 24
      common/src/main/java/com/yyy/common/enums/StocktakingStatusEnum.java
  66. 28
      common/src/main/java/com/yyy/common/enums/UserStatusEnum.java
  67. 41
      common/src/main/java/com/yyy/common/exception/CustomException.java
  68. 13
      common/src/main/java/com/yyy/common/exception/DemoModeException.java
  69. 56
      common/src/main/java/com/yyy/common/exception/GlobalException.java
  70. 56
      common/src/main/java/com/yyy/common/exception/ServiceException.java
  71. 24
      common/src/main/java/com/yyy/common/exception/UtilException.java
  72. 21
      common/src/main/java/com/yyy/common/exception/base/BaseException.java
  73. 17
      common/src/main/java/com/yyy/common/exception/file/FileException.java
  74. 13
      common/src/main/java/com/yyy/common/exception/file/FileNameLengthLimitExceededException.java
  75. 14
      common/src/main/java/com/yyy/common/exception/file/FileSizeLimitExceededException.java
  76. 59
      common/src/main/java/com/yyy/common/exception/file/FileUploadException.java
  77. 78
      common/src/main/java/com/yyy/common/exception/file/InvalidExtensionException.java
  78. 32
      common/src/main/java/com/yyy/common/exception/job/TaskException.java
  79. 14
      common/src/main/java/com/yyy/common/exception/user/BlackListException.java
  80. 16
      common/src/main/java/com/yyy/common/exception/user/CaptchaException.java
  81. 14
      common/src/main/java/com/yyy/common/exception/user/RoleBlockedException.java
  82. 14
      common/src/main/java/com/yyy/common/exception/user/UserBlockedException.java
  83. 14
      common/src/main/java/com/yyy/common/exception/user/UserDeleteException.java
  84. 16
      common/src/main/java/com/yyy/common/exception/user/UserException.java
  85. 14
      common/src/main/java/com/yyy/common/exception/user/UserNotExistsException.java
  86. 14
      common/src/main/java/com/yyy/common/exception/user/UserPasswordNotMatchException.java
  87. 14
      common/src/main/java/com/yyy/common/exception/user/UserPasswordRetryLimitCountException.java
  88. 14
      common/src/main/java/com/yyy/common/exception/user/UserPasswordRetryLimitExceedException.java
  89. 104
      common/src/main/java/com/yyy/common/utils/bean/BeanUtils.java
  90. 217
      common/src/main/java/com/yyy/common/utils/common/DateUtils.java
  91. 191
      common/src/main/java/com/yyy/common/utils/common/DictUtils.java
  92. 48
      common/src/main/java/com/yyy/common/utils/common/MD5Utils.java
  93. 34
      common/src/main/java/com/yyy/common/utils/common/PageUtils.java
  94. 217
      common/src/main/java/com/yyy/common/utils/common/ServletUtils.java
  95. 636
      common/src/main/java/com/yyy/common/utils/common/StringUtils.java
  96. 94
      common/src/main/java/com/yyy/common/utils/common/Threads.java
  97. 4
      common/src/main/java/com/yyy/common/utils/eam/DocumentsUtil.java
  98. 71
      common/src/main/java/com/yyy/common/utils/eam/ResidualValueCalculator.java
  99. 77
      common/src/main/java/com/yyy/common/utils/file/FileTypeUtils.java
  100. 231
      common/src/main/java/com/yyy/common/utils/file/FileUploadUtils.java

51
.gitignore

@ -0,0 +1,51 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
doc/
license/
logs/
script/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
.log
*.exe
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
.mvn
mvnw*
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
### generated files ###
bin/
gen/
### MAC ###
.DS_Store
### Other ###
logs/
log
temp/

90
admin/pom.xml

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yyy</artifactId>
<groupId>com.yyy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>admin</artifactId>
<description>web服务入口,用户相关模板</description>
<dependencies>
<dependency>
<groupId>com.yyy</groupId>
<artifactId>framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.yyy</groupId>
<artifactId>flowable</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.yyy</groupId>
<artifactId>license</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.6</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>

17
admin/src/main/java/com/yyy/Application.java

@ -0,0 +1,17 @@
package com.yyy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
/**
* @Author: fy
* @Date: 2024/03/21
* @Description:主启动类
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}

72
admin/src/main/java/com/yyy/web/config/SwaggerConfig.java

@ -0,0 +1,72 @@
package com.yyy.web.config;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.RequestParameterBuilder;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.Collections;
/**
* @Description knife4j配置类 访问urlhttp://ip:port/doc.html
**/
@EnableKnife4j
@Configuration
public class SwaggerConfig {
@Value("${swagger.base-package}")
private String basePackage;
@Value("${swagger.description}")
private String description;
@Value("${swagger.version}")
private String version;
@Value("${swagger.title}")
private String title;
@Value("${swagger.enabled}")
private boolean enabled;
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.enable(enabled)
.apiInfo(apiInfo())
.globalRequestParameters(
Collections.singletonList(new RequestParameterBuilder()
.name("Authorization")
.in(ParameterType.HEADER)
.required(true)
.build()))
.produces(Collections.singleton("application/json"))
.consumes(Collections.singleton("application/json")).select()
.apis(RequestHandlerSelectors.basePackage(basePackage))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.description(description)
.version(version)
.title(title)
.build();
}
@Bean
public Docket api_flowable() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.ant("/api/flowable/**"))
.build()
.groupName("审批流相关接口")
.pathMapping("/");
}
}

154
admin/src/main/java/com/yyy/web/controller/common/CommonController.java

@ -0,0 +1,154 @@
package com.yyy.web.controller.common;
import com.alibaba.fastjson.JSONObject;
import com.yyy.common.config.AppConfig;
import com.yyy.common.config.ServerConfig;
import com.yyy.common.constant.Constants;
import com.yyy.common.core.domain.Result;
import com.yyy.common.core.domain.ResultCode;
import com.yyy.common.utils.common.StringUtils;
import com.yyy.common.utils.file.FileUploadUtils;
import com.yyy.common.utils.file.FileUtils;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: fy
* @Date: 2024/03/21
* @Description:通用请求处理
*/
@Controller
@RequestMapping("/api/common")
public class CommonController {
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
private static final String FILE_DELIMETER = ",";
@Autowired
private ServerConfig serverConfig;
/**
* 通用下载请求
*
* @param fileName 文件名称
* @param delete 是否删除
*/
@ApiOperation(value = "通用下载请求")
@PostMapping("/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) {
try {
if (!FileUtils.checkAllowDownload(fileName)) {
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
}
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = AppConfig.getDownloadPath() + fileName;
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete) {
FileUtils.deleteFile(filePath);
}
} catch (Exception e) {
log.error("下载文件失败", e);
}
}
/**
* 通用上传请求单个
*/
@ApiOperation(value = "通用上传请求(单个)")
@PostMapping("/upload")
@ResponseBody
public Result uploadFile(MultipartFile file) throws Exception {
try {
// 上传文件路径
String filePath = AppConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
JSONObject result = new JSONObject();
result.put("url", url);
result.put("fileName", fileName);
result.put("newFileName", FileUtils.getName(fileName));
result.put("originalFilename", file.getOriginalFilename());
return new Result(ResultCode.success, result);
} catch (Exception e) {
return new Result(ResultCode.operate_failure, e.getMessage());
}
}
/**
* 通用上传请求多个
*/
@ApiOperation(value = "通用上传请求(多个)")
@PostMapping("/uploads")
@ResponseBody
public Result uploadFiles(List<MultipartFile> files) throws Exception {
try {
// 上传文件路径
String filePath = AppConfig.getUploadPath();
List<String> urls = new ArrayList<String>();
List<String> fileNames = new ArrayList<String>();
List<String> newFileNames = new ArrayList<String>();
List<String> originalFilenames = new ArrayList<String>();
for (MultipartFile file : files) {
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
urls.add(url);
fileNames.add(fileName);
newFileNames.add(FileUtils.getName(fileName));
originalFilenames.add(file.getOriginalFilename());
}
JSONObject result = new JSONObject();
result.put("urls", StringUtils.join(urls, FILE_DELIMETER));
result.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
result.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
result.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
return new Result(ResultCode.success, result);
} catch (Exception e) {
return new Result(ResultCode.operate_failure, e.getMessage());
}
}
/**
* 本地资源通用下载
*/
@ApiOperation(value = "本地资源通用下载")
@PostMapping("/download/resource")
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception {
try {
if (!FileUtils.checkAllowDownload(resource)) {
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
}
// 本地资源路径
String localPath = AppConfig.getProfile();
// 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream());
} catch (Exception e) {
log.error("下载文件失败", e);
}
}
}

88
admin/src/main/java/com/yyy/web/controller/ums/OauthController.java

@ -0,0 +1,88 @@
package com.yyy.web.controller.ums;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yyy.common.core.controller.BaseController;
import com.yyy.common.core.domain.Result;
import com.yyy.common.core.domain.dto.LoginDto;
import com.yyy.common.core.domain.entity.UmsUser;
import com.yyy.common.core.domain.vo.LoginVo;
import com.yyy.common.utils.common.MD5Utils;
import com.yyy.common.utils.security.JwtUtils;
import com.yyy.system.service.UmsMenuService;
import com.yyy.system.service.UmsOrganizationService;
import com.yyy.system.service.UmsRoleService;
import com.yyy.system.service.UmsUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Set;
/**
* @Description:登录授权相关接口
*/
@RestController
@Api(tags = "登录授权相关接口")
@RequestMapping("api/oauth")
public class OauthController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(OauthController.class);
/**
* 服务对象
*/
@Resource
private UmsOrganizationService umsOrganizationService;
@Resource
private UmsUserService umsUserService;
@Resource
private UmsRoleService roleService;
@Resource
private UmsMenuService umsMenuService;
@Resource
private JwtUtils jwtUtils;
/**
* 登录 TODO user_session表
*/
@PostMapping("/login")
@ApiOperation(value = "登录")
public Result<LoginVo> login(@RequestBody LoginDto loginDto, HttpServletRequest request) {
UmsUser user;
{
user = umsUserService.getOne(new QueryWrapper<UmsUser>().eq("login_name", loginDto.getLoginName()));
if (user == null || !StringUtils.equals(user.getPassword(), MD5Utils.inputPassToDBPass(loginDto.getPassword(), user.getSalt()))) {
return Result.INVALID_USER_PASS;
}
}
Set<String> roleSet = roleService.selectRoleKeys(user.getUserId());
Set<String> permsSet = umsMenuService.selectPermsByUserId(user.getUserId());
String Authorization = jwtUtils.getToken(user.getUserId(), request.getSession().getId(), "1.0.0", "web");
return success(LoginVo.builder()
.loginName(user.getLoginName())
.userName(user.getUserName())
.avatar(user.getAvatar())
.phone(user.getPhone())
.email(user.getEmail())
.Authorization(Authorization)
.roles(roleSet)
.permissions(permsSet)
.build());
}
/**
* 登出
*/
@PostMapping("/logout")
@ApiOperation(value = "登出")
public Result logout() {
return success();
}
}

104
admin/src/main/java/com/yyy/web/controller/ums/UmsMenuController.java

@ -0,0 +1,104 @@
package com.yyy.web.controller.ums;
import com.yyy.common.core.controller.BaseController;
import com.yyy.common.core.domain.Result;
import com.yyy.common.core.domain.dto.UmsMenuDto;
import com.yyy.common.core.domain.entity.UmsMenu;
import com.yyy.common.core.domain.vo.UmsMenuVo;
import com.yyy.common.core.page.TableDataInfo;
import com.yyy.common.utils.bean.BeanUtils;
import com.yyy.system.service.UmsMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 菜单表(ums_menu)表控制层
* @author Fangy
* @since 2024-04-03 17:18:31
*/
@RestController
@Api(tags = "菜单表")
@RequestMapping("api/umsMenu")
public class UmsMenuController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(UmsMenuController.class);
/**
* 服务对象
*/
@Resource
private UmsMenuService umsMenuService;
/**
* 查询分页数据
*
*/
@PostMapping("/list")
@ApiOperation(value = "查询分页数据")
public TableDataInfo list(@RequestBody UmsMenuDto umsMenuDto) {
startPage();
List<UmsMenu> list = umsMenuService.query(umsMenuDto);
return getDataTable(UmsMenuVo.ToVo(list));
}
@PostMapping("/listAll")
@ApiOperation(value = "查询所有数据")
public Result listAll() {
return success(UmsMenuVo.ToVo(umsMenuService.query(new UmsMenuDto())));
}
/**
* 查询详情数据
*
*/
@PostMapping("/query")
@ApiOperation(value = "查询详情数据")
public Result<UmsMenuVo> query(@RequestParam Long id) {
return success(UmsMenuVo.ToVo(umsMenuService.getById(id)));
}
/**
* 新增数据
*
*/
@PostMapping("/add")
@ApiOperation(value = "新增数据")
public Result add(@Validated @RequestBody UmsMenuDto umsMenuDto) {
UmsMenu umsMenu = new UmsMenu();
BeanUtils.copyProperties(umsMenuDto, umsMenu);
umsMenu.setCreateUser(getUserId());
return umsMenuService.save(umsMenu)?success():error();
}
/**
* 修改数据
*
*/
@PostMapping("/update")
@ApiOperation(value = "修改数据")
public Result update(@Validated @RequestBody UmsMenuDto umsMenuDto) {
UmsMenu umsMenu = new UmsMenu();
BeanUtils.copyProperties(umsMenuDto, umsMenu);
umsMenu.setUpdateUser(getUserId());
return umsMenuService.updateById(umsMenu) ? success() : error();
}
/**
* 删除数据
*
*/
@PostMapping("/delete")
@ApiOperation(value = "删除数据")
public Result delete(@RequestBody List<Long> idList) {
return umsMenuService.removeBatchByIds(idList) ? success() : error();
}
}

112
admin/src/main/java/com/yyy/web/controller/ums/UmsOrganizationController.java

@ -0,0 +1,112 @@
package com.yyy.web.controller.ums;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yyy.common.core.controller.BaseController;
import com.yyy.common.core.domain.Result;
import com.yyy.common.core.domain.dto.UmsOrganizationDto;
import com.yyy.common.core.domain.entity.UmsOrganization;
import com.yyy.common.core.domain.vo.UmsOrganizationVo;
import com.yyy.common.core.page.TableDataInfo;
import com.yyy.common.enums.OrganizationTypeEnum;
import com.yyy.common.utils.bean.BeanUtils;
import com.yyy.common.utils.common.StringUtils;
import com.yyy.system.service.UmsOrganizationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 组织信息表(ums_organization)表控制层
*
* @author Fangy
* @since 2024-04-03 09:47:06
*/
@RestController
@Api(tags = "组织信息表")
@RequestMapping("api/umsOrganization")
public class UmsOrganizationController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(UmsOrganizationController.class);
/**
* 服务对象
*/
@Resource
private UmsOrganizationService umsOrganizationService;
/**
* 组织树
*/
@PostMapping("/tree")
@ApiOperation(value = "组织树")
public Result<List<UmsOrganizationVo>> tree() {
return success(UmsOrganizationVo.ToVo(umsOrganizationService.list(new QueryWrapper<UmsOrganization>().eq("is_deleted", 0))));
}
/**
* 查询详情数据
*/
@PostMapping("/query")
@ApiOperation(value = "查询详情数据")
public Result<UmsOrganizationVo> query(@RequestParam Long id) {
return success(UmsOrganizationVo.ToVo(umsOrganizationService.getById(id)));
}
/**
* 新增数据
*/
@PostMapping("/add")
@ApiOperation(value = "新增数据")
public Result add(@Validated @RequestBody UmsOrganizationDto umsOrganizationDto) {
if (umsOrganizationDto.getParentId()==null){
umsOrganizationDto.setParentId(0L);
}
UmsOrganization parent = umsOrganizationService.getById(umsOrganizationDto.getParentId());
if (parent!=null){
String msg = OrganizationTypeEnum.enable(parent.getOrganizationType(),umsOrganizationDto.getOrganizationType()!=null?umsOrganizationDto.getOrganizationType():OrganizationTypeEnum.COMPANY.getCode());
if (StringUtils.isNotEmpty(msg)){
return error(msg);
}
}
UmsOrganization umsOrganization = new UmsOrganization();
BeanUtils.copyProperties(umsOrganizationDto, umsOrganization);
umsOrganization.setCreateUser(getUserId());
return umsOrganizationService.save(umsOrganization) ? success() : error();
}
/**
* 修改数据
*/
@PostMapping("/update")
@ApiOperation(value = "修改数据")
public Result update(@Validated @RequestBody UmsOrganizationDto umsOrganizationDto) {
UmsOrganization parent = umsOrganizationService.getById(umsOrganizationService.getById(umsOrganizationDto.getOrganizationId()).getParentId());
if (parent!=null){
String msg = OrganizationTypeEnum.enable(parent.getOrganizationType(),umsOrganizationDto.getOrganizationType()!=null?umsOrganizationDto.getOrganizationType():OrganizationTypeEnum.COMPANY.getCode());
if (StringUtils.isNotEmpty(msg)){
return error(msg);
}
}
UmsOrganization umsOrganization = new UmsOrganization();
BeanUtils.copyProperties(umsOrganizationDto, umsOrganization);
umsOrganization.setUpdateUser(getUserId());
return umsOrganizationService.updateById(umsOrganization) ? success() : error();
}
/**
* 删除数据
*/
@PostMapping("/delete")
@ApiOperation(value = "删除数据")
public Result delete(@RequestBody List<Long> idList) {
return umsOrganizationService.removeBatchByIds(idList) ? success() : error();
}
}

101
admin/src/main/java/com/yyy/web/controller/ums/UmsRoleController.java

@ -0,0 +1,101 @@
package com.yyy.web.controller.ums;
import com.yyy.common.core.controller.BaseController;
import com.yyy.common.core.domain.Result;
import com.yyy.common.core.domain.dto.UmsRoleDto;
import com.yyy.common.core.domain.entity.UmsRole;
import com.yyy.common.core.domain.vo.UmsRoleVo;
import com.yyy.common.core.page.TableDataInfo;
import com.yyy.common.utils.bean.BeanUtils;
import com.yyy.system.service.UmsRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 角色表(ums_role)表控制层
*
* @author Fangy
* @since 2024-04-03 16:14:02
*/
@RestController
@Api(tags = "角色表")
@RequestMapping("api/umsRole")
public class UmsRoleController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(UmsRoleController.class);
/**
* 服务对象
*/
@Resource
private UmsRoleService umsRoleService;
/**
* 查询分页数据
*/
@PostMapping("/list")
@ApiOperation(value = "查询分页数据")
public TableDataInfo list(@RequestBody UmsRoleDto umsRoleDto) {
startPage();
List<UmsRole> list = umsRoleService.query(umsRoleDto);
return getDataTable(UmsRoleVo.ToVo(list));
}
/**
* 查询详情数据
*/
@PostMapping("/query")
@ApiOperation(value = "查询详情数据")
public Result<UmsRoleVo> query(@RequestParam Long id) {
return success(UmsRoleVo.ToVo(umsRoleService.getById(id)));
}
/**
* 新增数据
*/
@PostMapping("/add")
@ApiOperation(value = "新增数据")
public Result add(@Validated @RequestBody UmsRoleDto umsRoleDto) {
Long id = umsRoleService.selectLatestPrimaryKey() + 1;
UmsRole umsRole = new UmsRole();
BeanUtils.copyProperties(umsRoleDto, umsRole);
umsRole.setCreateUser(getUserId());
umsRole.setRoleId(id);
if (umsRoleService.save(umsRole)){
umsRoleService.bindMenu(id, umsRoleDto.getMenuIdList());
return success();
}else {
return error();
}
}
/**
* 修改数据
*/
@PostMapping("/update")
@ApiOperation(value = "修改数据")
public Result update(@Validated @RequestBody UmsRoleDto umsRoleDto) {
UmsRole umsRole = new UmsRole();
BeanUtils.copyProperties(umsRoleDto, umsRole);
umsRole.setUpdateUser(getUserId());
return umsRoleService.updateById(umsRole) && umsRoleService.bindMenu(umsRoleDto.getRoleId(), umsRoleDto.getMenuIdList()) ? success() : error();
}
/**
* 删除数据
*/
@PostMapping("/delete")
@ApiOperation(value = "删除数据")
public Result delete(@RequestBody List<Long> idList) {
//TODO 删除角色关联的用户
//TODO 删除角色和权限的关联
return umsRoleService.removeBatchByIds(idList) ? success() : error();
}
}

233
admin/src/main/java/com/yyy/web/controller/ums/UmsUserController.java

@ -0,0 +1,233 @@
package com.yyy.web.controller.ums;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yyy.common.core.controller.BaseController;
import com.yyy.common.core.domain.Result;
import com.yyy.common.core.domain.dto.UmsUserAddDto;
import com.yyy.common.core.domain.dto.UmsUserPasswordDto;
import com.yyy.common.core.domain.dto.UmsUserQueryDto;
import com.yyy.common.core.domain.dto.UmsUserSelfDto;
import com.yyy.common.core.domain.entity.UmsUser;
import com.yyy.common.core.domain.vo.UmsUserVo;
import com.yyy.common.core.page.TableDataInfo;
import com.yyy.common.enums.ConfigEnum;
import com.yyy.common.utils.bean.BeanUtils;
import com.yyy.common.utils.common.MD5Utils;
import com.yyy.common.utils.common.StringUtils;
import com.yyy.common.utils.poi.ExcelUtil;
import com.yyy.system.service.UmsUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 用户表(ums_user)表控制层
*
* @author Fangy
* @since 2024-03-22 17:31:32
*/
@RestController
@Api(tags = "用户表")
@RequestMapping("api/umsUser")
public class UmsUserController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(UmsUserController.class);
/**
* 服务对象
*/
@Resource
private UmsUserService umsUserService;
/**
* 分页查询
*/
@PostMapping("/list")
@ApiOperation(value = "分页查询数据")
public TableDataInfo list(@RequestBody UmsUserQueryDto umsUserDto) {
startPage();
List<UmsUser> list = umsUserService.list(umsUserDto);
return getDataTable(UmsUserVo.ToVo(list));
}
/**
* 查询详情
*/
@PostMapping("/query")
@ApiOperation(value = "查询详情")
public Result<UmsUserVo> query(@RequestParam Long userId) {
return success(UmsUserVo.ToVo(umsUserService.getById(userId)));
}
@PostMapping("/queryByIds")
@ApiOperation(value = "查询多个")
public Result<UmsUserVo> queryByIds(@RequestBody List<Long> idList) {
return success(UmsUserVo.ToVo(umsUserService.listByIds(idList)));
}
/**
* 新增
*/
@PostMapping("/add")
@ApiOperation(value = "新增")
public Result add(@Validated @RequestBody UmsUserAddDto umsUserDto) {
if (!umsUserService.checkLoginNameUnique(null, umsUserDto.getLoginName())) {
return error("新增用户'" + umsUserDto.getLoginName() + "'失败,登录账号已存在");
} else if (!umsUserService.checkPhoneUnique(null, umsUserDto.getPhone())) {
return error("新增用户'" + umsUserDto.getLoginName() + "'失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(umsUserDto.getEmail()) && !umsUserService.checkEmailUnique(null, umsUserDto.getEmail())) {
return error("新增用户'" + umsUserDto.getLoginName() + "'失败,邮箱账号已存在");
}
String salt = MD5Utils.randomSalt();
UmsUser user = new UmsUser();
BeanUtils.copyProperties(umsUserDto, user);
user.setPassword(MD5Utils.inputPassToDBPass(umsUserDto.getPassword(), salt));
user.setSalt(salt);
user.setCreateUser(getUserId());
if (!umsUserService.save(user)) {
return error();
}
Long userId = umsUserService.getOne(new QueryWrapper<UmsUser>().eq("login_name", umsUserDto.getLoginName())).getUserId();
if (umsUserDto.getOrganizationId() != null) {
umsUserService.bindPost(userId, umsUserDto.getOrganizationId());
}
umsUserService.bindRole(userId, umsUserDto.getRoleId() != null ? umsUserDto.getRoleId() : Long.parseLong(ConfigEnum.DEFAULT_ROLE_ID.getInfo()));
return success();
}
/**
* 修改
*/
@PostMapping("/update")
@ApiOperation(value = "修改")
public Result update(@Validated @RequestBody UmsUserAddDto umsUserDto) {
if (!umsUserService.checkLoginNameUnique(umsUserDto.getUserId(), umsUserDto.getLoginName())) {
return error("修改用户'" + umsUserDto.getLoginName() + "'失败,登录账号已存在");
} else if (!umsUserService.checkPhoneUnique(umsUserDto.getUserId(), umsUserDto.getPhone())) {
return error("修改用户'" + umsUserDto.getLoginName() + "'失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(umsUserDto.getEmail()) && !umsUserService.checkEmailUnique(umsUserDto.getUserId(), umsUserDto.getEmail())) {
return error("修改用户'" + umsUserDto.getLoginName() + "'失败,邮箱账号已存在");
}
if (!umsUserService.update(umsUserDto, getUserId())) {
return error();
}
if (umsUserDto.getOrganizationId() != null) {
umsUserService.unbindPost(umsUserDto.getUserId());
umsUserService.bindPost(umsUserDto.getUserId(), umsUserDto.getOrganizationId());
}
if (umsUserDto.getRoleId() != null) {
umsUserService.unbindRole(umsUserDto.getUserId());
umsUserService.bindRole(umsUserDto.getUserId(), umsUserDto.getRoleId());
}
return success();
}
/**
* 修改个人基本信息
*/
@PostMapping("/update/selfInfo")
@ApiOperation(value = "修改个人基本信息")
public Result selfInfo(@Validated @RequestBody UmsUserSelfDto userSelfDto) {
if (StringUtils.isNotEmpty(userSelfDto.getPhone()) && !umsUserService.checkPhoneUnique(getUserId(), userSelfDto.getPhone())) {
return error("操作失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(userSelfDto.getEmail()) && !umsUserService.checkEmailUnique(getUserId(), userSelfDto.getEmail())) {
return error("操作失败,邮箱账号已存在");
}
UmsUserAddDto umsUserDto = new UmsUserAddDto();
BeanUtils.copyProperties(userSelfDto, umsUserDto);
umsUserDto.setUserId(getUserId());
return umsUserService.update(umsUserDto, getUserId()) ? success() : error();
}
/**
* 修改个人密码
*/
@PostMapping("/update/selfPassword")
@ApiOperation(value = "修改个人密码")
public Result selfPassword(@Validated @RequestBody UmsUserPasswordDto umsUserPasswordDto) {
UmsUser user = umsUserService.getById(getUserId());
if (!user.getPassword().equals(MD5Utils.inputPassToDBPass(umsUserPasswordDto.getOldPassword(), user.getSalt()))) {
return error("操作失败,旧密码错误,请重新输入!");
} else if (umsUserPasswordDto.getOldPassword().equals(umsUserPasswordDto.getNewPassword())) {
return error("操作失败,旧密码与新密码一致,请重新输入!");
} else if (!umsUserPasswordDto.getNewPassword().equals(umsUserPasswordDto.getCheckPassword())) {
return error("操作失败,两次输入的新密码不一致,请重新输入!");
}
String salt = MD5Utils.randomSalt();
user.setPassword(MD5Utils.inputPassToDBPass(umsUserPasswordDto.getNewPassword(), salt));
user.setSalt(salt);
user.setCreateUser(getUserId());
return umsUserService.updateById(user) ? success() : error();
}
/**
* 删除
*/
@PostMapping("/delete")
@ApiOperation(value = "删除")
public Result delete(@RequestBody List<Long> idList) {
umsUserService.unbindRole(idList);
umsUserService.unbindPost(idList);
return umsUserService.removeBatchByIds(idList) ? success() : error();
}
/**
* 用户-导出 TODO 用户-导入
*/
@PostMapping("/export")
@ApiOperation(value = "导出用户数据excel")
public void export(@RequestBody List<Long> idList, HttpServletResponse response) {
List<UmsUser> list = umsUserService.listByIds(idList);
ExcelUtil<UmsUser> util = new ExcelUtil<UmsUser>(UmsUser.class);
util.exportExcel(response, list, "用户数据");
}
/**
* 用户-导入
*/
@PostMapping("/importData")
@ApiOperation(value = "导入用户数据excel")
public Result importData(MultipartFile file) throws Exception {
ExcelUtil<UmsUser> util = new ExcelUtil<>(UmsUser.class);
List<UmsUser> userList = util.importExcel(file.getInputStream());
String salt = MD5Utils.randomSalt();
Long userId = umsUserService.selectLatestPrimaryKey() + 1;
userList.forEach(user -> {
});
for (UmsUser user : userList) {
user.setPassword(MD5Utils.inputPassToDBPass("123456", salt));
user.setSalt(salt);
user.setCreateUser(getUserId());
if (user.get_umsOrganization().getOrganizationId() != null) {
umsUserService.bindPost(userId, user.get_umsOrganization().getOrganizationId());
}
umsUserService.bindRole(userId, user.get_umsRole().getRoleId() != null ? user.get_umsRole().getRoleId() : Long.parseLong(ConfigEnum.DEFAULT_ROLE_ID.getInfo()));
userId++;
}
umsUserService.saveBatch(userList);
return success();
}
/**
* 用户-导入模板
*/
@PostMapping("/importTemplate")
@ApiOperation(value = "导入用户数据excel模板")
public void importTemplate(HttpServletResponse response) {
ExcelUtil<UmsUser> util = new ExcelUtil<UmsUser>(UmsUser.class);
util.importTemplateExcel(response, "用户数据");
}
}

69
admin/src/main/resources/application-dev.yml

@ -0,0 +1,69 @@
# 项目相关配置
app:
# 名称
name: 名称
# 版本
version: 1.0.0
# 版权
copyright: yyy版权所有
# 版权年份
copyrightYear: 2024
# 文件路径
profile: "D:/data/eam"
# 开发环境配置
server:
# 服务器的HTTP端口,默认为80
port: 80
servlet:
# 应用的访问路径
context-path: /
tomcat:
# tomcat的URI编码
uri-encoding: UTF-8
# 连接数满后的排队数,默认为100
accept-count: 1000
threads:
# tomcat最大线程数,默认为200
max: 800
# Tomcat启动初始化的线程数,默认值10
min-spare: 100
# 日志配置
logging:
level:
com.yyy: debug
org.springframework: warn
# mysql连接信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/eam?nullDatabaseMeansCurrent=true
username: root
password: 123456
type: com.mysql.cj.jdbc.MysqlDataSource
#spring:
# datasource:
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://47.109.27.8:3306/eam?nullDatabaseMeansCurrent=true
# username: admin
# password: "@Jiluo2019"
# type: com.mysql.cj.jdbc.MysqlDataSource
qr:
ttf: "/ttf/SimHei.ttf"
# License 相关配置
license:
# 主题
subject: license_eam
# 公钥别称
publicAlias: publicCert
# 访问公钥的密码
storePass: jiluo2019
# license 位置
licensePath: D:/license/license.lic
# 公钥位置
publicKeysStorePath: D:/license/publicCerts.keystore

60
admin/src/main/resources/application-prod.yml

@ -0,0 +1,60 @@
app:
# 名称
name: 固定资产管理系统
# 版本
version: 1.0.0
# 版权
copyright: 成都积络科技版权所有
# 版权年份
copyrightYear: 2024
# 文件路径
profile: "/data/eam"
# 开发环境配置
server:
# 服务器的HTTP端口,默认为80
port: 8280
servlet:
# 应用的访问路径
context-path: /
tomcat:
# tomcat的URI编码
uri-encoding: UTF-8
# 连接数满后的排队数,默认为100
accept-count: 1000
threads:
# tomcat最大线程数,默认为200
max: 800
# Tomcat启动初始化的线程数,默认值10
min-spare: 100
# 日志配置
logging:
level:
com.yyy: debug
org.springframework: warn
# 数据源配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/eam?nullDatabaseMeansCurrent=true
username: admin
password: "@Jiluo2019"
type: com.mysql.cj.jdbc.MysqlDataSource
qr:
ttf: "/ttf/SimHei.ttf"
# License 相关配置
license:
# 主题
subject: license_eam
# 公钥别称
publicAlias: publicCert
# 访问公钥的密码
storePass: jiluo2019
# license 位置
licensePath: /data/eam/license/license.lic
# 公钥位置
publicKeysStorePath: /data/eam/license/publicCerts.keystore

54
admin/src/main/resources/application.yml

@ -0,0 +1,54 @@
# Spring配置
spring:
application:
name: yyy
profiles:
active: prod
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
# mvc策略
mvc:
pathmatch:
matching-strategy: ANT_PATH_MATCHER
# MyBatis
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.yyy.common.core.domain.entity
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# Swagger配置
swagger:
base-package: "com.yyy"
description: ""
version: "1.0"
title: "接口文档"
enabled: true #是否开启swagger
minio:
endpoint: http://localhost #Minio服务ip
port: 9000
accessKey: minioadmin #访问的key
secretKey: minioadmin #访问的秘钥
secure: false
bucketName: "defaultbucket" #默认存储桶名称
enabled: false #是否开启minio
jwt:
config:
header: Authorization
refreshTime: 3600000 # 刷新时间 1小时
expiresTime: 7200000 # 过期 2小时
secretKey: jiluo2019

22
admin/src/main/resources/banner.txt

@ -0,0 +1,22 @@
////////////////////////////////////////////////////////////////////
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //
////////////////////////////////////////////////////////////////////

152
admin/src/main/resources/logback-spring.xml

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds">
<contextName>eam</contextName>
<!-- 应用名称 -->
<property name="log.name" value="eam" />
<!-- 日志级别: ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL <OFF -->
<property name="log.level" value="INFO" />
<!-- 日志文件路径 -->
<property name="log.path" value="logs" />
<!-- 日志内容长度限制,超过该字节数的日志内容倍自动截断,防止大量打印无效的数据到日志文件 -->
<property name="log.length" value="4096" />
<!-- 日志文件大小,超过该大小则滚动日志 -->
<property name="log.max.file" value="10MB" />
<!-- 滚动日志文件保留天数,超过则会清理较早的日志文件 -->
<property name="log.max.history" value="7" />
<!-- 日志容量限制,日志占用磁盘空间超过该阈值则自动清理较早的日志文件 -->
<property name="log.max.size" value="500MB" />
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${log.level}</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/${log.name}/${log.name}-info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %.-${log.length}msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.name}/${log.name}-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志文件大小-->
<maxFileSize>${log.max.file}</maxFileSize>
<!--日志文件保留天数-->
<maxHistory>${log.max.history}</maxHistory>
<!--日志文件总容量-->
<totalSizeCap>${log.max.size}</totalSizeCap>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/${log.name}/${log.name}-warn.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %.-${log.length}msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.name}/${log.name}-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${log.max.file}</maxFileSize>
<maxHistory>${log.max.history}</maxHistory>
<totalSizeCap>${log.max.size}</totalSizeCap>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/${log.name}/${log.name}-error.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %.-${log.length}msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.name}/${log.name}-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${log.max.file}</maxFileSize>
<maxHistory>${log.max.history}</maxHistory>
<totalSizeCap>${log.max.size}</totalSizeCap>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="PROTOCOL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/${log.name}/${log.name}-protocol.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %.-${log.length}msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.name}/${log.name}-protocol-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${log.max.file}</maxFileSize>
<maxHistory>${log.max.history}</maxHistory>
<totalSizeCap>${log.max.size}</totalSizeCap>
</rollingPolicy>
</appender>
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="MESSAGE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/${log.name}/${log.name}-message.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %.-${log.length}msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${log.name}/${log.name}-message-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${log.max.file}</maxFileSize>
<maxHistory>${log.max.history}</maxHistory>
<totalSizeCap>${log.max.size}</totalSizeCap>
</rollingPolicy>
</appender>
<logger name="org.spring" level="INFO" addtivity="false"/>
<logger name="com.alibaba" level="ERROR" addtivity="false"/>
<root level="${log.level}">
<appender-ref ref="CONSOLE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</configuration>

20
admin/src/main/resources/mybatis/mybatis-config.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<!-- 使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 允许JDBC 支持自动生成主键 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 指定 MyBatis 所用日志的具体实现 -->
<setting name="logImpl" value="SLF4J" />
<!-- 使用驼峰命名法转换字段 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
</settings>
</configuration>

100
common/pom.xml

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yyy</artifactId>
<groupId>com.yyy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common</artifactId>
<description>通用工具</description>
<dependencies>
<!-- Spring框架基本的核心工具 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- SpringWeb模块 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!--Shiro核心框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
</dependency>
<!-- Shiro使用EhCache缓存框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<!-- Mybatis-Plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<!-- jwt生成token的库 -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
</dependency>
</dependencies>
</project>

188
common/src/main/java/com/yyy/common/annotation/Excel.java

@ -0,0 +1,188 @@
package com.yyy.common.annotation;
import com.yyy.common.utils.poi.ExcelHandlerAdapter;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.math.BigDecimal;
/**
* 自定义导出Excel数据注解
*
* @author ruoyi
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel
{
/**
* 导出时在excel中排序
*/
public int sort() default Integer.MAX_VALUE;
/**
* 导出到Excel中的名字.
*/
public String name() default "";
/**
* 日期格式, : yyyy-MM-dd
*/
public String dateFormat() default "";
/**
* 如果是字典类型请设置字典的type值 (: sys_user_sex)
*/
public String dictType() default "";
/**
* 读取内容转表达式 (: 0=,1=,2=未知)
*/
public String readConverterExp() default "";
/**
* 分隔符读取字符串组内容
*/
public String separator() default ",";
/**
* BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
*/
public int scale() default -1;
/**
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
*/
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
/**
* 导出时在excel中每个列的高度
*/
public double height() default 14;
/**
* 导出时在excel中每个列的宽度
*/
public double width() default 16;
/**
* 文字后缀,% 90 变成90%
*/
public String suffix() default "";
/**
* 当值为空时,字段的默认值
*/
public String defaultValue() default "";
/**
* 提示信息
*/
public String prompt() default "";
/**
* 设置只能选择不能输入的列内容.
*/
public String[] combo() default {};
/**
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
*/
public boolean needMerge() default false;
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/
public boolean isExport() default true;
/**
* 另一个类中的属性名称,支持多级获取,以小数点隔开
*/
public String targetAttr() default "";
/**
* 是否自动统计数据,在最后追加一行统计数据总和
*/
public boolean isStatistics() default false;
/**
* 导出类型0数字 1字符串 2图片
*/
public ColumnType cellType() default ColumnType.STRING;
/**
* 导出列头背景颜色
*/
public IndexedColors headerBackgroundColor() default IndexedColors.SKY_BLUE;
/**
* 导出列头字体颜色
*/
public IndexedColors headerColor() default IndexedColors.WHITE;
/**
* 导出单元格背景颜色
*/
public IndexedColors backgroundColor() default IndexedColors.WHITE;
/**
* 导出单元格字体颜色
*/
public IndexedColors color() default IndexedColors.BLACK;
/**
* 导出字段对齐方式
*/
public HorizontalAlignment align() default HorizontalAlignment.CENTER;
/**
* 自定义数据处理器
*/
public Class<?> handler() default ExcelHandlerAdapter.class;
/**
* 自定义数据处理器参数
*/
public String[] args() default {};
/**
* 字段类型0导出导入1仅导出2仅导入
*/
Type type() default Type.ALL;
public enum Type
{
ALL(0), EXPORT(1), IMPORT(2);
private final int value;
Type(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
public enum ColumnType
{
NUMERIC(0), STRING(1), IMAGE(2);
private final int value;
ColumnType(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
}

17
common/src/main/java/com/yyy/common/annotation/Excels.java

@ -0,0 +1,17 @@
package com.yyy.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Excel注解集
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excels
{
Excel[] value();
}

102
common/src/main/java/com/yyy/common/config/AppConfig.java

@ -0,0 +1,102 @@
package com.yyy.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:全局配置类
*/
@Component
@ConfigurationProperties(prefix = "app")
public class AppConfig {
/** 项目名称 */
private static String name = "xxx";
/** 版本 */
private static String version = "1.0.0";
/** 版权 */
private static String copyright = "成都积络科技版权所有";
/** 版权年份 */
private static String copyrightYear = "2024";
/** 上传路径 */
// private static String profile = "D:\\";
private static String profile = "/data/eam";
public static String getName() {
return name;
}
public static void setName(String name) {
AppConfig.name = name;
}
public static String getVersion() {
return version;
}
public static void setVersion(String version) {
AppConfig.version = version;
}
public static String getCopyright() {
return copyright;
}
public static void setCopyright(String copyright) {
AppConfig.copyright = copyright;
}
public static String getCopyrightYear() {
return copyrightYear;
}
public static void setCopyrightYear(String copyrightYear) {
AppConfig.copyrightYear = copyrightYear;
}
public static String getProfile() {
return profile;
}
public static void setProfile(String profile) {
AppConfig.profile = profile;
}
/**
* 获取导入上传路径
*/
public static String getImportPath()
{
return getProfile() + "/import";
}
/**
* 获取头像上传路径
*/
public static String getAvatarPath()
{
return getProfile() + "/avatar";
}
/**
* 获取下载路径
*/
public static String getDownloadPath()
{
return getProfile() + "/download/";
}
/**
* 获取上传路径
*/
public static String getUploadPath()
{
return getProfile() + "/upload";
}
}

30
common/src/main/java/com/yyy/common/config/QRConfig.java

@ -0,0 +1,30 @@
package com.yyy.common.config;
import cn.hutool.extra.qrcode.QrConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.awt.*;
/**
* @Author: fy
* @Date: 2024/03/20
* @Description:采用JavaConfig的方式显示注入hutool中 生成二维码
*/
@Configuration
public class QRConfig {
@Bean
public QrConfig qrConfig(){
//初始宽度和高度
QrConfig qrConfig=new QrConfig(300,300);
//设置边距,即二维码和边框的距离
qrConfig.setMargin(2);
//设置前景色
qrConfig.setForeColor(Color.BLACK.getRGB());
//设置背景色
qrConfig.setBackColor(Color.WHITE.getRGB());
return qrConfig;
}
}

33
common/src/main/java/com/yyy/common/config/ServerConfig.java

@ -0,0 +1,33 @@
package com.yyy.common.config;
import com.yyy.common.utils.common.ServletUtils;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:服务相关配置
*/
@Component
public class ServerConfig
{
/**
* 获取完整的请求路径包括域名端口上下文访问路径
*
* @return 服务地址
*/
public String getUrl()
{
HttpServletRequest request = ServletUtils.getRequest();
return getDomain(request);
}
public static String getDomain(HttpServletRequest request)
{
StringBuffer url = request.getRequestURL();
String contextPath = request.getServletContext().getContextPath();
return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
}
}

146
common/src/main/java/com/yyy/common/constant/Constants.java

@ -0,0 +1,146 @@
package com.yyy.common.constant;
import com.google.common.collect.Lists;
import org.springframework.http.MediaType;
import java.util.List;
import java.util.Locale;
/**
* @Author: fy
* @Date: 2024/03/21
* @Description:通用常量信息
*/
public class Constants {
public static final String SESSION_USER_KEY = "user";
public static final List<MediaType> SUPPORTED_MEDIA_TYPES = Lists.newArrayList(
MediaType.APPLICATION_JSON,
MediaType.APPLICATION_ATOM_XML,
MediaType.APPLICATION_FORM_URLENCODED,
MediaType.APPLICATION_OCTET_STREAM,
MediaType.APPLICATION_PDF,
MediaType.APPLICATION_RSS_XML,
MediaType.APPLICATION_XHTML_XML,
MediaType.APPLICATION_XML,
MediaType.IMAGE_GIF,
MediaType.IMAGE_JPEG,
MediaType.IMAGE_PNG,
MediaType.TEXT_EVENT_STREAM,
MediaType.TEXT_HTML,
MediaType.TEXT_MARKDOWN,
MediaType.TEXT_PLAIN,
MediaType.TEXT_XML
);
/**
* UTF-8 字符集
*/
public static final String UTF8 = "UTF-8";
/**
* GBK 字符集
*/
public static final String GBK = "GBK";
/**
* 系统语言
*/
public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
/**
* http请求
*/
public static final String HTTP = "http://";
/**
* https请求
*/
public static final String HTTPS = "https://";
/**
* 通用成功标识
*/
public static final String SUCCESS = "0";
/**
* 通用失败标识
*/
public static final String FAIL = "1";
/**
* 登录成功
*/
public static final String LOGIN_SUCCESS = "Success";
/**
* 注销
*/
public static final String LOGOUT = "Logout";
/**
* 注册
*/
public static final String REGISTER = "Register";
/**
* 登录失败
*/
public static final String LOGIN_FAIL = "Error";
/**
* 系统用户授权缓存
*/
public static final String SYS_AUTH_CACHE = "sys-authCache";
/**
* 参数管理 cache name
*/
public static final String SYS_CONFIG_CACHE = "sys-config";
/**
* 参数管理 cache key
*/
public static final String SYS_CONFIG_KEY = "sys_config:";
/**
* 字典管理 cache name
*/
public static final String SYS_DICT_CACHE = "sys-dict";
/**
* 字典管理 cache key
*/
public static final String SYS_DICT_KEY = "sys_dict:";
/**
* 资源映射路径 前缀
*/
public static final String RESOURCE_PREFIX = "/file";
/**
* RMI 远程方法调用
*/
public static final String LOOKUP_RMI = "rmi:";
/**
* LDAP 远程方法调用
*/
public static final String LOOKUP_LDAP = "ldap:";
/**
* LDAPS 远程方法调用
*/
public static final String LOOKUP_LDAPS = "ldaps:";
//
// /**
// * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
// */
// public static final String[] JOB_WHITELIST_STR = { "com.ruoyi.quartz.task" };
//
// /**
// * 定时任务违规的字符
// */
// public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
// "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config", "com.ruoyi.generator" };
}

77
common/src/main/java/com/yyy/common/constant/ShiroConstants.java

@ -0,0 +1,77 @@
package com.yyy.common.constant;
/**
* Shiro通用常量
*/
public class ShiroConstants
{
/**
* 当前登录的用户
*/
public static final String CURRENT_USER = "currentUser";
/**
* 用户名字段
*/
public static final String CURRENT_USERNAME = "username";
/**
* 锁定屏幕字段
*/
public static final String LOCK_SCREEN = "lockscreen";
/**
* 消息key
*/
public static final String MESSAGE = "message";
/**
* 错误key
*/
public static final String ERROR = "errorMsg";
/**
* 编码格式
*/
public static final String ENCODING = "UTF-8";
/**
* 当前在线会话
*/
public static final String ONLINE_SESSION = "online_session";
/**
* 验证码key
*/
public static final String CURRENT_CAPTCHA = "captcha";
/**
* 验证码开关
*/
public static final String CURRENT_ENABLED = "captchaEnabled";
/**
* 验证码类型
*/
public static final String CURRENT_TYPE = "captchaType";
/**
* 验证码
*/
public static final String CURRENT_VALIDATECODE = "validateCode";
/**
* 验证码错误
*/
public static final String CAPTCHA_ERROR = "captchaError";
/**
* 登录记录缓存
*/
public static final String LOGIN_RECORD_CACHE = "loginRecordCache";
/**
* 系统活跃用户缓存
*/
public static final String SYS_USERCACHE = "sys-userCache";
}

249
common/src/main/java/com/yyy/common/core/controller/BaseController.java

@ -0,0 +1,249 @@
package com.yyy.common.core.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yyy.common.core.domain.Result;
import com.yyy.common.core.domain.ResultCode;
import com.yyy.common.core.domain.entity.UmsUser;
import com.yyy.common.core.page.PageDomain;
import com.yyy.common.core.page.TableDataInfo;
import com.yyy.common.core.page.TableSupport;
import com.yyy.common.utils.common.*;
import com.yyy.common.utils.security.JwtUtils;
import com.yyy.common.utils.sql.SqlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.beans.PropertyEditorSupport;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:web层通用数据处理
*/
@Component
public class BaseController {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
JwtUtils jwtUtils;
/**
* 将前台传递过来的日期格式的字符串自动转化为Date类型
*/
@InitBinder
public void initBinder(WebDataBinder binder)
{
// Date 类型转换
binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
{
@Override
public void setAsText(String text)
{
setValue(DateUtils.parseDate(text));
}
});
}
/**
* 设置请求分页数据
*/
protected void startPage()
{
//PageUtils.startPage();
}
/**
* 设置请求排序数据
*/
protected void startOrderBy()
{
PageDomain pageDomain = TableSupport.buildPageRequest();
if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
{
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
PageHelper.orderBy(orderBy);
}
}
/**
* 清理分页的线程变量
*/
protected void clearPage()
{
PageUtils.clearPage();
}
/**
* 获取request
*/
public HttpServletRequest getRequest()
{
return ServletUtils.getRequest();
}
/**
* 获取response
*/
public HttpServletResponse getResponse()
{
return ServletUtils.getResponse();
}
/**
* 获取session
*/
public HttpSession getSession()
{
return getRequest().getSession();
}
/**
* 响应请求分页数据
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected TableDataInfo getDataTable(List<?> list)
{
// TableDataInfo rspData = new TableDataInfo();
// rspData.setCode(0);
// rspData.setRows(list);
// rspData.setTotal(new PageInfo(list).getTotal());
// return rspData;
//TODO 优化成sql的limit
PageDomain pageDomain = TableSupport.buildPageRequest();
Integer pageNum = pageDomain.getPageNum();
Integer pageSize = pageDomain.getPageSize();
int num = list.size();
list = list.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(0);
rspData.setRows(list);
rspData.setTotal(num);
return rspData;
}
/**
* 响应返回结果
*
* @param rows 影响行数
* @return 操作结果
*/
protected Result toResult(int rows)
{
return rows > 0 ? success() : error();
}
/**
* 响应返回结果
*
* @param result 结果
* @return 操作结果
*/
protected Result toResult(boolean result)
{
return result ? success() : error();
}
/**
* 返回成功
*/
public Result success()
{
return Result.SUCCESS;
}
/**
* 返回失败消息
*/
public Result error()
{
return Result.FAILURE;
}
/**
* 返回成功消息
*/
public Result success(String message)
{
return new Result(ResultCode.success,message);
}
/**
* 返回成功数据
*/
public static Result success(Object data)
{
return new Result(ResultCode.success,data);
}
/**
* 返回失败消息
*/
public Result error(String message)
{
return new Result(ResultCode.operate_failure.getCode(),message);
}
/**
* 返回错误码消息
*/
public Result error(ResultCode code, String message)
{
return new Result(code, message);
}
/**
* 页面跳转
*/
public String redirect(String url)
{
return StringUtils.format("redirect:{}", url);
}
/**
* TODO 获取用户缓存信息
*/
public UmsUser getUser()
{
// return ShiroUtils.getUser();
return new UmsUser();
}
/**
* TODO 设置用户缓存信息
*/
public void setUser(UmsUser user)
{
// ShiroUtils.setUser(user);
}
/**
* 获取登录用户id
*/
public Long getUserId()
{
return Long.parseLong(jwtUtils.parseToken(ServletUtils.getRequest().getHeader("Authorization")).get("uid"));
}
/**
* 获取登录用户名
*/
public String getLoginName()
{
return getUser().getLoginName();
}
}

69
common/src/main/java/com/yyy/common/core/domain/Result.java

@ -0,0 +1,69 @@
package com.yyy.common.core.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
/**
* @Author: fy
* @Date: 2024/03/21
* @Description:统一返回结果
*/
@ApiModel("统一返回结果")
@ToString
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
public static final Result NOT_SUPPORT = new Result(ResultCode.not_support_operate);
public static final Result NOT_PRIVILEGED = new Result(ResultCode.not_privileged);
public static final Result INVALID_USER_PASS = new Result(ResultCode.invalidUserOrPassword);
public static final Result ILLEGAL_ARGUMENT = new Result(ResultCode.illegal_argument);
public static final Result FAILURE = new Result(ResultCode.operate_failure);
public static final Result ERROR = new Result(ResultCode.system_error);
public static final Result NOT_LOGIN = new Result(ResultCode.need_login);
public static final Result SUCCESS = new Result(ResultCode.success);
public static final Result INVALID_LICENSE = new Result(ResultCode.invalid_license);
@Getter
@Setter
@ApiModelProperty("状态码")
private int code;
@Getter
@Setter
@ApiModelProperty("描述信息")
private String desc;
@Getter
@Setter
@ApiModelProperty("响应结果数据")
private T body;
public Result(ResultCode resultCode) {
setCode(resultCode.getCode());
setDesc(resultCode.getDesc());
}
public Result(int code, String msg) {
setCode(code);
setDesc(msg);
}
/**
* 使用通用结果码生成对象
*/
public Result(ResultCode resultCode, T body) {
setCode(resultCode.getCode());
setDesc(resultCode.getDesc());
setBody(body);
}
/**
* 判断执行结果是否成功
*/
public boolean isSuccess() {
return ResultCode.success.getCode() == code;
}
}

32
common/src/main/java/com/yyy/common/core/domain/ResultCode.java

@ -0,0 +1,32 @@
package com.yyy.common.core.domain;
import lombok.Getter;
/**
* @Author: fy
* @Date: 2024/03/21
* @Description:统一结果码定义
*/
public enum ResultCode {
success(200, "成功"),
invalidUserOrPassword(300, "用户名或者密码错误!"),
illegal_argument(400, "参数错误!"),
need_login(401, "未登录!"),
not_support_operate(404, "不支持的请求!"),
not_privileged(405, "无权限执行该操作!"),
invalid_license(406, "您的证书无效,请核查服务器是否取得授权或重新申请证书!"),
system_error(500, "系统异常!"),
operate_failure(503, "操作失败!");
@Getter
private final int code;
@Getter
private final String desc;
ResultCode(int code, String desc) {
this.code = code;
this.desc = desc;
}
}

34
common/src/main/java/com/yyy/common/core/domain/dto/LoginDto.java

@ -0,0 +1,34 @@
package com.yyy.common.core.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* @Author: fy
* @Date: 2024/04/03
* @Description:
*/
@ApiModel("登录")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginDto implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(notes = "账号", required = true)
@NotBlank(message = "账号不能为空")
private String loginName;
@ApiModelProperty(notes = "密码", required = true)
@NotBlank(message = "密码不能为空")
private String password;
@ApiModelProperty(notes = "验证码")
private String code;
}

54
common/src/main/java/com/yyy/common/core/domain/dto/UmsMenuDto.java

@ -0,0 +1,54 @@
package com.yyy.common.core.domain.dto;
import java.util.Date;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Builder;
import javax.validation.constraints.NotBlank;
@ApiModel("菜单表(UmsMenuDto)传输数据类")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UmsMenuDto implements Serializable {
private static final long serialVersionUID = -26115459430198770L;
@ApiModelProperty(notes = "菜单ID")
private Long menuId;
@ApiModelProperty(notes = "菜单名称", required = true)
@NotBlank(message = "菜单名称不能为空")
private String menuName;
@ApiModelProperty(notes = "父主键ID")
private Long parentId;
@ApiModelProperty(notes = "排序")
private Integer sort;
@ApiModelProperty(notes = "请求路径")
private String url;
@ApiModelProperty(notes = "菜单类型(M目录 C菜单 F按钮)")
private String menuType;
@ApiModelProperty(notes = "菜单状态(1隐藏 0显示)")
private String visible;
@ApiModelProperty(notes = "权限标识")
private String permission;
@ApiModelProperty(notes = "菜单图标")
private String icon;
@ApiModelProperty(notes = "备注")
private String remark;
}

44
common/src/main/java/com/yyy/common/core/domain/dto/UmsOrganizationDto.java

@ -0,0 +1,44 @@
package com.yyy.common.core.domain.dto;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Builder;
import javax.validation.constraints.NotBlank;
@ApiModel("组织信息表(UmsOrganizationDto)传输数据类")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UmsOrganizationDto implements Serializable {
private static final long serialVersionUID = -22653557155840114L;
@ApiModelProperty(notes = "组织ID")
private Long organizationId;
@ApiModelProperty(notes = "组织名称", required = true)
@NotBlank(message = "组织名称不能为空")
private String organizationName;
@ApiModelProperty(notes = "组织类型(0:公司/1:部门/2:岗位)")
private String organizationType;
@ApiModelProperty(notes = "显示顺序")
private Integer orderNum;
@ApiModelProperty(notes = "父组织id")
private Long parentId;
@ApiModelProperty(notes = "深度")
private String depth;
@ApiModelProperty(notes = "状态(0:正常/1:停用)")
private String status;
}

44
common/src/main/java/com/yyy/common/core/domain/dto/UmsRoleDto.java

@ -0,0 +1,44 @@
package com.yyy.common.core.domain.dto;
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Builder;
import javax.validation.constraints.NotBlank;
@ApiModel("角色表(UmsRoleDto)传输数据类")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UmsRoleDto implements Serializable {
private static final long serialVersionUID = 154065236903833980L;
@ApiModelProperty("角色ID")
private Long roleId;
@ApiModelProperty(notes = "角色名称", required = true)
@NotBlank(message = "角色名称不能为空")
private String roleName;
@ApiModelProperty(notes = "角色权限字符串")
private String roleKey;
@ApiModelProperty(notes = "角色状态(0:正常/1:停用)")
private String status;
@ApiModelProperty("显示顺序")
private Integer roleSort;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("菜单权限idList")
private List<Long> menuIdList;
}

60
common/src/main/java/com/yyy/common/core/domain/dto/UmsUserAddDto.java

@ -0,0 +1,60 @@
package com.yyy.common.core.domain.dto;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
@ApiModel("用户表(UmsUserDto)传输数据类")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UmsUserAddDto implements Serializable {
private static final long serialVersionUID = -65838283669796140L;
@ApiModelProperty(notes = "主键")
private Long userId;
@ApiModelProperty(notes = "账号名", required = true)
@NotBlank(message = "账号名不能为空")
private String loginName;
@ApiModelProperty(notes = "姓名", required = true)
@NotBlank(message = "姓名不能为空")
private String userName;
@ApiModelProperty(notes = "用户邮箱")
private String email;
@ApiModelProperty(notes = "联系电话", required = true)
@NotBlank(message = "手机号码不能为空")
@Length(min = 11, max = 11, message = "手机号只能为11位")
@Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式有误")
private String phone;
@ApiModelProperty(notes = "状态(0-在职 1-离职)")
private String status;
@ApiModelProperty(notes = "密码")
private String password;
@ApiModelProperty(notes = "用户性别(0-男 1-女 2-未知)")
private String sex;
@ApiModelProperty(notes = "头像路径")
private String avatar;
@ApiModelProperty(notes = "岗位id")
private Long organizationId;
@ApiModelProperty(notes = "角色id")
private Long roleId;
}

33
common/src/main/java/com/yyy/common/core/domain/dto/UmsUserPasswordDto.java

@ -0,0 +1,33 @@
package com.yyy.common.core.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
@ApiModel("个人密码修改")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UmsUserPasswordDto implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(notes = "旧密码", required = true)
@NotBlank(message = "旧密码不能为空")
private String oldPassword;
@ApiModelProperty(notes = "新密码", required = true)
@NotBlank(message = "新密码不能为空")
private String newPassword;
@ApiModelProperty(notes = "确认密码", required = true)
@NotBlank(message = "确认密码不能为空")
private String checkPassword;
}

46
common/src/main/java/com/yyy/common/core/domain/dto/UmsUserQueryDto.java

@ -0,0 +1,46 @@
package com.yyy.common.core.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Author: fy
* @Date: 2024/04/02
* @Description:
*/
@ApiModel("用户查询")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UmsUserQueryDto implements Serializable {
private static final long serialVersionUID = -65838283669796140L;
@ApiModelProperty(notes = "账号名")
private String loginName;
@ApiModelProperty(notes = "姓名")
private String userName;
@ApiModelProperty(notes = "联系电话")
private String phone;
@ApiModelProperty(notes = "状态(0-在职 1-离职)")
private String status;
@ApiModelProperty(notes = "用户性别(0-男 1-女 2-未知)")
private String sex;
@ApiModelProperty(notes = "公司/部门/岗位id")
private Long organizationId;
@ApiModelProperty(notes = "角色id")
private Long roleId;
@ApiModelProperty(notes = "查询公司/部门下所有的人员信息")
private boolean tree = false;
}

39
common/src/main/java/com/yyy/common/core/domain/dto/UmsUserSelfDto.java

@ -0,0 +1,39 @@
package com.yyy.common.core.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
@ApiModel("个人基本信息修改")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UmsUserSelfDto implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(notes = "姓名", required = true)
@NotBlank(message = "姓名不能为空")
private String userName;
@ApiModelProperty(notes = "用户邮箱")
private String email;
@ApiModelProperty(notes = "联系电话")
@Length(min = 11, max = 11, message = "手机号只能为11位")
@Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式有误")
private String phone;
@ApiModelProperty(notes = "用户性别(0-男 1-女 2-未知)")
private String sex;
@ApiModelProperty(notes = "头像路径")
private String avatar;
}

118
common/src/main/java/com/yyy/common/core/domain/entity/UmsMenu.java

@ -0,0 +1,118 @@
package com.yyy.common.core.domain.entity;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 菜单表(UmsMenu)表实体类
*
* @author Fangy
* @since 2024-03-25 15:50:12
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "ums_menu")
public class UmsMenu {
private static final long serialVersionUID = -97647718306147532L;
/**
* 菜单ID(主键)
*/
@JsonIgnore
@TableId(value = "menu_id", type = IdType.AUTO)
private Long menuId;
/**
* 菜单名称
*/
@TableField("menu_name")
private String menuName;
/**
* 父主键ID
*/
@TableField("parent_id")
private Long parentId;
/**
* 排序
*/
@TableField("sort")
private Integer sort;
/**
* 请求路径
*/
@TableField("url")
private String url;
/**
* 菜单类型M目录 C菜单 F按钮
*/
@TableField("menu_type")
private String menuType;
/**
* 菜单状态1隐藏 0显示
*/
@TableField("visible")
private String visible;
/**
* 权限标识
*/
@TableField("permission")
private String permission;
/**
* 菜单图标
*/
@TableField("icon")
private String icon;
/**
* 创建人
*/
@TableField("create_user")
private Long createUser;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 修改人
*/
@TableField("update_user")
private Long updateUser;
/**
* 修改时间
*/
@JsonIgnore
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
/**
* 是否删除0正常/1删除
*/
@TableField("is_deleted")
private Object isDeleted;
/**
* 备注
*/
@TableField("remark")
private String remark;
}

100
common/src/main/java/com/yyy/common/core/domain/entity/UmsOrganization.java

@ -0,0 +1,100 @@
package com.yyy.common.core.domain.entity;
import java.util.Date;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* 组织信息表(UmsOrganization)表实体类
*
* @author Fangy
* @since 2024-04-03 09:47:07
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "ums_organization")
public class UmsOrganization {
private static final long serialVersionUID = -27479820178077875L;
/**
* 组织ID(主键)
*/
@JsonIgnore
@TableId(value = "organization_id", type = IdType.AUTO)
private Long organizationId;
/**
* 组织名称
*/
@TableField("organization_name")
private String organizationName;
/**
* 组织类型0公司/1部门/2岗位
*/
@TableField("organization_type")
private String organizationType;
/**
* 显示顺序
*/
@TableField("order_num")
private Integer orderNum;
/**
* 父组织id
*/
@TableField("parent_id")
private Long parentId;
/**
* 深度
*/
@TableField("depth")
private String depth;
/**
* 状态0正常/1停用
*/
@TableField("status")
private String status;
/**
* 是否删除有效0正常/1删除有效
*/
@TableField("is_deleted")
private String isDeleted;
/**
* 创建人
*/
@TableField("create_user")
private Long createUser;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 修改人
*/
@TableField("update_user")
private Long updateUser;
/**
* 修改时间
*/
@JsonIgnore
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}

104
common/src/main/java/com/yyy/common/core/domain/entity/UmsRole.java

@ -0,0 +1,104 @@
package com.yyy.common.core.domain.entity;
import java.util.Date;
import java.util.List;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* 角色表(UmsRole)表实体类
*
* @author Fangy
* @since 2024-04-03 16:14:03
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "ums_role")
public class UmsRole {
private static final long serialVersionUID = -51781180838006152L;
/**
* 角色ID(主键)
*/
@JsonIgnore
@TableId(value = "role_id", type = IdType.AUTO)
private Long roleId;
/**
* 角色名称
*/
@TableField("role_name")
private String roleName;
/**
* 角色权限字符串
*/
@TableField("role_key")
private String roleKey;
/**
* 显示顺序
*/
@TableField("role_sort")
private Integer roleSort;
/**
* 数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限
*/
@TableField("data_scope")
private String dataScope;
/**
* 角色状态0正常/1停用
*/
@TableField("status")
private String status;
/**
* 是否删除0正常/1删除
*/
@TableField("is_deleted")
private String isDeleted;
/**
* 创建人
*/
@TableField("create_user")
private Long createUser;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 修改人
*/
@TableField("update_user")
private Long updateUser;
/**
* 修改时间
*/
@JsonIgnore
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
/**
* 备注
*/
@TableField("remark")
private String remark;
@TableField(exist = false)
private List<UmsMenu> _menus;
}

34
common/src/main/java/com/yyy/common/core/domain/entity/UmsRoleMenu.java

@ -0,0 +1,34 @@
package com.yyy.common.core.domain.entity;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* 角色权限关联表(UmsRoleMenu)表实体类
*
* @author Fangy
* @since 2024-04-12 20:42:25
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "ums_role_menu")
public class UmsRoleMenu {
private static final long serialVersionUID = 686031140857580486L;
/**
* 角色ID(主键)
*/
@TableField("role_id")
private Long roleId;
/**
* 菜单ID(主键)
*/
@TableField("menu_id")
private Long menuId;
}

177
common/src/main/java/com/yyy/common/core/domain/entity/UmsUser.java

@ -0,0 +1,177 @@
package com.yyy.common.core.domain.entity;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.yyy.common.annotation.Excel;
import com.yyy.common.annotation.Excels;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
/**
* 用户表(UmsUser)表实体类
*
* @author Fangy
* @since 2024-03-22 17:47:19
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "ums_user")
public class UmsUser {
private static final long serialVersionUID = -73936105573664937L;
/**
* 用户ID(主键)
*/
@JsonIgnore
@TableId(value = "user_id", type = IdType.AUTO)
@Excel(name = "用户序号", cellType = Excel.ColumnType.NUMERIC, prompt = "用户编号")
private Long userId;
/**
* 登录账号
*/
@TableField("login_name")
@Excel(name = "登录账号")
private String loginName;
/**
* 用户昵称
*/
@TableField("user_name")
@Excel(name = "用户名称")
private String userName;
/**
* 用户邮箱
*/
@Excel(name = "用户邮箱")
@TableField("email")
private String email;
/**
* 联系电话
*/
@TableField("phone")
@Excel(name = "联系电话")
private String phone;
/**
* 密码
*/
@TableField("password")
private String password;
/**
* 盐加密
*/
@TableField("salt")
private String salt;
/**
* 状态0正常/1停用
*/
@TableField("status")
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
private String status;
/**
* 是否删除0正常/1删除
*/
@TableField("is_deleted")
private Integer isDeleted;
/**
* 最后登录IP
*/
@TableField("login_ip")
private String loginIp;
/**
* 最后登录时间
*/
@TableField("login_date")
private Date loginDate;
/**
* 密码最后更新时间
*/
@TableField("pwd_update_date")
private Date pwdUpdateDate;
/**
* 创建人
*/
@TableField("create_user")
private Long createUser;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 修改人
*/
@TableField("update_user")
private Long updateUser;
/**
* 修改时间
*/
@JsonIgnore
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
/**
* 备注
*/
@Excel(name = "备注")
@TableField("remark")
private String remark;
/**
* 用户性别0- 1- 2-未知
*/
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
@TableField("sex")
private String sex;
/**
* 头像路径
*/
@TableField("avatar")
private String avatar;
/**
* 部门对象
*/
@Excels({
@Excel(name = "部门id", targetAttr = "organizationId", type = Excel.Type.EXPORT),
@Excel(name = "部门名称", targetAttr = "organizationName", type = Excel.Type.EXPORT)
})
@TableField(exist = false)
private UmsOrganization _umsOrganization;
@Excels({
@Excel(name = "角色id", targetAttr = "roleId", type = Excel.Type.EXPORT),
@Excel(name = "角色名称", targetAttr = "roleName", type = Excel.Type.EXPORT)
})
@TableField(exist = false)
private UmsRole _umsRole;
public boolean isAdmin() {
return isAdmin(this.userId);
}
public static boolean isAdmin(Long userId) {
return userId != null && 1L == userId;
}
}

34
common/src/main/java/com/yyy/common/core/domain/entity/UmsUserOrganization.java

@ -0,0 +1,34 @@
package com.yyy.common.core.domain.entity;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* 组织信息关联表(UmsUserOrganization)表实体类
*
* @author Fangy
* @since 2024-04-03 14:51:55
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "ums_user_organization")
public class UmsUserOrganization {
private static final long serialVersionUID = 453006522982935793L;
/**
* 组织ID(主键)
*/
@JsonIgnore
private Long organizationId;
/**
* 员工ID(主键)
*/
@JsonIgnore
private Long userId;
}

34
common/src/main/java/com/yyy/common/core/domain/entity/UmsUserRole.java

@ -0,0 +1,34 @@
package com.yyy.common.core.domain.entity;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* 用户角色关联表(UmsUserRole)表实体类
*
* @author Fangy
* @since 2024-04-03 15:06:35
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "ums_user_role")
public class UmsUserRole {
private static final long serialVersionUID = 767125177028822730L;
/**
* 用户ID(主键)
*/
@JsonIgnore
private Long userId;
/**
* 角色ID(主键)
*/
@JsonIgnore
private Long roleId;
}

47
common/src/main/java/com/yyy/common/core/domain/vo/LoginVo.java

@ -0,0 +1,47 @@
package com.yyy.common.core.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Set;
/**
* @Author: fy
* @Date: 2024/04/03
* @Description:
*/
@ApiModel("登陆成功返回信息")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class LoginVo {
@ApiModelProperty("登录账号")
private String loginName;
@ApiModelProperty("用户名称")
private String userName;
@ApiModelProperty("用户头像地址")
private String avatar;
@ApiModelProperty("手机号")
private String phone;
@ApiModelProperty("邮箱")
private String email;
@ApiModelProperty("Token信息")
private String Authorization;
@ApiModelProperty("角色keySet")
private Set<String> roles;
@ApiModelProperty("权限标识Set")
private Set<String> permissions;
}

68
common/src/main/java/com/yyy/common/core/domain/vo/UmsMenuVo.java

@ -0,0 +1,68 @@
package com.yyy.common.core.domain.vo;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import com.yyy.common.core.domain.entity.UmsMenu;
import com.yyy.common.utils.bean.BeanUtils;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 菜单表(UmsMenu)视图数据类
*
* @author Fangy
* @since 2024-04-03 17:18:31
*/
@ApiModel("UmsMenuVo菜单表视图数据类")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UmsMenuVo {
@ApiModelProperty("菜单ID")
private Long menuId;
@ApiModelProperty("菜单名称")
private String menuName;
@ApiModelProperty("父主键ID")
private Long parentId;
@ApiModelProperty("排序")
private Integer sort;
@ApiModelProperty("请求路径")
private String url;
@ApiModelProperty("菜单类型(M目录 C菜单 F按钮)")
private String menuType;
@ApiModelProperty("菜单状态(1隐藏 0显示)")
private String visible;
@ApiModelProperty("权限标识")
private String permission;
@ApiModelProperty("菜单图标")
private String icon;
@ApiModelProperty("备注")
private String remark;
public static UmsMenuVo ToVo(UmsMenu umsMenu) {
UmsMenuVo umsMenuVo = new UmsMenuVo();
BeanUtils.copyProperties(umsMenu, umsMenuVo);
return umsMenuVo;
}
public static List<UmsMenuVo> ToVo(List<UmsMenu> umsMenus) {
return umsMenus.stream().map(UmsMenuVo::ToVo).collect(Collectors.toList());
}
}

52
common/src/main/java/com/yyy/common/core/domain/vo/UmsOrganizationVo.java

@ -0,0 +1,52 @@
package com.yyy.common.core.domain.vo;
import java.util.List;
import java.util.stream.Collectors;
import com.yyy.common.core.domain.entity.UmsOrganization;
import com.yyy.common.utils.bean.BeanUtils;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 组织信息表(UmsOrganization)视图数据类
*
* @author Fangy
* @since 2024-04-03 09:47:09
*/
@ApiModel("UmsOrganizationVo组织信息表视图数据类")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UmsOrganizationVo {
@ApiModelProperty("组织ID")
private Long organizationId;
@ApiModelProperty("组织名称")
private String organizationName;
@ApiModelProperty("组织类型(0:公司/1:部门/2:岗位)")
private String organizationType;
@ApiModelProperty("显示顺序")
private Integer orderNum;
@ApiModelProperty("父组织id")
private Long parentId;
@ApiModelProperty("深度")
private String depth;
@ApiModelProperty("状态(0:正常/1:停用)")
private String status;
public static UmsOrganizationVo ToVo(UmsOrganization umsOrganization) {
UmsOrganizationVo umsOrganizationVo = new UmsOrganizationVo();
BeanUtils.copyProperties(umsOrganization, umsOrganizationVo);
return umsOrganizationVo;
}
public static List<UmsOrganizationVo> ToVo(List<UmsOrganization> umsOrganizations) {
return umsOrganizations.stream().map(UmsOrganizationVo::ToVo).collect(Collectors.toList());
}
}

60
common/src/main/java/com/yyy/common/core/domain/vo/UmsRoleVo.java

@ -0,0 +1,60 @@
package com.yyy.common.core.domain.vo;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import com.yyy.common.core.domain.entity.UmsMenu;
import com.yyy.common.core.domain.entity.UmsRole;
import com.yyy.common.utils.bean.BeanUtils;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 角色表(UmsRole)视图数据类
*
* @author Fangy
* @since 2024-04-03 16:33:28
*/
@ApiModel("UmsRoleVo角色表视图数据类")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UmsRoleVo {
@ApiModelProperty("角色ID")
private Long roleId;
@ApiModelProperty("角色名称")
private String roleName;
@ApiModelProperty("角色权限字符串")
private String roleKey;
@ApiModelProperty("显示顺序")
private Integer roleSort;
@ApiModelProperty("角色状态(0:正常/1:停用)")
private String status;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("菜单权限")
private List<UmsMenu> _menus;
public static UmsRoleVo ToVo(UmsRole umsRole) {
UmsRoleVo umsRoleVo = new UmsRoleVo();
BeanUtils.copyProperties(umsRole, umsRoleVo);
return umsRoleVo;
}
public static List<UmsRoleVo> ToVo(List<UmsRole> umsRoles) {
return umsRoles.stream().map(UmsRoleVo::ToVo).collect(Collectors.toList());
}
}

69
common/src/main/java/com/yyy/common/core/domain/vo/UmsUserVo.java

@ -0,0 +1,69 @@
package com.yyy.common.core.domain.vo;
import com.yyy.common.core.domain.entity.UmsOrganization;
import com.yyy.common.core.domain.entity.UmsRole;
import com.yyy.common.core.domain.entity.UmsUser;
import com.yyy.common.utils.bean.BeanUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.util.List;
import java.util.stream.Collectors;
/**
* 用户表(UmsUser)视图数据类
*
* @author Fangy
* @since 2024-03-25 11:07:54
*/
@ApiModel("用户表(UmsUser)视图数据类")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UmsUserVo {
@ApiModelProperty("用户ID(主键)")
private Long userId;
@ApiModelProperty("用户昵称")
private String userName;
@ApiModelProperty("登录账号")
private String loginName;
@ApiModelProperty("用户邮箱")
private String email;
@ApiModelProperty("联系电话")
private String phone;
@ApiModelProperty("状态(0-在职 1-离职)")
private String status;
@ApiModelProperty("用户性别(0-男 1-女 2-未知)")
private String sex;
@ApiModelProperty("头像路径")
private String avatar;
@ApiModelProperty("岗位信息")
private UmsOrganization _umsOrganization;
@ApiModelProperty("角色信息")
private UmsRole _umsRole;
public static UmsUserVo ToVo(UmsUser umsUser) {
UmsUserVo umsUserVo = new UmsUserVo();
BeanUtils.copyProperties(umsUser,umsUserVo);
return umsUserVo;
}
public static List<UmsUserVo> ToVo(List<UmsUser> umsUsers) {
return umsUsers.stream().map(UmsUserVo::ToVo).collect(Collectors.toList());
}
}

89
common/src/main/java/com/yyy/common/core/page/PageDomain.java

@ -0,0 +1,89 @@
package com.yyy.common.core.page;
import com.yyy.common.utils.common.StringUtils;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:分页数据
*/
public class PageDomain
{
/** 当前记录起始索引 */
private Integer pageNum;
/** 每页显示记录数 */
private Integer pageSize;
/** 排序列 */
private String orderByColumn;
/** 排序的方向desc或者asc */
private String isAsc = "asc";
/** 分页参数合理化 */
private Boolean reasonable = true;
public String getOrderBy()
{
if (StringUtils.isEmpty(orderByColumn))
{
return "";
}
return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;
}
public Integer getPageNum()
{
return pageNum;
}
public void setPageNum(Integer pageNum)
{
this.pageNum = pageNum;
}
public Integer getPageSize()
{
return pageSize;
}
public void setPageSize(Integer pageSize)
{
this.pageSize = pageSize;
}
public String getOrderByColumn()
{
return orderByColumn;
}
public void setOrderByColumn(String orderByColumn)
{
this.orderByColumn = orderByColumn;
}
public String getIsAsc()
{
return isAsc;
}
public void setIsAsc(String isAsc)
{
this.isAsc = isAsc;
}
public Boolean getReasonable()
{
if (StringUtils.isNull(reasonable))
{
return Boolean.TRUE;
}
return reasonable;
}
public void setReasonable(Boolean reasonable)
{
this.reasonable = reasonable;
}
}

85
common/src/main/java/com/yyy/common/core/page/TableDataInfo.java

@ -0,0 +1,85 @@
package com.yyy.common.core.page;
import java.io.Serializable;
import java.util.List;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:表格分页数据对象
*/
public class TableDataInfo implements Serializable
{
private static final long serialVersionUID = 1L;
/** 总记录数 */
private long total;
/** 列表数据 */
private List<?> rows;
/** 消息状态码 */
private int code;
/** 消息内容 */
private String msg;
/**
* 表格数据对象
*/
public TableDataInfo()
{
}
/**
* 分页
*
* @param list 列表数据
* @param total 总记录数
*/
public TableDataInfo(List<?> list, int total)
{
this.rows = list;
this.total = total;
}
public long getTotal()
{
return total;
}
public void setTotal(long total)
{
this.total = total;
}
public List<?> getRows()
{
return rows;
}
public void setRows(List<?> rows)
{
this.rows = rows;
}
public int getCode()
{
return code;
}
public void setCode(int code)
{
this.code = code;
}
public String getMsg()
{
return msg;
}
public void setMsg(String msg)
{
this.msg = msg;
}
}

56
common/src/main/java/com/yyy/common/core/page/TableSupport.java

@ -0,0 +1,56 @@
package com.yyy.common.core.page;
import com.yyy.common.core.text.Convert;
import com.yyy.common.utils.common.ServletUtils;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:表格数据处理
*/
public class TableSupport
{
/**
* 当前记录起始索引
*/
public static final String PAGE_NUM = "pageNum";
/**
* 每页显示记录数
*/
public static final String PAGE_SIZE = "pageSize";
/**
* 排序列
*/
public static final String ORDER_BY_COLUMN = "orderByColumn";
/**
* 排序的方向 "desc" 或者 "asc".
*/
public static final String IS_ASC = "isAsc";
/**
* 分页参数合理化
*/
public static final String REASONABLE = "reasonable";
/**
* 封装分页对象
*/
public static PageDomain getPageDomain()
{
PageDomain pageDomain = new PageDomain();
pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1));
pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10));
pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE));
return pageDomain;
}
public static PageDomain buildPageRequest()
{
return getPageDomain();
}
}

118
common/src/main/java/com/yyy/common/core/qr/PdfCellUtill.java

@ -0,0 +1,118 @@
package com.yyy.common.core.qr;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
/**
* @Author: fy
* @Date: 2024/03/19
* @Description:二维码生成工具
*/
public class PdfCellUtill {
private static PdfPCell pdfCell;
/**
* 创建PdfCell
* @param content 内容文本短语
* @param font 字体
* @return 返回PdfCell
*/
public static PdfPCell createCell(String content,Font font){
pdfCell = new PdfPCell(new Phrase(content, font));
pdfCell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
pdfCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
pdfCell.setBorder(0);
return pdfCell;
}
/**
*
* 创建PdfCell
* @param content 内容文本短语
* @param font 字体
* @param horizontalAlignment 水平位置对齐
* @param verticalAlignment 垂直位置对齐
* @return 返回PdfCell
*/
public static PdfPCell createCell(String content,Font font,int horizontalAlignment,int verticalAlignment){
pdfCell = new PdfPCell(new Phrase(content, font));
pdfCell.setHorizontalAlignment(horizontalAlignment);
pdfCell.setVerticalAlignment(verticalAlignment);
pdfCell.setBorder(0);
return pdfCell;
}
/**
*
* 创建PdfCell
* @param content 内容文本短语
* @param font 字体
* @param horizontalAlignment 水平位置对齐
* @param verticalAlignment 垂直位置对齐
* @param colspan 合并列数
* @param rowspan 合并行数
* @return 返回PdfCell
*/
public static PdfPCell createCell(String content,Font font,int horizontalAlignment,int verticalAlignment ,int colspan,int rowspan){
pdfCell = new PdfPCell(new Phrase(content, font));
pdfCell.setHorizontalAlignment(horizontalAlignment);
pdfCell.setVerticalAlignment(verticalAlignment);
if(colspan>0){
pdfCell.setColspan(colspan);
}
if(rowspan>0){
pdfCell.setRowspan(rowspan);
}
pdfCell.setBorder(0);
return pdfCell;
}
/**
*
* @param content 内容文本段落
* @param font 字体
* @return 返回PdfCell
*/
public static PdfPCell createCellParagraph(String content,Font font){
pdfCell = new PdfPCell(new Paragraph(content, font));
pdfCell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
pdfCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
pdfCell.setBorder(0);
return pdfCell;
}
/**
*
* @param content 内容文本段落
* @param font 字体
* @param horizontalAlignment 水平对齐
* @param verticalAlignment 垂直位置对齐
* @return 返回PdfCell
*/
public static PdfPCell createCellParagraph(String content,Font font,int horizontalAlignment,int verticalAlignment){
pdfCell = new PdfPCell(new Paragraph(content, font));
pdfCell.setHorizontalAlignment(horizontalAlignment);
pdfCell.setVerticalAlignment(verticalAlignment);
pdfCell.setBorder(0);
return pdfCell;
}
/**
*
* @param content 内容文本段落
* @param font 字体
* @param horizontalAlignment 水平对齐
* @param verticalAlignment 垂直位置对齐
* @param colspan 合并列数
* @param rowspan 合并行数
* @return 返回PdfCell
*/
public static PdfPCell createCellParagraph(String content,Font font,int horizontalAlignment,int verticalAlignment,int colspan,int rowspan){
pdfCell = new PdfPCell(new Paragraph(content, font));
pdfCell.setHorizontalAlignment(horizontalAlignment);
pdfCell.setVerticalAlignment(verticalAlignment);
if(colspan>0){
pdfCell.setColspan(colspan);
}
if(rowspan>0){
pdfCell.setRowspan(rowspan);
}
pdfCell.setBorder(0);
return pdfCell;
}
}

197
common/src/main/java/com/yyy/common/core/qr/QrCodeManageAction.java

@ -0,0 +1,197 @@
package com.yyy.common.core.qr;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
/**
* @Author: fy
* @Date: 2024/03/19
* @Description:
*/
@Component
public class QrCodeManageAction {
@Autowired
private QrConfig config;
@Value("${app.profile}")
private String path;
@Value("${qr.ttf}")
private String ttf;
/**
* 预览二维码信息并可批量打印
*
* @return
*/
public void printQr(String name, String code, String date, String organization, HttpServletResponse response) {
response.setContentType("application/pdf");
try {
response.setHeader("content-disposition", "filename=qr.pdf");
OutputStream out = response.getOutputStream();
float[] rectSize = {4, 1, 4, 2};
printQrInfo(out, rectSize, name, code, date, organization);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 预览打印二维码pdf
*
*/
public void printQrInfo(OutputStream out, float[] rectSize, String name, String code, String date, String organization) throws IOException, DocumentException {
// SIMHEI.TTF 文件字体文件,可下载至本地 ,此处更改为相应本地地址
BaseFont bfChinese = BaseFont.createFont(path + ttf, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Rectangle rect = new Rectangle(170F, 85.0F);// A4纸张
rect.setBackgroundColor(BaseColor.WHITE);
//方正小标送简 常规 -标签标题
BaseFont bfChinese1 = BaseFont.createFont(path + ttf, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font song22 = new Font(bfChinese1, 8, Font.BOLD);
BaseFont bfChinese2 = BaseFont.createFont(path + ttf, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font fang16 = new Font(bfChinese2, 6, Font.BOLD);
BaseFont bfChinese3 = BaseFont.createFont(path + ttf, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font kai16 = new Font(bfChinese3, 7, Font.BOLD);
//西文 16号 Times New Roman
BaseFont bfChinese4 = BaseFont.createFont(path + ttf, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font roman16 = new Font(bfChinese4, 7, Font.BOLD);
//人名 方正行楷 FZXKJW.TTF
BaseFont bfChinese5 = BaseFont.createFont(path + ttf, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font fzxk16 = new Font(bfChinese5, 9);
Document doc = new Document(rect, rectSize[0], rectSize[1], rectSize[2], rectSize[3]);
PdfWriter writer = PdfWriter.getInstance(doc, out);
writer.setPdfVersion(PdfWriter.PDF_VERSION_1_2);
//文档属性
doc.addTitle("资产信息");
doc.open();
//加入内容
PdfPTable tab = new PdfPTable(1);
PdfPCell cell = new PdfPCell();
// for (int i = 0; i < infos.size(); i++) {
// createPrintQrInfo(doc, tab, cell, song22, fang16, kai16, roman16, fzxk16);
// }
createPrintQrInfo(doc, tab, cell, song22, fang16, kai16, roman16, fzxk16, name, code, date, organization);
doc.newPage();
doc.close();
}
private void createPrintQrInfo(Document doc, PdfPTable tab, PdfPCell cell, Font titleFont1, Font valueFont, Font kai16, Font roman16, Font fzxk16, String name, String code, String date, String organization) throws DocumentException {
//这里打印的是 60mm * 30mm 大小的标签,故这里参数很重要
int[] cellWidth = {35, 70, 65};
tab = new PdfPTable(3);
tab.setLockedWidth(true);
tab.setTotalWidth(165);
tab.getDefaultCell().setMinimumHeight(15f);
tab.setHorizontalAlignment(Element.ALIGN_CENTER);
tab.setWidths(cellWidth);
//cell = PdfCellUtill.createCell(ObjUtils.defaultIfNull("", titleFont1, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 3, 0));
// String content = (titleFont1 != null) ? titleFont1.toString() : "";
String content = "";
cell = PdfCellUtill.createCell(content, titleFont1);
cell.setFixedHeight(15f);
cell.setBorderWidthTop(0.5f);
cell.setBorderWidthLeft(0.5f);
cell.setBorderWidthRight(0.5f);
cell.setUseAscender(true);
cell.setVerticalAlignment(cell.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_CENTER); //水平居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //垂直居中
tab.addCell(cell);
cell = PdfCellUtill.createCell("资产名称", kai16, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 1, 0);
cell.setFixedHeight(15f);
cell.setBorderWidthTop(0.5f);
cell.setBorderWidthLeft(0.5f);
tab.addCell(cell);
cell = PdfCellUtill.createCell(name, valueFont, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 1, 0);
cell.setBorderWidthTop(0.5f);
cell.setBorderWidthLeft(0.5f);
cell.setBorderWidthRight(0.5f);
tab.addCell(cell);
Image imageQjPhoto = null;
// 二维码图片路径
try {
imageQjPhoto = Image.getInstance(QrCodeUtil.generate(code, config), null);
// 调整二维码图片大小
imageQjPhoto.scaleAbsolute(30, 30); // 设置宽度和高度
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
cell = PdfCellUtill.createCell("", valueFont, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 1, 4);
cell.setBorderWidthTop(0.5f);
cell.setBorderWidthLeft(0.5f);
cell.setBorderWidthRight(0.5f);
cell.setBorderWidthBottom(0.5f);
cell.addElement(imageQjPhoto);
tab.addCell(cell);
cell = PdfCellUtill.createCell("资产编号", kai16, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 1, 0);
cell.setFixedHeight(15f);
cell.setBorderWidthTop(0.5f);
cell.setBorderWidthLeft(0.5f);
tab.addCell(cell);
cell = PdfCellUtill.createCell(code, roman16, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 1, 0);
cell.setBorderWidthTop(0.5f);
cell.setBorderWidthLeft(0.5f);
cell.setBorderWidthRight(0.5f);
tab.addCell(cell);
cell = PdfCellUtill.createCell("购置日期", kai16, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 1, 0);
cell.setFixedHeight(15f);
cell.setBorderWidthTop(0.5f);
cell.setBorderWidthLeft(0.5f);
tab.addCell(cell);
cell = PdfCellUtill.createCell(date, roman16, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 1, 0);
cell.setBorderWidthTop(0.5f);
cell.setBorderWidthLeft(0.5f);
cell.setBorderWidthRight(0.5f);
tab.addCell(cell);
cell = PdfCellUtill.createCell("使用部门", kai16, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, 1, 0);
cell.setFixedHeight(15f);
cell.setBorderWidthTop(0.5f);
cell.setBorderWidthLeft(0.5f);
cell.setUseAscender(true);
cell.setVerticalAlignment(cell.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_CENTER); //水平居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //垂直居中
cell.setBorderWidthBottom(0.5f);
tab.addCell(cell);
cell = PdfCellUtill.createCell(organization, fzxk16, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 1, 0);
cell.setBorderWidthTop(0.5f);
cell.setBorderWidthLeft(0.5f);
cell.setBorderWidthRight(0.5f);
cell.setBorderWidthBottom(0.5f);
tab.addCell(cell);
doc.add(tab);
}
}

88
common/src/main/java/com/yyy/common/core/text/CharsetKit.java

@ -0,0 +1,88 @@
package com.yyy.common.core.text;
import com.yyy.common.utils.common.StringUtils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* 字符集工具类
*
* @author ruoyi
*/
public class CharsetKit
{
/** ISO-8859-1 */
public static final String ISO_8859_1 = "ISO-8859-1";
/** UTF-8 */
public static final String UTF_8 = "UTF-8";
/** GBK */
public static final String GBK = "GBK";
/** ISO-8859-1 */
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
/** UTF-8 */
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
/** GBK */
public static final Charset CHARSET_GBK = Charset.forName(GBK);
/**
* 转换为Charset对象
*
* @param charset 字符集为空则返回默认字符集
* @return Charset
*/
public static Charset charset(String charset)
{
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1
* @param destCharset 目标字符集默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, String srcCharset, String destCharset)
{
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1
* @param destCharset 目标字符集默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, Charset srcCharset, Charset destCharset)
{
if (null == srcCharset)
{
srcCharset = StandardCharsets.ISO_8859_1;
}
if (null == destCharset)
{
destCharset = StandardCharsets.UTF_8;
}
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
{
return source;
}
return new String(source.getBytes(srcCharset), destCharset);
}
/**
* @return 系统字符集编码
*/
public static String systemCharset()
{
return Charset.defaultCharset().name();
}
}

1007
common/src/main/java/com/yyy/common/core/text/Convert.java

File diff suppressed because it is too large

93
common/src/main/java/com/yyy/common/core/text/StrFormatter.java

@ -0,0 +1,93 @@
package com.yyy.common.core.text;
import com.yyy.common.utils.common.StringUtils;
/**
* 字符串格式化
*
* @author ruoyi
*/
public class StrFormatter
{
public static final String EMPTY_JSON = "{}";
public static final char C_BACKSLASH = '\\';
public static final char C_DELIM_START = '{';
public static final char C_DELIM_END = '}';
/**
* 格式化字符串<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* <br>
* 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param strPattern 字符串模板
* @param argArray 参数列表
* @return 结果
*/
public static String format(final String strPattern, final Object... argArray)
{
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
{
return strPattern;
}
final int strPatternLength = strPattern.length();
// 初始化定义好的长度以获得更好的性能
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
int handledPosition = 0;
int delimIndex;// 占位符所在位置
for (int argIndex = 0; argIndex < argArray.length; argIndex++)
{
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
if (delimIndex == -1)
{
if (handledPosition == 0)
{
return strPattern;
}
else
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
sbuf.append(strPattern, handledPosition, strPatternLength);
return sbuf.toString();
}
}
else
{
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
{
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
{
// 转义符之前还有一个转义符,占位符依旧有效
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
else
{
// 占位符被转义
argIndex--;
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(C_DELIM_START);
handledPosition = delimIndex + 1;
}
}
else
{
// 正常占位符
sbuf.append(strPattern, handledPosition, delimIndex);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
}
}
// 加入最后一个占位符后所有的字符
sbuf.append(strPattern, handledPosition, strPattern.length());
return sbuf.toString();
}
}

40
common/src/main/java/com/yyy/common/enums/AssetStatusEnum.java

@ -0,0 +1,40 @@
package com.yyy.common.enums;
public enum AssetStatusEnum {
UN_USEd(0, "闲置"),
IN_USE(1, "在用"),
BORROW(2, "借用中"),
REPAIR(3,"维修中"),
ALLOCATE(4, "调拨中"),
TOBE_SCRAPPED(5, "待报废"),
DISPOSED(6,"已处置"),
INVENTORY(7, "库存"),
SCRAPPED(8, "已报废");
private final Integer code;
private final String info;
AssetStatusEnum(Integer code, String info)
{
this.code = code;
this.info = info;
}
public Integer getCode()
{
return code;
}
public String getInfo()
{
return info;
}
public static String getInfoByCode(int code) {
for (AssetStatusEnum status : AssetStatusEnum.values()) {
if (status.getCode() == code) {
return status.getInfo();
}
}
return "Unknown";
}
}

29
common/src/main/java/com/yyy/common/enums/BusinessStatusEnum.java

@ -0,0 +1,29 @@
package com.yyy.common.enums;
public enum BusinessStatusEnum {
DRAFT(0, "草稿"),
COMPLETED(1, "已完成"),
REJECTED(2, "拒绝"),
APPROVED(3,"审批中"),
CANCELED(4, "取消"),
UNKNOWN(5, "未知");
private final Integer code;
private final String info;
BusinessStatusEnum(Integer code, String info)
{
this.code = code;
this.info = info;
}
public Integer getCode()
{
return code;
}
public String getInfo()
{
return info;
}
}

23
common/src/main/java/com/yyy/common/enums/ConfigEnum.java

@ -0,0 +1,23 @@
package com.yyy.common.enums;
public enum ConfigEnum {
DEFAULT_ROLE_ID(0, "3");
private final Integer code;
private final String info;
ConfigEnum(Integer code, String info)
{
this.code = code;
this.info = info;
}
public Integer getCode()
{
return code;
}
public String getInfo()
{
return info;
}
}

37
common/src/main/java/com/yyy/common/enums/DetectTypeEnum.java

@ -0,0 +1,37 @@
package com.yyy.common.enums;
public enum DetectTypeEnum {
ALLOCATE("allocate", "资产调拨"),
BORROW("borrow", "资产借用"),
COLLECTION("collection", "资产领用"),
OUTBOUND("outbound", "资产出库"),
REGISTRATION("registration","资产登记"),
RETURN("return", "资产归还"),
RETURN_INVENTORY("return_inventory", "资产退库"),
STORAGE("storage", "资产入库"),
TRANSFER("transfer", "资产转移"),
REPAIR_FAULT("repair_fault", "故障登记"),
REPAIR("repair", "设备报修"),
RETIREMENT("retirement", "资产报废"),
CLEAN("clean", "资产清理"),
UNKNOWN("null", "未知操作");
private final String code;
private final String info;
DetectTypeEnum(String code, String info)
{
this.code = code;
this.info = info;
}
public String getCode()
{
return code;
}
public String getInfo()
{
return info;
}
}

43
common/src/main/java/com/yyy/common/enums/EncodingEum.java

@ -0,0 +1,43 @@
package com.yyy.common.enums;
import com.yyy.common.utils.uuid.SnowFlakeUtil;
public enum EncodingEum {
ASSET("AS", "资产信息"),
ALLOCATE("AL", "资产调拨"),
BORROW("BR", "资产借用"),
COLLECTION("CO", "资产领用"),
OUTBOUND("OU", "资产出库"),
REGISTRATION("REG","资产登记"),
RETURN("RET", "资产归还"),
RETURN_INVENTORY("REI", "资产退库"),
STORAGE("ST", "资产入库"),
TRANSFER("TR", "资产转移"),
REPAIR_FAULT("REF", "故障登记"),
REPAIR("REP", "设备报修"),
RETIREMENT("REM", "资产报废"),
UNKNOWN("null", "未知操作");
private final String code;
private final String info;
EncodingEum(String code, String info)
{
this.code = code;
this.info = info;
}
public String getCode()
{
return code;
}
public String getInfo()
{
return info;
}
public String getBusinessId(){
return this.code + SnowFlakeUtil.getDefaultSnowFlakeId();
}
}

39
common/src/main/java/com/yyy/common/enums/OrganizationTypeEnum.java

@ -0,0 +1,39 @@
package com.yyy.common.enums;
/**
* 用户状态
*/
public enum OrganizationTypeEnum {
COMPANY("0", "公司"),
DEPARTMENT("1", "部门"),
POST("2", "岗位");
private final String code;
private final String info;
OrganizationTypeEnum(String code, String info) {
this.code = code;
this.info = info;
}
public String getCode() {
return code;
}
public String getInfo() {
return info;
}
public static String enable(String parentCode, String childrenCode) {
if (parentCode.equals(DEPARTMENT.code) && childrenCode.equals(COMPANY.code)){
return "部门下不能创建公司!";
}else if(parentCode.equals(POST.code)){
if (childrenCode.equals(COMPANY.code)){
return "岗位下不能创建公司!";
}else if (childrenCode.equals(DEPARTMENT.code)){
return "岗位下不能创建部门!";
}
}
return null;
}
}

35
common/src/main/java/com/yyy/common/enums/ScrapTypeEnum.java

@ -0,0 +1,35 @@
package com.yyy.common.enums;
public enum ScrapTypeEnum {
DAMAGED(1, "损坏"),
EXPIRED(2, "过期"),
LOST(3,"丢失");
private final Integer code;
private final String info;
ScrapTypeEnum(Integer code, String info)
{
this.code = code;
this.info = info;
}
public Integer getCode()
{
return code;
}
public String getInfo()
{
return info;
}
public static String getInfoByCode(int code) {
for (ScrapTypeEnum status : ScrapTypeEnum.values()) {
if (status.getCode() == code) {
return status.getInfo();
}
}
return "其他";
}
}

29
common/src/main/java/com/yyy/common/enums/SexEnum.java

@ -0,0 +1,29 @@
package com.yyy.common.enums;
/**
* @Author: fy
* @Date: 2024/04/02
* @Description:
*/
public enum SexEnum {
MAN("0", "男"), WOMAN("1", "女"), UNKNOWN("2", "未知");
private final String code;
private final String info;
SexEnum(String code, String info)
{
this.code = code;
this.info = info;
}
public String getCode()
{
return code;
}
public String getInfo()
{
return info;
}
}

28
common/src/main/java/com/yyy/common/enums/StockTackingDetailStatusEnum.java

@ -0,0 +1,28 @@
package com.yyy.common.enums;
public enum StockTackingDetailStatusEnum {
SURPLUS(0, "盘盈"),
SHORTAGE(1, "盘亏"),
COMPLETED(2, "已盘点"),
PENDING(3, "待盘点"),
EXCEPTION(4, "异常");
private final Integer code;
private final String info;
StockTackingDetailStatusEnum(Integer code, String info) {
this.code = code;
this.info = info;
}
public Integer getCode() {
return code;
}
public String getInfo() {
return info;
}
}

24
common/src/main/java/com/yyy/common/enums/StocktakingStatusEnum.java

@ -0,0 +1,24 @@
package com.yyy.common.enums;
public enum StocktakingStatusEnum {
NOT_STARTED(0, "未开始"),
IN_PROGRESS(1, "进行中"),
CANCELLED(2, "取消"),
COMPLETED(3, "已完成");
private final Integer code;
private final String info;
StocktakingStatusEnum(Integer code, String info) {
this.code = code;
this.info = info;
}
public Integer getCode() {
return code;
}
public String getInfo() {
return info;
}
}

28
common/src/main/java/com/yyy/common/enums/UserStatusEnum.java

@ -0,0 +1,28 @@
package com.yyy.common.enums;
/**
* 用户状态
*/
public enum UserStatusEnum
{
OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除");
private final String code;
private final String info;
UserStatusEnum(String code, String info)
{
this.code = code;
this.info = info;
}
public String getCode()
{
return code;
}
public String getInfo()
{
return info;
}
}

41
common/src/main/java/com/yyy/common/exception/CustomException.java

@ -0,0 +1,41 @@
package com.yyy.common.exception;
/**
* 自定义异常
*/
public class CustomException extends RuntimeException
{
private static final long serialVersionUID = 1L;
private Integer code;
private String message;
public CustomException(String message)
{
this.message = message;
}
public CustomException(String message, Integer code)
{
this.message = message;
this.code = code;
}
public CustomException(String message, Throwable e)
{
super(message, e);
this.message = message;
}
@Override
public String getMessage()
{
return message;
}
public Integer getCode()
{
return code;
}
}

13
common/src/main/java/com/yyy/common/exception/DemoModeException.java

@ -0,0 +1,13 @@
package com.yyy.common.exception;
/**
* 演示模式异常
*/
public class DemoModeException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public DemoModeException()
{
}
}

56
common/src/main/java/com/yyy/common/exception/GlobalException.java

@ -0,0 +1,56 @@
package com.yyy.common.exception;
/**
* 全局异常
*/
public class GlobalException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 错误提示
*/
private String message;
/**
* 错误明细内部调试错误
*
* {@link CommonResult#getDetailMessage()} 一致的设计
*/
private String detailMessage;
/**
* 空构造方法避免反序列化问题
*/
public GlobalException()
{
}
public GlobalException(String message)
{
this.message = message;
}
public String getDetailMessage()
{
return detailMessage;
}
public GlobalException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
@Override
public String getMessage()
{
return message;
}
public GlobalException setMessage(String message)
{
this.message = message;
return this;
}
}

56
common/src/main/java/com/yyy/common/exception/ServiceException.java

@ -0,0 +1,56 @@
package com.yyy.common.exception;
/**
* 业务异常
*/
public final class ServiceException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 错误提示
*/
private String message;
/**
* 错误明细内部调试错误
*
* {@link CommonResult#getDetailMessage()} 一致的设计
*/
private String detailMessage;
/**
* 空构造方法避免反序列化问题
*/
public ServiceException()
{
}
public ServiceException(String message)
{
this.message = message;
}
public String getDetailMessage()
{
return detailMessage;
}
public ServiceException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
@Override
public String getMessage()
{
return message;
}
public ServiceException setMessage(String message)
{
this.message = message;
return this;
}
}

24
common/src/main/java/com/yyy/common/exception/UtilException.java

@ -0,0 +1,24 @@
package com.yyy.common.exception;
/**
* 工具类异常
*/
public class UtilException extends RuntimeException
{
private static final long serialVersionUID = 8247610319171014183L;
public UtilException(Throwable e)
{
super(e.getMessage(), e);
}
public UtilException(String message)
{
super(message);
}
public UtilException(String message, Throwable throwable)
{
super(message, throwable);
}
}

21
common/src/main/java/com/yyy/common/exception/base/BaseException.java

@ -0,0 +1,21 @@
package com.yyy.common.exception.base;
import com.yyy.common.core.domain.Result;
import lombok.Getter;
/**
* @Author: fy
* @Date: 2024/03/21
* @Description:通用异常
*/
@Getter
public class BaseException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final Result result;
public BaseException(Result result) {
this.result = result;
}
}

17
common/src/main/java/com/yyy/common/exception/file/FileException.java

@ -0,0 +1,17 @@
package com.yyy.common.exception.file;
import com.yyy.common.core.domain.Result;
import com.yyy.common.exception.base.BaseException;
/**
* 文件信息异常类
*/
public class FileException extends BaseException {
private static final long serialVersionUID = 1L;
public FileException(String code, Object[] args) {
super(new Result(Integer.parseInt(code), "[FileException]:" + args.toString()));
}
}

13
common/src/main/java/com/yyy/common/exception/file/FileNameLengthLimitExceededException.java

@ -0,0 +1,13 @@
package com.yyy.common.exception.file;
/**
* 文件名称超长限制异常类
*
*/
public class FileNameLengthLimitExceededException extends FileException {
private static final long serialVersionUID = 1L;
public FileNameLengthLimitExceededException(int defaultFileNameLength) {
super("upload.filename.exceed.length", new Object[]{defaultFileNameLength});
}
}

14
common/src/main/java/com/yyy/common/exception/file/FileSizeLimitExceededException.java

@ -0,0 +1,14 @@
package com.yyy.common.exception.file;
/**
* 文件名大小限制异常类
*/
public class FileSizeLimitExceededException extends FileException
{
private static final long serialVersionUID = 1L;
public FileSizeLimitExceededException(long defaultMaxSize)
{
super("upload.exceed.maxSize", new Object[] { defaultMaxSize });
}
}

59
common/src/main/java/com/yyy/common/exception/file/FileUploadException.java

@ -0,0 +1,59 @@
package com.yyy.common.exception.file;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* 文件上传异常类
*/
public class FileUploadException extends Exception
{
private static final long serialVersionUID = 1L;
private final Throwable cause;
public FileUploadException()
{
this(null, null);
}
public FileUploadException(final String msg)
{
this(msg, null);
}
public FileUploadException(String msg, Throwable cause)
{
super(msg);
this.cause = cause;
}
@Override
public void printStackTrace(PrintStream stream)
{
super.printStackTrace(stream);
if (cause != null)
{
stream.println("Caused by:");
cause.printStackTrace(stream);
}
}
@Override
public void printStackTrace(PrintWriter writer)
{
super.printStackTrace(writer);
if (cause != null)
{
writer.println("Caused by:");
cause.printStackTrace(writer);
}
}
@Override
public Throwable getCause()
{
return cause;
}
}

78
common/src/main/java/com/yyy/common/exception/file/InvalidExtensionException.java

@ -0,0 +1,78 @@
package com.yyy.common.exception.file;
import java.util.Arrays;
/**
* 文件上传 误异常类
*/
public class InvalidExtensionException extends FileUploadException
{
private static final long serialVersionUID = 1L;
private String[] allowedExtension;
private String extension;
private String filename;
public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
{
super("文件[" + filename + "]后缀[" + extension + "]不正确,请上传" + Arrays.toString(allowedExtension) + "格式");
this.allowedExtension = allowedExtension;
this.extension = extension;
this.filename = filename;
}
public String[] getAllowedExtension()
{
return allowedExtension;
}
public String getExtension()
{
return extension;
}
public String getFilename()
{
return filename;
}
public static class InvalidImageExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
public static class InvalidFlashExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
public static class InvalidMediaExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
public static class InvalidVideoExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
}

32
common/src/main/java/com/yyy/common/exception/job/TaskException.java

@ -0,0 +1,32 @@
package com.yyy.common.exception.job;
/**
* 计划策略异常
*/
public class TaskException extends Exception
{
private static final long serialVersionUID = 1L;
private Code code;
public TaskException(String msg, Code code)
{
this(msg, code, null);
}
public TaskException(String msg, Code code, Exception nestedEx)
{
super(msg, nestedEx);
this.code = code;
}
public Code getCode()
{
return code;
}
public enum Code
{
TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE
}
}

14
common/src/main/java/com/yyy/common/exception/user/BlackListException.java

@ -0,0 +1,14 @@
package com.yyy.common.exception.user;
/**
* 黑名单IP异常类
*/
public class BlackListException extends UserException
{
private static final long serialVersionUID = 1L;
public BlackListException()
{
super("login.blocked", null);
}
}

16
common/src/main/java/com/yyy/common/exception/user/CaptchaException.java

@ -0,0 +1,16 @@
package com.yyy.common.exception.user;
/**
* 验证码错误异常类
*
* @author ruoyi
*/
public class CaptchaException extends UserException
{
private static final long serialVersionUID = 1L;
public CaptchaException()
{
super("user.jcaptcha.error", null);
}
}

14
common/src/main/java/com/yyy/common/exception/user/RoleBlockedException.java

@ -0,0 +1,14 @@
package com.yyy.common.exception.user;
/**
* 角色锁定异常类
*/
public class RoleBlockedException extends UserException
{
private static final long serialVersionUID = 1L;
public RoleBlockedException()
{
super("role.blocked", null);
}
}

14
common/src/main/java/com/yyy/common/exception/user/UserBlockedException.java

@ -0,0 +1,14 @@
package com.yyy.common.exception.user;
/**
* 用户锁定异常类
*/
public class UserBlockedException extends UserException
{
private static final long serialVersionUID = 1L;
public UserBlockedException()
{
super("user.blocked", null);
}
}

14
common/src/main/java/com/yyy/common/exception/user/UserDeleteException.java

@ -0,0 +1,14 @@
package com.yyy.common.exception.user;
/**
* 用户账号已被删除
*/
public class UserDeleteException extends UserException
{
private static final long serialVersionUID = 1L;
public UserDeleteException()
{
super("user.password.delete", null);
}
}

16
common/src/main/java/com/yyy/common/exception/user/UserException.java

@ -0,0 +1,16 @@
package com.yyy.common.exception.user;
import com.yyy.common.core.domain.Result;
import com.yyy.common.exception.base.BaseException;
/**
* 用户信息异常类
*/
public class UserException extends BaseException {
private static final long serialVersionUID = 1L;
public UserException(String code, Object[] args) {
super(new Result(Integer.parseInt(code), "[UserException]:" + args.toString()));
}
}

14
common/src/main/java/com/yyy/common/exception/user/UserNotExistsException.java

@ -0,0 +1,14 @@
package com.yyy.common.exception.user;
/**
* 用户不存在异常类
*/
public class UserNotExistsException extends UserException
{
private static final long serialVersionUID = 1L;
public UserNotExistsException()
{
super("user.not.exists", null);
}
}

14
common/src/main/java/com/yyy/common/exception/user/UserPasswordNotMatchException.java

@ -0,0 +1,14 @@
package com.yyy.common.exception.user;
/**
* 用户密码不正确或不符合规范异常类
*/
public class UserPasswordNotMatchException extends UserException
{
private static final long serialVersionUID = 1L;
public UserPasswordNotMatchException()
{
super("user.password.not.match", null);
}
}

14
common/src/main/java/com/yyy/common/exception/user/UserPasswordRetryLimitCountException.java

@ -0,0 +1,14 @@
package com.yyy.common.exception.user;
/**
* 用户错误记数异常类
*/
public class UserPasswordRetryLimitCountException extends UserException
{
private static final long serialVersionUID = 1L;
public UserPasswordRetryLimitCountException(int retryLimitCount)
{
super("user.password.retry.limit.count", new Object[] { retryLimitCount });
}
}

14
common/src/main/java/com/yyy/common/exception/user/UserPasswordRetryLimitExceedException.java

@ -0,0 +1,14 @@
package com.yyy.common.exception.user;
/**
* 用户错误最大次数异常类
*/
public class UserPasswordRetryLimitExceedException extends UserException
{
private static final long serialVersionUID = 1L;
public UserPasswordRetryLimitExceedException(int retryLimitCount)
{
super("user.password.retry.limit.exceed", new Object[] { retryLimitCount });
}
}

104
common/src/main/java/com/yyy/common/utils/bean/BeanUtils.java

@ -0,0 +1,104 @@
package com.yyy.common.utils.bean;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Author: fy
* @Date: 2024/03/25
* @Description: Bean 工具类
*/
public class BeanUtils extends org.springframework.beans.BeanUtils {
/**
* Bean方法名中属性名开始的下标
*/
private static final int BEAN_METHOD_PROP_INDEX = 3;
/**
* 匹配getter方法的正则表达式
*/
private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");
/**
* 匹配setter方法的正则表达式
*/
private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");
/**
* Bean属性复制工具方法
*
* @param dest 目标对象
* @param src 源对象
*/
public static void copyBeanProp(Object dest, Object src) {
try {
copyProperties(src, dest);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取对象的setter方法
*
* @param obj 对象
* @return 对象的setter方法列表
*/
public static List<Method> getSetterMethods(Object obj) {
// setter方法列表
List<Method> setterMethods = new ArrayList<Method>();
// 获取所有方法
Method[] methods = obj.getClass().getMethods();
// 查找setter方法
for (Method method : methods) {
Matcher m = SET_PATTERN.matcher(method.getName());
if (m.matches() && (method.getParameterTypes().length == 1)) {
setterMethods.add(method);
}
}
// 返回setter方法列表
return setterMethods;
}
/**
* 获取对象的getter方法
*
* @param obj 对象
* @return 对象的getter方法列表
*/
public static List<Method> getGetterMethods(Object obj) {
// getter方法列表
List<Method> getterMethods = new ArrayList<Method>();
// 获取所有方法
Method[] methods = obj.getClass().getMethods();
// 查找getter方法
for (Method method : methods) {
Matcher m = GET_PATTERN.matcher(method.getName());
if (m.matches() && (method.getParameterTypes().length == 0)) {
getterMethods.add(method);
}
}
// 返回getter方法列表
return getterMethods;
}
/**
* 检查Bean方法名中的属性名是否相等<br>
* 如getName()和setName()属性名一样getName()和setAge()属性名不一样
*
* @param m1 方法名1
* @param m2 方法名2
* @return 属性名一样返回true否则返回false
*/
public static boolean isMethodPropEquals(String m1, String m2) {
return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));
}
}

217
common/src/main/java/com/yyy/common/utils/common/DateUtils.java

@ -0,0 +1,217 @@
package com.yyy.common.utils.common;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Date;
import java.util.TimeZone;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:时间工具类
*/
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
public static String YYYY = "yyyy";
public static String YYYY_MM = "yyyy-MM";
public static String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
private static String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
/**
* 获取当前Date型日期
*
* @return Date() 当前日期
*/
public static Date getNowDate()
{
return new Date();
}
/**
* 获取当前日期, 默认格式为yyyy-MM-dd
*
* @return String
*/
public static String getDate()
{
return dateTimeNow(YYYY_MM_DD);
}
public static final String getTime()
{
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
}
public static final String dateTimeNow()
{
return dateTimeNow(YYYYMMDDHHMMSS);
}
public static final String dateTimeNow(final String format)
{
return parseDateToStr(format, new Date());
}
public static final String dateTime(final Date date)
{
return parseDateToStr(YYYY_MM_DD, date);
}
public static final String parseDateToStr(final String format, final Date date)
{
return new SimpleDateFormat(format).format(date);
}
public static final Date dateTime(final String format, final String ts)
{
try
{
return new SimpleDateFormat(format).parse(ts);
}
catch (ParseException e)
{
throw new RuntimeException(e);
}
}
/**
* 日期路径 即年// 如2018/08/08
*/
public static final String datePath()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyy/MM/dd");
}
/**
* 日期路径 即年// 如20180808
*/
public static final String dateTime()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyyMMdd");
}
/**
* 日期型字符串转化为日期 格式
*/
public static Date parseDate(Object str)
{
if (str == null)
{
return null;
}
try
{
return parseDate(str.toString(), parsePatterns);
}
catch (ParseException e)
{
return null;
}
}
public static Date parseDate(String dateString, String format)
{
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
return dateFormat.parse(dateString);
} catch (ParseException e) {
return null;
}
}
/**
* 日期型字符串转化为日期 格式
*/
public static Date parseDate1(Date date)
{
SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
String formattedDateStr = sdf.format(date);
try {
return sdf.parse(formattedDateStr);
} catch (ParseException e) {
return null;
}
}
/**
* 获取服务器启动时间
*/
public static Date getServerStartDate()
{
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
return new Date(time);
}
/**
* 计算相差天数
*/
public static int differentDaysByMillisecond(Date date1, Date date2)
{
return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
}
/**
* 计算时间差
*
* @param endDate 最后时间
* @param startTime 开始时间
* @return 时间差/小时/分钟
*/
public static String timeDistance(Date endDate, Date startTime)
{
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - startTime.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
long hour = diff % nd / nh;
// 计算差多少分钟
long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return day + "天" + hour + "小时" + min + "分钟";
}
/**
* 增加 LocalDateTime ==> Date
*/
public static Date toDate(LocalDateTime temporalAccessor)
{
ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
return Date.from(zdt.toInstant());
}
/**
* 增加 LocalDate ==> Date
*/
public static Date toDate(LocalDate temporalAccessor)
{
LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
return Date.from(zdt.toInstant());
}
}

191
common/src/main/java/com/yyy/common/utils/common/DictUtils.java

@ -0,0 +1,191 @@
package com.yyy.common.utils.common;
import com.yyy.common.constant.Constants;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 字典工具类
*
*/
@Component
public class DictUtils
{
/**
* 分隔符
*/
public static final String SEPARATOR = ",";
// /**
// * 设置字典缓存
// *
// * @param key 参数键
// * @param dictDatas 字典数据列表
// */
// public static void setDictCache(String key, List<SysDictData> dictDatas)
// {
// CacheUtils.put(getCacheName(), getCacheKey(key), dictDatas);
// }
//
// /**
// * 获取字典缓存
// *
// * @param key 参数键
// * @return dictDatas 字典数据列表
// */
// public static List<SysDictData> getDictCache(String key)
// {
// Object cacheObj = CacheUtils.get(getCacheName(), getCacheKey(key));
// if (StringUtils.isNotNull(cacheObj))
// {
// return StringUtils.cast(cacheObj);
// }
// return null;
// }
/**
* 根据字典类型和字典值获取字典标签
*
* @param dictType 字典类型
* @param dictValue 字典值
* @return 字典标签
*/
public static String getDictLabel(String dictType, String dictValue)
{
return getDictLabel(dictType, dictValue, SEPARATOR);
}
/**
* 根据字典类型和字典标签获取字典值
*
* @param dictType 字典类型
* @param dictLabel 字典标签
* @return 字典值
*/
public static String getDictValue(String dictType, String dictLabel)
{
return getDictValue(dictType, dictLabel, SEPARATOR);
}
/**
* 根据字典类型和字典值获取字典标签
*
* @param dictType 字典类型
* @param dictValue 字典值
* @param separator 分隔符
* @return 字典标签
*/
public static String getDictLabel(String dictType, String dictValue, String separator)
{
return dictType+separator+dictValue;
// StringBuilder propertyString = new StringBuilder();
// List<SysDictData> datas = getDictCache(dictType);
//
// if (StringUtils.containsAny(dictValue, separator) && StringUtils.isNotEmpty(datas))
// {
// for (SysDictData dict : datas)
// {
// for (String value : dictValue.split(separator))
// {
// if (value.equals(dict.getDictValue()))
// {
// propertyString.append(dict.getDictLabel()).append(separator);
// break;
// }
// }
// }
// }
// else
// {
// for (SysDictData dict : datas)
// {
// if (dictValue.equals(dict.getDictValue()))
// {
// return dict.getDictLabel();
// }
// }
// }
// return StringUtils.stripEnd(propertyString.toString(), separator);
}
/**
* 根据字典类型和字典标签获取字典值
*
* @param dictType 字典类型
* @param dictLabel 字典标签
* @param separator 分隔符
* @return 字典值
*/
public static String getDictValue(String dictType, String dictLabel, String separator)
{
return dictType+separator+dictLabel;
// StringBuilder propertyString = new StringBuilder();
// List<SysDictData> datas = getDictCache(dictType);
//
// if (StringUtils.containsAny(dictLabel, separator) && StringUtils.isNotEmpty(datas))
// {
// for (SysDictData dict : datas)
// {
// for (String label : dictLabel.split(separator))
// {
// if (label.equals(dict.getDictLabel()))
// {
// propertyString.append(dict.getDictValue()).append(separator);
// break;
// }
// }
// }
// }
// else
// {
// for (SysDictData dict : datas)
// {
// if (dictLabel.equals(dict.getDictLabel()))
// {
// return dict.getDictValue();
// }
// }
// }
// return StringUtils.stripEnd(propertyString.toString(), separator);
}
// /**
// * 删除指定字典缓存
// *
// * @param key 字典键
// */
// public static void removeDictCache(String key)
// {
// CacheUtils.remove(getCacheName(), getCacheKey(key));
// }
//
// /**
// * 清空字典缓存
// */
// public static void clearDictCache()
// {
// CacheUtils.removeAll(getCacheName());
// }
/**
* 获取cache name
*
* @return 缓存名
*/
public static String getCacheName()
{
return Constants.SYS_DICT_CACHE;
}
/**
* 设置cache key
*
* @param configKey 参数键
* @return 缓存键key
*/
public static String getCacheKey(String configKey)
{
return Constants.SYS_DICT_KEY + configKey;
}
}

48
common/src/main/java/com/yyy/common/utils/common/MD5Utils.java

@ -0,0 +1,48 @@
package com.yyy.common.utils.common;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import java.security.SecureRandom;
import java.util.Base64;
/**
* Created with IntelliJ IDEA.
*
* @Author: fy
* @Date: 2023/04/19/10:09
* @Description:MD5密码加密
*/
public class MD5Utils {
public static String md5(String src) {
return DigestUtils.md5DigestAsHex(src.getBytes());
}
//第一次加密
public static String inputPassToFormPass(String inputPass, String salt) {
//md5加密密码前,先对密码进行处理,按以下salt的规则处理密码
String str = "" + salt.charAt(0) + salt.charAt(2) + inputPass + salt.charAt(5) + salt.charAt(4);
return md5(str);
}
//第二次加密
public static String formPassToDBPass(String formPass, String salt) {
String str = "" + salt.charAt(0) + salt.charAt(2) + formPass + salt.charAt(5) + salt.charAt(4);
return md5(str);
}
//实际调用的方法,将第一次加密和第二次加密合并,结果应该一致
public static String inputPassToDBPass(String inputPass, String salt) {
String formPass = inputPassToFormPass(inputPass, salt);
String dbPass = formPassToDBPass(formPass, salt);
return dbPass;
}
public static String randomSalt() {
int length = 16;
SecureRandom random = new SecureRandom();
byte[] salt = new byte[length];
random.nextBytes(salt);
return Base64.getEncoder().encodeToString(salt);
}
}

34
common/src/main/java/com/yyy/common/utils/common/PageUtils.java

@ -0,0 +1,34 @@
package com.yyy.common.utils.common;
import com.github.pagehelper.PageHelper;
import com.yyy.common.core.page.PageDomain;
import com.yyy.common.core.page.TableSupport;
import com.yyy.common.utils.sql.SqlUtil;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:分页工具类
*/
public class PageUtils extends PageHelper {
/**
* 设置请求分页数据
*/
public static void startPage()
{
PageDomain pageDomain = TableSupport.buildPageRequest();
Integer pageNum = pageDomain.getPageNum();
Integer pageSize = pageDomain.getPageSize();
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
Boolean reasonable = pageDomain.getReasonable();
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
}
/**
* 清理分页的线程变量
*/
public static void clearPage()
{
PageHelper.clearPage();
}
}

217
common/src/main/java/com/yyy/common/utils/common/ServletUtils.java

@ -0,0 +1,217 @@
package com.yyy.common.utils.common;
import com.yyy.common.constant.Constants;
import com.yyy.common.core.text.Convert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:客户端工具类
*/
public class ServletUtils
{
/**
* 定义移动端请求的所有可能类型
*/
private final static String[] agent = { "Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser" };
/**
* 获取String参数
*/
public static String getParameter(String name)
{
return getRequest().getParameter(name);
}
/**
* 获取String参数
*/
public static String getParameter(String name, String defaultValue)
{
return Convert.toStr(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name)
{
return Convert.toInt(getRequest().getParameter(name));
}
/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name, Integer defaultValue)
{
return Convert.toInt(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name)
{
return Convert.toBool(getRequest().getParameter(name));
}
/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name, Boolean defaultValue)
{
return Convert.toBool(getRequest().getParameter(name), defaultValue);
}
/**
* 获取request
*/
public static HttpServletRequest getRequest()
{
return getRequestAttributes().getRequest();
}
/**
* 获取response
*/
public static HttpServletResponse getResponse()
{
return getRequestAttributes().getResponse();
}
/**
* 获取session
*/
public static HttpSession getSession()
{
return getRequest().getSession();
}
public static ServletRequestAttributes getRequestAttributes()
{
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
}
/**
* 将字符串渲染到客户端
*
* @param response 渲染对象
* @param string 待渲染的字符串
* @return null
*/
public static String renderString(HttpServletResponse response, String string)
{
try
{
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().print(string);
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
/**
* 是否是Ajax异步请求
*
* @param request
*/
public static boolean isAjaxRequest(HttpServletRequest request)
{
String accept = request.getHeader("accept");
if (accept != null && accept.contains("application/json"))
{
return true;
}
String xRequestedWith = request.getHeader("X-Requested-With");
if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest"))
{
return true;
}
String uri = request.getRequestURI();
if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
{
return true;
}
String ajax = request.getParameter("__ajax");
return StringUtils.inStringIgnoreCase(ajax, "json", "xml");
}
/**
* 判断User-Agent 是不是来自于手机
*/
public static boolean checkAgentIsMobile(String ua)
{
boolean flag = false;
if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;")))
{
// 排除 苹果桌面系统
if (!ua.contains("Windows NT") && !ua.contains("Macintosh"))
{
for (String item : agent)
{
if (ua.contains(item))
{
flag = true;
break;
}
}
}
}
return flag;
}
/**
* 内容编码
*
* @param str 内容
* @return 编码后的内容
*/
public static String urlEncode(String str)
{
try
{
return URLEncoder.encode(str, Constants.UTF8);
}
catch (UnsupportedEncodingException e)
{
return StringUtils.EMPTY;
}
}
/**
* 内容解码
*
* @param str 内容
* @return 解码后的内容
*/
public static String urlDecode(String str)
{
try
{
return URLDecoder.decode(str, Constants.UTF8);
}
catch (UnsupportedEncodingException e)
{
return StringUtils.EMPTY;
}
}
}

636
common/src/main/java/com/yyy/common/utils/common/StringUtils.java

@ -0,0 +1,636 @@
package com.yyy.common.utils.common;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.yyy.common.constant.Constants;
import com.yyy.common.core.text.StrFormatter;
import org.springframework.util.AntPathMatcher;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:
*/
/**
* 字符串工具类
*
* @author ruoyi
*/
public class StringUtils extends org.apache.commons.lang3.StringUtils
{
/** 空字符串 */
private static final String NULLSTR = "";
/** 下划线 */
private static final char SEPARATOR = '_';
/**
* 获取参数不为空值
*
* @param value defaultValue 要判断的value
* @return value 返回值
*/
public static <T> T nvl(T value, T defaultValue)
{
return value != null ? value : defaultValue;
}
/**
* * 判断一个Collection是否为空 包含ListSetQueue
*
* @param coll 要判断的Collection
* @return true为空 false非空
*/
public static boolean isEmpty(Collection<?> coll)
{
return isNull(coll) || coll.isEmpty();
}
/**
* * 判断一个Collection是否非空包含ListSetQueue
*
* @param coll 要判断的Collection
* @return true非空 false
*/
public static boolean isNotEmpty(Collection<?> coll)
{
return !isEmpty(coll);
}
/**
* * 判断一个对象数组是否为空
*
* @param objects 要判断的对象数组
** @return true为空 false非空
*/
public static boolean isEmpty(Object[] objects)
{
return isNull(objects) || (objects.length == 0);
}
/**
* * 判断一个对象数组是否非空
*
* @param objects 要判断的对象数组
* @return true非空 false
*/
public static boolean isNotEmpty(Object[] objects)
{
return !isEmpty(objects);
}
/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true为空 false非空
*/
public static boolean isEmpty(Map<?, ?> map)
{
return isNull(map) || map.isEmpty();
}
/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true非空 false
*/
public static boolean isNotEmpty(Map<?, ?> map)
{
return !isEmpty(map);
}
/**
* * 判断一个字符串是否为空串
*
* @param str String
* @return true为空 false非空
*/
public static boolean isEmpty(String str)
{
return isNull(str) || NULLSTR.equals(str.trim());
}
/**
* * 判断一个字符串是否为非空串
*
* @param str String
* @return true非空串 false空串
*/
public static boolean isNotEmpty(String str)
{
return !isEmpty(str);
}
/**
* * 判断一个对象是否为空
*
* @param object Object
* @return true为空 false非空
*/
public static boolean isNull(Object object)
{
return object == null;
}
/**
* * 判断一个对象是否非空
*
* @param object Object
* @return true非空 false
*/
public static boolean isNotNull(Object object)
{
return !isNull(object);
}
/**
* * 判断一个对象是否是数组类型Java基本型别的数组
*
* @param object 对象
* @return true是数组 false不是数组
*/
public static boolean isArray(Object object)
{
return isNotNull(object) && object.getClass().isArray();
}
/**
* 去空格
*/
public static String trim(String str)
{
return (str == null ? "" : str.trim());
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @return 结果
*/
public static String substring(final String str, int start)
{
if (str == null)
{
return NULLSTR;
}
if (start < 0)
{
start = str.length() + start;
}
if (start < 0)
{
start = 0;
}
if (start > str.length())
{
return NULLSTR;
}
return str.substring(start);
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @param end 结束
* @return 结果
*/
public static String substring(final String str, int start, int end)
{
if (str == null)
{
return NULLSTR;
}
if (end < 0)
{
end = str.length() + end;
}
if (start < 0)
{
start = str.length() + start;
}
if (end > str.length())
{
end = str.length();
}
if (start > end)
{
return NULLSTR;
}
if (start < 0)
{
start = 0;
}
if (end < 0)
{
end = 0;
}
return str.substring(start, end);
}
/**
* 格式化文本, {} 表示占位符<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* <br>
* 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param template 文本模板被替换的部分用 {} 表示
* @param params 参数值
* @return 格式化后的文本
*/
public static String format(String template, Object... params)
{
if (isEmpty(params) || isEmpty(template))
{
return template;
}
return StrFormatter.format(template, params);
}
/**
* 是否为http(s)://开头
*
* @param link 链接
* @return 结果
*/
public static boolean ishttp(String link)
{
return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);
}
/**
* 字符串转set
*
* @param str 字符串
* @param sep 分隔符
* @return set集合
*/
public static final Set<String> str2Set(String str, String sep)
{
return new HashSet<String>(str2List(str, sep, true, false));
}
/**
* 字符串转list
*
* @param str 字符串
* @param sep 分隔符
* @param filterBlank 过滤纯空白
* @param trim 去掉首尾空白
* @return list集合
*/
public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim)
{
List<String> list = new ArrayList<String>();
if (StringUtils.isEmpty(str))
{
return list;
}
// 过滤空白字符串
if (filterBlank && StringUtils.isBlank(str))
{
return list;
}
String[] split = str.split(sep);
for (String string : split)
{
if (filterBlank && StringUtils.isBlank(string))
{
continue;
}
if (trim)
{
string = string.trim();
}
list.add(string);
}
return list;
}
/**
* 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
*
* @param collection 给定的集合
* @param array 给定的数组
* @return boolean 结果
*/
public static boolean containsAny(Collection<String> collection, String... array)
{
if (isEmpty(collection) || isEmpty(array))
{
return false;
}
else
{
for (String str : array)
{
if (collection.contains(str))
{
return true;
}
}
return false;
}
}
/**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
*
* @param cs 指定字符串
* @param searchCharSequences 需要检查的字符串数组
* @return 是否包含任意一个字符串
*/
public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences)
{
if (isEmpty(cs) || isEmpty(searchCharSequences))
{
return false;
}
for (CharSequence testStr : searchCharSequences)
{
if (containsIgnoreCase(cs, testStr))
{
return true;
}
}
return false;
}
/**
* 驼峰转下划线命名
*/
public static String toUnderScoreCase(String str)
{
if (str == null)
{
return null;
}
StringBuilder sb = new StringBuilder();
// 前置字符是否大写
boolean preCharIsUpperCase = true;
// 当前字符是否大写
boolean curreCharIsUpperCase = true;
// 下一字符是否大写
boolean nexteCharIsUpperCase = true;
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if (i > 0)
{
preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
}
else
{
preCharIsUpperCase = false;
}
curreCharIsUpperCase = Character.isUpperCase(c);
if (i < (str.length() - 1))
{
nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
}
if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
{
sb.append(SEPARATOR);
}
else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
{
sb.append(SEPARATOR);
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
/**
* 是否包含字符串
*
* @param str 验证字符串
* @param strs 字符串组
* @return 包含返回true
*/
public static boolean inStringIgnoreCase(String str, String... strs)
{
if (str != null && strs != null)
{
for (String s : strs)
{
if (str.equalsIgnoreCase(trim(s)))
{
return true;
}
}
}
return false;
}
/**
* 删除最后一个字符串
*
* @param str 输入字符串
* @param spit 以什么类型结尾的
* @return 截取后的字符串
*/
public static String lastStringDel(String str, String spit)
{
if (!StringUtils.isEmpty(str) && str.endsWith(spit))
{
return str.subSequence(0, str.length() - 1).toString();
}
return str;
}
/**
* 将下划线大写方式命名的字符串转换为驼峰式如果转换前的下划线大写方式命名的字符串为空则返回空字符串 例如HELLO_WORLD->HelloWorld
*
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
public static String convertToCamelCase(String name)
{
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || name.isEmpty())
{
// 没必要转换
return "";
}
else if (!name.contains("_"))
{
// 不含下划线,仅将首字母大写
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
// 用下划线将原始字符串分割
String[] camels = name.split("_");
for (String camel : camels)
{
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if (camel.isEmpty())
{
continue;
}
// 首字母大写
result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase());
}
return result.toString();
}
/**
* 驼峰式命名法
* 例如user_name->userName
*/
public static String toCamelCase(String s)
{
if (s == null)
{
return null;
}
if (s.indexOf(SEPARATOR) == -1)
{
return s;
}
s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false;
for (int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
if (c == SEPARATOR)
{
upperCase = true;
}
else if (upperCase)
{
sb.append(Character.toUpperCase(c));
upperCase = false;
}
else
{
sb.append(c);
}
}
return sb.toString();
}
/**
* 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
*
* @param str 指定字符串
* @param strs 需要检查的字符串数组
* @return 是否匹配
*/
public static boolean matches(String str, List<String> strs)
{
if (isEmpty(str) || isEmpty(strs))
{
return false;
}
for (String pattern : strs)
{
if (isMatch(pattern, str))
{
return true;
}
}
return false;
}
/**
* 判断url是否与规则配置:
* ? 表示单个字符;
* * 表示一层路径内的任意字符串不可跨层级;
* ** 表示任意层路径;
*
* @param pattern 匹配规则
* @param url 需要匹配的url
* @return
*/
public static boolean isMatch(String pattern, String url)
{
AntPathMatcher matcher = new AntPathMatcher();
return matcher.match(pattern, url);
}
@SuppressWarnings("unchecked")
public static <T> T cast(Object obj)
{
return (T) obj;
}
/**
* 数字左边补齐0使之达到指定长度注意如果数字转换为字符串后长度大于size则只保留 最后size个字符
*
* @param num 数字对象
* @param size 字符串指定长度
* @return 返回数字的字符串格式该字符串为指定长度
*/
public static final String padl(final Number num, final int size)
{
return padl(num.toString(), size, '0');
}
/**
* 字符串左补齐如果原始字符串s长度大于size则只保留最后size个字符
*
* @param s 原始字符串
* @param size 字符串指定长度
* @param c 用于补齐的字符
* @return 返回指定长度的字符串由原字符串左补齐或截取得到
*/
public static final String padl(final String s, final int size, final char c)
{
final StringBuilder sb = new StringBuilder(size);
if (s != null)
{
final int len = s.length();
if (s.length() <= size)
{
for (int i = size - len; i > 0; i--)
{
sb.append(c);
}
sb.append(s);
}
else
{
return s.substring(len - size, len);
}
}
else
{
for (int i = size; i > 0; i--)
{
sb.append(c);
}
}
return sb.toString();
}
}

94
common/src/main/java/com/yyy/common/utils/common/Threads.java

@ -0,0 +1,94 @@
package com.yyy.common.utils.common;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.*;
/**
* 线程相关工具类.
*/
public class Threads
{
private static final Logger logger = LoggerFactory.getLogger(Threads.class);
/**
* sleep等待,单位为毫秒
*/
public static void sleep(long milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (InterruptedException e)
{
return;
}
}
/**
* 停止线程池
* 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
* 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
* 如果仍人超時則強制退出.
* 另对在shutdown时线程本身被调用中断做了处理.
*/
public static void shutdownAndAwaitTermination(ExecutorService pool)
{
if (pool != null && !pool.isShutdown())
{
pool.shutdown();
try
{
if (!pool.awaitTermination(120, TimeUnit.SECONDS))
{
pool.shutdownNow();
if (!pool.awaitTermination(120, TimeUnit.SECONDS))
{
logger.info("Pool did not terminate");
}
}
}
catch (InterruptedException ie)
{
pool.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
/**
* 打印线程异常信息
*/
public static void printException(Runnable r, Throwable t)
{
if (t == null && r instanceof Future<?>)
{
try
{
Future<?> future = (Future<?>) r;
if (future.isDone())
{
future.get();
}
}
catch (CancellationException ce)
{
t = ce;
}
catch (ExecutionException ee)
{
t = ee.getCause();
}
catch (InterruptedException ie)
{
Thread.currentThread().interrupt();
}
}
if (t != null)
{
logger.error(t.getMessage(), t);
}
}
}

4
common/src/main/java/com/yyy/common/utils/eam/DocumentsUtil.java

@ -0,0 +1,4 @@
package com.yyy.common.utils.eam;
public class DocumentsUtil {
}

71
common/src/main/java/com/yyy/common/utils/eam/ResidualValueCalculator.java

@ -0,0 +1,71 @@
package com.yyy.common.utils.eam;
import java.math.BigDecimal;
public class ResidualValueCalculator {
// 年限平均法
public static BigDecimal calculateResidualValueByAverageLife(BigDecimal originalValue, int usefulLife, int yearsDepreciated) {
BigDecimal depreciationPerYear = originalValue.divide(BigDecimal.valueOf(usefulLife), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal accumulatedDepreciation = depreciationPerYear.multiply(BigDecimal.valueOf(yearsDepreciated));
BigDecimal residualValue = originalValue.subtract(accumulatedDepreciation);
return residualValue;
}
// 按月折旧的年限平均法
public static BigDecimal calculateMonthlyDepreciationByAverageLife(BigDecimal originalValue, int usefulLifeInMonths, int monthsDepreciated) {
BigDecimal depreciationPerMonth = originalValue.divide(BigDecimal.valueOf(usefulLifeInMonths), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal accumulatedDepreciation = depreciationPerMonth.multiply(BigDecimal.valueOf(monthsDepreciated));
BigDecimal residualValue = originalValue.subtract(accumulatedDepreciation);
return residualValue;
}
// 工作量法
public static BigDecimal calculateResidualValueByUnitsOfWork(BigDecimal originalValue, BigDecimal totalUnitsOfWork, BigDecimal unitsOfWorkDone) {
BigDecimal depreciationPerUnit = originalValue.divide(totalUnitsOfWork, 2, BigDecimal.ROUND_HALF_UP);
BigDecimal accumulatedDepreciation = depreciationPerUnit.multiply(unitsOfWorkDone);
BigDecimal residualValue = originalValue.subtract(accumulatedDepreciation);
return residualValue;
}
// 双倍余额递减法
public static BigDecimal calculateResidualValueByDoubleDecliningBalance(BigDecimal originalValue, BigDecimal depreciationRate, int usefulLife, int yearsDepreciated) {
BigDecimal bookValue = originalValue;
for (int i = 1; i <= yearsDepreciated; i++) {
BigDecimal depreciationExpense = bookValue.multiply(depreciationRate).setScale(2, BigDecimal.ROUND_HALF_UP);
bookValue = bookValue.subtract(depreciationExpense);
}
return bookValue;
}
// 年数总和法
public static BigDecimal calculateResidualValueBySumOfTheYearsDigits(BigDecimal originalValue, int usefulLife, int yearsDepreciated) {
int sumOfYears = usefulLife * (usefulLife + 1) / 2;
BigDecimal depreciationPerYear = originalValue.divide(BigDecimal.valueOf(sumOfYears), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal accumulatedDepreciation = BigDecimal.ZERO;
for (int i = 1; i <= yearsDepreciated; i++) {
accumulatedDepreciation = accumulatedDepreciation.add(depreciationPerYear.multiply(BigDecimal.valueOf(usefulLife - i + 1)));
}
BigDecimal residualValue = originalValue.subtract(accumulatedDepreciation);
return residualValue;
}
public static void main(String[] args) {
BigDecimal originalValue = new BigDecimal("3000000.00"); // 资产原值
int usefulLife = 5; // 使用年限
int yearsDepreciated = 3; // 已折旧年限
BigDecimal totalUnitsOfWork = new BigDecimal("1000"); // 总工作量
BigDecimal unitsOfWorkDone = new BigDecimal("500"); // 完成的工作量
BigDecimal depreciationRate = new BigDecimal("0.2"); // 折旧率
BigDecimal residualValueAverageLife = calculateResidualValueByAverageLife(originalValue, usefulLife, yearsDepreciated);
BigDecimal residualValueUnitsOfWork = calculateResidualValueByUnitsOfWork(new BigDecimal("60.00"), new BigDecimal("50.00"), new BigDecimal("0.40"));
BigDecimal residualValueDoubleDecliningBalance = calculateResidualValueByDoubleDecliningBalance(originalValue, depreciationRate, usefulLife, yearsDepreciated);
BigDecimal residualValueSumOfTheYearsDigits = calculateResidualValueBySumOfTheYearsDigits(originalValue, usefulLife, yearsDepreciated);
System.out.println("资产残值 - 年限平均法: " + residualValueAverageLife);
System.out.println("年限平均法(按月): 资产残值 - " + calculateMonthlyDepreciationByAverageLife(originalValue,5*12,9));
System.out.println("资产残值 - 工作量法: " + residualValueUnitsOfWork);
System.out.println("资产残值 - 双倍余额递减法: " + residualValueDoubleDecliningBalance);
System.out.println("资产残值 - 年数总和法: " + residualValueSumOfTheYearsDigits);
}
}

77
common/src/main/java/com/yyy/common/utils/file/FileTypeUtils.java

@ -0,0 +1,77 @@
package com.yyy.common.utils.file;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
/**
* @Author: fy
* @Date: 2024/03/22
* @Description:文件类型工具类
*/
public class FileTypeUtils
{
/**
* 获取文件类型
* <p>
* 例如: ruoyi.txt, 返回: txt
*
* @param file 文件名
* @return 后缀不含".")
*/
public static String getFileType(File file)
{
if (null == file)
{
return StringUtils.EMPTY;
}
return getFileType(file.getName());
}
/**
* 获取文件类型
* <p>
* 例如: ruoyi.txt, 返回: txt
*
* @param fileName 文件名
* @return 后缀不含".")
*/
public static String getFileType(String fileName)
{
int separatorIndex = fileName.lastIndexOf(".");
if (separatorIndex < 0)
{
return "";
}
return fileName.substring(separatorIndex + 1).toLowerCase();
}
/**
* 获取文件类型
*
* @param photoByte 文件字节码
* @return 后缀不含".")
*/
public static String getFileExtendName(byte[] photoByte)
{
String strFileExtendName = "JPG";
if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
&& ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
{
strFileExtendName = "GIF";
}
else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
{
strFileExtendName = "JPG";
}
else if ((photoByte[0] == 66) && (photoByte[1] == 77))
{
strFileExtendName = "BMP";
}
else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
{
strFileExtendName = "PNG";
}
return strFileExtendName;
}
}

231
common/src/main/java/com/yyy/common/utils/file/FileUploadUtils.java

@ -0,0 +1,231 @@
package com.yyy.common.utils.file;
import com.yyy.common.config.AppConfig;
import com.yyy.common.constant.Constants;
import com.yyy.common.exception.file.FileNameLengthLimitExceededException;
import com.yyy.common.exception.file.FileSizeLimitExceededException;
import com.yyy.common.exception.file.InvalidExtensionException;
import com.yyy.common.utils.common.DateUtils;
import com.yyy.common.utils.common.StringUtils;
import com.yyy.common.utils.uuid.Seq;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Objects;
/**
* 文件上传工具类
*/
public class FileUploadUtils
{
/**
* 默认大小 50M
*/
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
/**
* 默认的文件名最大长度 100
*/
public static final int DEFAULT_FILE_NAME_LENGTH = 100;
/**
* 默认上传的地址
*/
private static String defaultBaseDir = AppConfig.getProfile();
public static void setDefaultBaseDir(String defaultBaseDir)
{
FileUploadUtils.defaultBaseDir = defaultBaseDir;
}
public static String getDefaultBaseDir()
{
return defaultBaseDir;
}
/**
* 以默认配置进行文件上传
*
* @param file 上传的文件
* @return 文件名称
* @throws Exception
*/
public static final String upload(MultipartFile file) throws IOException
{
try
{
return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
}
catch (Exception e)
{
throw new IOException(e.getMessage(), e);
}
}
/**
* 根据文件路径上传
*
* @param baseDir 相对应用的基目录
* @param file 上传的文件
* @return 文件名称
* @throws IOException
*/
public static final String upload(String baseDir, MultipartFile file) throws IOException
{
try
{
return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
}
catch (Exception e)
{
throw new IOException(e.getMessage(), e);
}
}
/**
* 文件上传
*
* @param baseDir 相对应用的基目录
* @param file 上传的文件
* @param allowedExtension 上传文件类型
* @return 返回上传成功的文件名
* @throws FileSizeLimitExceededException 如果超出最大大小
* @throws FileNameLengthLimitExceededException 文件名太长
* @throws IOException 比如读写文件出错时
* @throws InvalidExtensionException 文件校验异常
*/
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
InvalidExtensionException
{
int fileNameLength = Objects.requireNonNull(file.getOriginalFilename()).length();
if (fileNameLength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
{
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
}
assertAllowed(file, allowedExtension);
String fileName = extractFilename(file);
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
file.transferTo(Paths.get(absPath));
return getPathFileName(baseDir, fileName);
}
/**
* 编码文件名
*/
public static final String extractFilename(MultipartFile file)
{
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
}
public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
{
File desc = new File(uploadDir + File.separator + fileName);
if (!desc.exists())
{
if (!desc.getParentFile().exists())
{
desc.getParentFile().mkdirs();
}
}
return desc;
}
public static final String getPathFileName(String uploadDir, String fileName) throws IOException
{
int dirLastIndex = AppConfig.getProfile().length() + 1;
String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
}
/**
* 文件大小校验
*
* @param file 上传的文件
* @return
* @throws FileSizeLimitExceededException 如果超出最大大小
* @throws InvalidExtensionException
*/
public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
throws FileSizeLimitExceededException, InvalidExtensionException
{
long size = file.getSize();
if (size > DEFAULT_MAX_SIZE)
{
throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
}
String fileName = file.getOriginalFilename();
String extension = getExtension(file);
if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
{
if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
{
throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
fileName);
}
else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
{
throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
fileName);
}
else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
{
throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
fileName);
}
else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
{
throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
fileName);
}
else
{
throw new InvalidExtensionException(allowedExtension, extension, fileName);
}
}
}
/**
* 判断MIME类型是否是允许的MIME类型
*
* @param extension
* @param allowedExtension
* @return
*/
public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
{
for (String str : allowedExtension)
{
if (str.equalsIgnoreCase(extension))
{
return true;
}
}
return false;
}
/**
* 获取文件名的后缀
*
* @param file 表单文件
* @return 后缀名
*/
public static final String getExtension(MultipartFile file)
{
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
if (StringUtils.isEmpty(extension))
{
extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType()));
}
return extension;
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save