commit
d07f036e1e
418 changed files with 37937 additions and 0 deletions
-
18.editorconfig
-
46.gitignore
-
20LICENSE
-
0README.md
-
23alog-admin/Dockerfile
-
111alog-admin/pom.xml
-
23alog-admin/src/main/java/com/inscloudtech/AlogServiceApplication.java
-
18alog-admin/src/main/java/com/inscloudtech/AlogServiceServletInitializer.java
-
81alog-admin/src/main/java/com/inscloudtech/web/controller/common/CaptchaController.java
-
160alog-admin/src/main/java/com/inscloudtech/web/controller/common/CommonController.java
-
168alog-admin/src/main/java/com/inscloudtech/web/controller/monitor/CacheController.java
-
88alog-admin/src/main/java/com/inscloudtech/web/controller/monitor/SysLogininforController.java
-
74alog-admin/src/main/java/com/inscloudtech/web/controller/monitor/SysOperlogController.java
-
90alog-admin/src/main/java/com/inscloudtech/web/controller/monitor/SysUserOnlineController.java
-
136alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysConfigController.java
-
122alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysDeptController.java
-
164alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysDictDataController.java
-
124alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysDictTypeController.java
-
97alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysExceptionReportController.java
-
32alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysIndexController.java
-
144alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysLoginController.java
-
127alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysMenuController.java
-
80alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysNoticeController.java
-
105alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysOssConfigController.java
-
109alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysOssController.java
-
120alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysPostController.java
-
125alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysProfileController.java
-
40alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysRegisterController.java
-
228alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysRoleController.java
-
256alog-admin/src/main/java/com/inscloudtech/web/controller/system/SysUserController.java
-
124alog-admin/src/main/resources/application-dev.yml
-
128alog-admin/src/main/resources/application-prod.yml
-
281alog-admin/src/main/resources/application.yml
-
2alog-admin/src/main/resources/banner.txt
-
49alog-admin/src/main/resources/i18n/messages.properties
-
49alog-admin/src/main/resources/i18n/messages_en_US.properties
-
49alog-admin/src/main/resources/i18n/messages_zh_CN.properties
-
BINalog-admin/src/main/resources/ip2region.xdb
-
129alog-admin/src/main/resources/logback-plus.xml
-
28alog-admin/src/main/resources/spy.properties
-
45alog-admin/src/test/java/com/inscloudtech/test/AssertUnitTest.java
-
70alog-admin/src/test/java/com/inscloudtech/test/DemoUnitTest.java
-
72alog-admin/src/test/java/com/inscloudtech/test/ParamUnitTest.java
-
54alog-admin/src/test/java/com/inscloudtech/test/TagUnitTest.java
-
170alog-common/pom.xml
-
24alog-common/src/main/java/com/inscloudtech/common/annotation/CellMerge.java
-
28alog-common/src/main/java/com/inscloudtech/common/annotation/DataColumn.java
-
18alog-common/src/main/java/com/inscloudtech/common/annotation/DataPermission.java
-
29alog-common/src/main/java/com/inscloudtech/common/annotation/DictDataMapper.java
-
32alog-common/src/main/java/com/inscloudtech/common/annotation/ExcelDictFormat.java
-
30alog-common/src/main/java/com/inscloudtech/common/annotation/ExcelEnumFormat.java
-
47alog-common/src/main/java/com/inscloudtech/common/annotation/Log.java
-
41alog-common/src/main/java/com/inscloudtech/common/annotation/RateLimiter.java
-
29alog-common/src/main/java/com/inscloudtech/common/annotation/RepeatSubmit.java
-
24alog-common/src/main/java/com/inscloudtech/common/annotation/Sensitive.java
-
39alog-common/src/main/java/com/inscloudtech/common/annotation/Translation.java
-
21alog-common/src/main/java/com/inscloudtech/common/annotation/TranslationType.java
-
85alog-common/src/main/java/com/inscloudtech/common/captcha/UnsignedMathGenerator.java
-
77alog-common/src/main/java/com/inscloudtech/common/config/ProjectConfig.java
-
51alog-common/src/main/java/com/inscloudtech/common/constant/CacheConstants.java
-
58alog-common/src/main/java/com/inscloudtech/common/constant/CacheNames.java
-
85alog-common/src/main/java/com/inscloudtech/common/constant/Constants.java
-
193alog-common/src/main/java/com/inscloudtech/common/constant/GenConstants.java
-
93alog-common/src/main/java/com/inscloudtech/common/constant/HttpStatus.java
-
30alog-common/src/main/java/com/inscloudtech/common/constant/TransConstant.java
-
147alog-common/src/main/java/com/inscloudtech/common/constant/UserConstants.java
-
52alog-common/src/main/java/com/inscloudtech/common/convert/ExcelBigNumberConvert.java
-
73alog-common/src/main/java/com/inscloudtech/common/convert/ExcelDictConvert.java
-
97alog-common/src/main/java/com/inscloudtech/common/convert/ExcelEnumConvert.java
-
77alog-common/src/main/java/com/inscloudtech/common/core/controller/BaseController.java
-
63alog-common/src/main/java/com/inscloudtech/common/core/domain/BaseEntity.java
-
112alog-common/src/main/java/com/inscloudtech/common/core/domain/PageQuery.java
-
107alog-common/src/main/java/com/inscloudtech/common/core/domain/R.java
-
39alog-common/src/main/java/com/inscloudtech/common/core/domain/TreeEntity.java
-
38alog-common/src/main/java/com/inscloudtech/common/core/domain/dto/RoleDTO.java
-
29alog-common/src/main/java/com/inscloudtech/common/core/domain/dto/SysUserPasswordBo.java
-
60alog-common/src/main/java/com/inscloudtech/common/core/domain/dto/UserOnlineDTO.java
-
80alog-common/src/main/java/com/inscloudtech/common/core/domain/entity/SysDept.java
-
100alog-common/src/main/java/com/inscloudtech/common/core/domain/entity/SysDictData.java
-
65alog-common/src/main/java/com/inscloudtech/common/core/domain/entity/SysDictType.java
-
104alog-common/src/main/java/com/inscloudtech/common/core/domain/entity/SysMenu.java
-
124alog-common/src/main/java/com/inscloudtech/common/core/domain/entity/SysRole.java
-
180alog-common/src/main/java/com/inscloudtech/common/core/domain/entity/SysUser.java
-
61alog-common/src/main/java/com/inscloudtech/common/core/domain/event/ExceptionReportEvent.java
-
44alog-common/src/main/java/com/inscloudtech/common/core/domain/event/LogininforEvent.java
-
104alog-common/src/main/java/com/inscloudtech/common/core/domain/event/OperLogEvent.java
-
55alog-common/src/main/java/com/inscloudtech/common/core/domain/event/RequestLogEvent.java
-
30alog-common/src/main/java/com/inscloudtech/common/core/domain/model/EmailLoginBody.java
-
55alog-common/src/main/java/com/inscloudtech/common/core/domain/model/LoginBody.java
-
116alog-common/src/main/java/com/inscloudtech/common/core/domain/model/LoginUser.java
-
17alog-common/src/main/java/com/inscloudtech/common/core/domain/model/RegisterBody.java
-
28alog-common/src/main/java/com/inscloudtech/common/core/domain/model/SmsLoginBody.java
-
24alog-common/src/main/java/com/inscloudtech/common/core/domain/model/XcxLoginUser.java
-
192alog-common/src/main/java/com/inscloudtech/common/core/mapper/BaseMapperPlus.java
-
78alog-common/src/main/java/com/inscloudtech/common/core/page/TableDataInfo.java
-
18alog-common/src/main/java/com/inscloudtech/common/core/service/ConfigService.java
-
18alog-common/src/main/java/com/inscloudtech/common/core/service/DeptService.java
-
66alog-common/src/main/java/com/inscloudtech/common/core/service/DictService.java
-
18alog-common/src/main/java/com/inscloudtech/common/core/service/OssService.java
-
18alog-common/src/main/java/com/inscloudtech/common/core/service/SensitiveService.java
@ -0,0 +1,18 @@ |
|||
# http://editorconfig.org |
|||
root = true |
|||
|
|||
# 空格替代Tab缩进在各种编辑工具下效果一致 |
|||
[*] |
|||
indent_style = space |
|||
indent_size = 4 |
|||
charset = utf-8 |
|||
end_of_line = lf |
|||
trim_trailing_whitespace = true |
|||
insert_final_newline = true |
|||
|
|||
[*.{json,yml,yaml}] |
|||
indent_size = 2 |
|||
|
|||
[*.md] |
|||
insert_final_newline = false |
|||
trim_trailing_whitespace = false |
@ -0,0 +1,46 @@ |
|||
###################################################################### |
|||
# Build Tools |
|||
|
|||
.gradle |
|||
/build/ |
|||
!gradle/wrapper/gradle-wrapper.jar |
|||
|
|||
target/ |
|||
!.mvn/wrapper/maven-wrapper.jar |
|||
|
|||
###################################################################### |
|||
# IDE |
|||
|
|||
### STS ### |
|||
.apt_generated |
|||
.classpath |
|||
.factorypath |
|||
.project |
|||
.settings |
|||
.springBeans |
|||
|
|||
### IntelliJ IDEA ### |
|||
.idea |
|||
*.iws |
|||
*.iml |
|||
*.ipr |
|||
|
|||
### JRebel ### |
|||
rebel.xml |
|||
|
|||
### NetBeans ### |
|||
nbproject/private/ |
|||
build/* |
|||
nbbuild/ |
|||
nbdist/ |
|||
.nb-gradle/ |
|||
|
|||
###################################################################### |
|||
# Others |
|||
*.log |
|||
*.xml.versionsBackup |
|||
*.swp |
|||
|
|||
!*/build/*.java |
|||
!*/build/*.html |
|||
!*/build/*.xml |
@ -0,0 +1,20 @@ |
|||
The MIT License (MIT) |
|||
|
|||
Copyright (c) 2019 alog-service |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy of |
|||
this software and associated documentation files (the "Software"), to deal in |
|||
the Software without restriction, including without limitation the rights to |
|||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
|||
the Software, and to permit persons to whom the Software is furnished to do so, |
|||
subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in all |
|||
copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
|||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
|||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
|||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,23 @@ |
|||
FROM anapsix/alpine-java:8_server-jre_unlimited |
|||
|
|||
MAINTAINER Lion Li |
|||
|
|||
RUN mkdir -p /ruoyi/server/logs \ |
|||
/ruoyi/server/temp \ |
|||
/ruoyi/skywalking/agent |
|||
|
|||
WORKDIR /ruoyi/server |
|||
|
|||
ENV SERVER_PORT=8080 |
|||
|
|||
EXPOSE ${SERVER_PORT} |
|||
|
|||
ADD ./target/ruoyi-admin.jar ./app.jar |
|||
|
|||
ENTRYPOINT ["java", \ |
|||
"-Djava.security.egd=file:/dev/./urandom", \ |
|||
"-Dserver.port=${SERVER_PORT}", \ |
|||
# 应用名称 如果想区分集群节点监控 改成不同的名称即可 |
|||
# "-Dskywalking.agent.service_name=ruoyi-server", \ |
|||
# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \ |
|||
"-jar", "app.jar"] |
@ -0,0 +1,111 @@ |
|||
<?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>alog-service</artifactId> |
|||
<groupId>com.inscloudtech</groupId> |
|||
<version>4.8.2</version> |
|||
</parent> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<packaging>jar</packaging> |
|||
<artifactId>alog-admin</artifactId> |
|||
|
|||
<description> |
|||
web服务入口 |
|||
</description> |
|||
|
|||
<dependencies> |
|||
|
|||
<!-- spring-boot-devtools --> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-devtools</artifactId> |
|||
<optional>true</optional> <!-- 表示依赖不会传递 --> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.dameng</groupId> |
|||
<artifactId>DmJdbcDriver18</artifactId> |
|||
<version>8.1.2.192</version> |
|||
</dependency> |
|||
|
|||
<!-- 核心模块--> |
|||
<dependency> |
|||
<groupId>com.inscloudtech</groupId> |
|||
<artifactId>alog-framework</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.inscloudtech</groupId> |
|||
<artifactId>alog-system</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.inscloudtech</groupId> |
|||
<artifactId>alog-oss</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- 代码生成--> |
|||
<dependency> |
|||
<groupId>com.inscloudtech</groupId> |
|||
<artifactId>alog-generator</artifactId> |
|||
</dependency> |
|||
|
|||
|
|||
<dependency> |
|||
<groupId>com.inscloudtech</groupId> |
|||
<artifactId>alog-worker</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-test</artifactId> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
|
|||
<!-- skywalking 整合 logback --> |
|||
<!-- <dependency>--> |
|||
<!-- <groupId>org.apache.skywalking</groupId>--> |
|||
<!-- <artifactId>apm-toolkit-logback-1.x</artifactId>--> |
|||
<!-- <version>${与你的agent探针版本保持一致}</version>--> |
|||
<!-- </dependency>--> |
|||
<!-- <dependency>--> |
|||
<!-- <groupId>org.apache.skywalking</groupId>--> |
|||
<!-- <artifactId>apm-toolkit-trace</artifactId>--> |
|||
<!-- <version>${与你的agent探针版本保持一致}</version>--> |
|||
<!-- </dependency>--> |
|||
|
|||
</dependencies> |
|||
|
|||
<build> |
|||
<finalName>${project.artifactId}</finalName> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-maven-plugin</artifactId> |
|||
<version>${spring-boot.version}</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.2.2</version> |
|||
<configuration> |
|||
<failOnMissingWebXml>false</failOnMissingWebXml> |
|||
<warName>${project.artifactId}</warName> |
|||
</configuration> |
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
|
|||
</project> |
@ -0,0 +1,23 @@ |
|||
package com.inscloudtech; |
|||
|
|||
import org.springframework.boot.SpringApplication; |
|||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
|||
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; |
|||
|
|||
/** |
|||
* 启动程序 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@SpringBootApplication |
|||
public class AlogServiceApplication { |
|||
public static void main(String[] args) { |
|||
System.setProperty("spring.devtools.restart.enabled", "false"); |
|||
SpringApplication application = new SpringApplication(AlogServiceApplication.class); |
|||
application.setApplicationStartup(new BufferingApplicationStartup(2048)); |
|||
application.run(args); |
|||
System.out.println("------------服务启动成功"); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.inscloudtech; |
|||
|
|||
import org.springframework.boot.builder.SpringApplicationBuilder; |
|||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
|||
|
|||
/** |
|||
* web容器中进行部署 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public class AlogServiceServletInitializer extends SpringBootServletInitializer { |
|||
|
|||
@Override |
|||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { |
|||
return application.sources(AlogServiceApplication.class); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,81 @@ |
|||
package com.inscloudtech.web.controller.common; |
|||
|
|||
import cn.dev33.satoken.annotation.SaIgnore; |
|||
import cn.hutool.captcha.AbstractCaptcha; |
|||
import cn.hutool.captcha.generator.CodeGenerator; |
|||
import cn.hutool.core.util.IdUtil; |
|||
import com.inscloudtech.common.constant.CacheConstants; |
|||
import com.inscloudtech.common.constant.Constants; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.enums.CaptchaType; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.common.utils.redis.RedisUtils; |
|||
import com.inscloudtech.common.utils.reflect.ReflectUtils; |
|||
import com.inscloudtech.common.utils.spring.SpringUtils; |
|||
import com.inscloudtech.framework.config.properties.CaptchaProperties; |
|||
import com.inscloudtech.system.service.ISysConfigService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.expression.Expression; |
|||
import org.springframework.expression.ExpressionParser; |
|||
import org.springframework.expression.spel.standard.SpelExpressionParser; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
import java.time.Duration; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 验证码操作处理 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@SaIgnore |
|||
@Slf4j |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
public class CaptchaController { |
|||
|
|||
private final CaptchaProperties captchaProperties; |
|||
private final ISysConfigService configService; |
|||
|
|||
|
|||
/** |
|||
* 生成验证码 |
|||
*/ |
|||
@GetMapping("/captchaImage") |
|||
public R<Map<String, Object>> getCode() { |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
boolean captchaEnabled = configService.selectCaptchaEnabled(); |
|||
ajax.put("captchaEnabled", captchaEnabled); |
|||
if (!captchaEnabled) { |
|||
return R.ok(ajax); |
|||
} |
|||
// 保存验证码信息 |
|||
String uuid = IdUtil.simpleUUID(); |
|||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; |
|||
// 生成验证码 |
|||
CaptchaType captchaType = captchaProperties.getType(); |
|||
boolean isMath = CaptchaType.MATH == captchaType; |
|||
Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength(); |
|||
CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length); |
|||
AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz()); |
|||
captcha.setGenerator(codeGenerator); |
|||
captcha.createCode(); |
|||
String code = captcha.getCode(); |
|||
if (isMath) { |
|||
ExpressionParser parser = new SpelExpressionParser(); |
|||
Expression exp = parser.parseExpression(StringUtils.remove(code, "=")); |
|||
code = exp.getValue(String.class); |
|||
} |
|||
RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); |
|||
ajax.put("uuid", uuid); |
|||
ajax.put("img", captcha.getImageBase64()); |
|||
return R.ok(ajax); |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,160 @@ |
|||
package com.inscloudtech.web.controller.common; |
|||
|
|||
|
|||
import com.inscloudtech.common.config.ProjectConfig; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.common.utils.file.FileUploadUtils; |
|||
import com.inscloudtech.common.utils.file.FileUtils; |
|||
import com.inscloudtech.framework.config.ServerConfig; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.http.MediaType; |
|||
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.RestController; |
|||
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 ruoyi |
|||
*/ |
|||
@RestController |
|||
@RequestMapping("/common") |
|||
public class CommonController { |
|||
private static final Logger log = LoggerFactory.getLogger(CommonController.class); |
|||
private static final String FILE_DELIMETER = ","; |
|||
|
|||
@Autowired |
|||
private ProjectConfig projectConfig; |
|||
|
|||
// /** |
|||
// * 自定义 Minio 服务器上传请求 |
|||
// */ |
|||
// @PostMapping("/uploadMinio") |
|||
// public R uploadFileMinio(MultipartFile file) throws Exception { |
|||
// try { |
|||
// // 上传并返回新文件名称 |
|||
// String fileName = FileUploadUtils.uploadMinio(file); |
|||
// AjaxResult ajax = AjaxResult.success(); |
|||
// ajax.put("url", fileName); |
|||
// ajax.put("fileName", fileName); |
|||
// ajax.put("newFileName", FileUtils.getName(fileName)); |
|||
// ajax.put("originalFilename", file.getOriginalFilename()); |
|||
// return ajax; |
|||
// } catch (Exception e) { |
|||
// return AjaxResult.error(e.getMessage()); |
|||
// } |
|||
// } |
|||
|
|||
/** |
|||
* 通用下载请求 |
|||
* |
|||
* @param fileName 文件名称 |
|||
*/ |
|||
@GetMapping("/download") |
|||
public void fileDownload(String fileName, 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 = projectConfig.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); |
|||
} |
|||
} |
|||
|
|||
// /** |
|||
// * 通用上传请求(单个) |
|||
// */ |
|||
// @PostMapping("/upload") |
|||
// public AjaxResult uploadFile(MultipartFile file) throws Exception { |
|||
// try { |
|||
// // 上传文件路径 |
|||
// String filePath = ProjectConfig.getUploadPath(); |
|||
// // 上传并返回新文件名称 |
|||
// String fileName = FileUploadUtils.upload(filePath, file); |
|||
// String url = serverConfig.getUrl() + fileName; |
|||
// AjaxResult ajax = AjaxResult.success(); |
|||
// ajax.put("url", url); |
|||
// ajax.put("fileName", fileName); |
|||
// ajax.put("newFileName", FileUtils.getName(fileName)); |
|||
// ajax.put("originalFilename", file.getOriginalFilename()); |
|||
// return ajax; |
|||
// } catch (Exception e) { |
|||
// return AjaxResult.error(e.getMessage()); |
|||
// } |
|||
// } |
|||
// |
|||
// /** |
|||
// * 通用上传请求(多个) |
|||
// */ |
|||
// @PostMapping("/uploads") |
|||
// public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception { |
|||
// try { |
|||
// // 上传文件路径 |
|||
// String filePath = ProjectConfig.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()); |
|||
// } |
|||
// AjaxResult ajax = AjaxResult.success(); |
|||
// ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); |
|||
// ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); |
|||
// ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); |
|||
// ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); |
|||
// return ajax; |
|||
// } catch (Exception e) { |
|||
// return AjaxResult.error(e.getMessage()); |
|||
// } |
|||
// } |
|||
// |
|||
// /** |
|||
// * 本地资源通用下载 |
|||
// */ |
|||
// @GetMapping("/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 = ProjectConfig.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); |
|||
// } |
|||
// } |
|||
} |
@ -0,0 +1,168 @@ |
|||
package com.inscloudtech.web.controller.monitor; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import cn.hutool.core.collection.CollUtil; |
|||
import com.inscloudtech.common.constant.CacheConstants; |
|||
import com.inscloudtech.common.constant.CacheNames; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.utils.JsonUtils; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.common.utils.redis.CacheUtils; |
|||
import com.inscloudtech.common.utils.redis.RedisUtils; |
|||
import com.inscloudtech.system.domain.SysCache; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.redisson.spring.data.connection.RedissonConnectionFactory; |
|||
import org.springframework.data.redis.connection.RedisConnection; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import java.util.*; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* 缓存监控 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/monitor/cache") |
|||
public class CacheController { |
|||
|
|||
private final RedissonConnectionFactory connectionFactory; |
|||
|
|||
private final static List<SysCache> CACHES = new ArrayList<>(); |
|||
|
|||
static { |
|||
CACHES.add(new SysCache(CacheConstants.ONLINE_TOKEN_KEY, "在线用户")); |
|||
CACHES.add(new SysCache(CacheNames.SYS_CONFIG, "配置信息")); |
|||
CACHES.add(new SysCache(CacheNames.SYS_DICT, "数据字典")); |
|||
CACHES.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); |
|||
CACHES.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); |
|||
CACHES.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); |
|||
CACHES.add(new SysCache(CacheNames.SYS_OSS_CONFIG, "OSS配置")); |
|||
CACHES.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); |
|||
} |
|||
|
|||
/** |
|||
* 获取缓存监控列表 |
|||
*/ |
|||
@SaCheckPermission("monitor:cache:list") |
|||
@GetMapping() |
|||
public R<Map<String, Object>> getInfo() throws Exception { |
|||
RedisConnection connection = connectionFactory.getConnection(); |
|||
Properties info = connection.info(); |
|||
Properties commandStats = connection.info("commandstats"); |
|||
Long dbSize = connection.dbSize(); |
|||
|
|||
Map<String, Object> result = new HashMap<>(3); |
|||
result.put("info", info); |
|||
result.put("dbSize", dbSize); |
|||
|
|||
List<Map<String, String>> pieList = new ArrayList<>(); |
|||
if (commandStats != null) { |
|||
commandStats.stringPropertyNames().forEach(key -> { |
|||
Map<String, String> data = new HashMap<>(2); |
|||
String property = commandStats.getProperty(key); |
|||
data.put("name", StringUtils.removeStart(key, "cmdstat_")); |
|||
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); |
|||
pieList.add(data); |
|||
}); |
|||
} |
|||
result.put("commandStats", pieList); |
|||
return R.ok(result); |
|||
} |
|||
|
|||
/** |
|||
* 获取缓存监控缓存名列表 |
|||
*/ |
|||
@SaCheckPermission("monitor:cache:list") |
|||
@GetMapping("/getNames") |
|||
public R<List<SysCache>> cache() { |
|||
return R.ok(CACHES); |
|||
} |
|||
|
|||
/** |
|||
* 获取缓存监控Key列表 |
|||
* |
|||
* @param cacheName 缓存名 |
|||
*/ |
|||
@SaCheckPermission("monitor:cache:list") |
|||
@GetMapping("/getKeys/{cacheName}") |
|||
public R<Collection<String>> getCacheKeys(@PathVariable String cacheName) { |
|||
Collection<String> cacheKeys = new HashSet<>(0); |
|||
if (isCacheNames(cacheName)) { |
|||
Set<Object> keys = CacheUtils.keys(cacheName); |
|||
if (CollUtil.isNotEmpty(keys)) { |
|||
cacheKeys = keys.stream().map(Object::toString).collect(Collectors.toList()); |
|||
} |
|||
} else { |
|||
cacheKeys = RedisUtils.keys(cacheName + "*"); |
|||
} |
|||
return R.ok(cacheKeys); |
|||
} |
|||
|
|||
/** |
|||
* 获取缓存监控缓存值详情 |
|||
* |
|||
* @param cacheName 缓存名 |
|||
* @param cacheKey 缓存key |
|||
*/ |
|||
@SaCheckPermission("monitor:cache:list") |
|||
@GetMapping("/getValue/{cacheName}/{cacheKey}") |
|||
public R<SysCache> getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) { |
|||
Object cacheValue; |
|||
if (isCacheNames(cacheName)) { |
|||
cacheValue = CacheUtils.get(cacheName, cacheKey); |
|||
} else { |
|||
cacheValue = RedisUtils.getCacheObject(cacheKey); |
|||
} |
|||
SysCache sysCache = new SysCache(cacheName, cacheKey, JsonUtils.toJsonString(cacheValue)); |
|||
return R.ok(sysCache); |
|||
} |
|||
|
|||
/** |
|||
* 清理缓存监控缓存名 |
|||
* |
|||
* @param cacheName 缓存名 |
|||
*/ |
|||
@SaCheckPermission("monitor:cache:list") |
|||
@DeleteMapping("/clearCacheName/{cacheName}") |
|||
public R<Void> clearCacheName(@PathVariable String cacheName) { |
|||
if (isCacheNames(cacheName)) { |
|||
CacheUtils.clear(cacheName); |
|||
} else { |
|||
RedisUtils.deleteKeys(cacheName + "*"); |
|||
} |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 清理缓存监控Key |
|||
* |
|||
* @param cacheKey key名 |
|||
*/ |
|||
@SaCheckPermission("monitor:cache:list") |
|||
@DeleteMapping("/clearCacheKey/{cacheName}/{cacheKey}") |
|||
public R<Void> clearCacheKey(@PathVariable String cacheName, @PathVariable String cacheKey) { |
|||
if (isCacheNames(cacheName)) { |
|||
CacheUtils.evict(cacheName, cacheKey); |
|||
} else { |
|||
RedisUtils.deleteObject(cacheKey); |
|||
} |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 清理全部缓存监控 |
|||
*/ |
|||
@SaCheckPermission("monitor:cache:list") |
|||
@DeleteMapping("/clearCacheAll") |
|||
public R<Void> clearCacheAll() { |
|||
RedisUtils.deleteKeys("*"); |
|||
return R.ok(); |
|||
} |
|||
|
|||
private boolean isCacheNames(String cacheName) { |
|||
return !StringUtils.contains(cacheName, ":"); |
|||
} |
|||
} |
@ -0,0 +1,88 @@ |
|||
package com.inscloudtech.web.controller.monitor; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.constant.CacheConstants; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.utils.poi.ExcelUtil; |
|||
import com.inscloudtech.common.utils.redis.RedisUtils; |
|||
import com.inscloudtech.system.domain.SysLogininfor; |
|||
import com.inscloudtech.system.service.ISysLogininforService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 系统访问记录 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/monitor/logininfor") |
|||
public class SysLogininforController extends BaseController { |
|||
|
|||
private final ISysLogininforService logininforService; |
|||
|
|||
/** |
|||
* 获取系统访问记录列表 |
|||
*/ |
|||
@SaCheckPermission("monitor:logininfor:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysLogininfor> list(SysLogininfor logininfor, PageQuery pageQuery) { |
|||
return logininforService.selectPageLogininforList(logininfor, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 导出系统访问记录列表 |
|||
*/ |
|||
@Log(title = "登录日志", businessType = BusinessType.EXPORT) |
|||
@SaCheckPermission("monitor:logininfor:export") |
|||
@PostMapping("/export") |
|||
public void export(SysLogininfor logininfor, HttpServletResponse response) { |
|||
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor); |
|||
ExcelUtil.exportExcel(list, "登录日志", SysLogininfor.class, response); |
|||
} |
|||
|
|||
/** |
|||
* 批量删除登录日志 |
|||
* @param infoIds 日志ids |
|||
*/ |
|||
@SaCheckPermission("monitor:logininfor:remove") |
|||
@Log(title = "登录日志", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{infoIds}") |
|||
public R<Void> remove(@PathVariable Long[] infoIds) { |
|||
return toAjax(logininforService.deleteLogininforByIds(infoIds)); |
|||
} |
|||
|
|||
/** |
|||
* 清理系统访问记录 |
|||
*/ |
|||
@SaCheckPermission("monitor:logininfor:remove") |
|||
@Log(title = "登录日志", businessType = BusinessType.CLEAN) |
|||
@DeleteMapping("/clean") |
|||
public R<Void> clean() { |
|||
logininforService.cleanLogininfor(); |
|||
return R.ok(); |
|||
} |
|||
|
|||
@SaCheckPermission("monitor:logininfor:unlock") |
|||
@Log(title = "账户解锁", businessType = BusinessType.OTHER) |
|||
@GetMapping("/unlock/{userName}") |
|||
public R<Void> unlock(@PathVariable("userName") String userName) { |
|||
String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName; |
|||
if (RedisUtils.hasKey(loginName)) { |
|||
RedisUtils.deleteObject(loginName); |
|||
} |
|||
return R.ok(); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,74 @@ |
|||
package com.inscloudtech.web.controller.monitor; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.utils.poi.ExcelUtil; |
|||
import com.inscloudtech.system.domain.SysOperLog; |
|||
import com.inscloudtech.system.service.ISysOperLogService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 安全审计模块 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/monitor/operlog") |
|||
public class SysOperlogController extends BaseController { |
|||
|
|||
private final ISysOperLogService operLogService; |
|||
|
|||
/** |
|||
* 获取操作记录列表 |
|||
*/ |
|||
@SaCheckPermission("monitor:operlog:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysOperLog> list(SysOperLog operLog, PageQuery pageQuery) { |
|||
return operLogService.selectPageOperLogList(operLog, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 导出操作记录列表 |
|||
*/ |
|||
@Log(title = "操作", businessType = BusinessType.EXPORT) |
|||
@SaCheckPermission("monitor:operlog:export") |
|||
@PostMapping("/export") |
|||
public void export(SysOperLog operLog, HttpServletResponse response) { |
|||
List<SysOperLog> list = operLogService.selectOperLogList(operLog); |
|||
ExcelUtil.exportExcel(list, "操作", SysOperLog.class, response); |
|||
} |
|||
|
|||
/** |
|||
* 批量删除操作记录 |
|||
* @param operIds ids |
|||
*/ |
|||
@Log(title = "操作", businessType = BusinessType.DELETE) |
|||
@SaCheckPermission("monitor:operlog:remove") |
|||
@DeleteMapping("/{operIds}") |
|||
public R<Void> remove(@PathVariable Long[] operIds) { |
|||
return toAjax(operLogService.deleteOperLogByIds(operIds)); |
|||
} |
|||
|
|||
/** |
|||
* 清理操作记录 |
|||
*/ |
|||
@Log(title = "操作", businessType = BusinessType.CLEAN) |
|||
@SaCheckPermission("monitor:operlog:remove") |
|||
@DeleteMapping("/clean") |
|||
public R<Void> clean() { |
|||
operLogService.cleanOperLog(); |
|||
return R.ok(); |
|||
} |
|||
} |
@ -0,0 +1,90 @@ |
|||
package com.inscloudtech.web.controller.monitor; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import cn.dev33.satoken.exception.NotLoginException; |
|||
import cn.dev33.satoken.stp.StpUtil; |
|||
import cn.hutool.core.bean.BeanUtil; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.constant.CacheConstants; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.dto.UserOnlineDTO; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.utils.StreamUtils; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.common.utils.redis.RedisUtils; |
|||
import com.inscloudtech.system.domain.SysUserOnline; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Collections; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 在线用户监控 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/monitor/online") |
|||
public class SysUserOnlineController extends BaseController { |
|||
|
|||
/** |
|||
* 获取在线用户监控列表 |
|||
* |
|||
* @param ipaddr IP地址 |
|||
* @param userName 用户名 |
|||
*/ |
|||
@SaCheckPermission("monitor:online:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) { |
|||
// 获取所有未过期的 token |
|||
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false); |
|||
List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>(); |
|||
for (String key : keys) { |
|||
String token = StringUtils.substringAfterLast(key, ":"); |
|||
// 如果已经过期则跳过 |
|||
if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) { |
|||
continue; |
|||
} |
|||
userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token)); |
|||
} |
|||
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { |
|||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> |
|||
StringUtils.equals(ipaddr, userOnline.getIpaddr()) && |
|||
StringUtils.equals(userName, userOnline.getUserName()) |
|||
); |
|||
} else if (StringUtils.isNotEmpty(ipaddr)) { |
|||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> |
|||
StringUtils.equals(ipaddr, userOnline.getIpaddr()) |
|||
); |
|||
} else if (StringUtils.isNotEmpty(userName)) { |
|||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> |
|||
StringUtils.equals(userName, userOnline.getUserName()) |
|||
); |
|||
} |
|||
Collections.reverse(userOnlineDTOList); |
|||
userOnlineDTOList.removeAll(Collections.singleton(null)); |
|||
List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class); |
|||
return TableDataInfo.build(userOnlineList); |
|||
} |
|||
|
|||
/** |
|||
* 强退用户 |
|||
* |
|||
* @param tokenId token值 |
|||
*/ |
|||
@SaCheckPermission("monitor:online:forceLogout") |
|||
@Log(title = "在线用户", businessType = BusinessType.FORCE) |
|||
@DeleteMapping("/{tokenId}") |
|||
public R<Void> forceLogout(@PathVariable String tokenId) { |
|||
try { |
|||
StpUtil.kickoutByTokenValue(tokenId); |
|||
} catch (NotLoginException ignored) { |
|||
} |
|||
return R.ok(); |
|||
} |
|||
} |
@ -0,0 +1,136 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.utils.poi.ExcelUtil; |
|||
import com.inscloudtech.system.domain.SysConfig; |
|||
import com.inscloudtech.system.service.ISysConfigService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 参数配置 信息操作处理 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/config") |
|||
public class SysConfigController extends BaseController { |
|||
|
|||
private final ISysConfigService configService; |
|||
|
|||
/** |
|||
* 获取参数配置列表 |
|||
*/ |
|||
@SaCheckPermission("system:config:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysConfig> list(SysConfig config, PageQuery pageQuery) { |
|||
return configService.selectPageConfigList(config, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 导出参数配置列表 |
|||
*/ |
|||
@Log(title = "参数管理", businessType = BusinessType.EXPORT) |
|||
@SaCheckPermission("system:config:export") |
|||
@PostMapping("/export") |
|||
public void export(SysConfig config, HttpServletResponse response) { |
|||
List<SysConfig> list = configService.selectConfigList(config); |
|||
ExcelUtil.exportExcel(list, "参数数据", SysConfig.class, response); |
|||
} |
|||
|
|||
/** |
|||
* 根据参数编号获取详细信息 |
|||
* |
|||
* @param configId 参数ID |
|||
*/ |
|||
@SaCheckPermission("system:config:query") |
|||
@GetMapping(value = "/{configId}") |
|||
public R<SysConfig> getInfo(@PathVariable Long configId) { |
|||
return R.ok(configService.selectConfigById(configId)); |
|||
} |
|||
|
|||
/** |
|||
* 根据参数键名查询参数值 |
|||
* |
|||
* @param configKey 参数Key |
|||
*/ |
|||
@GetMapping(value = "/configKey/{configKey}") |
|||
public R<Void> getConfigKey(@PathVariable String configKey) { |
|||
return R.ok(configService.selectConfigByKey(configKey)); |
|||
} |
|||
|
|||
/** |
|||
* 新增参数配置 |
|||
*/ |
|||
@SaCheckPermission("system:config:add") |
|||
@Log(title = "参数管理", businessType = BusinessType.INSERT) |
|||
@PostMapping |
|||
public R<Void> add(@Validated @RequestBody SysConfig config) { |
|||
if (!configService.checkConfigKeyUnique(config)) { |
|||
return R.fail("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); |
|||
} |
|||
configService.insertConfig(config); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 修改参数配置 |
|||
*/ |
|||
@SaCheckPermission("system:config:edit") |
|||
@Log(title = "参数管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping |
|||
public R<Void> edit(@Validated @RequestBody SysConfig config) { |
|||
if (!configService.checkConfigKeyUnique(config)) { |
|||
return R.fail("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); |
|||
} |
|||
configService.updateConfig(config); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 根据参数键名修改参数配置 |
|||
*/ |
|||
@SaCheckPermission("system:config:edit") |
|||
@Log(title = "参数管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping("/updateByKey") |
|||
public R<Void> updateByKey(@RequestBody SysConfig config) { |
|||
configService.updateConfig(config); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 删除参数配置 |
|||
* |
|||
* @param configIds 参数ID串 |
|||
*/ |
|||
@SaCheckPermission("system:config:remove") |
|||
@Log(title = "参数管理", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{configIds}") |
|||
public R<Void> remove(@PathVariable Long[] configIds) { |
|||
configService.deleteConfigByIds(configIds); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 刷新参数缓存 |
|||
*/ |
|||
@SaCheckPermission("system:config:remove") |
|||
@Log(title = "参数管理", businessType = BusinessType.CLEAN) |
|||
@DeleteMapping("/refreshCache") |
|||
public R<Void> refreshCache() { |
|||
configService.resetConfigCache(); |
|||
return R.ok(); |
|||
} |
|||
} |
@ -0,0 +1,122 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import cn.hutool.core.convert.Convert; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.constant.UserConstants; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.entity.SysDept; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.system.service.ISysDeptService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 部门信息 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/dept") |
|||
public class SysDeptController extends BaseController { |
|||
|
|||
private final ISysDeptService deptService; |
|||
|
|||
/** |
|||
* 获取部门列表 |
|||
*/ |
|||
@SaCheckPermission("system:dept:list") |
|||
@GetMapping("/list") |
|||
public R<List<SysDept>> list(SysDept dept) { |
|||
List<SysDept> depts = deptService.selectDeptList(dept); |
|||
return R.ok(depts); |
|||
} |
|||
|
|||
/** |
|||
* 查询部门列表(排除节点) |
|||
* |
|||
* @param deptId 部门ID |
|||
*/ |
|||
@SaCheckPermission("system:dept:list") |
|||
@GetMapping("/list/exclude/{deptId}") |
|||
public R<List<SysDept>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) { |
|||
List<SysDept> depts = deptService.selectDeptList(new SysDept()); |
|||
depts.removeIf(d -> d.getDeptId().equals(deptId) |
|||
|| StringUtils.splitList(d.getAncestors()).contains(Convert.toStr(deptId))); |
|||
return R.ok(depts); |
|||
} |
|||
|
|||
/** |
|||
* 根据部门编号获取详细信息 |
|||
* |
|||
* @param deptId 部门ID |
|||
*/ |
|||
@SaCheckPermission("system:dept:query") |
|||
@GetMapping(value = "/{deptId}") |
|||
public R<SysDept> getInfo(@PathVariable Long deptId) { |
|||
deptService.checkDeptDataScope(deptId); |
|||
return R.ok(deptService.selectDeptById(deptId)); |
|||
} |
|||
|
|||
/** |
|||
* 新增部门 |
|||
*/ |
|||
@SaCheckPermission("system:dept:add") |
|||
@Log(title = "部门管理", businessType = BusinessType.INSERT) |
|||
@PostMapping |
|||
public R<Void> add(@Validated @RequestBody SysDept dept) { |
|||
if (!deptService.checkDeptNameUnique(dept)) { |
|||
return R.fail("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); |
|||
} |
|||
return toAjax(deptService.insertDept(dept)); |
|||
} |
|||
|
|||
/** |
|||
* 修改部门 |
|||
*/ |
|||
@SaCheckPermission("system:dept:edit") |
|||
@Log(title = "部门管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping |
|||
public R<Void> edit(@Validated @RequestBody SysDept dept) { |
|||
Long deptId = dept.getDeptId(); |
|||
deptService.checkDeptDataScope(deptId); |
|||
if (!deptService.checkDeptNameUnique(dept)) { |
|||
return R.fail("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); |
|||
} else if (dept.getParentId().equals(deptId)) { |
|||
return R.fail("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); |
|||
} else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus())) { |
|||
if (deptService.selectNormalChildrenDeptById(deptId) > 0) { |
|||
return R.fail("该部门包含未停用的子部门!"); |
|||
} else if (deptService.checkDeptExistUser(deptId)) { |
|||
return R.fail("该部门下存在已分配用户,不能禁用!"); |
|||
} |
|||
} |
|||
return toAjax(deptService.updateDept(dept)); |
|||
} |
|||
|
|||
/** |
|||
* 删除部门 |
|||
* |
|||
* @param deptId 部门ID |
|||
*/ |
|||
@SaCheckPermission("system:dept:remove") |
|||
@Log(title = "部门管理", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{deptId}") |
|||
public R<Void> remove(@PathVariable Long deptId) { |
|||
if (deptService.hasChildByDeptId(deptId)) { |
|||
return R.warn("存在下级部门,不允许删除"); |
|||
} |
|||
if (deptService.checkDeptExistUser(deptId)) { |
|||
return R.warn("部门存在用户,不允许删除"); |
|||
} |
|||
deptService.checkDeptDataScope(deptId); |
|||
return toAjax(deptService.deleteDeptById(deptId)); |
|||
} |
|||
} |
@ -0,0 +1,164 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.entity.SysDictData; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.excel.ExcelResult; |
|||
import com.inscloudtech.common.utils.poi.ExcelUtil; |
|||
import com.inscloudtech.system.domain.vo.SysUserImportVo; |
|||
import com.inscloudtech.system.domain.vo.TerminalListVo; |
|||
import com.inscloudtech.system.listener.SysUserImportListener; |
|||
import com.inscloudtech.system.service.ISysDictDataService; |
|||
import com.inscloudtech.system.service.ISysDictTypeService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.http.MediaType; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 数据字典信息 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/dict/data") |
|||
public class SysDictDataController extends BaseController { |
|||
|
|||
private final ISysDictDataService dictDataService; |
|||
private final ISysDictTypeService dictTypeService; |
|||
|
|||
/** |
|||
* 查询字典数据列表 |
|||
*/ |
|||
@SaCheckPermission("system:dict:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysDictData> list(SysDictData dictData, PageQuery pageQuery) { |
|||
return dictDataService.selectPageDictDataList(dictData, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 导出字典数据列表 |
|||
*/ |
|||
@Log(title = "字典数据", businessType = BusinessType.EXPORT) |
|||
@SaCheckPermission("system:dict:export") |
|||
@PostMapping("/export") |
|||
public void export(SysDictData dictData, HttpServletResponse response) { |
|||
List<SysDictData> list = dictDataService.selectDictDataList(dictData); |
|||
ExcelUtil.exportExcel(list, "字典数据", SysDictData.class, response); |
|||
} |
|||
|
|||
/** |
|||
* 查询字典数据详细 |
|||
* |
|||
* @param dictCode 字典code |
|||
*/ |
|||
@SaCheckPermission("system:dict:query") |
|||
@GetMapping(value = "/{dictCode}") |
|||
public R<SysDictData> getInfo(@PathVariable Long dictCode) { |
|||
return R.ok(dictDataService.selectDictDataById(dictCode)); |
|||
} |
|||
|
|||
/** |
|||
* 根据字典类型查询字典数据信息 |
|||
* |
|||
* @param dictType 字典类型 |
|||
*/ |
|||
@GetMapping(value = "/type/{dictType}") |
|||
public R<List<SysDictData>> dictType(@PathVariable String dictType) { |
|||
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType); |
|||
if (ObjectUtil.isNull(data)) { |
|||
data = new ArrayList<>(); |
|||
} |
|||
return R.ok(data); |
|||
} |
|||
|
|||
/** |
|||
* 新增字典类型 |
|||
*/ |
|||
@SaCheckPermission("system:dict:add") |
|||
@Log(title = "字典数据", businessType = BusinessType.INSERT) |
|||
@PostMapping |
|||
public R<Void> add(@Validated @RequestBody SysDictData dict) { |
|||
dictDataService.insertDictData(dict); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 修改保存字典类型 |
|||
*/ |
|||
@SaCheckPermission("system:dict:edit") |
|||
@Log(title = "字典数据", businessType = BusinessType.UPDATE) |
|||
@PutMapping |
|||
public R<Void> edit(@Validated @RequestBody SysDictData dict) { |
|||
dictDataService.updateDictData(dict); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 删除字典类型 |
|||
* |
|||
* @param dictCodes 字典code串 |
|||
*/ |
|||
@SaCheckPermission("system:dict:remove") |
|||
@Log(title = "字典类型", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{dictCodes}") |
|||
public R<Void> remove(@PathVariable Long[] dictCodes) { |
|||
dictDataService.deleteDictDataByIds(dictCodes); |
|||
return R.ok(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 导入终端列表 |
|||
*/ |
|||
@PostMapping(value = "/uploadTerminalList", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
|||
public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception { |
|||
ExcelResult<TerminalListVo> result = ExcelUtil.importExcel(file.getInputStream(), TerminalListVo.class, true); |
|||
List<TerminalListVo> list = result.getList(); |
|||
if(list.size() > 0){ |
|||
dictDataService.deleteDictDataByDictType("terminal_list"); |
|||
for (TerminalListVo vo : list) { |
|||
SysDictData sysDictData = new SysDictData(); |
|||
sysDictData.setDictType("terminal_list"); |
|||
String s = vo.getZdpp() + "-" + vo.getZdmc() + "-" + vo.getXtbb(); |
|||
sysDictData.setDictLabel(s); |
|||
sysDictData.setDictValue(s); |
|||
dictDataService.insertDictData(sysDictData); |
|||
} |
|||
} |
|||
return R.ok("终端列表更新完成!"); |
|||
} |
|||
|
|||
/** |
|||
* 导入框架列表 |
|||
*/ |
|||
@PostMapping(value = "/uploadFrameworkList", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
|||
public R<Void> importFrameworkList(@RequestPart("file") MultipartFile file) throws Exception { |
|||
ExcelResult<TerminalListVo> result = ExcelUtil.importExcel(file.getInputStream(), TerminalListVo.class, true); |
|||
List<TerminalListVo> list = result.getList(); |
|||
if(list.size() > 0){ |
|||
dictDataService.deleteDictDataByDictType("framework_list"); |
|||
for (TerminalListVo vo : list) { |
|||
SysDictData sysDictData = new SysDictData(); |
|||
sysDictData.setDictType("framework_list"); |
|||
sysDictData.setDictLabel(vo.getKjmc()); |
|||
sysDictData.setDictValue(vo.getKjmc()); |
|||
dictDataService.insertDictData(sysDictData); |
|||
} |
|||
} |
|||
return R.ok("框架列表更新完成!"); |
|||
} |
|||
} |
@ -0,0 +1,124 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.entity.SysDictType; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.utils.poi.ExcelUtil; |
|||
import com.inscloudtech.system.service.ISysDictTypeService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 数据字典信息 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/dict/type") |
|||
public class SysDictTypeController extends BaseController { |
|||
|
|||
private final ISysDictTypeService dictTypeService; |
|||
|
|||
/** |
|||
* 查询字典类型列表 |
|||
*/ |
|||
@SaCheckPermission("system:dict:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysDictType> list(SysDictType dictType, PageQuery pageQuery) { |
|||
return dictTypeService.selectPageDictTypeList(dictType, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 导出字典类型列表 |
|||
*/ |
|||
@Log(title = "字典类型", businessType = BusinessType.EXPORT) |
|||
@SaCheckPermission("system:dict:export") |
|||
@PostMapping("/export") |
|||
public void export(SysDictType dictType, HttpServletResponse response) { |
|||
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType); |
|||
ExcelUtil.exportExcel(list, "字典类型", SysDictType.class, response); |
|||
} |
|||
|
|||
/** |
|||
* 查询字典类型详细 |
|||
* |
|||
* @param dictId 字典ID |
|||
*/ |
|||
@SaCheckPermission("system:dict:query") |
|||
@GetMapping(value = "/{dictId}") |
|||
public R<SysDictType> getInfo(@PathVariable Long dictId) { |
|||
return R.ok(dictTypeService.selectDictTypeById(dictId)); |
|||
} |
|||
|
|||
/** |
|||
* 新增字典类型 |
|||
*/ |
|||
@SaCheckPermission("system:dict:add") |
|||
@Log(title = "字典类型", businessType = BusinessType.INSERT) |
|||
@PostMapping |
|||
public R<Void> add(@Validated @RequestBody SysDictType dict) { |
|||
if (!dictTypeService.checkDictTypeUnique(dict)) { |
|||
return R.fail("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); |
|||
} |
|||
dictTypeService.insertDictType(dict); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 修改字典类型 |
|||
*/ |
|||
@SaCheckPermission("system:dict:edit") |
|||
@Log(title = "字典类型", businessType = BusinessType.UPDATE) |
|||
@PutMapping |
|||
public R<Void> edit(@Validated @RequestBody SysDictType dict) { |
|||
if (!dictTypeService.checkDictTypeUnique(dict)) { |
|||
return R.fail("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); |
|||
} |
|||
dictTypeService.updateDictType(dict); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 删除字典类型 |
|||
* |
|||
* @param dictIds 字典ID串 |
|||
*/ |
|||
@SaCheckPermission("system:dict:remove") |
|||
@Log(title = "字典类型", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{dictIds}") |
|||
public R<Void> remove(@PathVariable Long[] dictIds) { |
|||
dictTypeService.deleteDictTypeByIds(dictIds); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 刷新字典缓存 |
|||
*/ |
|||
@SaCheckPermission("system:dict:remove") |
|||
@Log(title = "字典类型", businessType = BusinessType.CLEAN) |
|||
@DeleteMapping("/refreshCache") |
|||
public R<Void> refreshCache() { |
|||
dictTypeService.resetDictCache(); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 获取字典选择框列表 |
|||
*/ |
|||
@GetMapping("/optionselect") |
|||
public R<List<SysDictType>> optionselect() { |
|||
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll(); |
|||
return R.ok(dictTypes); |
|||
} |
|||
} |
@ -0,0 +1,97 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
/***/ |
|||
|
|||
|
|||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.annotation.RepeatSubmit; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.system.domain.SysExceptionReport; |
|||
import com.inscloudtech.system.domain.SysRequestLog; |
|||
import com.inscloudtech.system.service.SysExceptionReportService; |
|||
import com.inscloudtech.system.service.SysRequestLogService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
/** |
|||
* 异常情况报告 |
|||
* |
|||
* @author zfcf |
|||
* @date 2024-08-28 |
|||
*/ |
|||
|
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/functional/exceptionReport") |
|||
public class SysExceptionReportController { |
|||
|
|||
private final SysExceptionReportService iSysExceptionReportService; |
|||
|
|||
private final SysRequestLogService sysRequestLogService; |
|||
|
|||
|
|||
|
|||
/** |
|||
* 分页查询 |
|||
* @param |
|||
* @param |
|||
* @return |
|||
*/ |
|||
@GetMapping("/page") |
|||
public TableDataInfo<SysExceptionReport> page(PageQuery pageQuery, SysExceptionReport sysExceptionReport) { |
|||
Page page = new Page(); |
|||
page.setSize(pageQuery.getPageSize()); |
|||
page.setCurrent(pageQuery.getPageNum()); |
|||
|
|||
Page result = iSysExceptionReportService.page(page, Wrappers.query(sysExceptionReport).orderByDesc("oper_time")); |
|||
TableDataInfo dataInfo = new TableDataInfo(); |
|||
dataInfo.setTotal(result.getTotal()); |
|||
dataInfo.setRows(result.getRecords()); |
|||
return dataInfo; |
|||
} |
|||
|
|||
|
|||
|
|||
/** |
|||
* 修改异常情况报告已读 |
|||
* @param |
|||
* @return R |
|||
*/ |
|||
@Log(title = "异常情况报告", businessType = BusinessType.UPDATE) |
|||
@RepeatSubmit() |
|||
@PutMapping("/updateById") |
|||
public R updateById(@RequestBody SysExceptionReport report) { |
|||
return R.ok(iSysExceptionReportService.updateById(report)); |
|||
} |
|||
|
|||
/** |
|||
* 修改异常情况报告阈值 |
|||
* @param |
|||
* @return R |
|||
*/ |
|||
@Log(title = "异常情况报告", businessType = BusinessType.UPDATE) |
|||
@RepeatSubmit() |
|||
@PutMapping("/updateYz") |
|||
public R updateYz(@RequestBody SysRequestLog sysRequestLog) { |
|||
sysRequestLogService.updateYz(sysRequestLog); |
|||
return R.ok(); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 获取异常情况报告阈值 |
|||
* |
|||
*/ |
|||
@GetMapping("/getYzInfo") |
|||
public R getInfo() { |
|||
return R.ok(sysRequestLogService.getYzInfo()); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,32 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaIgnore; |
|||
import com.inscloudtech.common.config.ProjectConfig; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
/** |
|||
* 首页 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
public class SysIndexController { |
|||
|
|||
/** |
|||
* 系统基础配置 |
|||
*/ |
|||
private final ProjectConfig ruoyiConfig; |
|||
|
|||
/** |
|||
* 访问首页,提示语 |
|||
*/ |
|||
@SaIgnore |
|||
@GetMapping("/") |
|||
public String index() { |
|||
return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion()); |
|||
} |
|||
} |
@ -0,0 +1,144 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaIgnore; |
|||
import com.inscloudtech.common.constant.Constants; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.entity.SysMenu; |
|||
import com.inscloudtech.common.core.domain.entity.SysUser; |
|||
import com.inscloudtech.common.core.domain.model.EmailLoginBody; |
|||
import com.inscloudtech.common.core.domain.model.LoginBody; |
|||
import com.inscloudtech.common.core.domain.model.LoginUser; |
|||
import com.inscloudtech.common.core.domain.model.SmsLoginBody; |
|||
import com.inscloudtech.common.helper.LoginHelper; |
|||
import com.inscloudtech.system.domain.vo.RouterVo; |
|||
import com.inscloudtech.system.service.ISysMenuService; |
|||
import com.inscloudtech.system.service.ISysUserService; |
|||
import com.inscloudtech.system.service.SysLoginService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
import javax.validation.constraints.NotBlank; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 登录验证 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
public class SysLoginController { |
|||
|
|||
private final SysLoginService loginService; |
|||
private final ISysMenuService menuService; |
|||
private final ISysUserService userService; |
|||
|
|||
/** |
|||
* 登录方法 |
|||
* |
|||
* @param loginBody 登录信息 |
|||
* @return 结果 |
|||
*/ |
|||
@SaIgnore |
|||
@PostMapping("/login") |
|||
public R<Map<String, Object>> login(@Validated @RequestBody LoginBody loginBody) { |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
// 生成令牌 |
|||
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), |
|||
loginBody.getUuid()); |
|||
ajax.put(Constants.TOKEN, token); |
|||
return R.ok(ajax); |
|||
} |
|||
|
|||
/** |
|||
* 短信登录 |
|||
* |
|||
* @param smsLoginBody 登录信息 |
|||
* @return 结果 |
|||
*/ |
|||
@SaIgnore |
|||
@PostMapping("/smsLogin") |
|||
public R<Map<String, Object>> smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) { |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
// 生成令牌 |
|||
String token = loginService.smsLogin(smsLoginBody.getPhonenumber(), smsLoginBody.getSmsCode()); |
|||
ajax.put(Constants.TOKEN, token); |
|||
return R.ok(ajax); |
|||
} |
|||
|
|||
/** |
|||
* 邮件登录 |
|||
* |
|||
* @param body 登录信息 |
|||
* @return 结果 |
|||
*/ |
|||
@PostMapping("/emailLogin") |
|||
public R<Map<String, Object>> emailLogin(@Validated @RequestBody EmailLoginBody body) { |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
// 生成令牌 |
|||
String token = loginService.emailLogin(body.getEmail(), body.getEmailCode()); |
|||
ajax.put(Constants.TOKEN, token); |
|||
return R.ok(ajax); |
|||
} |
|||
|
|||
/** |
|||
* 小程序登录(示例) |
|||
* |
|||
* @param xcxCode 小程序code |
|||
* @return 结果 |
|||
*/ |
|||
@SaIgnore |
|||
@PostMapping("/xcxLogin") |
|||
public R<Map<String, Object>> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) { |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
// 生成令牌 |
|||
String token = loginService.xcxLogin(xcxCode); |
|||
ajax.put(Constants.TOKEN, token); |
|||
return R.ok(ajax); |
|||
} |
|||
|
|||
/** |
|||
* 退出登录 |
|||
*/ |
|||
@SaIgnore |
|||
@PostMapping("/logout") |
|||
public R<Void> logout() { |
|||
loginService.logout(); |
|||
return R.ok("退出成功"); |
|||
} |
|||
|
|||
/** |
|||
* 获取用户信息 |
|||
* |
|||
* @return 用户信息 |
|||
*/ |
|||
@GetMapping("getInfo") |
|||
public R<Map<String, Object>> getInfo() { |
|||
LoginUser loginUser = LoginHelper.getLoginUser(); |
|||
SysUser user = userService.selectUserById(loginUser.getUserId()); |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
ajax.put("user", user); |
|||
ajax.put("roles", loginUser.getRolePermission()); |
|||
ajax.put("permissions", loginUser.getMenuPermission()); |
|||
return R.ok(ajax); |
|||
} |
|||
|
|||
/** |
|||
* 获取路由信息 |
|||
* |
|||
* @return 路由信息 |
|||
*/ |
|||
@GetMapping("getRouters") |
|||
public R<List<RouterVo>> getRouters() { |
|||
Long userId = LoginHelper.getUserId(); |
|||
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId); |
|||
return R.ok(menuService.buildMenus(menus)); |
|||
} |
|||
} |
@ -0,0 +1,127 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import cn.hutool.core.lang.tree.Tree; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.constant.UserConstants; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.entity.SysMenu; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.system.service.ISysMenuService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 菜单信息 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/menu") |
|||
public class SysMenuController extends BaseController { |
|||
|
|||
private final ISysMenuService menuService; |
|||
|
|||
/** |
|||
* 获取菜单列表 |
|||
*/ |
|||
@SaCheckPermission("system:menu:list") |
|||
@GetMapping("/list") |
|||
public R<List<SysMenu>> list(SysMenu menu) { |
|||
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId()); |
|||
return R.ok(menus); |
|||
} |
|||
|
|||
/** |
|||
* 根据菜单编号获取详细信息 |
|||
* |
|||
* @param menuId 菜单ID |
|||
*/ |
|||
@SaCheckPermission("system:menu:query") |
|||
@GetMapping(value = "/{menuId}") |
|||
public R<SysMenu> getInfo(@PathVariable Long menuId) { |
|||
return R.ok(menuService.selectMenuById(menuId)); |
|||
} |
|||
|
|||
/** |
|||
* 获取菜单下拉树列表 |
|||
*/ |
|||
@GetMapping("/treeselect") |
|||
public R<List<Tree<Long>>> treeselect(SysMenu menu) { |
|||
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId()); |
|||
return R.ok(menuService.buildMenuTreeSelect(menus)); |
|||
} |
|||
|
|||
/** |
|||
* 加载对应角色菜单列表树 |
|||
* |
|||
* @param roleId 角色ID |
|||
*/ |
|||
@GetMapping(value = "/roleMenuTreeselect/{roleId}") |
|||
public R<Map<String, Object>> roleMenuTreeselect(@PathVariable("roleId") Long roleId) { |
|||
List<SysMenu> menus = menuService.selectMenuList(getUserId()); |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); |
|||
ajax.put("menus", menuService.buildMenuTreeSelect(menus)); |
|||
return R.ok(ajax); |
|||
} |
|||
|
|||
/** |
|||
* 新增菜单 |
|||
*/ |
|||
@SaCheckPermission("system:menu:add") |
|||
@Log(title = "菜单管理", businessType = BusinessType.INSERT) |
|||
@PostMapping |
|||
public R<Void> add(@Validated @RequestBody SysMenu menu) { |
|||
if (!menuService.checkMenuNameUnique(menu)) { |
|||
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); |
|||
} else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { |
|||
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); |
|||
} |
|||
return toAjax(menuService.insertMenu(menu)); |
|||
} |
|||
|
|||
/** |
|||
* 修改菜单 |
|||
*/ |
|||
@SaCheckPermission("system:menu:edit") |
|||
@Log(title = "菜单管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping |
|||
public R<Void> edit(@Validated @RequestBody SysMenu menu) { |
|||
if (!menuService.checkMenuNameUnique(menu)) { |
|||
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); |
|||
} else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) { |
|||
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); |
|||
} else if (menu.getMenuId().equals(menu.getParentId())) { |
|||
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); |
|||
} |
|||
return toAjax(menuService.updateMenu(menu)); |
|||
} |
|||
|
|||
/** |
|||
* 删除菜单 |
|||
* |
|||
* @param menuId 菜单ID |
|||
*/ |
|||
@SaCheckPermission("system:menu:remove") |
|||
@Log(title = "菜单管理", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{menuId}") |
|||
public R<Void> remove(@PathVariable("menuId") Long menuId) { |
|||
if (menuService.hasChildByMenuId(menuId)) { |
|||
return R.warn("存在子菜单,不允许删除"); |
|||
} |
|||
if (menuService.checkMenuExistRole(menuId)) { |
|||
return R.warn("菜单已分配,不允许删除"); |
|||
} |
|||
return toAjax(menuService.deleteMenuById(menuId)); |
|||
} |
|||
} |
@ -0,0 +1,80 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.system.domain.SysNotice; |
|||
import com.inscloudtech.system.service.ISysNoticeService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
/** |
|||
* 公告 信息操作处理 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/notice") |
|||
public class SysNoticeController extends BaseController { |
|||
|
|||
private final ISysNoticeService noticeService; |
|||
|
|||
/** |
|||
* 获取通知公告列表 |
|||
*/ |
|||
@SaCheckPermission("system:notice:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysNotice> list(SysNotice notice, PageQuery pageQuery) { |
|||
return noticeService.selectPageNoticeList(notice, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 根据通知公告编号获取详细信息 |
|||
* |
|||
* @param noticeId 公告ID |
|||
*/ |
|||
@SaCheckPermission("system:notice:query") |
|||
@GetMapping(value = "/{noticeId}") |
|||
public R<SysNotice> getInfo(@PathVariable Long noticeId) { |
|||
return R.ok(noticeService.selectNoticeById(noticeId)); |
|||
} |
|||
|
|||
/** |
|||
* 新增通知公告 |
|||
*/ |
|||
@SaCheckPermission("system:notice:add") |
|||
@Log(title = "通知公告", businessType = BusinessType.INSERT) |
|||
@PostMapping |
|||
public R<Void> add(@Validated @RequestBody SysNotice notice) { |
|||
return toAjax(noticeService.insertNotice(notice)); |
|||
} |
|||
|
|||
/** |
|||
* 修改通知公告 |
|||
*/ |
|||
@SaCheckPermission("system:notice:edit") |
|||
@Log(title = "通知公告", businessType = BusinessType.UPDATE) |
|||
@PutMapping |
|||
public R<Void> edit(@Validated @RequestBody SysNotice notice) { |
|||
return toAjax(noticeService.updateNotice(notice)); |
|||
} |
|||
|
|||
/** |
|||
* 删除通知公告 |
|||
* |
|||
* @param noticeIds 公告ID串 |
|||
*/ |
|||
@SaCheckPermission("system:notice:remove") |
|||
@Log(title = "通知公告", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{noticeIds}") |
|||
public R<Void> remove(@PathVariable Long[] noticeIds) { |
|||
return toAjax(noticeService.deleteNoticeByIds(noticeIds)); |
|||
} |
|||
} |
@ -0,0 +1,105 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.annotation.RepeatSubmit; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.core.validate.AddGroup; |
|||
import com.inscloudtech.common.core.validate.EditGroup; |
|||
import com.inscloudtech.common.core.validate.QueryGroup; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.system.domain.bo.SysOssConfigBo; |
|||
import com.inscloudtech.system.domain.vo.SysOssConfigVo; |
|||
import com.inscloudtech.system.service.ISysOssConfigService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import javax.validation.constraints.NotEmpty; |
|||
import javax.validation.constraints.NotNull; |
|||
import java.util.Arrays; |
|||
|
|||
/** |
|||
* 对象存储配置 |
|||
* |
|||
* @author inscloudtech |
|||
* @author 孤舟烟雨 |
|||
* @date 2021-08-13 |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/oss/config") |
|||
public class SysOssConfigController extends BaseController { |
|||
|
|||
private final ISysOssConfigService iSysOssConfigService; |
|||
|
|||
/** |
|||
* 查询对象存储配置列表 |
|||
*/ |
|||
@SaCheckPermission("system:oss:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysOssConfigVo> list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) { |
|||
return iSysOssConfigService.queryPageList(bo, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 获取对象存储配置详细信息 |
|||
* |
|||
* @param ossConfigId OSS配置ID |
|||
*/ |
|||
@SaCheckPermission("system:oss:query") |
|||
@GetMapping("/{ossConfigId}") |
|||
public R<SysOssConfigVo> getInfo(@NotNull(message = "主键不能为空") |
|||
@PathVariable Long ossConfigId) { |
|||
return R.ok(iSysOssConfigService.queryById(ossConfigId)); |
|||
} |
|||
|
|||
/** |
|||
* 新增对象存储配置 |
|||
*/ |
|||
@SaCheckPermission("system:oss:add") |
|||
@Log(title = "对象存储配置", businessType = BusinessType.INSERT) |
|||
@RepeatSubmit() |
|||
@PostMapping() |
|||
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) { |
|||
return toAjax(iSysOssConfigService.insertByBo(bo)); |
|||
} |
|||
|
|||
/** |
|||
* 修改对象存储配置 |
|||
*/ |
|||
@SaCheckPermission("system:oss:edit") |
|||
@Log(title = "对象存储配置", businessType = BusinessType.UPDATE) |
|||
@RepeatSubmit() |
|||
@PutMapping() |
|||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) { |
|||
return toAjax(iSysOssConfigService.updateByBo(bo)); |
|||
} |
|||
|
|||
/** |
|||
* 删除对象存储配置 |
|||
* |
|||
* @param ossConfigIds OSS配置ID串 |
|||
*/ |
|||
@SaCheckPermission("system:oss:remove") |
|||
@Log(title = "对象存储配置", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{ossConfigIds}") |
|||
public R<Void> remove(@NotEmpty(message = "主键不能为空") |
|||
@PathVariable Long[] ossConfigIds) { |
|||
return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true)); |
|||
} |
|||
|
|||
/** |
|||
* 状态修改 |
|||
*/ |
|||
@SaCheckPermission("system:oss:edit") |
|||
@Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE) |
|||
@PutMapping("/changeStatus") |
|||
public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) { |
|||
return toAjax(iSysOssConfigService.updateOssConfigStatus(bo)); |
|||
} |
|||
} |
@ -0,0 +1,109 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.core.validate.QueryGroup; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.system.domain.bo.SysOssBo; |
|||
import com.inscloudtech.system.domain.vo.SysOssVo; |
|||
import com.inscloudtech.system.service.ISysOssService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.http.MediaType; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import javax.validation.constraints.NotEmpty; |
|||
import java.io.IOException; |
|||
import java.util.Arrays; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 文件上传 控制层 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/oss") |
|||
public class SysOssController extends BaseController { |
|||
|
|||
private final ISysOssService iSysOssService; |
|||
|
|||
/** |
|||
* 查询OSS对象存储列表 |
|||
*/ |
|||
@SaCheckPermission("system:oss:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysOssVo> list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) { |
|||
return iSysOssService.queryPageList(bo, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 查询OSS对象基于id串 |
|||
* |
|||
* @param ossIds OSS对象ID串 |
|||
*/ |
|||
@SaCheckPermission("system:oss:list") |
|||
@GetMapping("/listByIds/{ossIds}") |
|||
public R<List<SysOssVo>> listByIds(@NotEmpty(message = "主键不能为空") |
|||
@PathVariable Long[] ossIds) { |
|||
List<SysOssVo> list = iSysOssService.listByIds(Arrays.asList(ossIds)); |
|||
return R.ok(list); |
|||
} |
|||
|
|||
/** |
|||
* 上传OSS对象存储 |
|||
* |
|||
* @param file 文件 |
|||
*/ |
|||
@SaCheckPermission("system:oss:upload") |
|||
@Log(title = "OSS对象存储", businessType = BusinessType.INSERT) |
|||
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
|||
public R<Map<String, String>> upload(@RequestPart("file") MultipartFile file) { |
|||
if (ObjectUtil.isNull(file)) { |
|||
return R.fail("上传文件不能为空"); |
|||
} |
|||
SysOssVo oss = iSysOssService.upload(file,false); |
|||
Map<String, String> map = new HashMap<>(2); |
|||
map.put("url", oss.getUrl()); |
|||
map.put("fileName", oss.getOriginalName()); |
|||
map.put("ossId", oss.getOssId().toString()); |
|||
return R.ok(map); |
|||
} |
|||
|
|||
/** |
|||
* 下载OSS对象 |
|||
* |
|||
* @param ossId OSS对象ID |
|||
*/ |
|||
// @SaCheckPermission("system:oss:download") |
|||
@GetMapping("/download/{ossId}") |
|||
public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException { |
|||
iSysOssService.download(ossId,response); |
|||
} |
|||
|
|||
/** |
|||
* 删除OSS对象存储 |
|||
* |
|||
* @param ossIds OSS对象ID串 |
|||
*/ |
|||
@SaCheckPermission("system:oss:remove") |
|||
@Log(title = "OSS对象存储", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{ossIds}") |
|||
public R<Void> remove(@NotEmpty(message = "主键不能为空") |
|||
@PathVariable Long[] ossIds) { |
|||
return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true)); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,120 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.constant.UserConstants; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.utils.poi.ExcelUtil; |
|||
import com.inscloudtech.system.domain.SysPost; |
|||
import com.inscloudtech.system.service.ISysPostService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 岗位信息操作处理 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/post") |
|||
public class SysPostController extends BaseController { |
|||
|
|||
private final ISysPostService postService; |
|||
|
|||
/** |
|||
* 获取岗位列表 |
|||
*/ |
|||
@SaCheckPermission("system:post:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysPost> list(SysPost post, PageQuery pageQuery) { |
|||
return postService.selectPagePostList(post, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 导出岗位列表 |
|||
*/ |
|||
@Log(title = "岗位管理", businessType = BusinessType.EXPORT) |
|||
@SaCheckPermission("system:post:export") |
|||
@PostMapping("/export") |
|||
public void export(SysPost post, HttpServletResponse response) { |
|||
List<SysPost> list = postService.selectPostList(post); |
|||
ExcelUtil.exportExcel(list, "岗位数据", SysPost.class, response); |
|||
} |
|||
|
|||
/** |
|||
* 根据岗位编号获取详细信息 |
|||
* |
|||
* @param postId 岗位ID |
|||
*/ |
|||
@SaCheckPermission("system:post:query") |
|||
@GetMapping(value = "/{postId}") |
|||
public R<SysPost> getInfo(@PathVariable Long postId) { |
|||
return R.ok(postService.selectPostById(postId)); |
|||
} |
|||
|
|||
/** |
|||
* 新增岗位 |
|||
*/ |
|||
@SaCheckPermission("system:post:add") |
|||
@Log(title = "岗位管理", businessType = BusinessType.INSERT) |
|||
@PostMapping |
|||
public R<Void> add(@Validated @RequestBody SysPost post) { |
|||
if (!postService.checkPostNameUnique(post)) { |
|||
return R.fail("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); |
|||
} else if (!postService.checkPostCodeUnique(post)) { |
|||
return R.fail("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); |
|||
} |
|||
return toAjax(postService.insertPost(post)); |
|||
} |
|||
|
|||
/** |
|||
* 修改岗位 |
|||
*/ |
|||
@SaCheckPermission("system:post:edit") |
|||
@Log(title = "岗位管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping |
|||
public R<Void> edit(@Validated @RequestBody SysPost post) { |
|||
if (!postService.checkPostNameUnique(post)) { |
|||
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); |
|||
} else if (!postService.checkPostCodeUnique(post)) { |
|||
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); |
|||
} else if (UserConstants.POST_DISABLE.equals(post.getStatus()) |
|||
&& postService.countUserPostById(post.getPostId()) > 0) { |
|||
return R.fail("该岗位下存在已分配用户,不能禁用!"); |
|||
} |
|||
return toAjax(postService.updatePost(post)); |
|||
} |
|||
|
|||
/** |
|||
* 删除岗位 |
|||
* |
|||
* @param postIds 岗位ID串 |
|||
*/ |
|||
@SaCheckPermission("system:post:remove") |
|||
@Log(title = "岗位管理", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{postIds}") |
|||
public R<Void> remove(@PathVariable Long[] postIds) { |
|||
return toAjax(postService.deletePostByIds(postIds)); |
|||
} |
|||
|
|||
/** |
|||
* 获取岗位选择框列表 |
|||
*/ |
|||
@GetMapping("/optionselect") |
|||
public R<List<SysPost>> optionselect() { |
|||
SysPost post = new SysPost(); |
|||
post.setStatus(UserConstants.POST_NORMAL); |
|||
List<SysPost> posts = postService.selectPostList(post); |
|||
return R.ok(posts); |
|||
} |
|||
} |
@ -0,0 +1,125 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.secure.BCrypt; |
|||
import cn.hutool.core.io.FileUtil; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.dto.SysUserPasswordBo; |
|||
import com.inscloudtech.common.core.domain.entity.SysUser; |
|||
import com.inscloudtech.common.encrypt.annotation.ApiEncrypt; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.helper.LoginHelper; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.common.utils.file.MimeTypeUtils; |
|||
import com.inscloudtech.system.domain.vo.SysOssVo; |
|||
import com.inscloudtech.system.service.ISysOssService; |
|||
import com.inscloudtech.system.service.ISysUserService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.http.MediaType; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 个人信息 业务处理 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/user/profile") |
|||
public class SysProfileController extends BaseController { |
|||
|
|||
private final ISysUserService userService; |
|||
private final ISysOssService iSysOssService; |
|||
|
|||
/** |
|||
* 个人信息 |
|||
*/ |
|||
@GetMapping |
|||
public R<Map<String, Object>> profile() { |
|||
SysUser user = userService.selectUserById(getUserId()); |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
ajax.put("user", user); |
|||
ajax.put("roleGroup", userService.selectUserRoleGroup(user.getUserName())); |
|||
ajax.put("postGroup", userService.selectUserPostGroup(user.getUserName())); |
|||
return R.ok(ajax); |
|||
} |
|||
|
|||
/** |
|||
* 修改用户 |
|||
*/ |
|||
@Log(title = "个人信息", businessType = BusinessType.UPDATE) |
|||
@PutMapping |
|||
public R<Void> updateProfile(@RequestBody SysUser user) { |
|||
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { |
|||
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); |
|||
} |
|||
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { |
|||
return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); |
|||
} |
|||
user.setUserId(getUserId()); |
|||
user.setUserName(null); |
|||
user.setPassword(null); |
|||
user.setAvatar(null); |
|||
user.setDeptId(null); |
|||
if (userService.updateUserProfile(user) > 0) { |
|||
return R.ok(); |
|||
} |
|||
return R.fail("修改个人信息异常,请联系管理员"); |
|||
} |
|||
|
|||
/** |
|||
* 重置密码 |
|||
* |
|||
*/ |
|||
@ApiEncrypt(response = true) |
|||
@Log(title = "个人信息", businessType = BusinessType.UPDATE) |
|||
@PutMapping("/updatePwd") |
|||
public R<Void> updatePwd(@RequestBody SysUserPasswordBo bo) { |
|||
SysUser user = userService.selectUserById(LoginHelper.getUserId()); |
|||
String userName = user.getUserName(); |
|||
String password = user.getPassword(); |
|||
if (!BCrypt.checkpw(bo.getOldPassword(), password)) { |
|||
return R.fail("修改密码失败,旧密码错误"); |
|||
} |
|||
if (BCrypt.checkpw(bo.getNewPassword(), password)) { |
|||
return R.fail("新密码不能与旧密码相同"); |
|||
} |
|||
|
|||
if (userService.resetUserPwd(userName, BCrypt.hashpw(bo.getNewPassword())) > 0) { |
|||
return R.ok(); |
|||
} |
|||
return R.fail("修改密码异常,请联系管理员"); |
|||
} |
|||
|
|||
/** |
|||
* 头像上传 |
|||
* |
|||
* @param avatarfile 用户头像 |
|||
*/ |
|||
@Log(title = "用户头像", businessType = BusinessType.UPDATE) |
|||
@PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
|||
public R<Map<String, Object>> avatar(@RequestPart("avatarfile") MultipartFile avatarfile) { |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
if (!avatarfile.isEmpty()) { |
|||
String extension = FileUtil.extName(avatarfile.getOriginalFilename()); |
|||
if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) { |
|||
return R.fail("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式"); |
|||
} |
|||
SysOssVo oss = iSysOssService.upload(avatarfile,false); |
|||
String avatar = oss.getUrl(); |
|||
if (userService.updateUserAvatar(getUsername(), avatar)) { |
|||
ajax.put("imgUrl", avatar); |
|||
return R.ok(ajax); |
|||
} |
|||
} |
|||
return R.fail("上传图片异常,请联系管理员"); |
|||
} |
|||
} |
@ -0,0 +1,40 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaIgnore; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.model.RegisterBody; |
|||
import com.inscloudtech.system.service.ISysConfigService; |
|||
import com.inscloudtech.system.service.SysRegisterService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
/** |
|||
* 注册验证 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
public class SysRegisterController extends BaseController { |
|||
|
|||
private final SysRegisterService registerService; |
|||
private final ISysConfigService configService; |
|||
|
|||
/** |
|||
* 用户注册 |
|||
*/ |
|||
@SaIgnore |
|||
@PostMapping("/register") |
|||
public R<Void> register(@Validated @RequestBody RegisterBody user) { |
|||
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) { |
|||
return R.fail("当前系统没有开启注册功能!"); |
|||
} |
|||
registerService.register(user); |
|||
return R.ok(); |
|||
} |
|||
} |
@ -0,0 +1,228 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.entity.SysDept; |
|||
import com.inscloudtech.common.core.domain.entity.SysRole; |
|||
import com.inscloudtech.common.core.domain.entity.SysUser; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.utils.poi.ExcelUtil; |
|||
import com.inscloudtech.system.domain.SysUserRole; |
|||
import com.inscloudtech.system.service.ISysDeptService; |
|||
import com.inscloudtech.system.service.ISysRoleService; |
|||
import com.inscloudtech.system.service.ISysUserService; |
|||
import com.inscloudtech.system.service.SysPermissionService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 角色信息 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/role") |
|||
public class SysRoleController extends BaseController { |
|||
|
|||
private final ISysRoleService roleService; |
|||
private final ISysUserService userService; |
|||
private final ISysDeptService deptService; |
|||
private final SysPermissionService permissionService; |
|||
|
|||
/** |
|||
* 获取角色信息列表 |
|||
*/ |
|||
@SaCheckPermission("system:role:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysRole> list(SysRole role, PageQuery pageQuery) { |
|||
return roleService.selectPageRoleList(role, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 导出角色信息列表 |
|||
*/ |
|||
@Log(title = "角色管理", businessType = BusinessType.EXPORT) |
|||
@SaCheckPermission("system:role:export") |
|||
@PostMapping("/export") |
|||
public void export(SysRole role, HttpServletResponse response) { |
|||
List<SysRole> list = roleService.selectRoleList(role); |
|||
ExcelUtil.exportExcel(list, "角色数据", SysRole.class, response); |
|||
} |
|||
|
|||
/** |
|||
* 根据角色编号获取详细信息 |
|||
* |
|||
* @param roleId 角色ID |
|||
*/ |
|||
@SaCheckPermission("system:role:query") |
|||
@GetMapping(value = "/{roleId}") |
|||
public R<SysRole> getInfo(@PathVariable Long roleId) { |
|||
roleService.checkRoleDataScope(roleId); |
|||
return R.ok(roleService.selectRoleById(roleId)); |
|||
} |
|||
|
|||
/** |
|||
* 新增角色 |
|||
*/ |
|||
@SaCheckPermission("system:role:add") |
|||
@Log(title = "角色管理", businessType = BusinessType.INSERT) |
|||
@PostMapping |
|||
public R<Void> add(@Validated @RequestBody SysRole role) { |
|||
roleService.checkRoleAllowed(role); |
|||
if (!roleService.checkRoleNameUnique(role)) { |
|||
return R.fail("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); |
|||
} else if (!roleService.checkRoleKeyUnique(role)) { |
|||
return R.fail("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); |
|||
} |
|||
return toAjax(roleService.insertRole(role)); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 修改保存角色 |
|||
*/ |
|||
@SaCheckPermission("system:role:edit") |
|||
@Log(title = "角色管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping |
|||
public R<Void> edit(@Validated @RequestBody SysRole role) { |
|||
roleService.checkRoleAllowed(role); |
|||
roleService.checkRoleDataScope(role.getRoleId()); |
|||
if (!roleService.checkRoleNameUnique(role)) { |
|||
return R.fail("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); |
|||
} else if (!roleService.checkRoleKeyUnique(role)) { |
|||
return R.fail("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); |
|||
} |
|||
|
|||
if (roleService.updateRole(role) > 0) { |
|||
roleService.cleanOnlineUserByRole(role.getRoleId()); |
|||
return R.ok(); |
|||
} |
|||
return R.fail("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); |
|||
} |
|||
|
|||
/** |
|||
* 修改保存数据权限 |
|||
*/ |
|||
@SaCheckPermission("system:role:edit") |
|||
@Log(title = "角色管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping("/dataScope") |
|||
public R<Void> dataScope(@RequestBody SysRole role) { |
|||
roleService.checkRoleAllowed(role); |
|||
roleService.checkRoleDataScope(role.getRoleId()); |
|||
return toAjax(roleService.authDataScope(role)); |
|||
} |
|||
|
|||
/** |
|||
* 状态修改 |
|||
*/ |
|||
@SaCheckPermission("system:role:edit") |
|||
@Log(title = "角色管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping("/changeStatus") |
|||
public R<Void> changeStatus(@RequestBody SysRole role) { |
|||
roleService.checkRoleAllowed(role); |
|||
roleService.checkRoleDataScope(role.getRoleId()); |
|||
return toAjax(roleService.updateRoleStatus(role)); |
|||
} |
|||
|
|||
/** |
|||
* 删除角色 |
|||
* |
|||
* @param roleIds 角色ID串 |
|||
*/ |
|||
@SaCheckPermission("system:role:remove") |
|||
@Log(title = "角色管理", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{roleIds}") |
|||
public R<Void> remove(@PathVariable Long[] roleIds) { |
|||
return toAjax(roleService.deleteRoleByIds(roleIds)); |
|||
} |
|||
|
|||
/** |
|||
* 获取角色选择框列表 |
|||
*/ |
|||
@SaCheckPermission("system:role:query") |
|||
@GetMapping("/optionselect") |
|||
public R<List<SysRole>> optionselect() { |
|||
return R.ok(roleService.selectRoleAll()); |
|||
} |
|||
|
|||
/** |
|||
* 查询已分配用户角色列表 |
|||
*/ |
|||
@SaCheckPermission("system:role:list") |
|||
@GetMapping("/authUser/allocatedList") |
|||
public TableDataInfo<SysUser> allocatedList(SysUser user, PageQuery pageQuery) { |
|||
return userService.selectAllocatedList(user, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 查询未分配用户角色列表 |
|||
*/ |
|||
@SaCheckPermission("system:role:list") |
|||
@GetMapping("/authUser/unallocatedList") |
|||
public TableDataInfo<SysUser> unallocatedList(SysUser user, PageQuery pageQuery) { |
|||
return userService.selectUnallocatedList(user, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 取消授权用户 |
|||
*/ |
|||
@SaCheckPermission("system:role:edit") |
|||
@Log(title = "角色管理", businessType = BusinessType.GRANT) |
|||
@PutMapping("/authUser/cancel") |
|||
public R<Void> cancelAuthUser(@RequestBody SysUserRole userRole) { |
|||
return toAjax(roleService.deleteAuthUser(userRole)); |
|||
} |
|||
|
|||
/** |
|||
* 批量取消授权用户 |
|||
* |
|||
* @param roleId 角色ID |
|||
* @param userIds 用户ID串 |
|||
*/ |
|||
@SaCheckPermission("system:role:edit") |
|||
@Log(title = "角色管理", businessType = BusinessType.GRANT) |
|||
@PutMapping("/authUser/cancelAll") |
|||
public R<Void> cancelAuthUserAll(Long roleId, Long[] userIds) { |
|||
return toAjax(roleService.deleteAuthUsers(roleId, userIds)); |
|||
} |
|||
|
|||
/** |
|||
* 批量选择用户授权 |
|||
* |
|||
* @param roleId 角色ID |
|||
* @param userIds 用户ID串 |
|||
*/ |
|||
@SaCheckPermission("system:role:edit") |
|||
@Log(title = "角色管理", businessType = BusinessType.GRANT) |
|||
@PutMapping("/authUser/selectAll") |
|||
public R<Void> selectAuthUserAll(Long roleId, Long[] userIds) { |
|||
roleService.checkRoleDataScope(roleId); |
|||
return toAjax(roleService.insertAuthUsers(roleId, userIds)); |
|||
} |
|||
|
|||
/** |
|||
* 获取对应角色部门树列表 |
|||
* |
|||
* @param roleId 角色ID |
|||
*/ |
|||
@SaCheckPermission("system:role:list") |
|||
@GetMapping(value = "/deptTree/{roleId}") |
|||
public R<Map<String, Object>> roleDeptTreeselect(@PathVariable("roleId") Long roleId) { |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); |
|||
ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); |
|||
return R.ok(ajax); |
|||
} |
|||
} |
@ -0,0 +1,256 @@ |
|||
package com.inscloudtech.web.controller.system; |
|||
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import cn.dev33.satoken.secure.BCrypt; |
|||
import cn.hutool.core.bean.BeanUtil; |
|||
import cn.hutool.core.lang.tree.Tree; |
|||
import cn.hutool.core.util.ArrayUtil; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.inscloudtech.common.annotation.Log; |
|||
import com.inscloudtech.common.constant.UserConstants; |
|||
import com.inscloudtech.common.core.controller.BaseController; |
|||
import com.inscloudtech.common.core.domain.PageQuery; |
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.entity.SysDept; |
|||
import com.inscloudtech.common.core.domain.entity.SysRole; |
|||
import com.inscloudtech.common.core.domain.entity.SysUser; |
|||
import com.inscloudtech.common.core.page.TableDataInfo; |
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.excel.ExcelResult; |
|||
import com.inscloudtech.common.helper.LoginHelper; |
|||
import com.inscloudtech.common.utils.StreamUtils; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.common.utils.poi.ExcelUtil; |
|||
import com.inscloudtech.system.domain.SysPost; |
|||
import com.inscloudtech.system.domain.vo.SysUserExportVo; |
|||
import com.inscloudtech.system.domain.vo.SysUserImportVo; |
|||
import com.inscloudtech.system.listener.SysUserImportListener; |
|||
import com.inscloudtech.system.service.ISysDeptService; |
|||
import com.inscloudtech.system.service.ISysPostService; |
|||
import com.inscloudtech.system.service.ISysRoleService; |
|||
import com.inscloudtech.system.service.ISysUserService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.http.MediaType; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 用户信息 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/system/user") |
|||
public class SysUserController extends BaseController { |
|||
|
|||
private final ISysUserService userService; |
|||
private final ISysRoleService roleService; |
|||
private final ISysPostService postService; |
|||
private final ISysDeptService deptService; |
|||
|
|||
/** |
|||
* 获取用户列表 |
|||
*/ |
|||
@SaCheckPermission("system:user:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<SysUser> list(SysUser user, PageQuery pageQuery) { |
|||
return userService.selectPageUserList(user, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 导出用户列表 |
|||
*/ |
|||
@Log(title = "用户管理", businessType = BusinessType.EXPORT) |
|||
@SaCheckPermission("system:user:export") |
|||
@PostMapping("/export") |
|||
public void export(SysUser user, HttpServletResponse response) { |
|||
List<SysUser> list = userService.selectUserList(user); |
|||
List<SysUserExportVo> listVo = BeanUtil.copyToList(list, SysUserExportVo.class); |
|||
for (int i = 0; i < list.size(); i++) { |
|||
SysDept dept = list.get(i).getDept(); |
|||
SysUserExportVo vo = listVo.get(i); |
|||
if (ObjectUtil.isNotEmpty(dept)) { |
|||
vo.setDeptName(dept.getDeptName()); |
|||
vo.setLeader(dept.getLeader()); |
|||
} |
|||
} |
|||
ExcelUtil.exportExcel(listVo, "用户数据", SysUserExportVo.class, response); |
|||
} |
|||
|
|||
/** |
|||
* 导入数据 |
|||
* |
|||
* @param file 导入文件 |
|||
* @param updateSupport 是否更新已存在数据 |
|||
*/ |
|||
@Log(title = "用户管理", businessType = BusinessType.IMPORT) |
|||
@SaCheckPermission("system:user:import") |
|||
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
|||
public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception { |
|||
ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport)); |
|||
return R.ok(result.getAnalysis()); |
|||
} |
|||
|
|||
/** |
|||
* 获取导入模板 |
|||
*/ |
|||
@PostMapping("/importTemplate") |
|||
public void importTemplate(HttpServletResponse response) { |
|||
ExcelUtil.exportExcel(new ArrayList<>(), "用户数据", SysUserImportVo.class, response); |
|||
} |
|||
|
|||
/** |
|||
* 根据用户编号获取详细信息 |
|||
* |
|||
* @param userId 用户ID |
|||
*/ |
|||
@SaCheckPermission("system:user:query") |
|||
@GetMapping(value = {"/", "/{userId}"}) |
|||
public R<Map<String, Object>> getInfo(@PathVariable(value = "userId", required = false) Long userId) { |
|||
userService.checkUserDataScope(userId); |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
SysRole role = new SysRole(); |
|||
role.setStatus(UserConstants.ROLE_NORMAL); |
|||
SysPost post = new SysPost(); |
|||
post.setStatus(UserConstants.POST_NORMAL); |
|||
List<SysRole> roles = roleService.selectRoleList(role); |
|||
ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin())); |
|||
ajax.put("posts", postService.selectPostList(post)); |
|||
if (ObjectUtil.isNotNull(userId)) { |
|||
SysUser sysUser = userService.selectUserById(userId); |
|||
ajax.put("user", sysUser); |
|||
ajax.put("postIds", postService.selectPostListByUserId(userId)); |
|||
ajax.put("roleIds", StreamUtils.toList(sysUser.getRoles(), SysRole::getRoleId)); |
|||
} |
|||
return R.ok(ajax); |
|||
} |
|||
|
|||
/** |
|||
* 新增用户 |
|||
*/ |
|||
@SaCheckPermission("system:user:add") |
|||
@Log(title = "用户管理", businessType = BusinessType.INSERT) |
|||
@PostMapping |
|||
public R<Void> add(@Validated @RequestBody SysUser user) { |
|||
deptService.checkDeptDataScope(user.getDeptId()); |
|||
if (!userService.checkUserNameUnique(user)) { |
|||
return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); |
|||
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { |
|||
return R.fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); |
|||
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { |
|||
return R.fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); |
|||
} |
|||
user.setPassword(BCrypt.hashpw(user.getPassword())); |
|||
return toAjax(userService.insertUser(user)); |
|||
} |
|||
|
|||
/** |
|||
* 修改用户 |
|||
*/ |
|||
// @SaCheckPermission("system:user:edit") |
|||
@Log(title = "用户管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping |
|||
public R<Void> edit(@Validated @RequestBody SysUser user) { |
|||
userService.checkUserAllowed(user); |
|||
userService.checkUserDataScope(user.getUserId()); |
|||
deptService.checkDeptDataScope(user.getDeptId()); |
|||
if (!userService.checkUserNameUnique(user)) { |
|||
return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); |
|||
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) { |
|||
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); |
|||
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { |
|||
return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); |
|||
} |
|||
return toAjax(userService.updateUser(user)); |
|||
} |
|||
|
|||
/** |
|||
* 删除用户 |
|||
* |
|||
* @param userIds 角色ID串 |
|||
*/ |
|||
@SaCheckPermission("system:user:remove") |
|||
@Log(title = "用户管理", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{userIds}") |
|||
public R<Void> remove(@PathVariable Long[] userIds) { |
|||
if (ArrayUtil.contains(userIds, getUserId())) { |
|||
return R.fail("当前用户不能删除"); |
|||
} |
|||
return toAjax(userService.deleteUserByIds(userIds)); |
|||
} |
|||
|
|||
/** |
|||
* 重置密码 |
|||
*/ |
|||
@SaCheckPermission("system:user:resetPwd") |
|||
@Log(title = "用户管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping("/resetPwd") |
|||
public R<Void> resetPwd(@RequestBody SysUser user) { |
|||
userService.checkUserAllowed(user); |
|||
userService.checkUserDataScope(user.getUserId()); |
|||
user.setPassword(BCrypt.hashpw(user.getPassword())); |
|||
return toAjax(userService.resetPwd(user)); |
|||
} |
|||
|
|||
/** |
|||
* 状态修改 |
|||
*/ |
|||
@SaCheckPermission("system:user:edit") |
|||
@Log(title = "用户管理", businessType = BusinessType.UPDATE) |
|||
@PutMapping("/changeStatus") |
|||
public R<Void> changeStatus(@RequestBody SysUser user) { |
|||
userService.checkUserAllowed(user); |
|||
userService.checkUserDataScope(user.getUserId()); |
|||
return toAjax(userService.updateUserStatus(user)); |
|||
} |
|||
|
|||
/** |
|||
* 根据用户编号获取授权角色 |
|||
* |
|||
* @param userId 用户ID |
|||
*/ |
|||
@SaCheckPermission("system:user:query") |
|||
@GetMapping("/authRole/{userId}") |
|||
public R<Map<String, Object>> authRole(@PathVariable Long userId) { |
|||
SysUser user = userService.selectUserById(userId); |
|||
List<SysRole> roles = roleService.selectRolesByUserId(userId); |
|||
Map<String, Object> ajax = new HashMap<>(); |
|||
ajax.put("user", user); |
|||
ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin())); |
|||
return R.ok(ajax); |
|||
} |
|||
|
|||
/** |
|||
* 用户授权角色 |
|||
* |
|||
* @param userId 用户Id |
|||
* @param roleIds 角色ID串 |
|||
*/ |
|||
@SaCheckPermission("system:user:edit") |
|||
@Log(title = "用户管理", businessType = BusinessType.GRANT) |
|||
@PutMapping("/authRole") |
|||
public R<Void> insertAuthRole(Long userId, Long[] roleIds) { |
|||
userService.checkUserDataScope(userId); |
|||
userService.insertUserAuth(userId, roleIds); |
|||
return R.ok(); |
|||
} |
|||
|
|||
/** |
|||
* 获取部门树列表 |
|||
*/ |
|||
@SaCheckPermission("system:user:list") |
|||
@GetMapping("/deptTree") |
|||
public R<List<Tree<Long>>> deptTree(SysDept dept) { |
|||
return R.ok(deptService.selectDeptTreeList(dept)); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,124 @@ |
|||
--- # 数据源配置 |
|||
spring: |
|||
datasource: |
|||
type: com.zaxxer.hikari.HikariDataSource |
|||
# 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content |
|||
dynamic: |
|||
# 性能分析插件(有性能损耗 不建议生产环境使用) |
|||
p6spy: true |
|||
# 设置默认的数据源或者数据源组,默认值即为 master |
|||
primary: master |
|||
# 严格模式 匹配不到数据源则报错 |
|||
strict: true |
|||
datasource: |
|||
# 主库数据源 |
|||
master: |
|||
type: ${spring.datasource.type} |
|||
driverClassName: dm.jdbc.driver.DmDriver |
|||
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 |
|||
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) |
|||
url: jdbc:dm://192.168.3.20:52360?keywords=(domain, top) |
|||
username: ALOG |
|||
password: Alog!@5212 |
|||
hikari: |
|||
# 最大连接池数量 |
|||
maxPoolSize: 20 |
|||
# 最小空闲线程数量 |
|||
minIdle: 10 |
|||
# 配置获取连接等待超时的时间 |
|||
connectionTimeout: 30000 |
|||
# 校验超时时间 |
|||
validationTimeout: 5000 |
|||
# 空闲连接存活最大时间,默认10分钟 |
|||
idleTimeout: 600000 |
|||
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 |
|||
maxLifetime: 1800000 |
|||
# 多久检查一次连接的活性 |
|||
keepaliveTime: 30000 |
|||
|
|||
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) |
|||
spring: |
|||
redis: |
|||
# 地址 |
|||
host: localhost |
|||
# 端口,默认为6379 |
|||
port: 6379 |
|||
# 数据库索引 |
|||
database: 4 |
|||
# 密码(如没有密码请注释掉) |
|||
# password: 123456 |
|||
# 连接超时时间 |
|||
timeout: 10s |
|||
# 是否开启ssl |
|||
ssl: false |
|||
|
|||
redisson: |
|||
# redis key前缀 |
|||
keyPrefix: |
|||
# 线程池数量 |
|||
threads: 4 |
|||
# Netty线程池数量 |
|||
nettyThreads: 8 |
|||
# 单节点配置 |
|||
singleServerConfig: |
|||
# 客户端名称 |
|||
clientName: ${alogService.name} |
|||
# 最小空闲连接数 |
|||
connectionMinimumIdleSize: 8 |
|||
# 连接池大小 |
|||
connectionPoolSize: 32 |
|||
# 连接空闲超时,单位:毫秒 |
|||
idleConnectionTimeout: 10000 |
|||
# 命令等待超时,单位:毫秒 |
|||
timeout: 3000 |
|||
# 发布和订阅连接池大小 |
|||
subscriptionConnectionPoolSize: 50 |
|||
|
|||
--- # mail 邮件发送 |
|||
mail: |
|||
enabled: false |
|||
host: smtp.163.com |
|||
port: 465 |
|||
# 是否需要用户名密码验证 |
|||
auth: true |
|||
# 发送方,遵循RFC-822标准 |
|||
from: xxx@163.com |
|||
# 用户名(注意:如果使用foxmail邮箱,此处user为qq号) |
|||
user: xxx@163.com |
|||
# 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助) |
|||
pass: xxxxxxxxxx |
|||
# 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。 |
|||
starttlsEnable: true |
|||
# 使用SSL安全连接 |
|||
sslEnable: true |
|||
# SMTP超时时长,单位毫秒,缺省值不超时 |
|||
timeout: 0 |
|||
# Socket连接超时值,单位毫秒,缺省值不超时 |
|||
connectionTimeout: 0 |
|||
|
|||
--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商 |
|||
# https://wind.kim/doc/start 文档地址 各个厂商可同时使用 |
|||
sms: |
|||
# 阿里云 dysmsapi.aliyuncs.com |
|||
alibaba: |
|||
#请求地址 默认为 dysmsapi.aliyuncs.com 如无特殊改变可以不用设置 |
|||
requestUrl: dysmsapi.aliyuncs.com |
|||
#阿里云的accessKey |
|||
accessKeyId: xxxxxxx |
|||
#阿里云的accessKeySecret |
|||
accessKeySecret: xxxxxxx |
|||
#短信签名 |
|||
signature: 测试 |
|||
tencent: |
|||
#请求地址默认为 sms.tencentcloudapi.com 如无特殊改变可不用设置 |
|||
requestUrl: sms.tencentcloudapi.com |
|||
#腾讯云的accessKey |
|||
accessKeyId: xxxxxxx |
|||
#腾讯云的accessKeySecret |
|||
accessKeySecret: xxxxxxx |
|||
#短信签名 |
|||
signature: 测试 |
|||
#短信sdkAppId |
|||
sdkAppId: appid |
|||
#地域信息默认为 ap-guangzhou 如无特殊改变可不用设置 |
|||
territory: ap-guangzhou |
@ -0,0 +1,128 @@ |
|||
--- # 临时文件存储位置 避免临时文件被系统清理报错 |
|||
spring.servlet.multipart.location: /app/testp/temp |
|||
|
|||
--- # 数据源配置 |
|||
spring: |
|||
datasource: |
|||
type: com.zaxxer.hikari.HikariDataSource |
|||
# 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content |
|||
dynamic: |
|||
# 性能分析插件(有性能损耗 不建议生产环境使用) |
|||
p6spy: false |
|||
# 设置默认的数据源或者数据源组,默认值即为 master |
|||
primary: master |
|||
# 严格模式 匹配不到数据源则报错 |
|||
strict: true |
|||
datasource: |
|||
# 主库数据源 |
|||
master: |
|||
type: ${spring.datasource.type} |
|||
driverClassName: dm.jdbc.driver.DmDriver |
|||
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 |
|||
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) |
|||
url: jdbc:dm://192.168.3.20:52360?schema=ALOGrewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8 |
|||
username: ALOG |
|||
password: Alog!@5212 |
|||
# 从库数据源 |
|||
hikari: |
|||
# 最大连接池数量 |
|||
maxPoolSize: 20 |
|||
# 最小空闲线程数量 |
|||
minIdle: 10 |
|||
# 配置获取连接等待超时的时间 |
|||
connectionTimeout: 30000 |
|||
# 校验超时时间 |
|||
validationTimeout: 5000 |
|||
# 空闲连接存活最大时间,默认10分钟 |
|||
idleTimeout: 600000 |
|||
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 |
|||
maxLifetime: 1800000 |
|||
# 多久检查一次连接的活性 |
|||
keepaliveTime: 30000 |
|||
|
|||
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) |
|||
spring: |
|||
redis: |
|||
# 地址 |
|||
host: 127.0.0.1 |
|||
# 端口,默认为6379 |
|||
port: 6379 |
|||
# 数据库索引 |
|||
database: 4 |
|||
# 密码(如没有密码请注释掉) |
|||
password: 123456 |
|||
# 连接超时时间 |
|||
timeout: 10s |
|||
# 是否开启ssl |
|||
ssl: false |
|||
|
|||
redisson: |
|||
# redis key前缀 |
|||
keyPrefix: |
|||
# 线程池数量 |
|||
threads: 16 |
|||
# Netty线程池数量 |
|||
nettyThreads: 32 |
|||
# 单节点配置 |
|||
singleServerConfig: |
|||
# 客户端名称 |
|||
clientName: ${alogService.name} |
|||
# 最小空闲连接数 |
|||
connectionMinimumIdleSize: 32 |
|||
# 连接池大小 |
|||
connectionPoolSize: 64 |
|||
# 连接空闲超时,单位:毫秒 |
|||
idleConnectionTimeout: 10000 |
|||
# 命令等待超时,单位:毫秒 |
|||
timeout: 3000 |
|||
# 发布和订阅连接池大小 |
|||
subscriptionConnectionPoolSize: 50 |
|||
|
|||
--- # mail 邮件发送 |
|||
mail: |
|||
enabled: false |
|||
host: smtp.163.com |
|||
port: 465 |
|||
# 是否需要用户名密码验证 |
|||
auth: true |
|||
# 发送方,遵循RFC-822标准 |
|||
from: xxx@163.com |
|||
# 用户名(注意:如果使用foxmail邮箱,此处user为qq号) |
|||
user: xxx@163.com |
|||
# 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助) |
|||
pass: xxxxxxxxxx |
|||
# 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。 |
|||
starttlsEnable: true |
|||
# 使用SSL安全连接 |
|||
sslEnable: true |
|||
# SMTP超时时长,单位毫秒,缺省值不超时 |
|||
timeout: 0 |
|||
# Socket连接超时值,单位毫秒,缺省值不超时 |
|||
connectionTimeout: 0 |
|||
|
|||
--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商 |
|||
# https://wind.kim/doc/start 文档地址 各个厂商可同时使用 |
|||
sms: |
|||
# 阿里云 dysmsapi.aliyuncs.com |
|||
alibaba: |
|||
#请求地址 默认为 dysmsapi.aliyuncs.com 如无特殊改变可以不用设置 |
|||
requestUrl: dysmsapi.aliyuncs.com |
|||
#阿里云的accessKey |
|||
accessKeyId: xxxxxxx |
|||
#阿里云的accessKeySecret |
|||
accessKeySecret: xxxxxxx |
|||
#短信签名 |
|||
signature: 测试 |
|||
tencent: |
|||
#请求地址默认为 sms.tencentcloudapi.com 如无特殊改变可不用设置 |
|||
requestUrl: sms.tencentcloudapi.com |
|||
#腾讯云的accessKey |
|||
accessKeyId: xxxxxxx |
|||
#腾讯云的accessKeySecret |
|||
accessKeySecret: xxxxxxx |
|||
#短信签名 |
|||
signature: 测试 |
|||
#短信sdkAppId |
|||
sdkAppId: appid |
|||
#地域信息默认为 ap-guangzhou 如无特殊改变可不用设置 |
|||
territory: ap-guangzhou |
@ -0,0 +1,281 @@ |
|||
# 项目相关配置 |
|||
alogService: |
|||
# 名称 |
|||
name: testP |
|||
# 版本 |
|||
version: ${alog-service.version} |
|||
# 版权年份 |
|||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) |
|||
profile: /app/testp/uploadPath |
|||
copyrightYear: 2024 |
|||
# 缓存懒加载 |
|||
cacheLazy: false |
|||
|
|||
captcha: |
|||
# 页面 <参数设置> 可开启关闭 验证码校验 |
|||
# 验证码类型 math 数组计算 char 字符验证 |
|||
type: MATH |
|||
# line 线段干扰 circle 圆圈干扰 shear 扭曲干扰 |
|||
category: CIRCLE |
|||
# 数字验证码位数 |
|||
numberLength: 1 |
|||
# 字符验证码长度 |
|||
charLength: 4 |
|||
|
|||
# 开发环境配置 |
|||
server: |
|||
# 服务器的HTTP端口,默认为8080 |
|||
port: 30541 |
|||
servlet: |
|||
# 应用的访问路径 |
|||
context-path: / |
|||
# undertow 配置 |
|||
undertow: |
|||
# HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的 |
|||
max-http-post-size: -1 |
|||
# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 |
|||
# 每块buffer的空间大小,越小的空间被利用越充分 |
|||
buffer-size: 512 |
|||
# 是否分配的直接内存 |
|||
direct-buffers: true |
|||
threads: |
|||
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 |
|||
io: 8 |
|||
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载 |
|||
worker: 256 |
|||
|
|||
# 日志配置 |
|||
logging: |
|||
level: |
|||
com.ruoyi: @logging.level@ |
|||
org.springframework: warn |
|||
config: classpath:logback-plus.xml |
|||
|
|||
# 用户配置 |
|||
user: |
|||
password: |
|||
# 密码最大错误次数 |
|||
maxRetryCount: 5 |
|||
# 密码锁定时间(默认10分钟) |
|||
lockTime: 10 |
|||
|
|||
# Spring配置 |
|||
spring: |
|||
application: |
|||
name: ${alogService.name} |
|||
# 资源信息 |
|||
messages: |
|||
# 国际化资源文件路径 |
|||
basename: i18n/messages |
|||
profiles: |
|||
active: @profiles.active@ |
|||
# 文件上传 |
|||
servlet: |
|||
multipart: |
|||
# 单个文件大小 |
|||
max-file-size: 10240MB |
|||
# 设置总上传的文件大小 |
|||
max-request-size: 10240MB |
|||
# 服务模块 |
|||
devtools: |
|||
restart: |
|||
# 热部署开关 |
|||
enabled: true |
|||
mvc: |
|||
pathmatch: |
|||
matching-strategy: ant_path_matcher |
|||
format: |
|||
date-time: yyyy-MM-dd HH:mm:ss |
|||
jackson: |
|||
# 日期格式化 |
|||
date-format: yyyy-MM-dd HH:mm:ss |
|||
serialization: |
|||
# 格式化输出 |
|||
indent_output: false |
|||
# 忽略无法转换的对象 |
|||
fail_on_empty_beans: false |
|||
deserialization: |
|||
# 允许对象忽略json中不存在的属性 |
|||
fail_on_unknown_properties: false |
|||
|
|||
# Sa-Token配置 |
|||
sa-token: |
|||
# token名称 (同时也是cookie名称) |
|||
token-name: Authorization |
|||
# token有效期 设为一天 (必定过期) 单位: 秒 |
|||
timeout: 86400 |
|||
# 多端不同 token 有效期 可查看 LoginHelper.loginByDevice 方法自定义 |
|||
# token最低活跃时间 (指定时间无操作就过期) 单位: 秒 |
|||
active-timeout: 1800 |
|||
# 允许动态设置 token 有效期 |
|||
dynamic-active-timeout: true |
|||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) |
|||
is-concurrent: true |
|||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) |
|||
is-share: false |
|||
# 是否尝试从header里读取token |
|||
is-read-header: true |
|||
# 是否尝试从cookie里读取token |
|||
is-read-cookie: false |
|||
# token前缀 |
|||
token-prefix: "Bearer" |
|||
# jwt秘钥 |
|||
jwt-secret-key: abcdefghijklmnopqrstuvwxyz |
|||
|
|||
# security配置 |
|||
security: |
|||
# 排除路径 |
|||
excludes: |
|||
# 静态资源 |
|||
- /*.html |
|||
- /**/*.html |
|||
- /**/*.css |
|||
- /**/*.js |
|||
# 公共路径 |
|||
- /favicon.ico |
|||
- /error |
|||
# swagger 文档配置 |
|||
- /*/api-docs |
|||
- /*/api-docs/** |
|||
|
|||
|
|||
# MyBatisPlus配置 |
|||
# https://baomidou.com/config/ |
|||
mybatis-plus: |
|||
# 不支持多包, 如有需要可在注解配置 或 提升扫包等级 |
|||
# 例如 com.**.**.mapper |
|||
mapperPackage: com.inscloudtech.**.mapper |
|||
# 对应的 XML 文件位置 |
|||
mapperLocations: classpath*:mapper/**/*Mapper.xml |
|||
# 实体扫描,多个package用逗号或者分号分隔 |
|||
typeAliasesPackage: com.inscloudtech.**.domain |
|||
# 启动时是否检查 MyBatis XML 文件的存在,默认不检查 |
|||
checkConfigLocation: false |
|||
configuration: |
|||
# 自动驼峰命名规则(camel case)映射 |
|||
mapUnderscoreToCamelCase: true |
|||
# MyBatis 自动映射策略 |
|||
# NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射 |
|||
autoMappingBehavior: PARTIAL |
|||
# MyBatis 自动映射时未知列或未知属性处理策 |
|||
# NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息 |
|||
autoMappingUnknownColumnBehavior: NONE |
|||
# 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl |
|||
# 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl |
|||
# 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl |
|||
logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl |
|||
global-config: |
|||
# 是否打印 Logo banner |
|||
banner: false |
|||
dbConfig: |
|||
# 主键类型 |
|||
# AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID |
|||
idType: ASSIGN_ID |
|||
# 逻辑已删除值 |
|||
logicDeleteValue: 2 |
|||
# 逻辑未删除值 |
|||
logicNotDeleteValue: 0 |
|||
# 字段验证策略之 insert,在 insert 的时候的字段验证策略 |
|||
# IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 默认 NEVER 不加入 SQL |
|||
insertStrategy: NOT_NULL |
|||
# 字段验证策略之 update,在 update 的时候的字段验证策略 |
|||
updateStrategy: NOT_NULL |
|||
# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件 |
|||
where-strategy: NOT_NULL |
|||
|
|||
# 数据加密 |
|||
mybatis-encryptor: |
|||
# 是否开启加密 |
|||
enable: true |
|||
# 默认加密算法 |
|||
algorithm: BASE64 |
|||
# 编码方式 BASE64/HEX。默认BASE64 |
|||
encode: BASE64 |
|||
# 安全秘钥 对称算法的秘钥 如:AES,SM4 |
|||
password: |
|||
# 公私钥 非对称算法的公私钥 如:SM2,RSA |
|||
publicKey: |
|||
privateKey: MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANBBEeueWlXlkkj2+WY5l+IWe42d8b5K28g+G/CFKC/yYAEHtqGlCsBOrb+YBkG9mPzmuYA/n9k0NFIc8E8yY5vZQaroyFBrTTWEzG9RY2f7Y3svVyybs6jpXSUs4xff8abo7wL1Y/wUaeatTViamxYnyTvdTmLm3d+JjRij68rxAgMBAAECgYAB0TnhXraSopwIVRfmboea1b0upl+BUdTJcmci412UjrKr5aE695ZLPkXbFXijVu7HJlyyv94NVUdaMACV7Ku/S2RuNB70M7YJm8rAjHFC3/i2ZeIM60h1Ziy4QKv0XM3pRATlDCDNhC1WUrtQCQSgU8kcp6eUUppruOqDzcY04QJBAPm9+sBP9CwDRgy3e5+V8aZtJkwDstb0lVVV/KY890cydVxiCwvX3fqVnxKMlb+x0YtH0sb9v+71xvK2lGobaRECQQDVePU6r/cCEfpc+nkWF6osAH1f8Mux3rYv2DoBGvaPzV2BGfsLed4neRfCwWNCKvGPCdW+L0xMJg8+RwaoBUPhAkAT5kViqXxFPYWJYd1h2+rDXhMdH3ZSlm6HvDBDdrwlWinr0Iwcx3iSjPV93uHXwm118aUj4fg3LDJMCKxOwBxhAkByrQXfvwOMYygBprRBf/j0plazoWFrbd6lGR0f1uI5IfNnFRPdeFw1DEINZ2Hw+6zEUF44SqRMC+4IYJNc02dBAkBCgy7RvfyV/A7N6kKXxTHauY0v6XwSSvpeKtRJkbIcRWOdIYvaHO9L7cklj3vIEdwjSUp9K4VTBYYlmAz1xh03", publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQQRHrnlpV5ZJI9vlmOZfiFnuNnfG+StvIPhvwhSgv8mABB7ahpQrATq2/mAZBvZj85rmAP5/ZNDRSHPBPMmOb2UGq6MhQa001hMxvUWNn+2N7L1csm7Oo6V0lLOMX3/Gm6O8C9WP8FGnmrU1YmpsWJ8k73U5i5t3fiY0Yo+vK8QIDAQAB |
|||
|
|||
|
|||
springdoc: |
|||
api-docs: |
|||
# 是否开启接口文档 |
|||
enabled: true |
|||
# swagger-ui: |
|||
# # 持久化认证数据 |
|||
# persistAuthorization: true |
|||
info: |
|||
# 标题 |
|||
title: '标题:${alogService.name}后台管理系统_接口文档' |
|||
# 描述 |
|||
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...' |
|||
# 版本 |
|||
version: '版本号: ${alog-service.version}' |
|||
components: |
|||
# 鉴权方式配置 |
|||
security-schemes: |
|||
apiKey: |
|||
type: APIKEY |
|||
in: HEADER |
|||
name: ${sa-token.token-name} |
|||
#这里定义了两个分组,可定义多个,也可以不定义 |
|||
group-configs: |
|||
- group: 1.系统模块 |
|||
packages-to-scan: com.inscloudtech.web |
|||
- group: 2.功能测试子平台 |
|||
packages-to-scan: com.inscloudtech.functional |
|||
- group: 3.演示模块 |
|||
packages-to-scan: com.inscloudtech.demo |
|||
|
|||
# 防止XSS攻击 |
|||
xss: |
|||
# 过滤开关 |
|||
enabled: true |
|||
# 排除链接(多个用逗号分隔) |
|||
excludes: /system/notice |
|||
# 匹配链接 |
|||
urlPatterns: /system/*,/monitor/*,/tool/* |
|||
|
|||
# 全局线程池相关配置 |
|||
thread-pool: |
|||
# 是否开启线程池 |
|||
enabled: false |
|||
# 队列最大长度 |
|||
queueCapacity: 128 |
|||
# 线程池维护线程所允许的空闲时间 |
|||
keepAliveSeconds: 300 |
|||
|
|||
--- # 分布式锁 lock4j 全局配置 |
|||
lock4j: |
|||
# 获取分布式锁超时时间,默认为 3000 毫秒 |
|||
acquire-timeout: 3000 |
|||
# 分布式锁的超时时间,默认为 30 秒 |
|||
expire: 30000 |
|||
|
|||
--- # Actuator 监控端点的配置项 |
|||
#management: |
|||
# endpoints: |
|||
# port: -1 # 修改端口,跳过安全漏洞扫描 |
|||
# web: |
|||
# exposure: |
|||
# include: '*' |
|||
# endpoint: |
|||
# enabled-by-default: false #关闭监控 |
|||
# health: |
|||
# show-details: ALWAYS |
|||
# logfile: |
|||
# external-file: ./logs/sys-console.log |
|||
|
|||
# api接口加密 |
|||
api-decrypt: |
|||
# 是否开启全局接口加密 |
|||
enabled: true |
|||
# AES 加密头标识 |
|||
headerFlag: encrypt-key |
|||
# 响应加密公钥 非对称算法的公私钥 如:SM2,RSA 使用者请自行更换 |
|||
# 对应前端解密私钥 |
|||
publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOaMhVBSMYjtP1iIF/QX0nyJHnjGKxt4vTOULpLd4knEYS8s7lRElyvS6BApUgEhNbce1d8c9dI8G4cppNNBNtcCAwEAAQ== |
|||
# 请求解密私钥 非对称算法的公私钥 如:SM2,RSA 使用者请自行更换 |
|||
# 对应前端加密公钥 |
|||
privateKey: MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA5oyFUFIxiO0/WIgX 9BfSfIkeeMYrG3i9M5Qukt3iScRhLyzuVESXK9LoEClSASE1tx7V3xz10jwbhymk 00E21wIDAQABAkEA4Uhe3OX0UYDDbZdPEM5WeCrlA89hQC7zcvtRp2H6RWks2GNM eyVuCwRPzTTo34H1zOmRsPfulKxuBH3I0FvtQQIhAP7YLGg2J+js6e2OHo469AQL x86lfFn8mAClVu+lbY27AiEA55glDr4Rg851fMnZrt+fDbpv4dzAPR+RGR6aFPdx G5UCIAMWZ2NT1KPzytm/8QrUGAS8h80vIBSPBOBtIGKC5JLlAiBbTXsGld431XQy Dy3XqGd/NQoYxDuxnTlJ6uuZ6ndYBQIhAKyr5tFVSCWpJfOcNwadwOBo7UNm2o1g YkUjS69f2zxC |
@ -0,0 +1,2 @@ |
|||
Application Version: ${alog-service.version} |
|||
Spring Boot Version: ${spring-boot.version} |
@ -0,0 +1,49 @@ |
|||
#错误消息 |
|||
not.null=* 必须填写 |
|||
user.jcaptcha.error=验证码错误 |
|||
user.jcaptcha.expire=验证码已失效 |
|||
user.not.exists=对不起, 您的账号:{0} 不存在. |
|||
user.password.not.match=用户不存在/密码错误 |
|||
user.password.retry.limit.count=密码输入错误{0}次 |
|||
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 |
|||
user.password.delete=对不起,您的账号:{0} 已被删除 |
|||
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员 |
|||
role.blocked=角色已封禁,请联系管理员 |
|||
user.logout.success=退出成功 |
|||
length.not.valid=长度必须在{min}到{max}个字符之间 |
|||
user.username.not.blank=用户名不能为空 |
|||
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 |
|||
user.username.length.valid=账户长度必须在{min}到{max}个字符之间 |
|||
user.password.not.blank=用户密码不能为空 |
|||
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间 |
|||
user.password.not.valid=* 5-50个字符 |
|||
user.email.not.valid=邮箱格式错误 |
|||
user.email.not.blank=邮箱不能为空 |
|||
user.phonenumber.not.blank=用户手机号不能为空 |
|||
user.mobile.phone.number.not.valid=手机号格式错误 |
|||
user.login.success=登录成功 |
|||
user.register.success=注册成功 |
|||
user.register.save.error=保存用户 {0} 失败,注册账号已存在 |
|||
user.register.error=注册失败,请联系系统管理人员 |
|||
user.notfound=请重新登录 |
|||
user.forcelogout=管理员强制退出,请重新登录 |
|||
user.unknown.error=未知错误,请重新登录 |
|||
##文件上传消息 |
|||
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB! |
|||
upload.filename.exceed.length=上传的文件名最长{0}个字符 |
|||
##权限 |
|||
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] |
|||
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] |
|||
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] |
|||
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] |
|||
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] |
|||
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] |
|||
repeat.submit.message=不允许重复提交,请稍候再试 |
|||
rate.limiter.message=访问过于频繁,请稍候再试 |
|||
sms.code.not.blank=短信验证码不能为空 |
|||
sms.code.retry.limit.count=短信验证码输入错误{0}次 |
|||
sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟 |
|||
email.code.not.blank=邮箱验证码不能为空 |
|||
email.code.retry.limit.count=邮箱验证码输入错误{0}次 |
|||
email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟 |
|||
xcx.code.not.blank=小程序code不能为空 |
@ -0,0 +1,49 @@ |
|||
#错误消息 |
|||
not.null=* Required fill in |
|||
user.jcaptcha.error=Captcha error |
|||
user.jcaptcha.expire=Captcha invalid |
|||
user.not.exists=Sorry, your account: {0} does not exist |
|||
user.password.not.match=User does not exist/Password error |
|||
user.password.retry.limit.count=Password input error {0} times |
|||
user.password.retry.limit.exceed=Password input error {0} times, account locked for {1} minutes |
|||
user.password.delete=Sorry, your account:{0} has been deleted |
|||
user.blocked=Sorry, your account: {0} has been disabled. Please contact the administrator |
|||
role.blocked=Role disabled,please contact administrators |
|||
user.logout.success=Exit successful |
|||
length.not.valid=The length must be between {min} and {max} characters |
|||
user.username.not.blank=Username cannot be blank |
|||
user.username.not.valid=* 2 to 20 chinese characters, letters, numbers or underscores, and must start with a non number |
|||
user.username.length.valid=Account length must be between {min} and {max} characters |
|||
user.password.not.blank=Password cannot be empty |
|||
user.password.length.valid=Password length must be between {min} and {max} characters |
|||
user.password.not.valid=* 5-50 characters |
|||
user.email.not.valid=Mailbox format error |
|||
user.email.not.blank=Mailbox cannot be blank |
|||
user.phonenumber.not.blank=Phone number cannot be blank |
|||
user.mobile.phone.number.not.valid=Phone number format error |
|||
user.login.success=Login successful |
|||
user.register.success=Register successful |
|||
user.register.save.error=Failed to save user {0}, The registered account already exists |
|||
user.register.error=Register failed, please contact system administrator |
|||
user.notfound=Please login again |
|||
user.forcelogout=The administrator is forced to exit,please login again |
|||
user.unknown.error=Unknown error, please login again |
|||
##文件上传消息 |
|||
upload.exceed.maxSize=The uploaded file size exceeds the limit file size!<br/>the maximum allowed file size is:{0}MB! |
|||
upload.filename.exceed.length=The maximum length of uploaded file name is {0} characters |
|||
##权限 |
|||
no.permission=You do not have permission to the data,please contact your administrator to add permissions [{0}] |
|||
no.create.permission=You do not have permission to create data,please contact your administrator to add permissions [{0}] |
|||
no.update.permission=You do not have permission to modify data,please contact your administrator to add permissions [{0}] |
|||
no.delete.permission=You do not have permission to delete data,please contact your administrator to add permissions [{0}] |
|||
no.export.permission=You do not have permission to export data,please contact your administrator to add permissions [{0}] |
|||
no.view.permission=You do not have permission to view data,please contact your administrator to add permissions [{0}] |
|||
repeat.submit.message=Repeat submit is not allowed, please try again later |
|||
rate.limiter.message=Visit too frequently, please try again later |
|||
sms.code.not.blank=Sms code cannot be blank |
|||
sms.code.retry.limit.count=Sms code input error {0} times |
|||
sms.code.retry.limit.exceed=Sms code input error {0} times, account locked for {1} minutes |
|||
email.code.not.blank=Email code cannot be blank |
|||
email.code.retry.limit.count=Email code input error {0} times |
|||
email.code.retry.limit.exceed=Email code input error {0} times, account locked for {1} minutes |
|||
xcx.code.not.blank=Mini program code cannot be blank |
@ -0,0 +1,49 @@ |
|||
#错误消息 |
|||
not.null=* 必须填写 |
|||
user.jcaptcha.error=验证码错误 |
|||
user.jcaptcha.expire=验证码已失效 |
|||
user.not.exists=对不起, 您的账号:{0} 不存在. |
|||
user.password.not.match=用户不存在/密码错误 |
|||
user.password.retry.limit.count=密码输入错误{0}次 |
|||
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 |
|||
user.password.delete=对不起,您的账号:{0} 已被删除 |
|||
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员 |
|||
role.blocked=角色已封禁,请联系管理员 |
|||
user.logout.success=退出成功 |
|||
length.not.valid=长度必须在{min}到{max}个字符之间 |
|||
user.username.not.blank=用户名不能为空 |
|||
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 |
|||
user.username.length.valid=账户长度必须在{min}到{max}个字符之间 |
|||
user.password.not.blank=用户密码不能为空 |
|||
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间 |
|||
user.password.not.valid=* 5-50个字符 |
|||
user.email.not.valid=邮箱格式错误 |
|||
user.email.not.blank=邮箱不能为空 |
|||
user.phonenumber.not.blank=用户手机号不能为空 |
|||
user.mobile.phone.number.not.valid=手机号格式错误 |
|||
user.login.success=登录成功 |
|||
user.register.success=注册成功 |
|||
user.register.save.error=保存用户 {0} 失败,注册账号已存在 |
|||
user.register.error=注册失败,请联系系统管理人员 |
|||
user.notfound=请重新登录 |
|||
user.forcelogout=管理员强制退出,请重新登录 |
|||
user.unknown.error=未知错误,请重新登录 |
|||
##文件上传消息 |
|||
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB! |
|||
upload.filename.exceed.length=上传的文件名最长{0}个字符 |
|||
##权限 |
|||
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] |
|||
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] |
|||
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] |
|||
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] |
|||
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] |
|||
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] |
|||
repeat.submit.message=不允许重复提交,请稍候再试 |
|||
rate.limiter.message=访问过于频繁,请稍候再试 |
|||
sms.code.not.blank=短信验证码不能为空 |
|||
sms.code.retry.limit.count=短信验证码输入错误{0}次 |
|||
sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟 |
|||
email.code.not.blank=邮箱验证码不能为空 |
|||
email.code.retry.limit.count=邮箱验证码输入错误{0}次 |
|||
email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟 |
|||
xcx.code.not.blank=小程序code不能为空 |
@ -0,0 +1,129 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<configuration> |
|||
<property name="log.path" value="./logs"/> |
|||
<property name="console.log.pattern" |
|||
value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/> |
|||
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/> |
|||
|
|||
<!-- 控制台输出 --> |
|||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> |
|||
<encoder> |
|||
<pattern>${console.log.pattern}</pattern> |
|||
<charset>utf-8</charset> |
|||
</encoder> |
|||
</appender> |
|||
|
|||
<!-- 控制台输出 --> |
|||
<appender name="file_console" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
|||
<file>${log.path}/sys-console.log</file> |
|||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
|||
<!-- 日志文件名格式 --> |
|||
<fileNamePattern>${log.path}/sys-console.%d{yyyy-MM-dd}.log</fileNamePattern> |
|||
<!-- 日志最大 1天 --> |
|||
<maxHistory>1</maxHistory> |
|||
</rollingPolicy> |
|||
<encoder> |
|||
<pattern>${log.pattern}</pattern> |
|||
<charset>utf-8</charset> |
|||
</encoder> |
|||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
|||
<!-- 过滤的级别 --> |
|||
<level>INFO</level> |
|||
</filter> |
|||
</appender> |
|||
|
|||
<!-- 系统日志输出 --> |
|||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
|||
<file>${log.path}/sys-info.log</file> |
|||
<!-- 循环政策:基于时间创建日志文件 --> |
|||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
|||
<!-- 日志文件名格式 --> |
|||
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern> |
|||
<!-- 日志最大的历史 60天 --> |
|||
<maxHistory>60</maxHistory> |
|||
</rollingPolicy> |
|||
<encoder> |
|||
<pattern>${log.pattern}</pattern> |
|||
</encoder> |
|||
<filter class="ch.qos.logback.classic.filter.LevelFilter"> |
|||
<!-- 过滤的级别 --> |
|||
<level>INFO</level> |
|||
<!-- 匹配时的操作:接收(记录) --> |
|||
<onMatch>ACCEPT</onMatch> |
|||
<!-- 不匹配时的操作:拒绝(不记录) --> |
|||
<onMismatch>DENY</onMismatch> |
|||
</filter> |
|||
</appender> |
|||
|
|||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
|||
<file>${log.path}/sys-error.log</file> |
|||
<!-- 循环政策:基于时间创建日志文件 --> |
|||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
|||
<!-- 日志文件名格式 --> |
|||
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern> |
|||
<!-- 日志最大的历史 60天 --> |
|||
<maxHistory>60</maxHistory> |
|||
</rollingPolicy> |
|||
<encoder> |
|||
<pattern>${log.pattern}</pattern> |
|||
</encoder> |
|||
<filter class="ch.qos.logback.classic.filter.LevelFilter"> |
|||
<!-- 过滤的级别 --> |
|||
<level>ERROR</level> |
|||
<!-- 匹配时的操作:接收(记录) --> |
|||
<onMatch>ACCEPT</onMatch> |
|||
<!-- 不匹配时的操作:拒绝(不记录) --> |
|||
<onMismatch>DENY</onMismatch> |
|||
</filter> |
|||
</appender> |
|||
|
|||
<!-- info异步输出 --> |
|||
<appender name="async_info" class="ch.qos.logback.classic.AsyncAppender"> |
|||
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> |
|||
<discardingThreshold>0</discardingThreshold> |
|||
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> |
|||
<queueSize>512</queueSize> |
|||
<!-- 添加附加的appender,最多只能添加一个 --> |
|||
<appender-ref ref="file_info"/> |
|||
</appender> |
|||
|
|||
<!-- error异步输出 --> |
|||
<appender name="async_error" class="ch.qos.logback.classic.AsyncAppender"> |
|||
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> |
|||
<discardingThreshold>0</discardingThreshold> |
|||
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> |
|||
<queueSize>512</queueSize> |
|||
<!-- 添加附加的appender,最多只能添加一个 --> |
|||
<appender-ref ref="file_error"/> |
|||
</appender> |
|||
|
|||
<!-- 整合 skywalking 控制台输出 tid --> |
|||
<!-- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">--> |
|||
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">--> |
|||
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">--> |
|||
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>--> |
|||
<!-- </layout>--> |
|||
<!-- <charset>utf-8</charset>--> |
|||
<!-- </encoder>--> |
|||
<!-- </appender>--> |
|||
|
|||
<!-- 整合 skywalking 推送采集日志 --> |
|||
<!-- <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">--> |
|||
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">--> |
|||
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">--> |
|||
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>--> |
|||
<!-- </layout>--> |
|||
<!-- <charset>utf-8</charset>--> |
|||
<!-- </encoder>--> |
|||
<!-- </appender>--> |
|||
|
|||
<!--系统操作日志--> |
|||
<root level="info"> |
|||
<appender-ref ref="console" /> |
|||
<appender-ref ref="async_info" /> |
|||
<appender-ref ref="async_error" /> |
|||
<appender-ref ref="file_console" /> |
|||
<!-- <appender-ref ref="sky_log"/>--> |
|||
</root> |
|||
|
|||
</configuration> |
@ -0,0 +1,28 @@ |
|||
# p6spy 性能分析插件配置文件 |
|||
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory |
|||
# 自定义日志打印 |
|||
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger |
|||
#日志输出到控制台 |
|||
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger |
|||
# 使用日志系统记录 sql |
|||
#appender=com.p6spy.engine.spy.appender.Slf4JLogger |
|||
# 设置 p6spy driver 代理 |
|||
#deregisterdrivers=true |
|||
# 取消JDBC URL前缀 |
|||
useprefix=true |
|||
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset. |
|||
excludecategories=info,debug,result,commit,resultset |
|||
# 日期格式 |
|||
dateformat=yyyy-MM-dd HH:mm:ss |
|||
# SQL语句打印时间格式 |
|||
databaseDialectTimestampFormat=yyyy-MM-dd HH:mm:ss |
|||
# 实际驱动可多个 |
|||
#driverlist=org.h2.Driver |
|||
# 是否开启慢SQL记录 |
|||
outagedetection=true |
|||
# 慢SQL记录标准 2 秒 |
|||
outagedetectioninterval=2 |
|||
# 是否过滤 Log |
|||
filter=true |
|||
# 过滤 Log 时所排除的 sql 关键字,以逗号分隔 |
|||
exclude=SELECT 1 |
@ -0,0 +1,45 @@ |
|||
package com.inscloudtech.test; |
|||
|
|||
import org.junit.jupiter.api.Assertions; |
|||
import org.junit.jupiter.api.DisplayName; |
|||
import org.junit.jupiter.api.Test; |
|||
|
|||
/** |
|||
* 断言单元测试案例 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@DisplayName("断言单元测试案例") |
|||
public class AssertUnitTest { |
|||
|
|||
@DisplayName("测试 assertEquals 方法") |
|||
@Test |
|||
public void testAssertEquals() { |
|||
Assertions.assertEquals("666", new String("666")); |
|||
Assertions.assertNotEquals("666", new String("666")); |
|||
} |
|||
|
|||
@DisplayName("测试 assertSame 方法") |
|||
@Test |
|||
public void testAssertSame() { |
|||
Object obj = new Object(); |
|||
Object obj1 = obj; |
|||
Assertions.assertSame(obj, obj1); |
|||
Assertions.assertNotSame(obj, obj1); |
|||
} |
|||
|
|||
@DisplayName("测试 assertTrue 方法") |
|||
@Test |
|||
public void testAssertTrue() { |
|||
Assertions.assertTrue(true); |
|||
Assertions.assertFalse(true); |
|||
} |
|||
|
|||
@DisplayName("测试 assertNull 方法") |
|||
@Test |
|||
public void testAssertNull() { |
|||
Assertions.assertNull(null); |
|||
Assertions.assertNotNull(null); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,70 @@ |
|||
package com.inscloudtech.test; |
|||
|
|||
import com.inscloudtech.common.config.ProjectConfig; |
|||
import org.junit.jupiter.api.*; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.boot.test.context.SpringBootTest; |
|||
|
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
/** |
|||
* 单元测试案例 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@SpringBootTest // 此注解只能在 springboot 主包下使用 需包含 main 方法与 yml 配置文件 |
|||
@DisplayName("单元测试案例") |
|||
public class DemoUnitTest { |
|||
|
|||
@Autowired |
|||
private ProjectConfig ruoYiConfig; |
|||
|
|||
@DisplayName("测试 @SpringBootTest @Test @DisplayName 注解") |
|||
@Test |
|||
public void testTest() { |
|||
System.out.println(ruoYiConfig); |
|||
} |
|||
|
|||
@Disabled |
|||
@DisplayName("测试 @Disabled 注解") |
|||
@Test |
|||
public void testDisabled() { |
|||
System.out.println(ruoYiConfig); |
|||
} |
|||
|
|||
@Timeout(value = 2L, unit = TimeUnit.SECONDS) |
|||
@DisplayName("测试 @Timeout 注解") |
|||
@Test |
|||
public void testTimeout() throws InterruptedException { |
|||
Thread.sleep(3000); |
|||
System.out.println(ruoYiConfig); |
|||
} |
|||
|
|||
|
|||
@DisplayName("测试 @RepeatedTest 注解") |
|||
@RepeatedTest(3) |
|||
public void testRepeatedTest() { |
|||
System.out.println(666); |
|||
} |
|||
|
|||
@BeforeAll |
|||
public static void testBeforeAll() { |
|||
System.out.println("@BeforeAll =================="); |
|||
} |
|||
|
|||
@BeforeEach |
|||
public void testBeforeEach() { |
|||
System.out.println("@BeforeEach =================="); |
|||
} |
|||
|
|||
@AfterEach |
|||
public void testAfterEach() { |
|||
System.out.println("@AfterEach =================="); |
|||
} |
|||
|
|||
@AfterAll |
|||
public static void testAfterAll() { |
|||
System.out.println("@AfterAll =================="); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,72 @@ |
|||
package com.inscloudtech.test; |
|||
|
|||
import com.inscloudtech.common.enums.UserType; |
|||
import org.junit.jupiter.api.AfterEach; |
|||
import org.junit.jupiter.api.BeforeEach; |
|||
import org.junit.jupiter.api.DisplayName; |
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.EnumSource; |
|||
import org.junit.jupiter.params.provider.MethodSource; |
|||
import org.junit.jupiter.params.provider.NullSource; |
|||
import org.junit.jupiter.params.provider.ValueSource; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.stream.Stream; |
|||
|
|||
/** |
|||
* 带参数单元测试案例 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@DisplayName("带参数单元测试案例") |
|||
public class ParamUnitTest { |
|||
|
|||
@DisplayName("测试 @ValueSource 注解") |
|||
@ParameterizedTest |
|||
@ValueSource(strings = {"t1", "t2", "t3"}) |
|||
public void testValueSource(String str) { |
|||
System.out.println(str); |
|||
} |
|||
|
|||
@DisplayName("测试 @NullSource 注解") |
|||
@ParameterizedTest |
|||
@NullSource |
|||
public void testNullSource(String str) { |
|||
System.out.println(str); |
|||
} |
|||
|
|||
@DisplayName("测试 @EnumSource 注解") |
|||
@ParameterizedTest |
|||
@EnumSource(UserType.class) |
|||
public void testEnumSource(UserType type) { |
|||
System.out.println(type.getUserType()); |
|||
} |
|||
|
|||
@DisplayName("测试 @MethodSource 注解") |
|||
@ParameterizedTest |
|||
@MethodSource("getParam") |
|||
public void testMethodSource(String str) { |
|||
System.out.println(str); |
|||
} |
|||
|
|||
public static Stream<String> getParam() { |
|||
List<String> list = new ArrayList<>(); |
|||
list.add("t1"); |
|||
list.add("t2"); |
|||
list.add("t3"); |
|||
return list.stream(); |
|||
} |
|||
|
|||
@BeforeEach |
|||
public void testBeforeEach() { |
|||
System.out.println("@BeforeEach =================="); |
|||
} |
|||
|
|||
@AfterEach |
|||
public void testAfterEach() { |
|||
System.out.println("@AfterEach =================="); |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,54 @@ |
|||
package com.inscloudtech.test; |
|||
|
|||
import org.junit.jupiter.api.*; |
|||
import org.springframework.boot.test.context.SpringBootTest; |
|||
|
|||
/** |
|||
* 标签单元测试案例 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@SpringBootTest |
|||
@DisplayName("标签单元测试案例") |
|||
public class TagUnitTest { |
|||
|
|||
@Tag("dev") |
|||
@DisplayName("测试 @Tag dev") |
|||
@Test |
|||
public void testTagDev() { |
|||
System.out.println("dev"); |
|||
} |
|||
|
|||
@Tag("prod") |
|||
@DisplayName("测试 @Tag prod") |
|||
@Test |
|||
public void testTagProd() { |
|||
System.out.println("prod"); |
|||
} |
|||
|
|||
@Tag("local") |
|||
@DisplayName("测试 @Tag local") |
|||
@Test |
|||
public void testTagLocal() { |
|||
System.out.println("local"); |
|||
} |
|||
|
|||
@Tag("exclude") |
|||
@DisplayName("测试 @Tag exclude") |
|||
@Test |
|||
public void testTagExclude() { |
|||
System.out.println("exclude"); |
|||
} |
|||
|
|||
@BeforeEach |
|||
public void testBeforeEach() { |
|||
System.out.println("@BeforeEach =================="); |
|||
} |
|||
|
|||
@AfterEach |
|||
public void testAfterEach() { |
|||
System.out.println("@AfterEach =================="); |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,170 @@ |
|||
<?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>alog-service</artifactId> |
|||
<groupId>com.inscloudtech</groupId> |
|||
<version>4.8.2</version> |
|||
</parent> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
|
|||
<artifactId>alog-common</artifactId> |
|||
|
|||
<description> |
|||
common通用工具 |
|||
</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> |
|||
|
|||
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ --> |
|||
<dependency> |
|||
<groupId>cn.dev33</groupId> |
|||
<artifactId>sa-token-spring-boot-starter</artifactId> |
|||
</dependency> |
|||
<!-- Sa-Token 整合 jwt --> |
|||
<dependency> |
|||
<groupId>cn.dev33</groupId> |
|||
<artifactId>sa-token-jwt</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- 自定义验证注解 --> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-validation</artifactId> |
|||
</dependency> |
|||
|
|||
<!--常用工具类 --> |
|||
<dependency> |
|||
<groupId>org.apache.commons</groupId> |
|||
<artifactId>commons-lang3</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- JSON工具类 --> |
|||
<dependency> |
|||
<groupId>com.fasterxml.jackson.core</groupId> |
|||
<artifactId>jackson-databind</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>easyexcel</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- yml解析器 --> |
|||
<dependency> |
|||
<groupId>org.yaml</groupId> |
|||
<artifactId>snakeyaml</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- servlet包 --> |
|||
<dependency> |
|||
<groupId>javax.servlet</groupId> |
|||
<artifactId>javax.servlet-api</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.baomidou</groupId> |
|||
<artifactId>mybatis-plus-boot-starter</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- dynamic-datasource 多数据源--> |
|||
<dependency> |
|||
<groupId>com.baomidou</groupId> |
|||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>cn.hutool</groupId> |
|||
<artifactId>hutool-core</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>cn.hutool</groupId> |
|||
<artifactId>hutool-http</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>cn.hutool</groupId> |
|||
<artifactId>hutool-captcha</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>cn.hutool</groupId> |
|||
<artifactId>hutool-jwt</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>cn.hutool</groupId> |
|||
<artifactId>hutool-extra</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.sun.mail</groupId> |
|||
<artifactId>jakarta.mail</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.springdoc</groupId> |
|||
<artifactId>springdoc-openapi-webmvc-core</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.springdoc</groupId> |
|||
<artifactId>springdoc-openapi-javadoc</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- 自动生成YML配置关联JSON文件 --> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-configuration-processor</artifactId> |
|||
</dependency> |
|||
|
|||
<!--redisson--> |
|||
<dependency> |
|||
<groupId>org.redisson</groupId> |
|||
<artifactId>redisson-spring-boot-starter</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.redisson</groupId> |
|||
<artifactId>redisson-spring-data-27</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.baomidou</groupId> |
|||
<artifactId>lock4j-redisson-spring-boot-starter</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- 加密包引入 --> |
|||
<dependency> |
|||
<groupId>org.bouncycastle</groupId> |
|||
<artifactId>bcprov-jdk15to18</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- 离线IP地址定位库 --> |
|||
<dependency> |
|||
<groupId>org.lionsoul</groupId> |
|||
<artifactId>ip2region</artifactId> |
|||
</dependency> |
|||
|
|||
</dependencies> |
|||
|
|||
</project> |
@ -0,0 +1,24 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import com.inscloudtech.common.excel.CellMergeStrategy; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* excel 列单元格合并(合并列相同项) |
|||
* |
|||
* 需搭配 {@link CellMergeStrategy} 策略使用 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Target(ElementType.FIELD) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Inherited |
|||
public @interface CellMerge { |
|||
|
|||
/** |
|||
* col index |
|||
*/ |
|||
int index() default -1; |
|||
|
|||
} |
@ -0,0 +1,28 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 数据权限 |
|||
* |
|||
* 一个注解只能对应一个模板 |
|||
* |
|||
* @author inscloudtech |
|||
* @version 3.5.0 |
|||
*/ |
|||
@Target(ElementType.METHOD) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Documented |
|||
public @interface DataColumn { |
|||
|
|||
/** |
|||
* 占位符关键字 |
|||
*/ |
|||
String[] key() default "deptName"; |
|||
|
|||
/** |
|||
* 占位符替换值 |
|||
*/ |
|||
String[] value() default "dept_id"; |
|||
|
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 数据权限组 |
|||
* |
|||
* @author inscloudtech |
|||
* @version 3.5.0 |
|||
*/ |
|||
@Target({ElementType.METHOD, ElementType.TYPE}) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Documented |
|||
public @interface DataPermission { |
|||
|
|||
DataColumn[] value(); |
|||
|
|||
} |
@ -0,0 +1,29 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; |
|||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
|||
import com.inscloudtech.common.jackson.DictDataJsonSerializer; |
|||
|
|||
import java.lang.annotation.ElementType; |
|||
import java.lang.annotation.Retention; |
|||
import java.lang.annotation.RetentionPolicy; |
|||
import java.lang.annotation.Target; |
|||
|
|||
/** |
|||
* 字典数据映射注解 |
|||
* |
|||
* @author itino |
|||
* @deprecated 建议使用通用翻译注解 |
|||
*/ |
|||
@Deprecated |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Target({ElementType.FIELD, ElementType.METHOD}) |
|||
@JacksonAnnotationsInside |
|||
@JsonSerialize(using = DictDataJsonSerializer.class) |
|||
public @interface DictDataMapper { |
|||
|
|||
/** |
|||
* 设置字典的type值 (如: sys_user_sex) |
|||
*/ |
|||
String dictType() default ""; |
|||
} |
@ -0,0 +1,32 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 字典格式化 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Target({ElementType.FIELD}) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Inherited |
|||
public @interface ExcelDictFormat { |
|||
|
|||
/** |
|||
* 如果是字典类型,请设置字典的type值 (如: sys_user_sex) |
|||
*/ |
|||
String dictType() default ""; |
|||
|
|||
/** |
|||
* 读取内容转表达式 (如: 0=男,1=女,2=未知) |
|||
*/ |
|||
String readConverterExp() default ""; |
|||
|
|||
/** |
|||
* 分隔符,读取字符串组内容 |
|||
*/ |
|||
String separator() default StringUtils.SEPARATOR; |
|||
|
|||
} |
@ -0,0 +1,30 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 枚举格式化 |
|||
* |
|||
* @author Liang |
|||
*/ |
|||
@Target({ElementType.FIELD}) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Inherited |
|||
public @interface ExcelEnumFormat { |
|||
|
|||
/** |
|||
* 字典枚举类型 |
|||
*/ |
|||
Class<? extends Enum<?>> enumClass(); |
|||
|
|||
/** |
|||
* 字典枚举类中对应的code属性名称,默认为code |
|||
*/ |
|||
String codeField() default "code"; |
|||
|
|||
/** |
|||
* 字典枚举类中对应的text属性名称,默认为text |
|||
*/ |
|||
String textField() default "text"; |
|||
|
|||
} |
@ -0,0 +1,47 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import com.inscloudtech.common.enums.BusinessType; |
|||
import com.inscloudtech.common.enums.OperatorType; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 自定义安全审计模块注解 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Target({ElementType.PARAMETER, ElementType.METHOD}) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Documented |
|||
public @interface Log { |
|||
/** |
|||
* 模块 |
|||
*/ |
|||
String title() default ""; |
|||
|
|||
/** |
|||
* 功能 |
|||
*/ |
|||
BusinessType businessType() default BusinessType.OTHER; |
|||
|
|||
/** |
|||
* 操作人类别 |
|||
*/ |
|||
OperatorType operatorType() default OperatorType.MANAGE; |
|||
|
|||
/** |
|||
* 是否保存请求的参数 |
|||
*/ |
|||
boolean isSaveRequestData() default true; |
|||
|
|||
/** |
|||
* 是否保存响应的参数 |
|||
*/ |
|||
boolean isSaveResponseData() default true; |
|||
|
|||
/** |
|||
* 排除指定的请求参数 |
|||
*/ |
|||
String[] excludeParamNames() default {}; |
|||
|
|||
} |
@ -0,0 +1,41 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import com.inscloudtech.common.enums.LimitType; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 限流注解 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Target(ElementType.METHOD) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Documented |
|||
public @interface RateLimiter { |
|||
/** |
|||
* 限流key,支持使用Spring el表达式来动态获取方法上的参数值 |
|||
* 格式类似于 #code.id #{#code} |
|||
*/ |
|||
String key() default ""; |
|||
|
|||
/** |
|||
* 限流时间,单位秒 |
|||
*/ |
|||
int time() default 60; |
|||
|
|||
/** |
|||
* 限流次数 |
|||
*/ |
|||
int count() default 100; |
|||
|
|||
/** |
|||
* 限流类型 |
|||
*/ |
|||
LimitType limitType() default LimitType.DEFAULT; |
|||
|
|||
/** |
|||
* 提示消息 支持国际化 格式为 {code} |
|||
*/ |
|||
String message() default "{rate.limiter.message}"; |
|||
} |
@ -0,0 +1,29 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
/** |
|||
* 自定义注解防止表单重复提交 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Inherited |
|||
@Target(ElementType.METHOD) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Documented |
|||
public @interface RepeatSubmit { |
|||
|
|||
/** |
|||
* 间隔时间(ms),小于此时间视为重复提交 |
|||
*/ |
|||
int interval() default 5000; |
|||
|
|||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS; |
|||
|
|||
/** |
|||
* 提示消息 支持国际化 格式为 {code} |
|||
*/ |
|||
String message() default "{repeat.submit.message}"; |
|||
|
|||
} |
@ -0,0 +1,24 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; |
|||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
|||
import com.inscloudtech.common.enums.SensitiveStrategy; |
|||
import com.inscloudtech.common.jackson.SensitiveJsonSerializer; |
|||
|
|||
import java.lang.annotation.ElementType; |
|||
import java.lang.annotation.Retention; |
|||
import java.lang.annotation.RetentionPolicy; |
|||
import java.lang.annotation.Target; |
|||
|
|||
/** |
|||
* 数据脱敏注解 |
|||
* |
|||
* @author zhujie |
|||
*/ |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Target(ElementType.FIELD) |
|||
@JacksonAnnotationsInside |
|||
@JsonSerialize(using = SensitiveJsonSerializer.class) |
|||
public @interface Sensitive { |
|||
SensitiveStrategy strategy(); |
|||
} |
@ -0,0 +1,39 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; |
|||
import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
|||
import com.inscloudtech.common.translation.handler.TranslationHandler; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 通用翻译注解 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Inherited |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Target({ElementType.FIELD, ElementType.METHOD}) |
|||
@Documented |
|||
@JacksonAnnotationsInside |
|||
@JsonSerialize(using = TranslationHandler.class) |
|||
public @interface Translation { |
|||
|
|||
/** |
|||
* 类型 (需与实现类上的 {@link com.inscloudtech.common.annotation.TranslationType} 注解type对应) |
|||
* <p> |
|||
* 默认取当前字段的值 如果设置了 @{@link Translation#mapper()} 则取映射字段的值 |
|||
*/ |
|||
String type(); |
|||
|
|||
/** |
|||
* 映射字段 (如果不为空则取此字段的值) |
|||
*/ |
|||
String mapper() default ""; |
|||
|
|||
/** |
|||
* 其他条件 例如: 字典type(sys_user_sex) |
|||
*/ |
|||
String other() default ""; |
|||
|
|||
} |
@ -0,0 +1,21 @@ |
|||
package com.inscloudtech.common.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 翻译类型注解 (标注到{@link com.inscloudtech.common.translation.TranslationInterface} 的实现类) |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Inherited |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Target({ElementType.TYPE}) |
|||
@Documented |
|||
public @interface TranslationType { |
|||
|
|||
/** |
|||
* 类型 |
|||
*/ |
|||
String type(); |
|||
|
|||
} |
@ -0,0 +1,85 @@ |
|||
package com.inscloudtech.common.captcha; |
|||
|
|||
import cn.hutool.captcha.generator.CodeGenerator; |
|||
import cn.hutool.core.math.Calculator; |
|||
import cn.hutool.core.util.CharUtil; |
|||
import cn.hutool.core.util.RandomUtil; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
|
|||
/** |
|||
* 无符号计算生成器 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public class UnsignedMathGenerator implements CodeGenerator { |
|||
|
|||
private static final long serialVersionUID = -5514819971774091076L; |
|||
|
|||
private static final String OPERATORS = "+-*"; |
|||
|
|||
/** |
|||
* 参与计算数字最大长度 |
|||
*/ |
|||
private final int numberLength; |
|||
|
|||
/** |
|||
* 构造 |
|||
*/ |
|||
public UnsignedMathGenerator() { |
|||
this(2); |
|||
} |
|||
|
|||
/** |
|||
* 构造 |
|||
* |
|||
* @param numberLength 参与计算最大数字位数 |
|||
*/ |
|||
public UnsignedMathGenerator(int numberLength) { |
|||
this.numberLength = numberLength; |
|||
} |
|||
|
|||
@Override |
|||
public String generate() { |
|||
final int limit = getLimit(); |
|||
int a = RandomUtil.randomInt(limit); |
|||
int b = RandomUtil.randomInt(limit); |
|||
String max = Integer.toString(Math.max(a,b)); |
|||
String min = Integer.toString(Math.min(a,b)); |
|||
max = StringUtils.rightPad(max, this.numberLength, CharUtil.SPACE); |
|||
min = StringUtils.rightPad(min, this.numberLength, CharUtil.SPACE); |
|||
|
|||
return max + RandomUtil.randomChar(OPERATORS) + min + '='; |
|||
} |
|||
|
|||
@Override |
|||
public boolean verify(String code, String userInputCode) { |
|||
int result; |
|||
try { |
|||
result = Integer.parseInt(userInputCode); |
|||
} catch (NumberFormatException e) { |
|||
// 用户输入非数字 |
|||
return false; |
|||
} |
|||
|
|||
final int calculateResult = (int) Calculator.conversion(code); |
|||
return result == calculateResult; |
|||
} |
|||
|
|||
/** |
|||
* 获取验证码长度 |
|||
* |
|||
* @return 验证码长度 |
|||
*/ |
|||
public int getLength() { |
|||
return this.numberLength * 2 + 2; |
|||
} |
|||
|
|||
/** |
|||
* 根据长度获取参与计算数字最大值 |
|||
* |
|||
* @return 最大值 |
|||
*/ |
|||
private int getLimit() { |
|||
return Integer.parseInt("1" + StringUtils.repeat('0', this.numberLength)); |
|||
} |
|||
} |
@ -0,0 +1,77 @@ |
|||
package com.inscloudtech.common.config; |
|||
|
|||
import lombok.Data; |
|||
import org.springframework.boot.context.properties.ConfigurationProperties; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* 读取项目相关配置 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@Component |
|||
@ConfigurationProperties(prefix = "alog-service") |
|||
public class ProjectConfig { |
|||
|
|||
/** |
|||
* 项目名称 |
|||
*/ |
|||
private String name; |
|||
|
|||
/** |
|||
* 版本 |
|||
*/ |
|||
private String version; |
|||
|
|||
/** |
|||
* 版权年份 |
|||
*/ |
|||
private String copyrightYear; |
|||
|
|||
/** |
|||
* 缓存懒加载 |
|||
*/ |
|||
private boolean cacheLazy; |
|||
|
|||
private static String profile; |
|||
|
|||
|
|||
public static String getProfile() { |
|||
return profile; |
|||
} |
|||
|
|||
public void setProfile(String profile) { |
|||
ProjectConfig.profile = profile; |
|||
} |
|||
|
|||
/** |
|||
* 获取导入上传路径 |
|||
*/ |
|||
public String getImportPath() { |
|||
return getProfile() + "/import"; |
|||
} |
|||
|
|||
/** |
|||
* 获取头像上传路径 |
|||
*/ |
|||
public String getAvatarPath() { |
|||
return getProfile() + "/avatar"; |
|||
} |
|||
|
|||
/** |
|||
* 获取下载路径 |
|||
*/ |
|||
public String getDownloadPath() { |
|||
return getProfile() + "/download/"; |
|||
} |
|||
|
|||
/** |
|||
* 获取上传路径 |
|||
*/ |
|||
public static String getUploadPath() { |
|||
return getProfile() + "/upload"; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,51 @@ |
|||
package com.inscloudtech.common.constant; |
|||
|
|||
/** |
|||
* 缓存的key 常量 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface CacheConstants { |
|||
|
|||
/** |
|||
* 在线用户 redis key |
|||
*/ |
|||
String ONLINE_TOKEN_KEY = "online_tokens:"; |
|||
|
|||
/** |
|||
* 验证码 redis key |
|||
*/ |
|||
String CAPTCHA_CODE_KEY = "captcha_codes:"; |
|||
|
|||
/** |
|||
* 参数管理 cache key |
|||
*/ |
|||
String SYS_CONFIG_KEY = "sys_config:"; |
|||
|
|||
/** |
|||
* 字典管理 cache key |
|||
*/ |
|||
String SYS_DICT_KEY = "sys_dict:"; |
|||
|
|||
/** |
|||
* 防重提交 redis key |
|||
*/ |
|||
String REPEAT_SUBMIT_KEY = "repeat_submit:"; |
|||
|
|||
/** |
|||
* 限流 redis key |
|||
*/ |
|||
String RATE_LIMIT_KEY = "rate_limit:"; |
|||
|
|||
/** |
|||
* 登录账户密码错误次数 redis key |
|||
*/ |
|||
String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; |
|||
|
|||
/** |
|||
* 限流 |
|||
*/ |
|||
String RATE_LIMITER_TIME = "rateLimiterConfig:"; |
|||
|
|||
String RATE_LIMITER_COUNT = "rateLimiterCount:"; |
|||
} |
@ -0,0 +1,58 @@ |
|||
package com.inscloudtech.common.constant; |
|||
|
|||
/** |
|||
* 缓存组名称常量 |
|||
* <p> |
|||
* key 格式为 cacheNames#ttl#maxIdleTime#maxSize |
|||
* <p> |
|||
* ttl 过期时间 如果设置为0则不过期 默认为0 |
|||
* maxIdleTime 最大空闲时间 根据LRU算法清理空闲数据 如果设置为0则不检测 默认为0 |
|||
* maxSize 组最大长度 根据LRU算法清理溢出数据 如果设置为0则无限长 默认为0 |
|||
* <p> |
|||
* 例子: test#60s、test#0#60s、test#0#1m#1000、test#1h#0#500 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface CacheNames { |
|||
|
|||
/** |
|||
* 演示案例 |
|||
*/ |
|||
String DEMO_CACHE = "demo:cache#60s#10m#20"; |
|||
|
|||
/** |
|||
* 系统配置 |
|||
*/ |
|||
String SYS_CONFIG = "sys_config"; |
|||
|
|||
/** |
|||
* 数据字典 |
|||
*/ |
|||
String SYS_DICT = "sys_dict"; |
|||
|
|||
/** |
|||
* 用户账户 |
|||
*/ |
|||
String SYS_USER_NAME = "sys_user_name#30d"; |
|||
|
|||
/** |
|||
* 部门 |
|||
*/ |
|||
String SYS_DEPT = "sys_dept#30d"; |
|||
|
|||
/** |
|||
* OSS内容 |
|||
*/ |
|||
String SYS_OSS = "sys_oss#30d"; |
|||
|
|||
/** |
|||
* OSS配置 |
|||
*/ |
|||
String SYS_OSS_CONFIG = "sys_oss_config"; |
|||
|
|||
/** |
|||
* 在线用户 |
|||
*/ |
|||
String ONLINE_TOKEN = "online_tokens"; |
|||
|
|||
} |
@ -0,0 +1,85 @@ |
|||
package com.inscloudtech.common.constant; |
|||
|
|||
/** |
|||
* 通用常量信息 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface Constants { |
|||
|
|||
/** |
|||
* UTF-8 字符集 |
|||
*/ |
|||
String UTF8 = "UTF-8"; |
|||
|
|||
/** |
|||
* GBK 字符集 |
|||
*/ |
|||
String GBK = "GBK"; |
|||
|
|||
/** |
|||
* www主域 |
|||
*/ |
|||
String WWW = "www."; |
|||
|
|||
/** |
|||
* http请求 |
|||
*/ |
|||
String HTTP = "http://"; |
|||
|
|||
/** |
|||
* https请求 |
|||
*/ |
|||
String HTTPS = "https://"; |
|||
|
|||
/** |
|||
* 通用成功标识 |
|||
*/ |
|||
String SUCCESS = "0"; |
|||
|
|||
/** |
|||
* 通用失败标识 |
|||
*/ |
|||
String FAIL = "1"; |
|||
|
|||
/** |
|||
* 登录成功 |
|||
*/ |
|||
String LOGIN_SUCCESS = "Success"; |
|||
|
|||
/** |
|||
* 注销 |
|||
*/ |
|||
String LOGOUT = "Logout"; |
|||
|
|||
/** |
|||
* 注册 |
|||
*/ |
|||
String REGISTER = "Register"; |
|||
|
|||
/** |
|||
* 登录失败 |
|||
*/ |
|||
String LOGIN_FAIL = "Error"; |
|||
|
|||
/** |
|||
* 验证码有效期(分钟) |
|||
*/ |
|||
Integer CAPTCHA_EXPIRATION = 2; |
|||
|
|||
/** |
|||
* 令牌 |
|||
*/ |
|||
String TOKEN = "token"; |
|||
|
|||
/** |
|||
* 资源映射路径 前缀 |
|||
*/ |
|||
String RESOURCE_PREFIX = "/profile"; |
|||
|
|||
/** |
|||
* ip黑名单 |
|||
*/ |
|||
String BLACK_IP_LIST = "blackIpList"; |
|||
} |
|||
|
@ -0,0 +1,193 @@ |
|||
package com.inscloudtech.common.constant; |
|||
|
|||
/** |
|||
* 代码生成通用常量 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface GenConstants { |
|||
/** |
|||
* 单表(增删改查) |
|||
*/ |
|||
String TPL_CRUD = "crud"; |
|||
|
|||
/** |
|||
* 树表(增删改查) |
|||
*/ |
|||
String TPL_TREE = "tree"; |
|||
|
|||
/** |
|||
* 主子表(增删改查) |
|||
*/ |
|||
String TPL_SUB = "sub"; |
|||
|
|||
/** |
|||
* 树编码字段 |
|||
*/ |
|||
String TREE_CODE = "treeCode"; |
|||
|
|||
/** |
|||
* 树父编码字段 |
|||
*/ |
|||
String TREE_PARENT_CODE = "treeParentCode"; |
|||
|
|||
/** |
|||
* 树名称字段 |
|||
*/ |
|||
String TREE_NAME = "treeName"; |
|||
|
|||
/** |
|||
* 上级菜单ID字段 |
|||
*/ |
|||
String PARENT_MENU_ID = "parentMenuId"; |
|||
|
|||
/** |
|||
* 上级菜单名称字段 |
|||
*/ |
|||
String PARENT_MENU_NAME = "parentMenuName"; |
|||
|
|||
/** |
|||
* 数据库字符串类型 |
|||
*/ |
|||
String[] COLUMNTYPE_STR = {"char", "varchar", "nvarchar", "varchar2"}; |
|||
|
|||
/** |
|||
* 数据库文本类型 |
|||
*/ |
|||
String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext"}; |
|||
|
|||
/** |
|||
* 数据库时间类型 |
|||
*/ |
|||
String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp"}; |
|||
|
|||
/** |
|||
* 数据库数字类型 |
|||
*/ |
|||
String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer", |
|||
"bit", "bigint", "float", "double", "decimal"}; |
|||
|
|||
/** |
|||
* BO对象 不需要添加字段 |
|||
*/ |
|||
String[] COLUMNNAME_NOT_ADD = {"create_by", "create_time", "del_flag", "update_by", |
|||
"update_time", "version"}; |
|||
|
|||
/** |
|||
* BO对象 不需要编辑字段 |
|||
*/ |
|||
String[] COLUMNNAME_NOT_EDIT = {"create_by", "create_time", "del_flag", "update_by", |
|||
"update_time", "version"}; |
|||
|
|||
/** |
|||
* VO对象 不需要返回字段 |
|||
*/ |
|||
String[] COLUMNNAME_NOT_LIST = {"create_by", "create_time", "del_flag", "update_by", |
|||
"update_time", "version"}; |
|||
|
|||
/** |
|||
* BO对象 不需要查询字段 |
|||
*/ |
|||
String[] COLUMNNAME_NOT_QUERY = {"id", "create_by", "create_time", "del_flag", "update_by", |
|||
"update_time", "remark", "version"}; |
|||
|
|||
/** |
|||
* Entity基类字段 |
|||
*/ |
|||
String[] BASE_ENTITY = {"createBy", "createTime", "updateBy", "updateTime"}; |
|||
|
|||
/** |
|||
* Tree基类字段 |
|||
*/ |
|||
String[] TREE_ENTITY = {"parentName", "parentId", "children"}; |
|||
|
|||
/** |
|||
* 文本框 |
|||
*/ |
|||
String HTML_INPUT = "input"; |
|||
|
|||
/** |
|||
* 文本域 |
|||
*/ |
|||
String HTML_TEXTAREA = "textarea"; |
|||
|
|||
/** |
|||
* 下拉框 |
|||
*/ |
|||
String HTML_SELECT = "select"; |
|||
|
|||
/** |
|||
* 单选框 |
|||
*/ |
|||
String HTML_RADIO = "radio"; |
|||
|
|||
/** |
|||
* 复选框 |
|||
*/ |
|||
String HTML_CHECKBOX = "checkbox"; |
|||
|
|||
/** |
|||
* 日期控件 |
|||
*/ |
|||
String HTML_DATETIME = "datetime"; |
|||
|
|||
/** |
|||
* 图片上传控件 |
|||
*/ |
|||
String HTML_IMAGE_UPLOAD = "imageUpload"; |
|||
|
|||
/** |
|||
* 文件上传控件 |
|||
*/ |
|||
String HTML_FILE_UPLOAD = "fileUpload"; |
|||
|
|||
/** |
|||
* 富文本控件 |
|||
*/ |
|||
String HTML_EDITOR = "editor"; |
|||
|
|||
/** |
|||
* 字符串类型 |
|||
*/ |
|||
String TYPE_STRING = "String"; |
|||
|
|||
/** |
|||
* 整型 |
|||
*/ |
|||
String TYPE_INTEGER = "Integer"; |
|||
|
|||
/** |
|||
* 长整型 |
|||
*/ |
|||
String TYPE_LONG = "Long"; |
|||
|
|||
/** |
|||
* 浮点型 |
|||
*/ |
|||
String TYPE_DOUBLE = "Double"; |
|||
|
|||
/** |
|||
* 高精度计算类型 |
|||
*/ |
|||
String TYPE_BIGDECIMAL = "BigDecimal"; |
|||
|
|||
/** |
|||
* 时间类型 |
|||
*/ |
|||
String TYPE_DATE = "Date"; |
|||
|
|||
/** |
|||
* 模糊查询 |
|||
*/ |
|||
String QUERY_LIKE = "LIKE"; |
|||
|
|||
/** |
|||
* 相等查询 |
|||
*/ |
|||
String QUERY_EQ = "EQ"; |
|||
|
|||
/** |
|||
* 需要 |
|||
*/ |
|||
String REQUIRE = "1"; |
|||
} |
@ -0,0 +1,93 @@ |
|||
package com.inscloudtech.common.constant; |
|||
|
|||
/** |
|||
* 返回状态码 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface HttpStatus { |
|||
/** |
|||
* 操作成功 |
|||
*/ |
|||
int SUCCESS = 200; |
|||
|
|||
/** |
|||
* 对象创建成功 |
|||
*/ |
|||
int CREATED = 201; |
|||
|
|||
/** |
|||
* 请求已经被接受 |
|||
*/ |
|||
int ACCEPTED = 202; |
|||
|
|||
/** |
|||
* 操作已经执行成功,但是没有返回数据 |
|||
*/ |
|||
int NO_CONTENT = 204; |
|||
|
|||
/** |
|||
* 资源已被移除 |
|||
*/ |
|||
int MOVED_PERM = 301; |
|||
|
|||
/** |
|||
* 重定向 |
|||
*/ |
|||
int SEE_OTHER = 303; |
|||
|
|||
/** |
|||
* 资源没有被修改 |
|||
*/ |
|||
int NOT_MODIFIED = 304; |
|||
|
|||
/** |
|||
* 参数列表错误(缺少,格式不匹配) |
|||
*/ |
|||
int BAD_REQUEST = 400; |
|||
|
|||
/** |
|||
* 未授权 |
|||
*/ |
|||
int UNAUTHORIZED = 401; |
|||
|
|||
/** |
|||
* 访问受限,授权过期 |
|||
*/ |
|||
int FORBIDDEN = 403; |
|||
|
|||
/** |
|||
* 资源,服务未找到 |
|||
*/ |
|||
int NOT_FOUND = 404; |
|||
|
|||
/** |
|||
* 不允许的http方法 |
|||
*/ |
|||
int BAD_METHOD = 405; |
|||
|
|||
/** |
|||
* 资源冲突,或者资源被锁 |
|||
*/ |
|||
int CONFLICT = 409; |
|||
|
|||
/** |
|||
* 不支持的数据,媒体类型 |
|||
*/ |
|||
int UNSUPPORTED_TYPE = 415; |
|||
|
|||
/** |
|||
* 系统内部错误 |
|||
*/ |
|||
int ERROR = 500; |
|||
|
|||
/** |
|||
* 接口未实现 |
|||
*/ |
|||
int NOT_IMPLEMENTED = 501; |
|||
|
|||
/** |
|||
* 系统警告消息 |
|||
*/ |
|||
int WARN = 601; |
|||
} |
@ -0,0 +1,30 @@ |
|||
package com.inscloudtech.common.constant; |
|||
|
|||
/** |
|||
* 翻译常量 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface TransConstant { |
|||
|
|||
/** |
|||
* 用户id转账号 |
|||
*/ |
|||
String USER_ID_TO_NAME = "user_id_to_name"; |
|||
|
|||
/** |
|||
* 部门id转名称 |
|||
*/ |
|||
String DEPT_ID_TO_NAME = "dept_id_to_name"; |
|||
|
|||
/** |
|||
* 字典type转label |
|||
*/ |
|||
String DICT_TYPE_TO_LABEL = "dict_type_to_label"; |
|||
|
|||
/** |
|||
* ossId转url |
|||
*/ |
|||
String OSS_ID_TO_URL = "oss_id_to_url"; |
|||
|
|||
} |
@ -0,0 +1,147 @@ |
|||
package com.inscloudtech.common.constant; |
|||
|
|||
/** |
|||
* 用户常量信息 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface UserConstants { |
|||
|
|||
/** |
|||
* 平台内系统用户的唯一标志 |
|||
*/ |
|||
String SYS_USER = "SYS_USER"; |
|||
|
|||
/** |
|||
* 正常状态 |
|||
*/ |
|||
String NORMAL = "0"; |
|||
|
|||
/** |
|||
* 异常状态 |
|||
*/ |
|||
String EXCEPTION = "1"; |
|||
|
|||
/** |
|||
* 用户正常状态 |
|||
*/ |
|||
String USER_NORMAL = "0"; |
|||
|
|||
/** |
|||
* 用户封禁状态 |
|||
*/ |
|||
String USER_DISABLE = "1"; |
|||
|
|||
/** |
|||
* 角色正常状态 |
|||
*/ |
|||
String ROLE_NORMAL = "0"; |
|||
|
|||
/** |
|||
* 角色封禁状态 |
|||
*/ |
|||
String ROLE_DISABLE = "1"; |
|||
|
|||
/** |
|||
* 部门正常状态 |
|||
*/ |
|||
String DEPT_NORMAL = "0"; |
|||
|
|||
/** |
|||
* 部门停用状态 |
|||
*/ |
|||
String DEPT_DISABLE = "1"; |
|||
|
|||
/** |
|||
* 岗位正常状态 |
|||
*/ |
|||
String POST_NORMAL = "0"; |
|||
|
|||
/** |
|||
* 岗位停用状态 |
|||
*/ |
|||
String POST_DISABLE = "1"; |
|||
|
|||
/** |
|||
* 字典正常状态 |
|||
*/ |
|||
String DICT_NORMAL = "0"; |
|||
|
|||
/** |
|||
* 是否为系统默认(是) |
|||
*/ |
|||
String YES = "Y"; |
|||
|
|||
/** |
|||
* 是否菜单外链(是) |
|||
*/ |
|||
String YES_FRAME = "0"; |
|||
|
|||
/** |
|||
* 是否菜单外链(否) |
|||
*/ |
|||
String NO_FRAME = "1"; |
|||
|
|||
/** |
|||
* 菜单正常状态 |
|||
*/ |
|||
String MENU_NORMAL = "0"; |
|||
|
|||
/** |
|||
* 菜单停用状态 |
|||
*/ |
|||
String MENU_DISABLE = "1"; |
|||
|
|||
/** |
|||
* 菜单类型(目录) |
|||
*/ |
|||
String TYPE_DIR = "M"; |
|||
|
|||
/** |
|||
* 菜单类型(菜单) |
|||
*/ |
|||
String TYPE_MENU = "C"; |
|||
|
|||
/** |
|||
* 菜单类型(按钮) |
|||
*/ |
|||
String TYPE_BUTTON = "F"; |
|||
|
|||
/** |
|||
* Layout组件标识 |
|||
*/ |
|||
String LAYOUT = "Layout"; |
|||
|
|||
/** |
|||
* ParentView组件标识 |
|||
*/ |
|||
String PARENT_VIEW = "ParentView"; |
|||
|
|||
/** |
|||
* InnerLink组件标识 |
|||
*/ |
|||
String INNER_LINK = "InnerLink"; |
|||
|
|||
/** |
|||
* 用户名长度限制 |
|||
*/ |
|||
int USERNAME_MIN_LENGTH = 2; |
|||
int USERNAME_MAX_LENGTH = 20; |
|||
|
|||
/** |
|||
* 密码长度限制 |
|||
*/ |
|||
int PASSWORD_MIN_LENGTH = 5; |
|||
int PASSWORD_MAX_LENGTH = 20; |
|||
|
|||
/** |
|||
* 管理员ID |
|||
*/ |
|||
Long ADMIN_ID = 1L; |
|||
|
|||
/** |
|||
* 管理员角色key |
|||
*/ |
|||
String ADMIN_ROLE_KEY = "admin"; |
|||
|
|||
} |
@ -0,0 +1,52 @@ |
|||
package com.inscloudtech.common.convert; |
|||
|
|||
import cn.hutool.core.convert.Convert; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.alibaba.excel.converters.Converter; |
|||
import com.alibaba.excel.enums.CellDataTypeEnum; |
|||
import com.alibaba.excel.metadata.GlobalConfiguration; |
|||
import com.alibaba.excel.metadata.data.ReadCellData; |
|||
import com.alibaba.excel.metadata.data.WriteCellData; |
|||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import java.math.BigDecimal; |
|||
|
|||
/** |
|||
* 大数值转换 |
|||
* Excel 数值长度位15位 大于15位的数值转换位字符串 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Slf4j |
|||
public class ExcelBigNumberConvert implements Converter<Long> { |
|||
|
|||
@Override |
|||
public Class<Long> supportJavaTypeKey() { |
|||
return Long.class; |
|||
} |
|||
|
|||
@Override |
|||
public CellDataTypeEnum supportExcelTypeKey() { |
|||
return CellDataTypeEnum.STRING; |
|||
} |
|||
|
|||
@Override |
|||
public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
|||
return Convert.toLong(cellData.getData()); |
|||
} |
|||
|
|||
@Override |
|||
public WriteCellData<Object> convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
|||
if (ObjectUtil.isNotNull(object)) { |
|||
String str = Convert.toStr(object); |
|||
if (str.length() > 15) { |
|||
return new WriteCellData<>(str); |
|||
} |
|||
} |
|||
WriteCellData<Object> cellData = new WriteCellData<>(new BigDecimal(object)); |
|||
cellData.setType(CellDataTypeEnum.NUMBER); |
|||
return cellData; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,73 @@ |
|||
package com.inscloudtech.common.convert; |
|||
|
|||
import cn.hutool.core.annotation.AnnotationUtil; |
|||
import cn.hutool.core.convert.Convert; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.alibaba.excel.converters.Converter; |
|||
import com.alibaba.excel.enums.CellDataTypeEnum; |
|||
import com.alibaba.excel.metadata.GlobalConfiguration; |
|||
import com.alibaba.excel.metadata.data.ReadCellData; |
|||
import com.alibaba.excel.metadata.data.WriteCellData; |
|||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
|||
import com.inscloudtech.common.annotation.ExcelDictFormat; |
|||
import com.inscloudtech.common.core.service.DictService; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.common.utils.poi.ExcelUtil; |
|||
import com.inscloudtech.common.utils.spring.SpringUtils; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import java.lang.reflect.Field; |
|||
|
|||
/** |
|||
* 字典格式化转换处理 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Slf4j |
|||
public class ExcelDictConvert implements Converter<Object> { |
|||
|
|||
@Override |
|||
public Class<Object> supportJavaTypeKey() { |
|||
return Object.class; |
|||
} |
|||
|
|||
@Override |
|||
public CellDataTypeEnum supportExcelTypeKey() { |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
|||
ExcelDictFormat anno = getAnnotation(contentProperty.getField()); |
|||
String type = anno.dictType(); |
|||
String label = cellData.getStringValue(); |
|||
String value; |
|||
if (StringUtils.isBlank(type)) { |
|||
value = ExcelUtil.reverseByExp(label, anno.readConverterExp(), anno.separator()); |
|||
} else { |
|||
value = SpringUtils.getBean(DictService.class).getDictValue(type, label, anno.separator()); |
|||
} |
|||
return Convert.convert(contentProperty.getField().getType(), value); |
|||
} |
|||
|
|||
@Override |
|||
public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
|||
if (ObjectUtil.isNull(object)) { |
|||
return new WriteCellData<>(""); |
|||
} |
|||
ExcelDictFormat anno = getAnnotation(contentProperty.getField()); |
|||
String type = anno.dictType(); |
|||
String value = Convert.toStr(object); |
|||
String label; |
|||
if (StringUtils.isBlank(type)) { |
|||
label = ExcelUtil.convertByExp(value, anno.readConverterExp(), anno.separator()); |
|||
} else { |
|||
label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator()); |
|||
} |
|||
return new WriteCellData<>(label); |
|||
} |
|||
|
|||
private ExcelDictFormat getAnnotation(Field field) { |
|||
return AnnotationUtil.getAnnotation(field, ExcelDictFormat.class); |
|||
} |
|||
} |
@ -0,0 +1,97 @@ |
|||
package com.inscloudtech.common.convert; |
|||
|
|||
import cn.hutool.core.annotation.AnnotationUtil; |
|||
import cn.hutool.core.convert.Convert; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.alibaba.excel.converters.Converter; |
|||
import com.alibaba.excel.enums.CellDataTypeEnum; |
|||
import com.alibaba.excel.metadata.GlobalConfiguration; |
|||
import com.alibaba.excel.metadata.data.ReadCellData; |
|||
import com.alibaba.excel.metadata.data.WriteCellData; |
|||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
|||
import com.inscloudtech.common.annotation.ExcelEnumFormat; |
|||
import com.inscloudtech.common.utils.reflect.ReflectUtils; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import java.lang.reflect.Field; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 枚举格式化转换处理 |
|||
* |
|||
* @author Liang |
|||
*/ |
|||
@Slf4j |
|||
public class ExcelEnumConvert implements Converter<Object> { |
|||
|
|||
@Override |
|||
public Class<Object> supportJavaTypeKey() { |
|||
return Object.class; |
|||
} |
|||
|
|||
@Override |
|||
public CellDataTypeEnum supportExcelTypeKey() { |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
|||
cellData.checkEmpty(); |
|||
// Excel中填入的是枚举中指定的描述 |
|||
Object textValue = null; |
|||
switch (cellData.getType()) { |
|||
case STRING: |
|||
case DIRECT_STRING: |
|||
case RICH_TEXT_STRING: |
|||
textValue = cellData.getStringValue(); |
|||
break; |
|||
case NUMBER: |
|||
textValue = cellData.getNumberValue(); |
|||
break; |
|||
case BOOLEAN: |
|||
textValue = cellData.getBooleanValue(); |
|||
break; |
|||
default: |
|||
throw new IllegalArgumentException("单元格类型异常!"); |
|||
} |
|||
// 如果是空值 |
|||
if (ObjectUtil.isNull(textValue)) { |
|||
return null; |
|||
} |
|||
Map<Object, String> enumCodeToTextMap = beforeConvert(contentProperty); |
|||
// 从Java输出至Excel是code转text |
|||
// 因此从Excel转Java应该将text与code对调 |
|||
Map<Object, Object> enumTextToCodeMap = new HashMap<>(); |
|||
enumCodeToTextMap.forEach((key, value) -> enumTextToCodeMap.put(value, key)); |
|||
// 应该从text -> code中查找 |
|||
Object codeValue = enumTextToCodeMap.get(textValue); |
|||
return Convert.convert(contentProperty.getField().getType(), codeValue); |
|||
} |
|||
|
|||
@Override |
|||
public WriteCellData<String> convertToExcelData(Object object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
|||
if (ObjectUtil.isNull(object)) { |
|||
return new WriteCellData<>(""); |
|||
} |
|||
Map<Object, String> enumValueMap = beforeConvert(contentProperty); |
|||
String value = Convert.toStr(enumValueMap.get(object), ""); |
|||
return new WriteCellData<>(value); |
|||
} |
|||
|
|||
private Map<Object, String> beforeConvert(ExcelContentProperty contentProperty) { |
|||
ExcelEnumFormat anno = getAnnotation(contentProperty.getField()); |
|||
Map<Object, String> enumValueMap = new HashMap<>(); |
|||
Enum<?>[] enumConstants = anno.enumClass().getEnumConstants(); |
|||
for (Enum<?> enumConstant : enumConstants) { |
|||
Object codeValue = ReflectUtils.invokeGetter(enumConstant, anno.codeField()); |
|||
String textValue = ReflectUtils.invokeGetter(enumConstant, anno.textField()); |
|||
enumValueMap.put(codeValue, textValue); |
|||
} |
|||
return enumValueMap; |
|||
} |
|||
|
|||
private ExcelEnumFormat getAnnotation(Field field) { |
|||
return AnnotationUtil.getAnnotation(field, ExcelEnumFormat.class); |
|||
} |
|||
} |
@ -0,0 +1,77 @@ |
|||
package com.inscloudtech.common.core.controller; |
|||
|
|||
import com.inscloudtech.common.core.domain.R; |
|||
import com.inscloudtech.common.core.domain.model.LoginUser; |
|||
import com.inscloudtech.common.helper.LoginHelper; |
|||
import com.inscloudtech.common.utils.DownLoadUtils; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
|
|||
/** |
|||
* web层通用数据处理 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public class BaseController { |
|||
|
|||
/** |
|||
* 响应返回结果 |
|||
* |
|||
* @param rows 影响行数 |
|||
* @return 操作结果 |
|||
*/ |
|||
protected R<Void> toAjax(int rows) { |
|||
return rows > 0 ? R.ok() : R.fail(); |
|||
} |
|||
|
|||
/** |
|||
* 响应返回结果 |
|||
* |
|||
* @param result 结果 |
|||
* @return 操作结果 |
|||
*/ |
|||
protected R<Void> toAjax(boolean result) { |
|||
return result ? R.ok() : R.fail(); |
|||
} |
|||
|
|||
/** |
|||
* 页面跳转 |
|||
*/ |
|||
public String redirect(String url) { |
|||
return StringUtils.format("redirect:{}", url); |
|||
} |
|||
|
|||
/** |
|||
* 获取用户缓存信息 |
|||
*/ |
|||
public LoginUser getLoginUser() { |
|||
return LoginHelper.getLoginUser(); |
|||
} |
|||
|
|||
/** |
|||
* 获取登录用户id |
|||
*/ |
|||
public Long getUserId() { |
|||
return LoginHelper.getUserId(); |
|||
} |
|||
|
|||
/** |
|||
* 获取登录部门id |
|||
*/ |
|||
public Long getDeptId() { |
|||
return LoginHelper.getDeptId(); |
|||
} |
|||
|
|||
/** |
|||
* 获取登录用户名 |
|||
*/ |
|||
public String getUsername() { |
|||
return LoginHelper.getUsername(); |
|||
} |
|||
|
|||
public void doDownLoad(String filepath,HttpServletResponse response){ |
|||
DownLoadUtils.doDownLoad(filepath,response); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,63 @@ |
|||
package com.inscloudtech.common.core.domain; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.FieldFill; |
|||
import com.baomidou.mybatisplus.annotation.TableField; |
|||
import com.fasterxml.jackson.annotation.JsonIgnore; |
|||
import com.fasterxml.jackson.annotation.JsonInclude; |
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Date; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* Entity基类 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class BaseEntity implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 搜索值 |
|||
*/ |
|||
@JsonIgnore |
|||
@TableField(exist = false) |
|||
private String searchValue; |
|||
|
|||
/** |
|||
* 创建者 |
|||
*/ |
|||
@TableField(fill = FieldFill.INSERT) |
|||
private String createBy; |
|||
|
|||
/** |
|||
* 创建时间 |
|||
*/ |
|||
@TableField(fill = FieldFill.INSERT) |
|||
private Date createTime; |
|||
|
|||
/** |
|||
* 更新者 |
|||
*/ |
|||
@TableField(fill = FieldFill.INSERT_UPDATE) |
|||
private String updateBy; |
|||
|
|||
/** |
|||
* 更新时间 |
|||
*/ |
|||
@TableField(fill = FieldFill.INSERT_UPDATE) |
|||
private Date updateTime; |
|||
|
|||
/** |
|||
* 请求参数 |
|||
*/ |
|||
@JsonInclude(JsonInclude.Include.NON_EMPTY) |
|||
@TableField(exist = false) |
|||
private Map<String, Object> params = new HashMap<>(); |
|||
|
|||
} |
@ -0,0 +1,112 @@ |
|||
package com.inscloudtech.common.core.domain; |
|||
|
|||
import cn.hutool.core.collection.CollUtil; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.baomidou.mybatisplus.core.metadata.OrderItem; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.inscloudtech.common.exception.ServiceException; |
|||
import com.inscloudtech.common.utils.StringUtils; |
|||
import com.inscloudtech.common.utils.sql.SqlUtil; |
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 分页查询实体类 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class PageQuery implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 分页大小 |
|||
*/ |
|||
private Integer pageSize; |
|||
|
|||
/** |
|||
* 当前页数 |
|||
*/ |
|||
private Integer pageNum; |
|||
|
|||
/** |
|||
* 排序列 |
|||
*/ |
|||
private String orderByColumn; |
|||
|
|||
/** |
|||
* 排序的方向desc或者asc |
|||
*/ |
|||
private String isAsc; |
|||
|
|||
/** |
|||
* 当前记录起始索引 默认值 |
|||
*/ |
|||
public static final int DEFAULT_PAGE_NUM = 1; |
|||
|
|||
/** |
|||
* 每页显示记录数 默认值 默认查全部 |
|||
*/ |
|||
public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE; |
|||
|
|||
public <T> Page<T> build() { |
|||
Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM); |
|||
Integer pageSize = ObjectUtil.defaultIfNull(getPageSize(), DEFAULT_PAGE_SIZE); |
|||
if (pageNum <= 0) { |
|||
pageNum = DEFAULT_PAGE_NUM; |
|||
} |
|||
Page<T> page = new Page<>(pageNum, pageSize); |
|||
List<OrderItem> orderItems = buildOrderItem(); |
|||
if (CollUtil.isNotEmpty(orderItems)) { |
|||
page.addOrder(orderItems); |
|||
} |
|||
return page; |
|||
} |
|||
|
|||
/** |
|||
* 构建排序 |
|||
* |
|||
* 支持的用法如下: |
|||
* {isAsc:"asc",orderByColumn:"id"} order by id asc |
|||
* {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc |
|||
* {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc |
|||
* {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc |
|||
*/ |
|||
private List<OrderItem> buildOrderItem() { |
|||
if (StringUtils.isBlank(orderByColumn) || StringUtils.isBlank(isAsc)) { |
|||
return null; |
|||
} |
|||
String orderBy = SqlUtil.escapeOrderBySql(orderByColumn); |
|||
orderBy = StringUtils.toUnderScoreCase(orderBy); |
|||
|
|||
// 兼容前端排序类型 |
|||
isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"}); |
|||
|
|||
String[] orderByArr = orderBy.split(StringUtils.SEPARATOR); |
|||
String[] isAscArr = isAsc.split(StringUtils.SEPARATOR); |
|||
if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) { |
|||
throw new ServiceException("排序参数有误"); |
|||
} |
|||
|
|||
List<OrderItem> list = new ArrayList<>(); |
|||
// 每个字段各自排序 |
|||
for (int i = 0; i < orderByArr.length; i++) { |
|||
String orderByStr = orderByArr[i]; |
|||
String isAscStr = isAscArr.length == 1 ? isAscArr[0] : isAscArr[i]; |
|||
if ("asc".equals(isAscStr)) { |
|||
list.add(OrderItem.asc(orderByStr)); |
|||
} else if ("desc".equals(isAscStr)) { |
|||
list.add(OrderItem.desc(orderByStr)); |
|||
} else { |
|||
throw new ServiceException("排序参数有误"); |
|||
} |
|||
} |
|||
return list; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,107 @@ |
|||
package com.inscloudtech.common.core.domain; |
|||
|
|||
import com.inscloudtech.common.constant.HttpStatus; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 响应信息主体 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Data |
|||
@NoArgsConstructor |
|||
public class R<T> implements Serializable { |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 成功 |
|||
*/ |
|||
public static final int SUCCESS = 200; |
|||
|
|||
/** |
|||
* 失败 |
|||
*/ |
|||
public static final int FAIL = 500; |
|||
|
|||
private int code; |
|||
|
|||
private String msg; |
|||
|
|||
private T data; |
|||
|
|||
public static <T> R<T> ok() { |
|||
return restResult(null, SUCCESS, "操作成功"); |
|||
} |
|||
|
|||
public static <T> R<T> ok(T data) { |
|||
return restResult(data, SUCCESS, "操作成功"); |
|||
} |
|||
|
|||
public static <T> R<T> ok(String msg) { |
|||
return restResult(null, SUCCESS, msg); |
|||
} |
|||
|
|||
public static <T> R<T> ok(String msg, T data) { |
|||
return restResult(data, SUCCESS, msg); |
|||
} |
|||
|
|||
public static <T> R<T> fail() { |
|||
return restResult(null, FAIL, "操作失败"); |
|||
} |
|||
|
|||
public static <T> R<T> fail(String msg) { |
|||
return restResult(null, FAIL, msg); |
|||
} |
|||
|
|||
public static <T> R<T> fail(T data) { |
|||
return restResult(data, FAIL, "操作失败"); |
|||
} |
|||
|
|||
public static <T> R<T> fail(String msg, T data) { |
|||
return restResult(data, FAIL, msg); |
|||
} |
|||
|
|||
public static <T> R<T> fail(int code, String msg) { |
|||
return restResult(null, code, msg); |
|||
} |
|||
|
|||
/** |
|||
* 返回警告消息 |
|||
* |
|||
* @param msg 返回内容 |
|||
* @return 警告消息 |
|||
*/ |
|||
public static <T> R<T> warn(String msg) { |
|||
return restResult(null, HttpStatus.WARN, msg); |
|||
} |
|||
|
|||
/** |
|||
* 返回警告消息 |
|||
* |
|||
* @param msg 返回内容 |
|||
* @param data 数据对象 |
|||
* @return 警告消息 |
|||
*/ |
|||
public static <T> R<T> warn(String msg, T data) { |
|||
return restResult(data, HttpStatus.WARN, msg); |
|||
} |
|||
|
|||
private static <T> R<T> restResult(T data, int code, String msg) { |
|||
R<T> r = new R<>(); |
|||
r.setCode(code); |
|||
r.setData(data); |
|||
r.setMsg(msg); |
|||
return r; |
|||
} |
|||
|
|||
public static <T> Boolean isError(R<T> ret) { |
|||
return !isSuccess(ret); |
|||
} |
|||
|
|||
public static <T> Boolean isSuccess(R<T> ret) { |
|||
return R.SUCCESS == ret.getCode(); |
|||
} |
|||
} |
@ -0,0 +1,39 @@ |
|||
package com.inscloudtech.common.core.domain; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.TableField; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* Tree基类 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
public class TreeEntity<T> extends BaseEntity { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 父菜单名称 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private String parentName; |
|||
|
|||
/** |
|||
* 父菜单ID |
|||
*/ |
|||
private Long parentId; |
|||
|
|||
/** |
|||
* 子部门 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private List<T> children = new ArrayList<>(); |
|||
|
|||
} |
@ -0,0 +1,38 @@ |
|||
package com.inscloudtech.common.core.domain.dto; |
|||
|
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 角色 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@NoArgsConstructor |
|||
public class RoleDTO implements Serializable { |
|||
|
|||
/** |
|||
* 角色ID |
|||
*/ |
|||
private Long roleId; |
|||
|
|||
/** |
|||
* 角色名称 |
|||
*/ |
|||
private String roleName; |
|||
|
|||
/** |
|||
* 角色权限 |
|||
*/ |
|||
private String roleKey; |
|||
|
|||
/** |
|||
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) |
|||
*/ |
|||
private String dataScope; |
|||
|
|||
} |
@ -0,0 +1,29 @@ |
|||
package com.inscloudtech.common.core.domain.dto; |
|||
|
|||
import lombok.Data; |
|||
|
|||
|
|||
import javax.validation.constraints.NotBlank; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 用户密码修改bo |
|||
*/ |
|||
@Data |
|||
public class SysUserPasswordBo implements Serializable { |
|||
|
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 旧密码 |
|||
*/ |
|||
@NotBlank(message = "旧密码不能为空") |
|||
private String oldPassword; |
|||
|
|||
/** |
|||
* 新密码 |
|||
*/ |
|||
@NotBlank(message = "新密码不能为空") |
|||
private String newPassword; |
|||
} |
@ -0,0 +1,60 @@ |
|||
package com.inscloudtech.common.core.domain.dto; |
|||
|
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 当前在线会话 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@NoArgsConstructor |
|||
public class UserOnlineDTO implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 会话编号 |
|||
*/ |
|||
private String tokenId; |
|||
|
|||
/** |
|||
* 部门名称 |
|||
*/ |
|||
private String deptName; |
|||
|
|||
/** |
|||
* 用户名称 |
|||
*/ |
|||
private String userName; |
|||
|
|||
/** |
|||
* 登录IP地址 |
|||
*/ |
|||
private String ipaddr; |
|||
|
|||
/** |
|||
* 登录地址 |
|||
*/ |
|||
private String loginLocation; |
|||
|
|||
/** |
|||
* 浏览器类型 |
|||
*/ |
|||
private String browser; |
|||
|
|||
/** |
|||
* 操作系统 |
|||
*/ |
|||
private String os; |
|||
|
|||
/** |
|||
* 登录时间 |
|||
*/ |
|||
private Long loginTime; |
|||
|
|||
} |
@ -0,0 +1,80 @@ |
|||
package com.inscloudtech.common.core.domain.entity; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.TableId; |
|||
import com.baomidou.mybatisplus.annotation.TableLogic; |
|||
import com.baomidou.mybatisplus.annotation.TableName; |
|||
import com.inscloudtech.common.core.domain.TreeEntity; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
import javax.validation.constraints.Email; |
|||
import javax.validation.constraints.NotBlank; |
|||
import javax.validation.constraints.NotNull; |
|||
import javax.validation.constraints.Size; |
|||
|
|||
/** |
|||
* 部门表 sys_dept |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@TableName("sys_dept") |
|||
public class SysDept extends TreeEntity<SysDept> { |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 部门ID |
|||
*/ |
|||
@TableId(value = "dept_id") |
|||
private Long deptId; |
|||
|
|||
/** |
|||
* 部门名称 |
|||
*/ |
|||
@NotBlank(message = "部门名称不能为空") |
|||
@Size(min = 0, max = 30, message = "部门名称长度不能超过{max}个字符") |
|||
private String deptName; |
|||
|
|||
/** |
|||
* 显示顺序 |
|||
*/ |
|||
@NotNull(message = "显示顺序不能为空") |
|||
private Integer orderNum; |
|||
|
|||
/** |
|||
* 负责人 |
|||
*/ |
|||
private String leader; |
|||
|
|||
/** |
|||
* 联系电话 |
|||
*/ |
|||
@Size(min = 0, max = 11, message = "联系电话长度不能超过{max}个字符") |
|||
private String phone; |
|||
|
|||
/** |
|||
* 邮箱 |
|||
*/ |
|||
@Email(message = "邮箱格式不正确") |
|||
@Size(min = 0, max = 50, message = "邮箱长度不能超过{max}个字符") |
|||
private String email; |
|||
|
|||
/** |
|||
* 部门状态:0正常,1停用 |
|||
*/ |
|||
private String status; |
|||
|
|||
/** |
|||
* 删除标志(0代表存在 2代表删除) |
|||
*/ |
|||
@TableLogic |
|||
private String delFlag; |
|||
|
|||
/** |
|||
* 祖级列表 |
|||
*/ |
|||
private String ancestors; |
|||
|
|||
} |
@ -0,0 +1,100 @@ |
|||
package com.inscloudtech.common.core.domain.entity; |
|||
|
|||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
|||
import com.alibaba.excel.annotation.ExcelProperty; |
|||
import com.baomidou.mybatisplus.annotation.TableId; |
|||
import com.baomidou.mybatisplus.annotation.TableName; |
|||
import com.inscloudtech.common.annotation.ExcelDictFormat; |
|||
import com.inscloudtech.common.constant.UserConstants; |
|||
import com.inscloudtech.common.convert.ExcelDictConvert; |
|||
import com.inscloudtech.common.core.domain.BaseEntity; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
import javax.validation.constraints.NotBlank; |
|||
import javax.validation.constraints.Size; |
|||
|
|||
/** |
|||
* 字典数据表 sys_dict_data |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@TableName("sys_dict_data") |
|||
@ExcelIgnoreUnannotated |
|||
public class SysDictData extends BaseEntity { |
|||
|
|||
/** |
|||
* 字典编码 |
|||
*/ |
|||
@ExcelProperty(value = "字典编码") |
|||
@TableId(value = "dict_code") |
|||
private Long dictCode; |
|||
|
|||
/** |
|||
* 字典排序 |
|||
*/ |
|||
@ExcelProperty(value = "字典排序") |
|||
private Integer dictSort; |
|||
|
|||
/** |
|||
* 字典标签 |
|||
*/ |
|||
@ExcelProperty(value = "字典标签") |
|||
@NotBlank(message = "字典标签不能为空") |
|||
@Size(min = 0, max = 100, message = "字典标签长度不能超过{max}个字符") |
|||
private String dictLabel; |
|||
|
|||
/** |
|||
* 字典键值 |
|||
*/ |
|||
@ExcelProperty(value = "字典键值") |
|||
@NotBlank(message = "字典键值不能为空") |
|||
@Size(min = 0, max = 100, message = "字典键值长度不能超过{max}个字符") |
|||
private String dictValue; |
|||
|
|||
/** |
|||
* 字典类型 |
|||
*/ |
|||
@ExcelProperty(value = "字典类型") |
|||
@NotBlank(message = "字典类型不能为空") |
|||
@Size(min = 0, max = 100, message = "字典类型长度不能超过{max}个字符") |
|||
private String dictType; |
|||
|
|||
/** |
|||
* 样式属性(其他样式扩展) |
|||
*/ |
|||
@Size(min = 0, max = 100, message = "样式属性长度不能超过{max}个字符") |
|||
private String cssClass; |
|||
|
|||
/** |
|||
* 表格字典样式 |
|||
*/ |
|||
private String listClass; |
|||
|
|||
/** |
|||
* 是否默认(Y是 N否) |
|||
*/ |
|||
@ExcelProperty(value = "是否默认", converter = ExcelDictConvert.class) |
|||
@ExcelDictFormat(dictType = "sys_yes_no") |
|||
private String isDefault; |
|||
|
|||
/** |
|||
* 状态(0正常 1停用) |
|||
*/ |
|||
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class) |
|||
@ExcelDictFormat(dictType = "sys_normal_disable") |
|||
private String status; |
|||
|
|||
/** |
|||
* 备注 |
|||
*/ |
|||
private String remark; |
|||
|
|||
public boolean getDefault() { |
|||
return UserConstants.YES.equals(this.isDefault); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,65 @@ |
|||
package com.inscloudtech.common.core.domain.entity; |
|||
|
|||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
|||
import com.alibaba.excel.annotation.ExcelProperty; |
|||
import com.baomidou.mybatisplus.annotation.TableId; |
|||
import com.baomidou.mybatisplus.annotation.TableName; |
|||
import com.inscloudtech.common.annotation.ExcelDictFormat; |
|||
import com.inscloudtech.common.convert.ExcelDictConvert; |
|||
import com.inscloudtech.common.core.domain.BaseEntity; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
import javax.validation.constraints.NotBlank; |
|||
import javax.validation.constraints.Pattern; |
|||
import javax.validation.constraints.Size; |
|||
|
|||
/** |
|||
* 字典类型表 sys_dict_type |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@TableName("sys_dict_type") |
|||
@ExcelIgnoreUnannotated |
|||
public class SysDictType extends BaseEntity { |
|||
|
|||
/** |
|||
* 字典主键 |
|||
*/ |
|||
@ExcelProperty(value = "字典主键") |
|||
@TableId(value = "dict_id") |
|||
private Long dictId; |
|||
|
|||
/** |
|||
* 字典名称 |
|||
*/ |
|||
@ExcelProperty(value = "字典名称") |
|||
@NotBlank(message = "字典名称不能为空") |
|||
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过{max}个字符") |
|||
private String dictName; |
|||
|
|||
/** |
|||
* 字典类型 |
|||
*/ |
|||
@ExcelProperty(value = "字典类型") |
|||
@NotBlank(message = "字典类型不能为空") |
|||
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过{max}个字符") |
|||
@Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") |
|||
private String dictType; |
|||
|
|||
/** |
|||
* 状态(0正常 1停用) |
|||
*/ |
|||
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class) |
|||
@ExcelDictFormat(dictType = "sys_normal_disable") |
|||
private String status; |
|||
|
|||
/** |
|||
* 备注 |
|||
*/ |
|||
private String remark; |
|||
|
|||
} |
@ -0,0 +1,104 @@ |
|||
package com.inscloudtech.common.core.domain.entity; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.TableId; |
|||
import com.baomidou.mybatisplus.annotation.TableName; |
|||
import com.fasterxml.jackson.annotation.JsonInclude; |
|||
import com.inscloudtech.common.core.domain.TreeEntity; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
import javax.validation.constraints.NotBlank; |
|||
import javax.validation.constraints.NotNull; |
|||
import javax.validation.constraints.Size; |
|||
|
|||
/** |
|||
* 菜单权限表 sys_menu |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@TableName("sys_menu") |
|||
public class SysMenu extends TreeEntity<SysMenu> { |
|||
|
|||
/** |
|||
* 菜单ID |
|||
*/ |
|||
@TableId(value = "menu_id") |
|||
private Long menuId; |
|||
|
|||
/** |
|||
* 菜单名称 |
|||
*/ |
|||
@NotBlank(message = "菜单名称不能为空") |
|||
@Size(min = 0, max = 50, message = "菜单名称长度不能超过{max}个字符") |
|||
private String menuName; |
|||
|
|||
/** |
|||
* 显示顺序 |
|||
*/ |
|||
@NotNull(message = "显示顺序不能为空") |
|||
private Integer orderNum; |
|||
|
|||
/** |
|||
* 路由地址 |
|||
*/ |
|||
@Size(min = 0, max = 200, message = "路由地址不能超过{max}个字符") |
|||
private String path; |
|||
|
|||
/** |
|||
* 组件路径 |
|||
*/ |
|||
@Size(min = 0, max = 200, message = "组件路径不能超过{max}个字符") |
|||
private String component; |
|||
|
|||
/** |
|||
* 路由参数 |
|||
*/ |
|||
private String queryParam; |
|||
|
|||
/** |
|||
* 是否为外链(0是 1否) |
|||
*/ |
|||
private String isFrame; |
|||
|
|||
/** |
|||
* 是否缓存(0缓存 1不缓存) |
|||
*/ |
|||
private String isCache; |
|||
|
|||
/** |
|||
* 类型(M目录 C菜单 F按钮) |
|||
*/ |
|||
@NotBlank(message = "菜单类型不能为空") |
|||
private String menuType; |
|||
|
|||
/** |
|||
* 显示状态(0显示 1隐藏) |
|||
*/ |
|||
private String visible; |
|||
|
|||
/** |
|||
* 菜单状态(0正常 1停用) |
|||
*/ |
|||
private String status; |
|||
|
|||
/** |
|||
* 权限字符串 |
|||
*/ |
|||
@JsonInclude(JsonInclude.Include.NON_NULL) |
|||
@Size(min = 0, max = 100, message = "权限标识长度不能超过{max}个字符") |
|||
private String perms; |
|||
|
|||
/** |
|||
* 菜单图标 |
|||
*/ |
|||
private String icon; |
|||
|
|||
/** |
|||
* 备注 |
|||
*/ |
|||
private String remark; |
|||
|
|||
} |
@ -0,0 +1,124 @@ |
|||
package com.inscloudtech.common.core.domain.entity; |
|||
|
|||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
|||
import com.alibaba.excel.annotation.ExcelProperty; |
|||
import com.baomidou.mybatisplus.annotation.TableField; |
|||
import com.baomidou.mybatisplus.annotation.TableId; |
|||
import com.baomidou.mybatisplus.annotation.TableLogic; |
|||
import com.baomidou.mybatisplus.annotation.TableName; |
|||
import com.inscloudtech.common.annotation.ExcelDictFormat; |
|||
import com.inscloudtech.common.constant.UserConstants; |
|||
import com.inscloudtech.common.convert.ExcelDictConvert; |
|||
import com.inscloudtech.common.core.domain.BaseEntity; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import javax.validation.constraints.NotBlank; |
|||
import javax.validation.constraints.NotNull; |
|||
import javax.validation.constraints.Size; |
|||
|
|||
/** |
|||
* 角色表 sys_role |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@NoArgsConstructor |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@TableName("sys_role") |
|||
@ExcelIgnoreUnannotated |
|||
public class SysRole extends BaseEntity { |
|||
|
|||
/** |
|||
* 角色ID |
|||
*/ |
|||
@ExcelProperty(value = "角色序号") |
|||
@TableId(value = "role_id") |
|||
private Long roleId; |
|||
|
|||
/** |
|||
* 角色名称 |
|||
*/ |
|||
@ExcelProperty(value = "角色名称") |
|||
@NotBlank(message = "角色名称不能为空") |
|||
@Size(min = 0, max = 30, message = "角色名称长度不能超过{max}个字符") |
|||
private String roleName; |
|||
|
|||
/** |
|||
* 角色权限 |
|||
*/ |
|||
@ExcelProperty(value = "角色权限") |
|||
@NotBlank(message = "权限字符不能为空") |
|||
@Size(min = 0, max = 100, message = "权限字符长度不能超过{max}个字符") |
|||
private String roleKey; |
|||
|
|||
/** |
|||
* 角色排序 |
|||
*/ |
|||
@ExcelProperty(value = "角色排序") |
|||
@NotNull(message = "显示顺序不能为空") |
|||
private Integer roleSort; |
|||
|
|||
/** |
|||
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) |
|||
*/ |
|||
@ExcelProperty(value = "数据范围", converter = ExcelDictConvert.class) |
|||
@ExcelDictFormat(readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") |
|||
private String dataScope; |
|||
|
|||
/** |
|||
* 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) |
|||
*/ |
|||
private Boolean menuCheckStrictly; |
|||
|
|||
/** |
|||
* 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) |
|||
*/ |
|||
private Boolean deptCheckStrictly; |
|||
|
|||
/** |
|||
* 角色状态(0正常 1停用) |
|||
*/ |
|||
@ExcelProperty(value = "角色状态", converter = ExcelDictConvert.class) |
|||
@ExcelDictFormat(dictType = "sys_normal_disable") |
|||
private String status; |
|||
|
|||
/** |
|||
* 删除标志(0代表存在 2代表删除) |
|||
*/ |
|||
@TableLogic |
|||
private String delFlag; |
|||
|
|||
/** |
|||
* 备注 |
|||
*/ |
|||
private String remark; |
|||
|
|||
/** |
|||
* 用户是否存在此角色标识 默认不存在 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private boolean flag = false; |
|||
|
|||
/** |
|||
* 菜单组 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private Long[] menuIds; |
|||
|
|||
/** |
|||
* 部门组(数据权限) |
|||
*/ |
|||
@TableField(exist = false) |
|||
private Long[] deptIds; |
|||
|
|||
public SysRole(Long roleId) { |
|||
this.roleId = roleId; |
|||
} |
|||
|
|||
public boolean isAdmin() { |
|||
return UserConstants.ADMIN_ID.equals(this.roleId); |
|||
} |
|||
} |
@ -0,0 +1,180 @@ |
|||
package com.inscloudtech.common.core.domain.entity; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.*; |
|||
import com.fasterxml.jackson.annotation.JsonIgnore; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
import com.inscloudtech.common.annotation.Sensitive; |
|||
import com.inscloudtech.common.constant.UserConstants; |
|||
import com.inscloudtech.common.core.domain.BaseEntity; |
|||
import com.inscloudtech.common.enums.SensitiveStrategy; |
|||
import com.inscloudtech.common.xss.Xss; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
import org.hibernate.validator.constraints.Length; |
|||
|
|||
import javax.validation.constraints.Email; |
|||
import javax.validation.constraints.NotBlank; |
|||
import javax.validation.constraints.Size; |
|||
import java.util.Date; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 用户对象 sys_user |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@NoArgsConstructor |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@TableName("sys_user") |
|||
public class SysUser extends BaseEntity { |
|||
|
|||
/** |
|||
* 用户ID |
|||
*/ |
|||
@TableId(value = "user_id") |
|||
private Long userId; |
|||
|
|||
/** |
|||
* 部门ID |
|||
*/ |
|||
private Long deptId; |
|||
|
|||
/** |
|||
* 用户账号/手机号码 |
|||
*/ |
|||
@Xss(message = "用户账号不能包含脚本字符") |
|||
@Size(min = 0, max = 30, message = "用户账号长度不能超过{max}个字符") |
|||
private String userName; |
|||
|
|||
/** |
|||
* 用户昵称 |
|||
*/ |
|||
@Xss(message = "用户昵称不能包含脚本字符") |
|||
@Size(min = 0, max = 30, message = "用户昵称长度不能超过{max}个字符") |
|||
private String nickName; |
|||
|
|||
/** |
|||
* 用户类型(sys_user系统用户) |
|||
*/ |
|||
private String userType; |
|||
|
|||
/** |
|||
* 用户邮箱 |
|||
*/ |
|||
@Sensitive(strategy = SensitiveStrategy.EMAIL) |
|||
@Email(message = "邮箱格式不正确") |
|||
@Size(min = 0, max = 50, message = "邮箱长度不能超过{max}个字符") |
|||
private String email; |
|||
|
|||
/** |
|||
* 手机号码 |
|||
*/ |
|||
@Sensitive(strategy = SensitiveStrategy.PHONE) |
|||
private String phonenumber; |
|||
|
|||
/** |
|||
* 用户性别 |
|||
*/ |
|||
private String sex; |
|||
|
|||
/** |
|||
* 用户头像 |
|||
*/ |
|||
private String avatar; |
|||
|
|||
/** |
|||
* 密码 |
|||
*/ |
|||
@TableField( |
|||
insertStrategy = FieldStrategy.NOT_EMPTY, |
|||
updateStrategy = FieldStrategy.NOT_EMPTY, |
|||
whereStrategy = FieldStrategy.NOT_EMPTY |
|||
) |
|||
private String password; |
|||
|
|||
@JsonIgnore |
|||
@JsonProperty |
|||
public String getPassword() { |
|||
return password; |
|||
} |
|||
|
|||
/** |
|||
* 帐号状态(0正常 1停用) |
|||
*/ |
|||
private String status; |
|||
|
|||
/** |
|||
* 删除标志(0代表存在 2代表删除) |
|||
*/ |
|||
@TableLogic |
|||
private String delFlag; |
|||
|
|||
/** |
|||
* 最后登录IP |
|||
*/ |
|||
private String loginIp; |
|||
|
|||
/** |
|||
* 最后登录时间 |
|||
*/ |
|||
private Date loginDate; |
|||
|
|||
/** |
|||
* 备注 |
|||
*/ |
|||
private String remark; |
|||
|
|||
/** |
|||
* 角色名称 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private String roleName; |
|||
|
|||
|
|||
/** |
|||
* 部门对象 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private SysDept dept; |
|||
|
|||
/** |
|||
* 角色对象 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private List<SysRole> roles; |
|||
|
|||
/** |
|||
* 角色组 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private Long[] roleIds; |
|||
|
|||
/** |
|||
* 岗位组 |
|||
*/ |
|||
@TableField(exist = false) |
|||
private Long[] postIds; |
|||
|
|||
/** |
|||
* 数据权限 当前角色ID |
|||
*/ |
|||
@TableField(exist = false) |
|||
private Long roleId; |
|||
|
|||
/** |
|||
* 公司名称 |
|||
*/ |
|||
private String companyName; |
|||
|
|||
public SysUser(Long userId) { |
|||
this.userId = userId; |
|||
} |
|||
|
|||
public boolean isAdmin() { |
|||
return UserConstants.ADMIN_ID.equals(this.userId); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,61 @@ |
|||
package com.inscloudtech.common.core.domain.event; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* 操作日志事件 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class ExceptionReportEvent implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 日志主键 |
|||
*/ |
|||
private Long operId; |
|||
|
|||
/** |
|||
* 请求方法 |
|||
*/ |
|||
private String method; |
|||
|
|||
/** |
|||
* 请求方式 |
|||
*/ |
|||
private String requestMethod; |
|||
|
|||
|
|||
/** |
|||
* 操作人员 |
|||
*/ |
|||
private String operName; |
|||
|
|||
/** |
|||
* 请求url |
|||
*/ |
|||
private String operUrl; |
|||
|
|||
/** |
|||
* 操作地址 |
|||
*/ |
|||
private String operIp; |
|||
|
|||
/** |
|||
* 操作地点 |
|||
*/ |
|||
private String operLocation; |
|||
|
|||
/** |
|||
* 请求参数 |
|||
*/ |
|||
private String msg; |
|||
|
|||
|
|||
} |
@ -0,0 +1,44 @@ |
|||
package com.inscloudtech.common.core.domain.event; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 登录事件 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class LogininforEvent implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 用户账号 |
|||
*/ |
|||
private String username; |
|||
|
|||
/** |
|||
* 登录状态 0成功 1失败 |
|||
*/ |
|||
private String status; |
|||
|
|||
/** |
|||
* 提示消息 |
|||
*/ |
|||
private String message; |
|||
|
|||
/** |
|||
* 请求体 |
|||
*/ |
|||
private HttpServletRequest request; |
|||
|
|||
/** |
|||
* 其他参数 |
|||
*/ |
|||
private Object[] args; |
|||
|
|||
} |
@ -0,0 +1,104 @@ |
|||
package com.inscloudtech.common.core.domain.event; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* 操作日志事件 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class OperLogEvent implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 日志主键 |
|||
*/ |
|||
private Long operId; |
|||
|
|||
/** |
|||
* 操作模块 |
|||
*/ |
|||
private String title; |
|||
|
|||
/** |
|||
* 业务类型(0其它 1新增 2修改 3删除) |
|||
*/ |
|||
private Integer businessType; |
|||
|
|||
/** |
|||
* 业务类型数组 |
|||
*/ |
|||
private Integer[] businessTypes; |
|||
|
|||
/** |
|||
* 请求方法 |
|||
*/ |
|||
private String method; |
|||
|
|||
/** |
|||
* 请求方式 |
|||
*/ |
|||
private String requestMethod; |
|||
|
|||
/** |
|||
* 操作类别(0其它 1后台用户 2手机端用户) |
|||
*/ |
|||
private Integer operatorType; |
|||
|
|||
/** |
|||
* 操作人员 |
|||
*/ |
|||
private String operName; |
|||
|
|||
/** |
|||
* 部门名称 |
|||
*/ |
|||
private String deptName; |
|||
|
|||
/** |
|||
* 请求url |
|||
*/ |
|||
private String operUrl; |
|||
|
|||
/** |
|||
* 操作地址 |
|||
*/ |
|||
private String operIp; |
|||
|
|||
/** |
|||
* 操作地点 |
|||
*/ |
|||
private String operLocation; |
|||
|
|||
/** |
|||
* 请求参数 |
|||
*/ |
|||
private String operParam; |
|||
|
|||
/** |
|||
* 返回参数 |
|||
*/ |
|||
private String jsonResult; |
|||
|
|||
/** |
|||
* 操作状态(0正常 1异常) |
|||
*/ |
|||
private Integer status; |
|||
|
|||
/** |
|||
* 错误消息 |
|||
*/ |
|||
private String errorMsg; |
|||
|
|||
/** |
|||
* 操作时间 |
|||
*/ |
|||
private Date operTime; |
|||
|
|||
} |
@ -0,0 +1,55 @@ |
|||
package com.inscloudtech.common.core.domain.event; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* 操作日志事件 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class RequestLogEvent implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 日志主键 |
|||
*/ |
|||
private Long operId; |
|||
|
|||
/** |
|||
* 请求方式 |
|||
*/ |
|||
private String requestMethod; |
|||
|
|||
|
|||
/** |
|||
* 操作人员 |
|||
*/ |
|||
private String operName; |
|||
|
|||
/** |
|||
* 请求url |
|||
*/ |
|||
private String operUrl; |
|||
|
|||
/** |
|||
* 操作地址 |
|||
*/ |
|||
private String operIp; |
|||
|
|||
/** |
|||
* 操作地点 |
|||
*/ |
|||
private String operLocation; |
|||
|
|||
/** |
|||
* 请求参数 |
|||
*/ |
|||
private String operParam; |
|||
|
|||
} |
@ -0,0 +1,30 @@ |
|||
package com.inscloudtech.common.core.domain.model; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import javax.validation.constraints.Email; |
|||
import javax.validation.constraints.NotBlank; |
|||
|
|||
/** |
|||
* 邮箱登录对象 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class EmailLoginBody { |
|||
|
|||
/** |
|||
* 邮箱 |
|||
*/ |
|||
@NotBlank(message = "{user.email.not.blank}") |
|||
@Email(message = "{user.email.not.valid}") |
|||
private String email; |
|||
|
|||
/** |
|||
* 邮箱code |
|||
*/ |
|||
@NotBlank(message = "{email.code.not.blank}") |
|||
private String emailCode; |
|||
|
|||
} |
@ -0,0 +1,55 @@ |
|||
package com.inscloudtech.common.core.domain.model; |
|||
|
|||
import com.inscloudtech.common.constant.UserConstants; |
|||
import lombok.Data; |
|||
import org.hibernate.validator.constraints.Length; |
|||
|
|||
import javax.validation.constraints.NotBlank; |
|||
|
|||
/** |
|||
* 用户登录对象 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class LoginBody { |
|||
|
|||
/** |
|||
* 手机号 |
|||
*/ |
|||
// @Length(min = 11, max = 11, message = "{user.mobile.phone.number.not.valid}") |
|||
private String username; |
|||
|
|||
|
|||
/** |
|||
* 用户昵称 |
|||
*/ |
|||
@Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "用户长度必须在2到20个字符之间") |
|||
private String nickName; |
|||
|
|||
|
|||
/** |
|||
* 公司名称 |
|||
*/ |
|||
@Length(min = 5, max =50, message = "公司名称长度必须在5到50个字符之间") |
|||
private String companyName; |
|||
|
|||
/** |
|||
* 用户密码 |
|||
*/ |
|||
@NotBlank(message = "{user.password.not.blank}") |
|||
@Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}") |
|||
private String password; |
|||
|
|||
/** |
|||
* 验证码 |
|||
*/ |
|||
private String code; |
|||
|
|||
/** |
|||
* 唯一标识 |
|||
*/ |
|||
private String uuid; |
|||
|
|||
} |
@ -0,0 +1,116 @@ |
|||
package com.inscloudtech.common.core.domain.model; |
|||
|
|||
import com.inscloudtech.common.core.domain.dto.RoleDTO; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.List; |
|||
import java.util.Set; |
|||
|
|||
/** |
|||
* 登录用户身份权限 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@NoArgsConstructor |
|||
public class LoginUser implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 用户ID |
|||
*/ |
|||
private Long userId; |
|||
|
|||
/** |
|||
* 部门ID |
|||
*/ |
|||
private Long deptId; |
|||
|
|||
/** |
|||
* 部门名 |
|||
*/ |
|||
private String deptName; |
|||
|
|||
/** |
|||
* 用户唯一标识 |
|||
*/ |
|||
private String token; |
|||
|
|||
/** |
|||
* 用户类型 |
|||
*/ |
|||
private String userType; |
|||
|
|||
/** |
|||
* 登录时间 |
|||
*/ |
|||
private Long loginTime; |
|||
|
|||
/** |
|||
* 过期时间 |
|||
*/ |
|||
private Long expireTime; |
|||
|
|||
/** |
|||
* 登录IP地址 |
|||
*/ |
|||
private String ipaddr; |
|||
|
|||
/** |
|||
* 登录地点 |
|||
*/ |
|||
private String loginLocation; |
|||
|
|||
/** |
|||
* 浏览器类型 |
|||
*/ |
|||
private String browser; |
|||
|
|||
/** |
|||
* 操作系统 |
|||
*/ |
|||
private String os; |
|||
|
|||
/** |
|||
* 菜单权限 |
|||
*/ |
|||
private Set<String> menuPermission; |
|||
|
|||
/** |
|||
* 角色权限 |
|||
*/ |
|||
private Set<String> rolePermission; |
|||
|
|||
/** |
|||
* 用户名 |
|||
*/ |
|||
private String username; |
|||
|
|||
/** |
|||
* 角色对象 |
|||
*/ |
|||
private List<RoleDTO> roles; |
|||
|
|||
/** |
|||
* 数据权限 当前角色ID |
|||
*/ |
|||
private Long roleId; |
|||
|
|||
/** |
|||
* 获取登录id |
|||
*/ |
|||
public String getLoginId() { |
|||
if (userType == null) { |
|||
throw new IllegalArgumentException("用户类型不能为空"); |
|||
} |
|||
if (userId == null) { |
|||
throw new IllegalArgumentException("用户ID不能为空"); |
|||
} |
|||
return userType + ":" + userId; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,17 @@ |
|||
package com.inscloudtech.common.core.domain.model; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
/** |
|||
* 用户注册对象 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
public class RegisterBody extends LoginBody { |
|||
|
|||
private String userType; |
|||
|
|||
} |
@ -0,0 +1,28 @@ |
|||
package com.inscloudtech.common.core.domain.model; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import javax.validation.constraints.NotBlank; |
|||
|
|||
/** |
|||
* 短信登录对象 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
public class SmsLoginBody { |
|||
|
|||
/** |
|||
* 手机号 |
|||
*/ |
|||
@NotBlank(message = "{user.phonenumber.not.blank}") |
|||
private String phonenumber; |
|||
|
|||
/** |
|||
* 短信code |
|||
*/ |
|||
@NotBlank(message = "{sms.code.not.blank}") |
|||
private String smsCode; |
|||
|
|||
} |
@ -0,0 +1,24 @@ |
|||
package com.inscloudtech.common.core.domain.model; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
/** |
|||
* 小程序登录用户身份权限 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@NoArgsConstructor |
|||
public class XcxLoginUser extends LoginUser { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* openid |
|||
*/ |
|||
private String openid; |
|||
|
|||
} |
@ -0,0 +1,192 @@ |
|||
package com.inscloudtech.common.core.mapper; |
|||
|
|||
import cn.hutool.core.collection.CollUtil; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import com.baomidou.mybatisplus.core.conditions.Wrapper; |
|||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import com.baomidou.mybatisplus.core.toolkit.*; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.baomidou.mybatisplus.extension.toolkit.Db; |
|||
import com.inscloudtech.common.utils.BeanCopyUtils; |
|||
import org.apache.ibatis.logging.Log; |
|||
import org.apache.ibatis.logging.LogFactory; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Collection; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 自定义 Mapper 接口, 实现 自定义扩展 |
|||
* |
|||
* @param <M> mapper 泛型 |
|||
* @param <T> table 泛型 |
|||
* @param <V> vo 泛型 |
|||
* @author inscloudtech |
|||
* @since 2021-05-13 |
|||
*/ |
|||
@SuppressWarnings("unchecked") |
|||
public interface BaseMapperPlus<M, T, V> extends BaseMapper<T> { |
|||
|
|||
Log log = LogFactory.getLog(BaseMapperPlus.class); |
|||
|
|||
default Class<V> currentVoClass() { |
|||
return (Class<V>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 2); |
|||
} |
|||
|
|||
default Class<T> currentModelClass() { |
|||
return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 1); |
|||
} |
|||
|
|||
default Class<M> currentMapperClass() { |
|||
return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseMapperPlus.class, 0); |
|||
} |
|||
|
|||
default List<T> selectList() { |
|||
return this.selectList(new QueryWrapper<>()); |
|||
} |
|||
|
|||
/** |
|||
* 批量插入 |
|||
*/ |
|||
default boolean insertBatch(Collection<T> entityList) { |
|||
return Db.saveBatch(entityList); |
|||
} |
|||
|
|||
/** |
|||
* 批量更新 |
|||
*/ |
|||
default boolean updateBatchById(Collection<T> entityList) { |
|||
return Db.updateBatchById(entityList); |
|||
} |
|||
|
|||
/** |
|||
* 批量插入或更新 |
|||
*/ |
|||
default boolean insertOrUpdateBatch(Collection<T> entityList) { |
|||
return Db.saveOrUpdateBatch(entityList); |
|||
} |
|||
|
|||
/** |
|||
* 批量插入(包含限制条数) |
|||
*/ |
|||
default boolean insertBatch(Collection<T> entityList, int batchSize) { |
|||
return Db.saveBatch(entityList, batchSize); |
|||
} |
|||
|
|||
/** |
|||
* 批量更新(包含限制条数) |
|||
*/ |
|||
default boolean updateBatchById(Collection<T> entityList, int batchSize) { |
|||
return Db.updateBatchById(entityList, batchSize); |
|||
} |
|||
|
|||
/** |
|||
* 批量插入或更新(包含限制条数) |
|||
*/ |
|||
default boolean insertOrUpdateBatch(Collection<T> entityList, int batchSize) { |
|||
return Db.saveOrUpdateBatch(entityList, batchSize); |
|||
} |
|||
|
|||
/** |
|||
* 插入或更新(包含限制条数) |
|||
*/ |
|||
default boolean insertOrUpdate(T entity) { |
|||
return Db.saveOrUpdate(entity); |
|||
} |
|||
|
|||
default V selectVoById(Serializable id) { |
|||
return selectVoById(id, this.currentVoClass()); |
|||
} |
|||
|
|||
/** |
|||
* 根据 ID 查询 |
|||
*/ |
|||
default <C> C selectVoById(Serializable id, Class<C> voClass) { |
|||
T obj = this.selectById(id); |
|||
if (ObjectUtil.isNull(obj)) { |
|||
return null; |
|||
} |
|||
return BeanCopyUtils.copy(obj, voClass); |
|||
} |
|||
|
|||
default List<V> selectVoBatchIds(Collection<? extends Serializable> idList) { |
|||
return selectVoBatchIds(idList, this.currentVoClass()); |
|||
} |
|||
|
|||
/** |
|||
* 查询(根据ID 批量查询) |
|||
*/ |
|||
default <C> List<C> selectVoBatchIds(Collection<? extends Serializable> idList, Class<C> voClass) { |
|||
List<T> list = this.selectBatchIds(idList); |
|||
if (CollUtil.isEmpty(list)) { |
|||
return CollUtil.newArrayList(); |
|||
} |
|||
return BeanCopyUtils.copyList(list, voClass); |
|||
} |
|||
|
|||
default List<V> selectVoByMap(Map<String, Object> map) { |
|||
return selectVoByMap(map, this.currentVoClass()); |
|||
} |
|||
|
|||
/** |
|||
* 查询(根据 columnMap 条件) |
|||
*/ |
|||
default <C> List<C> selectVoByMap(Map<String, Object> map, Class<C> voClass) { |
|||
List<T> list = this.selectByMap(map); |
|||
if (CollUtil.isEmpty(list)) { |
|||
return CollUtil.newArrayList(); |
|||
} |
|||
return BeanCopyUtils.copyList(list, voClass); |
|||
} |
|||
|
|||
default V selectVoOne(Wrapper<T> wrapper) { |
|||
return selectVoOne(wrapper, this.currentVoClass()); |
|||
} |
|||
|
|||
/** |
|||
* 根据 entity 条件,查询一条记录 |
|||
*/ |
|||
default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass) { |
|||
T obj = this.selectOne(wrapper); |
|||
if (ObjectUtil.isNull(obj)) { |
|||
return null; |
|||
} |
|||
return BeanCopyUtils.copy(obj, voClass); |
|||
} |
|||
|
|||
default List<V> selectVoList(Wrapper<T> wrapper) { |
|||
return selectVoList(wrapper, this.currentVoClass()); |
|||
} |
|||
|
|||
/** |
|||
* 根据 entity 条件,查询全部记录 |
|||
*/ |
|||
default <C> List<C> selectVoList(Wrapper<T> wrapper, Class<C> voClass) { |
|||
List<T> list = this.selectList(wrapper); |
|||
if (CollUtil.isEmpty(list)) { |
|||
return CollUtil.newArrayList(); |
|||
} |
|||
return BeanCopyUtils.copyList(list, voClass); |
|||
} |
|||
|
|||
default <P extends IPage<V>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper) { |
|||
return selectVoPage(page, wrapper, this.currentVoClass()); |
|||
} |
|||
|
|||
/** |
|||
* 分页查询VO |
|||
*/ |
|||
default <C, P extends IPage<C>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<C> voClass) { |
|||
List<T> list = this.selectList(page, wrapper); |
|||
IPage<C> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal()); |
|||
if (CollUtil.isEmpty(list)) { |
|||
return (P) voPage; |
|||
} |
|||
voPage.setRecords(BeanCopyUtils.copyList(list, voClass)); |
|||
return (P) voPage; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,78 @@ |
|||
package com.inscloudtech.common.core.page; |
|||
|
|||
import cn.hutool.http.HttpStatus; |
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 表格分页数据对象 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
|
|||
@Data |
|||
@NoArgsConstructor |
|||
public class TableDataInfo<T> implements Serializable { |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 总记录数 |
|||
*/ |
|||
private long total; |
|||
|
|||
/** |
|||
* 列表数据 |
|||
*/ |
|||
private List<T> rows; |
|||
|
|||
/** |
|||
* 消息状态码 |
|||
*/ |
|||
private int code; |
|||
|
|||
/** |
|||
* 消息内容 |
|||
*/ |
|||
private String msg; |
|||
|
|||
/** |
|||
* 分页 |
|||
* |
|||
* @param list 列表数据 |
|||
* @param total 总记录数 |
|||
*/ |
|||
public TableDataInfo(List<T> list, long total) { |
|||
this.rows = list; |
|||
this.total = total; |
|||
} |
|||
|
|||
public static <T> TableDataInfo<T> build(IPage<T> page) { |
|||
TableDataInfo<T> rspData = new TableDataInfo<>(); |
|||
rspData.setCode(HttpStatus.HTTP_OK); |
|||
rspData.setMsg("查询成功"); |
|||
rspData.setRows(page.getRecords()); |
|||
rspData.setTotal(page.getTotal()); |
|||
return rspData; |
|||
} |
|||
|
|||
public static <T> TableDataInfo<T> build(List<T> list) { |
|||
TableDataInfo<T> rspData = new TableDataInfo<>(); |
|||
rspData.setCode(HttpStatus.HTTP_OK); |
|||
rspData.setMsg("查询成功"); |
|||
rspData.setRows(list); |
|||
rspData.setTotal(list.size()); |
|||
return rspData; |
|||
} |
|||
|
|||
public static <T> TableDataInfo<T> build() { |
|||
TableDataInfo<T> rspData = new TableDataInfo<>(); |
|||
rspData.setCode(HttpStatus.HTTP_OK); |
|||
rspData.setMsg("查询成功"); |
|||
return rspData; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.inscloudtech.common.core.service; |
|||
|
|||
/** |
|||
* 通用 参数配置服务 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface ConfigService { |
|||
|
|||
/** |
|||
* 根据参数 key 获取参数值 |
|||
* |
|||
* @param configKey 参数 key |
|||
* @return 参数值 |
|||
*/ |
|||
String getConfigValue(String configKey); |
|||
|
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.inscloudtech.common.core.service; |
|||
|
|||
/** |
|||
* 通用 部门服务 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface DeptService { |
|||
|
|||
/** |
|||
* 通过部门ID查询部门名称 |
|||
* |
|||
* @param deptIds 部门ID串逗号分隔 |
|||
* @return 部门名称串逗号分隔 |
|||
*/ |
|||
String selectDeptNameByIds(String deptIds); |
|||
|
|||
} |
@ -0,0 +1,66 @@ |
|||
package com.inscloudtech.common.core.service; |
|||
|
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 通用 字典服务 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface DictService { |
|||
|
|||
/** |
|||
* 分隔符 |
|||
*/ |
|||
String SEPARATOR = ","; |
|||
|
|||
/** |
|||
* 根据字典类型和字典值获取字典标签 |
|||
* |
|||
* @param dictType 字典类型 |
|||
* @param dictValue 字典值 |
|||
* @return 字典标签 |
|||
*/ |
|||
default String getDictLabel(String dictType, String dictValue) { |
|||
return getDictLabel(dictType, dictValue, SEPARATOR); |
|||
} |
|||
|
|||
/** |
|||
* 根据字典类型和字典标签获取字典值 |
|||
* |
|||
* @param dictType 字典类型 |
|||
* @param dictLabel 字典标签 |
|||
* @return 字典值 |
|||
*/ |
|||
default String getDictValue(String dictType, String dictLabel) { |
|||
return getDictValue(dictType, dictLabel, SEPARATOR); |
|||
} |
|||
|
|||
/** |
|||
* 根据字典类型和字典值获取字典标签 |
|||
* |
|||
* @param dictType 字典类型 |
|||
* @param dictValue 字典值 |
|||
* @param separator 分隔符 |
|||
* @return 字典标签 |
|||
*/ |
|||
String getDictLabel(String dictType, String dictValue, String separator); |
|||
|
|||
/** |
|||
* 根据字典类型和字典标签获取字典值 |
|||
* |
|||
* @param dictType 字典类型 |
|||
* @param dictLabel 字典标签 |
|||
* @param separator 分隔符 |
|||
* @return 字典值 |
|||
*/ |
|||
String getDictValue(String dictType, String dictLabel, String separator); |
|||
|
|||
/** |
|||
* 获取字典下所有的字典值与标签 |
|||
* |
|||
* @param dictType 字典类型 |
|||
* @return dictValue为key,dictLabel为值组成的Map |
|||
*/ |
|||
Map<String, String> getAllDictByDictType(String dictType); |
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.inscloudtech.common.core.service; |
|||
|
|||
/** |
|||
* 通用 OSS服务 |
|||
* |
|||
* @author inscloudtech |
|||
*/ |
|||
public interface OssService { |
|||
|
|||
/** |
|||
* 通过ossId查询对应的url |
|||
* |
|||
* @param ossIds ossId串逗号分隔 |
|||
* @return url串逗号分隔 |
|||
*/ |
|||
String selectUrlByIds(String ossIds); |
|||
|
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.inscloudtech.common.core.service; |
|||
|
|||
/** |
|||
* 脱敏服务 |
|||
* 默认管理员不过滤 |
|||
* 需自行根据业务重写实现 |
|||
* |
|||
* @author inscloudtech |
|||
* @version 3.6.0 |
|||
*/ |
|||
public interface SensitiveService { |
|||
|
|||
/** |
|||
* 是否脱敏 |
|||
*/ |
|||
boolean isSensitive(); |
|||
|
|||
} |
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue