245 changed files with 20 additions and 29637 deletions
@ -1,12 +0,0 @@ |
|||||
<component name="ProjectRunConfigurationManager"> |
|
||||
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> |
|
||||
<deployment type="dockerfile"> |
|
||||
<settings> |
|
||||
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.2.3" /> |
|
||||
<option name="buildOnly" value="true" /> |
|
||||
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" /> |
|
||||
</settings> |
|
||||
</deployment> |
|
||||
<method v="2" /> |
|
||||
</configuration> |
|
||||
</component> |
|
||||
@ -1,12 +0,0 @@ |
|||||
<component name="ProjectRunConfigurationManager"> |
|
||||
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="演示机"> |
|
||||
<deployment type="dockerfile"> |
|
||||
<settings> |
|
||||
<option name="imageTag" value="ruoyi/ruoyi-server:5.2.3" /> |
|
||||
<option name="buildOnly" value="true" /> |
|
||||
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" /> |
|
||||
</settings> |
|
||||
</deployment> |
|
||||
<method v="2" /> |
|
||||
</configuration> |
|
||||
</component> |
|
||||
@ -1,12 +0,0 @@ |
|||||
<component name="ProjectRunConfigurationManager"> |
|
||||
<configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> |
|
||||
<deployment type="dockerfile"> |
|
||||
<settings> |
|
||||
<option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.2.3" /> |
|
||||
<option name="buildOnly" value="true" /> |
|
||||
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-snailjob-server/Dockerfile" /> |
|
||||
</settings> |
|
||||
</deployment> |
|
||||
<method v="2" /> |
|
||||
</configuration> |
|
||||
</component> |
|
||||
@ -1,20 +0,0 @@ |
|||||
The MIT License (MIT) |
|
||||
|
|
||||
Copyright (c) 2019 RuoYi-Vue-Plus |
|
||||
|
|
||||
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. |
|
||||
@ -1,8 +0,0 @@ |
|||||
Application Version: ${revision} |
|
||||
Spring Boot Version: ${spring-boot.version} |
|
||||
__________ _____.___.__ ____ ____ __________.__ |
|
||||
\______ \__ __ ____\__ | |__| \ \ / /_ __ ____ \______ \ | __ __ ______ |
|
||||
| _/ | \/ _ \/ | | | ______ \ Y / | \_/ __ \ ______ | ___/ | | | \/ ___/ |
|
||||
| | \ | ( <_> )____ | | /_____/ \ /| | /\ ___/ /_____/ | | | |_| | /\___ \ |
|
||||
|____|_ /____/ \____// ______|__| \___/ |____/ \___ > |____| |____/____//____ > |
|
||||
\/ \/ \/ \/ |
|
||||
@ -1,46 +0,0 @@ |
|||||
<?xml version="1.0" encoding="UTF-8"?> |
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|
||||
xmlns="http://maven.apache.org/POM/4.0.0" |
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|
||||
<parent> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common</artifactId> |
|
||||
<version>${revision}</version> |
|
||||
</parent> |
|
||||
<modelVersion>4.0.0</modelVersion> |
|
||||
|
|
||||
<artifactId>ruoyi-common-job</artifactId> |
|
||||
|
|
||||
<description> |
|
||||
ruoyi-common-job 定时任务 |
|
||||
</description> |
|
||||
|
|
||||
<dependencies> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.springframework.boot</groupId> |
|
||||
<artifactId>spring-boot-autoconfigure</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<!-- SnailJob client --> |
|
||||
<dependency> |
|
||||
<groupId>com.aizuda</groupId> |
|
||||
<artifactId>snail-job-client-starter</artifactId> |
|
||||
</dependency> |
|
||||
<dependency> |
|
||||
<groupId>com.aizuda</groupId> |
|
||||
<artifactId>snail-job-client-job-core</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.projectlombok</groupId> |
|
||||
<artifactId>lombok</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-core</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
</dependencies> |
|
||||
</project> |
|
||||
@ -1,37 +0,0 @@ |
|||||
package org.dromara.common.job.config; |
|
||||
|
|
||||
import ch.qos.logback.classic.Logger; |
|
||||
import ch.qos.logback.classic.LoggerContext; |
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent; |
|
||||
import com.aizuda.snailjob.client.common.appender.SnailLogbackAppender; |
|
||||
import com.aizuda.snailjob.client.common.event.SnailClientStartingEvent; |
|
||||
import com.aizuda.snailjob.client.starter.EnableSnailJob; |
|
||||
import org.slf4j.LoggerFactory; |
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration; |
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
|
||||
import org.springframework.context.event.EventListener; |
|
||||
import org.springframework.scheduling.annotation.EnableScheduling; |
|
||||
|
|
||||
/** |
|
||||
* 启动定时任务 |
|
||||
* |
|
||||
* @author opensnail |
|
||||
* @date 2024-05-17 |
|
||||
*/ |
|
||||
@AutoConfiguration |
|
||||
@ConditionalOnProperty(prefix = "snail-job", name = "enabled", havingValue = "true") |
|
||||
@EnableScheduling |
|
||||
@EnableSnailJob |
|
||||
public class SnailJobConfig { |
|
||||
|
|
||||
@EventListener(SnailClientStartingEvent.class) |
|
||||
public void onStarting(SnailClientStartingEvent event) { |
|
||||
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); |
|
||||
SnailLogbackAppender<ILoggingEvent> ca = new SnailLogbackAppender<>(); |
|
||||
ca.setName("snail_log_appender"); |
|
||||
ca.start(); |
|
||||
Logger rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME); |
|
||||
rootLogger.addAppender(ca); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1 +0,0 @@ |
|||||
org.dromara.common.job.config.SnailJobConfig |
|
||||
@ -1,19 +0,0 @@ |
|||||
<?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>ruoyi-vue-plus</artifactId> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<version>${revision}</version> |
|
||||
</parent> |
|
||||
<modelVersion>4.0.0</modelVersion> |
|
||||
<artifactId>ruoyi-extend</artifactId> |
|
||||
<packaging>pom</packaging> |
|
||||
|
|
||||
<modules> |
|
||||
<module>ruoyi-monitor-admin</module> |
|
||||
<module>ruoyi-snailjob-server</module> |
|
||||
</modules> |
|
||||
|
|
||||
</project> |
|
||||
@ -1,20 +0,0 @@ |
|||||
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/ |
|
||||
FROM bellsoft/liberica-openjdk-debian:17.0.11-cds |
|
||||
#FROM bellsoft/liberica-openjdk-debian:21.0.3-cds |
|
||||
#FROM findepi/graalvm:java17-native |
|
||||
|
|
||||
LABEL maintainer="Lion Li" |
|
||||
|
|
||||
RUN mkdir -p /ruoyi/monitor/logs |
|
||||
|
|
||||
WORKDIR /ruoyi/monitor |
|
||||
|
|
||||
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" |
|
||||
|
|
||||
EXPOSE 9090 |
|
||||
|
|
||||
ADD ./target/ruoyi-monitor-admin.jar ./app.jar |
|
||||
|
|
||||
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom \ |
|
||||
-XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \ |
|
||||
-jar app.jar |
|
||||
@ -1,76 +0,0 @@ |
|||||
<?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>ruoyi-extend</artifactId> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<version>${revision}</version> |
|
||||
</parent> |
|
||||
<modelVersion>4.0.0</modelVersion> |
|
||||
<packaging>jar</packaging> |
|
||||
<artifactId>ruoyi-monitor-admin</artifactId> |
|
||||
|
|
||||
<dependencies> |
|
||||
<!-- SpringBoot Web容器 --> |
|
||||
<dependency> |
|
||||
<groupId>org.springframework.boot</groupId> |
|
||||
<artifactId>spring-boot-starter-web</artifactId> |
|
||||
<exclusions> |
|
||||
<exclusion> |
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId> |
|
||||
<groupId>org.springframework.boot</groupId> |
|
||||
</exclusion> |
|
||||
</exclusions> |
|
||||
</dependency> |
|
||||
<!-- web 容器使用 undertow 性能更强 --> |
|
||||
<dependency> |
|
||||
<groupId>org.springframework.boot</groupId> |
|
||||
<artifactId>spring-boot-starter-undertow</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<!-- spring security 安全认证 --> |
|
||||
<dependency> |
|
||||
<groupId>org.springframework.boot</groupId> |
|
||||
<artifactId>spring-boot-starter-security</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>de.codecentric</groupId> |
|
||||
<artifactId>spring-boot-admin-starter-server</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>de.codecentric</groupId> |
|
||||
<artifactId>spring-boot-admin-starter-client</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.projectlombok</groupId> |
|
||||
<artifactId>lombok</artifactId> |
|
||||
</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> |
|
||||
</plugins> |
|
||||
</build> |
|
||||
|
|
||||
</project> |
|
||||
@ -1,19 +0,0 @@ |
|||||
package org.dromara.monitor.admin; |
|
||||
|
|
||||
import org.springframework.boot.SpringApplication; |
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
|
||||
|
|
||||
/** |
|
||||
* Admin 监控启动程序 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@SpringBootApplication |
|
||||
public class MonitorAdminApplication { |
|
||||
|
|
||||
public static void main(String[] args) { |
|
||||
SpringApplication.run(MonitorAdminApplication.class, args); |
|
||||
System.out.println("Admin 监控启动成功"); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,31 +0,0 @@ |
|||||
package org.dromara.monitor.admin.config; |
|
||||
|
|
||||
import de.codecentric.boot.admin.server.config.EnableAdminServer; |
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
|
||||
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; |
|
||||
import org.springframework.boot.task.ThreadPoolTaskExecutorBuilder; |
|
||||
import org.springframework.context.annotation.Bean; |
|
||||
import org.springframework.context.annotation.Configuration; |
|
||||
import org.springframework.context.annotation.Lazy; |
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
|
||||
|
|
||||
import java.util.concurrent.Executor; |
|
||||
|
|
||||
/** |
|
||||
* springboot-admin server配置类 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@Configuration |
|
||||
@EnableAdminServer |
|
||||
public class AdminServerConfig { |
|
||||
|
|
||||
@Lazy |
|
||||
@Bean(name = TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME) |
|
||||
@ConditionalOnMissingBean(Executor.class) |
|
||||
public ThreadPoolTaskExecutor applicationTaskExecutor(ThreadPoolTaskExecutorBuilder builder) { |
|
||||
return builder.build(); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
} |
|
||||
@ -1,54 +0,0 @@ |
|||||
package org.dromara.monitor.admin.config; |
|
||||
|
|
||||
import de.codecentric.boot.admin.server.config.AdminServerProperties; |
|
||||
import org.springframework.context.annotation.Bean; |
|
||||
import org.springframework.context.annotation.Configuration; |
|
||||
import org.springframework.security.config.Customizer; |
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; |
|
||||
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; |
|
||||
import org.springframework.security.web.SecurityFilterChain; |
|
||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; |
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; |
|
||||
|
|
||||
/** |
|
||||
* admin 监控 安全配置 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@EnableWebSecurity |
|
||||
@Configuration |
|
||||
public class SecurityConfig { |
|
||||
|
|
||||
private final String adminContextPath; |
|
||||
|
|
||||
public SecurityConfig(AdminServerProperties adminServerProperties) { |
|
||||
this.adminContextPath = adminServerProperties.getContextPath(); |
|
||||
} |
|
||||
|
|
||||
@Bean |
|
||||
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { |
|
||||
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); |
|
||||
successHandler.setTargetUrlParameter("redirectTo"); |
|
||||
successHandler.setDefaultTargetUrl(adminContextPath + "/"); |
|
||||
|
|
||||
return httpSecurity |
|
||||
.headers((header) -> |
|
||||
header.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) |
|
||||
.authorizeHttpRequests((authorize) -> |
|
||||
authorize.requestMatchers( |
|
||||
new AntPathRequestMatcher(adminContextPath + "/assets/**"), |
|
||||
new AntPathRequestMatcher(adminContextPath + "/login") |
|
||||
).permitAll() |
|
||||
.anyRequest().authenticated()) |
|
||||
.formLogin((formLogin) -> |
|
||||
formLogin.loginPage(adminContextPath + "/login").successHandler(successHandler)) |
|
||||
.logout((logout) -> |
|
||||
logout.logoutUrl(adminContextPath + "/logout")) |
|
||||
.httpBasic(Customizer.withDefaults()) |
|
||||
.csrf(AbstractHttpConfigurer::disable) |
|
||||
.build(); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,55 +0,0 @@ |
|||||
package org.dromara.monitor.admin.notifier; |
|
||||
|
|
||||
import de.codecentric.boot.admin.server.domain.entities.Instance; |
|
||||
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository; |
|
||||
import de.codecentric.boot.admin.server.domain.events.InstanceEvent; |
|
||||
import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent; |
|
||||
import de.codecentric.boot.admin.server.notify.AbstractEventNotifier; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.springframework.stereotype.Component; |
|
||||
import reactor.core.publisher.Mono; |
|
||||
|
|
||||
import static de.codecentric.boot.admin.server.domain.values.StatusInfo.*; |
|
||||
|
|
||||
/** |
|
||||
* 自定义事件通知处理 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
@Component |
|
||||
public class CustomNotifier extends AbstractEventNotifier { |
|
||||
|
|
||||
protected CustomNotifier(InstanceRepository repository) { |
|
||||
super(repository); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
@SuppressWarnings("all") |
|
||||
protected Mono<Void> doNotify(InstanceEvent event, Instance instance) { |
|
||||
return Mono.fromRunnable(() -> { |
|
||||
// 实例状态改变事件
|
|
||||
if (event instanceof InstanceStatusChangedEvent) { |
|
||||
// 获取实例注册名称
|
|
||||
String registName = instance.getRegistration().getName(); |
|
||||
// 获取实例ID
|
|
||||
String instanceId = event.getInstance().getValue(); |
|
||||
// 获取实例状态
|
|
||||
String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(); |
|
||||
// 获取服务URL
|
|
||||
String serviceUrl = instance.getRegistration().getServiceUrl(); |
|
||||
String statusName = switch (status) { |
|
||||
case STATUS_UP -> "服务上线"; // 实例成功启动并可以正常处理请求
|
|
||||
case STATUS_OFFLINE -> "服务离线"; //实例被手动或自动地从服务中移除
|
|
||||
case STATUS_RESTRICTED -> "服务受限"; //表示实例在某些方面受限,可能无法完全提供所有服务
|
|
||||
case STATUS_OUT_OF_SERVICE -> "停止服务状态"; //表示实例已被标记为停止提供服务,可能是计划内维护或测试
|
|
||||
case STATUS_DOWN -> "服务下线"; //实例因崩溃、错误或其他原因停止运行
|
|
||||
case STATUS_UNKNOWN -> "服务未知异常"; //监控系统无法确定实例的当前状态
|
|
||||
default -> "未知状态"; //没有匹配的状态
|
|
||||
}; |
|
||||
log.info("Instance Status Change: 状态名称【{}】, 注册名称【{}】, 实例ID【{}】, 状态【{}】, 服务URL【{}】", |
|
||||
statusName, registName, instanceId, status, serviceUrl); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
@ -1,48 +0,0 @@ |
|||||
server: |
|
||||
port: 9090 |
|
||||
spring: |
|
||||
application: |
|
||||
name: ruoyi-monitor-admin |
|
||||
profiles: |
|
||||
active: @profiles.active@ |
|
||||
|
|
||||
logging: |
|
||||
config: classpath:logback-plus.xml |
|
||||
|
|
||||
--- # 监控中心服务端配置 |
|
||||
spring: |
|
||||
security: |
|
||||
user: |
|
||||
name: @monitor.username@ |
|
||||
password: @monitor.password@ |
|
||||
boot: |
|
||||
admin: |
|
||||
ui: |
|
||||
title: RuoYi-Vue-Plus服务监控中心 |
|
||||
context-path: /admin |
|
||||
|
|
||||
--- # Actuator 监控端点的配置项 |
|
||||
management: |
|
||||
endpoints: |
|
||||
web: |
|
||||
exposure: |
|
||||
include: '*' |
|
||||
endpoint: |
|
||||
health: |
|
||||
show-details: ALWAYS |
|
||||
logfile: |
|
||||
external-file: ./logs/ruoyi-monitor-admin.log |
|
||||
|
|
||||
--- # 监控配置 |
|
||||
spring.boot.admin.client: |
|
||||
# 增加客户端开关 |
|
||||
enabled: true |
|
||||
# 设置 Spring Boot Admin Server 地址 |
|
||||
url: http://localhost:9090/admin |
|
||||
instance: |
|
||||
service-host-type: IP |
|
||||
metadata: |
|
||||
username: ${spring.boot.admin.client.username} |
|
||||
userpassword: ${spring.boot.admin.client.password} |
|
||||
username: @monitor.username@ |
|
||||
password: @monitor.password@ |
|
||||
@ -1,8 +0,0 @@ |
|||||
Application Version: ${revision} |
|
||||
Spring Boot Version: ${spring-boot.version} |
|
||||
__ __ _ _ _ _ |
|
||||
| \/ | (_) | /\ | | (_) |
|
||||
| \ / | ___ _ __ _| |_ ___ _ __ ______ / \ __| |_ __ ___ _ _ __ |
|
||||
| |\/| |/ _ \| '_ \| | __/ _ \| '__|______/ /\ \ / _` | '_ ` _ \| | '_ \ |
|
||||
| | | | (_) | | | | | || (_) | | / ____ \ (_| | | | | | | | | | | |
|
||||
|_| |_|\___/|_| |_|_|\__\___/|_| /_/ \_\__,_|_| |_| |_|_|_| |_| |
|
||||
@ -1,34 +0,0 @@ |
|||||
<?xml version="1.0" encoding="UTF-8"?> |
|
||||
<configuration debug="false" scan="true" scanPeriod="1 seconds"> |
|
||||
|
|
||||
<contextName>logback</contextName> |
|
||||
<property name="log.path" value="./logs/ruoyi-monitor-admin"/> |
|
||||
<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" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
|
||||
<file>${log.path}.log</file> |
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
|
||||
<fileNamePattern>${log.path}.%d{yyyy-MM-dd}.log</fileNamePattern> |
|
||||
<!-- 日志最大的历史 60天 --> |
|
||||
<maxHistory>60</maxHistory> |
|
||||
</rollingPolicy> |
|
||||
<encoder> |
|
||||
<pattern>${log.pattern}</pattern> |
|
||||
</encoder> |
|
||||
</appender> |
|
||||
|
|
||||
<root level="info"> |
|
||||
<appender-ref ref="console"/> |
|
||||
<appender-ref ref="file"/> |
|
||||
</root> |
|
||||
|
|
||||
</configuration> |
|
||||
@ -1,21 +0,0 @@ |
|||||
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/ |
|
||||
FROM bellsoft/liberica-openjdk-debian:17.0.11-cds |
|
||||
#FROM bellsoft/liberica-openjdk-debian:21.0.3-cds |
|
||||
#FROM findepi/graalvm:java17-native |
|
||||
|
|
||||
LABEL maintainer="Lion Li" |
|
||||
|
|
||||
RUN mkdir -p /ruoyi/snailjob/logs |
|
||||
|
|
||||
WORKDIR /ruoyi/snailjob |
|
||||
|
|
||||
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="-Xms512m -Xmx1024m" |
|
||||
|
|
||||
EXPOSE 8800 |
|
||||
EXPOSE 17888 |
|
||||
|
|
||||
ADD ./target/ruoyi-snailjob-server.jar ./app.jar |
|
||||
|
|
||||
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom \ |
|
||||
-XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \ |
|
||||
-jar app.jar |
|
||||
@ -1,58 +0,0 @@ |
|||||
<?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> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-extend</artifactId> |
|
||||
<version>${revision}</version> |
|
||||
</parent> |
|
||||
<modelVersion>4.0.0</modelVersion> |
|
||||
<packaging>jar</packaging> |
|
||||
<artifactId>ruoyi-snailjob-server</artifactId> |
|
||||
|
|
||||
<dependencies> |
|
||||
<dependency> |
|
||||
<groupId>com.aizuda</groupId> |
|
||||
<artifactId>snail-job-server-starter</artifactId> |
|
||||
<version>${snailjob.version}</version> |
|
||||
<exclusions> |
|
||||
<exclusion> |
|
||||
<groupId>org.scala-lang</groupId> |
|
||||
<artifactId>scala-library</artifactId> |
|
||||
</exclusion> |
|
||||
</exclusions> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.scala-lang</groupId> |
|
||||
<artifactId>scala-library</artifactId> |
|
||||
<version>2.13.9</version> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>de.codecentric</groupId> |
|
||||
<artifactId>spring-boot-admin-starter-client</artifactId> |
|
||||
<version>${spring-boot-admin.version}</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> |
|
||||
<executions> |
|
||||
<execution> |
|
||||
<goals> |
|
||||
<goal>repackage</goal> |
|
||||
</goals> |
|
||||
</execution> |
|
||||
</executions> |
|
||||
</plugin> |
|
||||
</plugins> |
|
||||
</build> |
|
||||
|
|
||||
</project> |
|
||||
@ -1,64 +0,0 @@ |
|||||
package com.aizuda.snailjob.server.starter.filter; |
|
||||
|
|
||||
import jakarta.servlet.*; |
|
||||
import jakarta.servlet.http.HttpServletRequest; |
|
||||
import jakarta.servlet.http.HttpServletResponse; |
|
||||
|
|
||||
import java.io.IOException; |
|
||||
import java.nio.charset.StandardCharsets; |
|
||||
import java.util.Base64; |
|
||||
|
|
||||
public class ActuatorAuthFilter implements Filter { |
|
||||
|
|
||||
private final String username; |
|
||||
private final String password; |
|
||||
|
|
||||
public ActuatorAuthFilter(String username, String password) { |
|
||||
this.username = username; |
|
||||
this.password = password; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { |
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest; |
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse; |
|
||||
|
|
||||
// 获取 Authorization 头
|
|
||||
String authHeader = request.getHeader("Authorization"); |
|
||||
|
|
||||
if (authHeader == null || !authHeader.startsWith("Basic ")) { |
|
||||
// 如果没有提供 Authorization 或者格式不对,则返回 401
|
|
||||
response.setHeader("WWW-Authenticate", "Basic realm=\"realm\""); |
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
// 解码 Base64 编码的用户名和密码
|
|
||||
String base64Credentials = authHeader.substring("Basic ".length()); |
|
||||
byte[] credDecoded = Base64.getDecoder().decode(base64Credentials); |
|
||||
String credentials = new String(credDecoded, StandardCharsets.UTF_8); |
|
||||
String[] split = credentials.split(":"); |
|
||||
if (split.length != 2) { |
|
||||
response.setHeader("WWW-Authenticate", "Basic realm=\"realm\""); |
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); |
|
||||
return; |
|
||||
} |
|
||||
// 验证用户名和密码
|
|
||||
if (!username.equals(split[0]) && password.equals(split[1])) { |
|
||||
response.setHeader("WWW-Authenticate", "Basic realm=\"realm\""); |
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); |
|
||||
return; |
|
||||
} |
|
||||
// 如果认证成功,继续处理请求
|
|
||||
filterChain.doFilter(request, response); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void init(FilterConfig filterConfig) { |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void destroy() { |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,29 +0,0 @@ |
|||||
package com.aizuda.snailjob.server.starter.filter; |
|
||||
|
|
||||
import org.springframework.beans.factory.annotation.Value; |
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean; |
|
||||
import org.springframework.context.annotation.Bean; |
|
||||
import org.springframework.context.annotation.Configuration; |
|
||||
|
|
||||
/** |
|
||||
* 权限安全配置 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@Configuration |
|
||||
public class SecurityConfig { |
|
||||
|
|
||||
@Value("${spring.boot.admin.client.username}") |
|
||||
private String username; |
|
||||
@Value("${spring.boot.admin.client.password}") |
|
||||
private String password; |
|
||||
|
|
||||
@Bean |
|
||||
public FilterRegistrationBean<ActuatorAuthFilter> actuatorFilterRegistrationBean() { |
|
||||
FilterRegistrationBean<ActuatorAuthFilter> registrationBean = new FilterRegistrationBean<>(); |
|
||||
registrationBean.setFilter(new ActuatorAuthFilter(username, password)); |
|
||||
registrationBean.addUrlPatterns("/actuator", "/actuator/**"); |
|
||||
return registrationBean; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,19 +0,0 @@ |
|||||
package org.dromara.snailjob; |
|
||||
|
|
||||
import org.springframework.boot.SpringApplication; |
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
|
||||
|
|
||||
/** |
|
||||
* SnailJob Server 启动程序 |
|
||||
* |
|
||||
* @author opensnail |
|
||||
* @date 2024-05-17 |
|
||||
*/ |
|
||||
@SpringBootApplication |
|
||||
public class SnailJobServerApplication { |
|
||||
|
|
||||
public static void main(String[] args) { |
|
||||
SpringApplication.run(com.aizuda.snailjob.server.SnailJobServerApplication.class, args); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,50 +0,0 @@ |
|||||
spring: |
|
||||
datasource: |
|
||||
type: com.zaxxer.hikari.HikariDataSource |
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver |
|
||||
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true |
|
||||
username: root |
|
||||
password: root |
|
||||
hikari: |
|
||||
connection-timeout: 30000 |
|
||||
validation-timeout: 5000 |
|
||||
minimum-idle: 10 |
|
||||
maximum-pool-size: 20 |
|
||||
idle-timeout: 600000 |
|
||||
max-lifetime: 900000 |
|
||||
keepaliveTime: 30000 |
|
||||
|
|
||||
--- # snail-job 服务端配置 |
|
||||
snail-job: |
|
||||
# 拉取重试数据的每批次的大小 |
|
||||
retry-pull-page-size: 1000 |
|
||||
# 拉取重试数据的每批次的大小 |
|
||||
job-pull-page-size: 1000 |
|
||||
# 服务端netty端口 |
|
||||
netty-port: 17888 |
|
||||
# 一个客户端每秒最多接收的重试数量指令 |
|
||||
limiter: 1000 |
|
||||
# 号段模式下步长配置 |
|
||||
step: 100 |
|
||||
# 日志保存时间(单位: day) |
|
||||
log-storage: 90 |
|
||||
# 回调配置 |
|
||||
callback: |
|
||||
#回调最大执行次数 |
|
||||
max-count: 288 |
|
||||
#间隔时间 |
|
||||
trigger-interval: 900 |
|
||||
retry-max-pull-count: 10 |
|
||||
|
|
||||
--- # 监控中心配置 |
|
||||
spring.boot.admin.client: |
|
||||
# 增加客户端开关 |
|
||||
enabled: true |
|
||||
url: http://localhost:9090/admin |
|
||||
instance: |
|
||||
service-host-type: IP |
|
||||
metadata: |
|
||||
username: ${spring.boot.admin.client.username} |
|
||||
userpassword: ${spring.boot.admin.client.password} |
|
||||
username: @monitor.username@ |
|
||||
password: @monitor.password@ |
|
||||
@ -1,50 +0,0 @@ |
|||||
spring: |
|
||||
datasource: |
|
||||
type: com.zaxxer.hikari.HikariDataSource |
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver |
|
||||
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true |
|
||||
username: root |
|
||||
password: root |
|
||||
hikari: |
|
||||
connection-timeout: 30000 |
|
||||
validation-timeout: 5000 |
|
||||
minimum-idle: 10 |
|
||||
maximum-pool-size: 20 |
|
||||
idle-timeout: 600000 |
|
||||
max-lifetime: 900000 |
|
||||
keepaliveTime: 30000 |
|
||||
|
|
||||
--- # snail-job 服务端配置 |
|
||||
snail-job: |
|
||||
# 拉取重试数据的每批次的大小 |
|
||||
retry-pull-page-size: 1000 |
|
||||
# 拉取重试数据的每批次的大小 |
|
||||
job-pull-page-size: 1000 |
|
||||
# 服务端 netty 端口 |
|
||||
netty-port: 17888 |
|
||||
# 一个客户端每秒最多接收的重试数量指令 |
|
||||
limiter: 1000 |
|
||||
# 号段模式下步长配置 |
|
||||
step: 100 |
|
||||
# 日志保存时间(单位: day) |
|
||||
log-storage: 90 |
|
||||
# 回调配置 |
|
||||
callback: |
|
||||
#回调最大执行次数 |
|
||||
max-count: 288 |
|
||||
#间隔时间 |
|
||||
trigger-interval: 900 |
|
||||
retry-max-pull-count: 10 |
|
||||
|
|
||||
--- # 监控中心配置 |
|
||||
spring.boot.admin.client: |
|
||||
# 增加客户端开关 |
|
||||
enabled: true |
|
||||
url: http://localhost:9090/admin |
|
||||
instance: |
|
||||
service-host-type: IP |
|
||||
metadata: |
|
||||
username: ${spring.boot.admin.client.username} |
|
||||
userpassword: ${spring.boot.admin.client.password} |
|
||||
username: @monitor.username@ |
|
||||
password: @monitor.password@ |
|
||||
@ -1,39 +0,0 @@ |
|||||
server: |
|
||||
port: 8800 |
|
||||
servlet: |
|
||||
context-path: /snail-job |
|
||||
|
|
||||
spring: |
|
||||
application: |
|
||||
name: ruoyi-snailjob-server |
|
||||
profiles: |
|
||||
active: @profiles.active@ |
|
||||
web: |
|
||||
resources: |
|
||||
static-locations: classpath:admin/ |
|
||||
|
|
||||
mybatis-plus: |
|
||||
typeAliasesPackage: com.aizuda.snailjob.template.datasource.persistence.po |
|
||||
global-config: |
|
||||
db-config: |
|
||||
where-strategy: NOT_EMPTY |
|
||||
capital-mode: false |
|
||||
logic-delete-value: 1 |
|
||||
logic-not-delete-value: 0 |
|
||||
configuration: |
|
||||
map-underscore-to-camel-case: true |
|
||||
cache-enabled: true |
|
||||
|
|
||||
logging: |
|
||||
config: classpath:logback-plus.xml |
|
||||
|
|
||||
management: |
|
||||
endpoints: |
|
||||
web: |
|
||||
exposure: |
|
||||
include: '*' |
|
||||
endpoint: |
|
||||
health: |
|
||||
show-details: ALWAYS |
|
||||
logfile: |
|
||||
external-file: ./logs/ruoyi-snailjob-server/console.log |
|
||||
@ -1,11 +0,0 @@ |
|||||
Application Version: ${revision} |
|
||||
Spring Boot Version: ${spring-boot.version} |
|
||||
_ _ _ _ |
|
||||
(_) (_) | | |
|
||||
___ _ __ __ _ _| |_ ___ | |__ ______ ___ ___ _ ____ _____ _ __ |
|
||||
/ __| '_ \ / _` | | | |/ _ \| '_ \______/ __|/ _ \ '__\ \ / / _ \ '__| |
|
||||
\__ \ | | | (_| | | | | (_) | |_) | \__ \ __/ | \ V / __/ | |
|
||||
|___/_| |_|\__,_|_|_| |\___/|_.__/ |___/\___|_| \_/ \___|_| |
|
||||
_/ | |
|
||||
|__/ |
|
||||
|
|
||||
@ -1,92 +0,0 @@ |
|||||
<?xml version="1.0" encoding="UTF-8"?> |
|
||||
<configuration> |
|
||||
<property name="log.path" value="./logs/ruoyi-snailjob-server" /> |
|
||||
<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}/console.log</file> |
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
|
||||
<!-- 日志文件名格式 --> |
|
||||
<fileNamePattern>${log.path}/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}/info.log</file> |
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
|
||||
<FileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</FileNamePattern> |
|
||||
<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}/error.log</file> |
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
|
||||
<FileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log |
|
||||
</FileNamePattern> |
|
||||
<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> |
|
||||
|
|
||||
<appender name ="async_info" class= "ch.qos.logback.classic.AsyncAppender"> |
|
||||
<discardingThreshold >100</discardingThreshold> |
|
||||
<queueSize>1024</queueSize> |
|
||||
<appender-ref ref ="file_info"/> |
|
||||
</appender> |
|
||||
|
|
||||
<appender name ="async_error" class= "ch.qos.logback.classic.AsyncAppender"> |
|
||||
<discardingThreshold >100</discardingThreshold> |
|
||||
<queueSize>1024</queueSize> |
|
||||
<appender-ref ref ="file_error"/> |
|
||||
</appender> |
|
||||
|
|
||||
<!-- SnailJob appender --> |
|
||||
<appender name="snail_log_server_appender" class="com.aizuda.snailjob.server.common.appender.SnailJobServerLogbackAppender"> |
|
||||
</appender> |
|
||||
|
|
||||
<!-- 控制台输出日志级别 --> |
|
||||
<root level="info"> |
|
||||
<appender-ref ref="console" /> |
|
||||
<appender-ref ref="async_info" /> |
|
||||
<appender-ref ref="async_error" /> |
|
||||
<appender-ref ref="snail_log_server_appender" /> |
|
||||
</root> |
|
||||
</configuration> |
|
||||
@ -1,108 +0,0 @@ |
|||||
<?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> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-modules</artifactId> |
|
||||
<version>${revision}</version> |
|
||||
</parent> |
|
||||
<modelVersion>4.0.0</modelVersion> |
|
||||
|
|
||||
<artifactId>ruoyi-demo</artifactId> |
|
||||
|
|
||||
<description> |
|
||||
demo模块 |
|
||||
</description> |
|
||||
|
|
||||
<dependencies> |
|
||||
|
|
||||
<!-- 通用工具--> |
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-core</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-doc</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-sms</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-mail</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-redis</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-idempotent</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-mybatis</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-log</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-excel</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-security</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-web</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-ratelimiter</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-translation</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-sensitive</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-encrypt</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-tenant</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-websocket</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
</dependencies> |
|
||||
|
|
||||
</project> |
|
||||
@ -1,52 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.mail.utils.MailUtils; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.springframework.validation.annotation.Validated; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
import java.io.File; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 邮件发送案例 |
|
||||
* |
|
||||
* @author Michelle.Chung |
|
||||
*/ |
|
||||
@Validated |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/mail") |
|
||||
public class MailController { |
|
||||
|
|
||||
/** |
|
||||
* 发送邮件 |
|
||||
* |
|
||||
* @param to 接收人 |
|
||||
* @param subject 标题 |
|
||||
* @param text 内容 |
|
||||
*/ |
|
||||
@GetMapping("/sendSimpleMessage") |
|
||||
public R<Void> sendSimpleMessage(String to, String subject, String text) { |
|
||||
MailUtils.sendText(to, subject, text); |
|
||||
return R.ok(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 发送邮件(带附件) |
|
||||
* |
|
||||
* @param to 接收人 |
|
||||
* @param subject 标题 |
|
||||
* @param text 内容 |
|
||||
* @param filePath 附件路径 |
|
||||
*/ |
|
||||
@GetMapping("/sendMessageWithAttachment") |
|
||||
public R<Void> sendMessageWithAttachment(String to, String subject, String text, String filePath) { |
|
||||
MailUtils.sendText(to, subject, text, new File(filePath)); |
|
||||
return R.ok(); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,95 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import org.dromara.common.core.constant.CacheNames; |
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.redis.utils.RedisUtils; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.springframework.cache.annotation.CacheEvict; |
|
||||
import org.springframework.cache.annotation.CachePut; |
|
||||
import org.springframework.cache.annotation.Cacheable; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
import java.time.Duration; |
|
||||
|
|
||||
/** |
|
||||
* spring-cache 演示案例 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
// 类级别 缓存统一配置
|
|
||||
//@CacheConfig(cacheNames = CacheNames.DEMO_CACHE)
|
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/cache") |
|
||||
public class RedisCacheController { |
|
||||
|
|
||||
/** |
|
||||
* 测试 @Cacheable |
|
||||
* <p> |
|
||||
* 表示这个方法有了缓存的功能,方法的返回值会被缓存下来 |
|
||||
* 下一次调用该方法前,会去检查是否缓存中已经有值 |
|
||||
* 如果有就直接返回,不调用方法 |
|
||||
* 如果没有,就调用方法,然后把结果缓存起来 |
|
||||
* 这个注解「一般用在查询方法上」 |
|
||||
* <p> |
|
||||
* 重点说明: 缓存注解严谨与其他筛选数据功能一起使用 |
|
||||
* 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题 |
|
||||
* <p> |
|
||||
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数 |
|
||||
*/ |
|
||||
@Cacheable(cacheNames = "demo:cache#60s#10m#20", key = "#key", condition = "#key != null") |
|
||||
@GetMapping("/test1") |
|
||||
public R<String> test1(String key, String value) { |
|
||||
return R.ok("操作成功", value); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 测试 @CachePut |
|
||||
* <p> |
|
||||
* 加了@CachePut注解的方法,会把方法的返回值put到缓存里面缓存起来,供其它地方使用 |
|
||||
* 它「通常用在新增或者实时更新方法上」 |
|
||||
* <p> |
|
||||
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数 |
|
||||
*/ |
|
||||
@CachePut(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null") |
|
||||
@GetMapping("/test2") |
|
||||
public R<String> test2(String key, String value) { |
|
||||
return R.ok("操作成功", value); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 测试 @CacheEvict |
|
||||
* <p> |
|
||||
* 使用了CacheEvict注解的方法,会清空指定缓存 |
|
||||
* 「一般用在删除的方法上」 |
|
||||
* <p> |
|
||||
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数 |
|
||||
*/ |
|
||||
@CacheEvict(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null") |
|
||||
@GetMapping("/test3") |
|
||||
public R<String> test3(String key, String value) { |
|
||||
return R.ok("操作成功", value); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 测试设置过期时间 |
|
||||
* 手动设置过期时间10秒 |
|
||||
* 11秒后获取 判断是否相等 |
|
||||
*/ |
|
||||
@GetMapping("/test6") |
|
||||
public R<Boolean> test6(String key, String value) { |
|
||||
RedisUtils.setCacheObject(key, value); |
|
||||
boolean flag = RedisUtils.expire(key, Duration.ofSeconds(10)); |
|
||||
System.out.println("***********" + flag); |
|
||||
try { |
|
||||
Thread.sleep(11 * 1000); |
|
||||
} catch (InterruptedException e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
Object obj = RedisUtils.getCacheObject(key); |
|
||||
return R.ok(value.equals(obj)); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,71 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import com.baomidou.lock.LockInfo; |
|
||||
import com.baomidou.lock.LockTemplate; |
|
||||
import com.baomidou.lock.annotation.Lock4j; |
|
||||
import com.baomidou.lock.executor.RedissonLockExecutor; |
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
import java.time.LocalTime; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 测试分布式锁的样例 |
|
||||
* |
|
||||
* @author shenxinquan |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/redisLock") |
|
||||
public class RedisLockController { |
|
||||
|
|
||||
@Autowired |
|
||||
private LockTemplate lockTemplate; |
|
||||
|
|
||||
/** |
|
||||
* 测试lock4j 注解 |
|
||||
*/ |
|
||||
@Lock4j(keys = {"#key"}) |
|
||||
@GetMapping("/testLock4j") |
|
||||
public R<String> testLock4j(String key, String value) { |
|
||||
System.out.println("start:" + key + ",time:" + LocalTime.now().toString()); |
|
||||
try { |
|
||||
Thread.sleep(10000); |
|
||||
} catch (InterruptedException e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
System.out.println("end :" + key + ",time:" + LocalTime.now().toString()); |
|
||||
return R.ok("操作成功", value); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 测试lock4j 工具 |
|
||||
*/ |
|
||||
@GetMapping("/testLock4jLockTemplate") |
|
||||
public R<String> testLock4jLockTemplate(String key, String value) { |
|
||||
final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class); |
|
||||
if (null == lockInfo) { |
|
||||
throw new RuntimeException("业务处理中,请稍后再试"); |
|
||||
} |
|
||||
// 获取锁成功,处理业务
|
|
||||
try { |
|
||||
try { |
|
||||
Thread.sleep(8000); |
|
||||
} catch (InterruptedException e) { |
|
||||
//
|
|
||||
} |
|
||||
System.out.println("执行简单方法1 , 当前线程:" + Thread.currentThread().getName()); |
|
||||
} finally { |
|
||||
//释放锁
|
|
||||
lockTemplate.releaseLock(lockInfo); |
|
||||
} |
|
||||
//结束
|
|
||||
return R.ok("操作成功", value); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,47 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.redis.utils.RedisUtils; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
/** |
|
||||
* Redis 发布订阅 演示案例 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/redis/pubsub") |
|
||||
public class RedisPubSubController { |
|
||||
|
|
||||
/** |
|
||||
* 发布消息 |
|
||||
* |
|
||||
* @param key 通道Key |
|
||||
* @param value 发送内容 |
|
||||
*/ |
|
||||
@GetMapping("/pub") |
|
||||
public R<Void> pub(String key, String value) { |
|
||||
RedisUtils.publish(key, value, consumer -> { |
|
||||
System.out.println("发布通道 => " + key + ", 发送值 => " + value); |
|
||||
}); |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 订阅消息 |
|
||||
* |
|
||||
* @param key 通道Key |
|
||||
*/ |
|
||||
@GetMapping("/sub") |
|
||||
public R<Void> sub(String key) { |
|
||||
RedisUtils.subscribe(key, String.class, msg -> { |
|
||||
System.out.println("订阅通道 => " + key + ", 接收值 => " + msg); |
|
||||
}); |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,64 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.ratelimiter.annotation.RateLimiter; |
|
||||
import org.dromara.common.ratelimiter.enums.LimitType; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 测试分布式限流样例 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/rateLimiter") |
|
||||
public class RedisRateLimiterController { |
|
||||
|
|
||||
/** |
|
||||
* 测试全局限流 |
|
||||
* 全局影响 |
|
||||
*/ |
|
||||
@RateLimiter(count = 2, time = 10) |
|
||||
@GetMapping("/test") |
|
||||
public R<String> test(String value) { |
|
||||
return R.ok("操作成功", value); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 测试请求IP限流 |
|
||||
* 同一IP请求受影响 |
|
||||
*/ |
|
||||
@RateLimiter(count = 2, time = 10, limitType = LimitType.IP) |
|
||||
@GetMapping("/testip") |
|
||||
public R<String> testip(String value) { |
|
||||
return R.ok("操作成功", value); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 测试集群实例限流 |
|
||||
* 启动两个后端服务互不影响 |
|
||||
*/ |
|
||||
@RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER) |
|
||||
@GetMapping("/testcluster") |
|
||||
public R<String> testcluster(String value) { |
|
||||
return R.ok("操作成功", value); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 测试请求IP限流(key基于参数获取) |
|
||||
* 同一IP请求受影响 |
|
||||
* |
|
||||
* 简单变量获取 #变量 复杂表达式 #{#变量 != 1 ? 1 : 0} |
|
||||
*/ |
|
||||
@RateLimiter(count = 2, time = 10, limitType = LimitType.IP, key = "#value") |
|
||||
@GetMapping("/testObj") |
|
||||
public R<String> testObj(String value) { |
|
||||
return R.ok("操作成功", value); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,82 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.sms4j.api.SmsBlend; |
|
||||
import org.dromara.sms4j.api.entity.SmsResponse; |
|
||||
import org.dromara.sms4j.core.factory.SmsFactory; |
|
||||
import org.springframework.validation.annotation.Validated; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
import java.util.LinkedHashMap; |
|
||||
|
|
||||
/** |
|
||||
* 短信演示案例 |
|
||||
* 请先阅读文档 否则无法使用 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @version 4.2.0 |
|
||||
*/ |
|
||||
@Validated |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/sms") |
|
||||
public class SmsController { |
|
||||
/** |
|
||||
* 发送短信Aliyun |
|
||||
* |
|
||||
* @param phones 电话号 |
|
||||
* @param templateId 模板ID |
|
||||
*/ |
|
||||
@GetMapping("/sendAliyun") |
|
||||
public R<Object> sendAliyun(String phones, String templateId) { |
|
||||
LinkedHashMap<String, String> map = new LinkedHashMap<>(1); |
|
||||
map.put("code", "1234"); |
|
||||
SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); |
|
||||
SmsResponse smsResponse = smsBlend.sendMessage(phones, templateId, map); |
|
||||
return R.ok(smsResponse); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 发送短信Tencent |
|
||||
* |
|
||||
* @param phones 电话号 |
|
||||
* @param templateId 模板ID |
|
||||
*/ |
|
||||
@GetMapping("/sendTencent") |
|
||||
public R<Object> sendTencent(String phones, String templateId) { |
|
||||
LinkedHashMap<String, String> map = new LinkedHashMap<>(1); |
|
||||
// map.put("2", "测试测试");
|
|
||||
map.put("1", "1234"); |
|
||||
SmsBlend smsBlend = SmsFactory.getSmsBlend("config2"); |
|
||||
SmsResponse smsResponse = smsBlend.sendMessage(phones, templateId, map); |
|
||||
return R.ok(smsResponse); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 添加黑名单 |
|
||||
* |
|
||||
* @param phone 手机号 |
|
||||
*/ |
|
||||
@GetMapping("/addBlacklist") |
|
||||
public R<Object> addBlacklist(String phone){ |
|
||||
SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); |
|
||||
smsBlend.joinInBlacklist(phone); |
|
||||
return R.ok(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 移除黑名单 |
|
||||
* |
|
||||
* @param phone 手机号 |
|
||||
*/ |
|
||||
@GetMapping("/removeBlacklist") |
|
||||
public R<Object> removeBlacklist(String phone){ |
|
||||
SmsBlend smsBlend = SmsFactory.getSmsBlend("config1"); |
|
||||
smsBlend.removeFromBlacklist(phone); |
|
||||
return R.ok(); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,31 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.springframework.http.MediaType; |
|
||||
import org.springframework.web.bind.annotation.PostMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestPart; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
import org.springframework.web.multipart.MultipartFile; |
|
||||
|
|
||||
/** |
|
||||
* swagger3 用法示例 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@RestController |
|
||||
@RequestMapping("/swagger/demo") |
|
||||
public class Swagger3DemoController { |
|
||||
|
|
||||
/** |
|
||||
* 上传请求 |
|
||||
* 必须使用 @RequestPart 注解标注为文件 |
|
||||
* |
|
||||
* @param file 文件 |
|
||||
*/ |
|
||||
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
|
||||
public R<String> upload(@RequestPart("file") MultipartFile file) { |
|
||||
return R.ok("操作成功", file.getOriginalFilename()); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,90 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.web.core.BaseController; |
|
||||
import org.dromara.demo.domain.TestDemo; |
|
||||
import org.dromara.demo.mapper.TestDemoMapper; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.springframework.web.bind.annotation.DeleteMapping; |
|
||||
import org.springframework.web.bind.annotation.PostMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* 测试批量方法 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-05-30 |
|
||||
*/ |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/batch") |
|
||||
public class TestBatchController extends BaseController { |
|
||||
|
|
||||
/** |
|
||||
* 为了便于测试 直接引入mapper |
|
||||
*/ |
|
||||
private final TestDemoMapper testDemoMapper; |
|
||||
|
|
||||
/** |
|
||||
* 新增批量方法 可完美替代 saveBatch 秒级插入上万数据 (对mysql负荷较大) |
|
||||
* <p> |
|
||||
* 3.5.0 版本 增加 rewriteBatchedStatements=true 批处理参数 使 MP 原生批处理可以达到同样的速度 |
|
||||
*/ |
|
||||
@PostMapping("/add") |
|
||||
// @DS("slave")
|
|
||||
public R<Void> add() { |
|
||||
List<TestDemo> list = new ArrayList<>(); |
|
||||
for (int i = 0; i < 1000; i++) { |
|
||||
TestDemo testDemo = new TestDemo(); |
|
||||
testDemo.setOrderNum(-1); |
|
||||
testDemo.setTestKey("批量新增"); |
|
||||
testDemo.setValue("测试新增"); |
|
||||
list.add(testDemo); |
|
||||
} |
|
||||
return toAjax(testDemoMapper.insertBatch(list)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 新增或更新 可完美替代 saveOrUpdateBatch 高性能 |
|
||||
* <p> |
|
||||
* 3.5.0 版本 增加 rewriteBatchedStatements=true 批处理参数 使 MP 原生批处理可以达到同样的速度 |
|
||||
*/ |
|
||||
@PostMapping("/addOrUpdate") |
|
||||
// @DS("slave")
|
|
||||
public R<Void> addOrUpdate() { |
|
||||
List<TestDemo> list = new ArrayList<>(); |
|
||||
for (int i = 0; i < 1000; i++) { |
|
||||
TestDemo testDemo = new TestDemo(); |
|
||||
testDemo.setOrderNum(-1); |
|
||||
testDemo.setTestKey("批量新增"); |
|
||||
testDemo.setValue("测试新增"); |
|
||||
list.add(testDemo); |
|
||||
} |
|
||||
testDemoMapper.insertBatch(list); |
|
||||
for (int i = 0; i < list.size(); i++) { |
|
||||
TestDemo testDemo = list.get(i); |
|
||||
testDemo.setTestKey("批量新增或修改"); |
|
||||
testDemo.setValue("批量新增或修改"); |
|
||||
if (i % 2 == 0) { |
|
||||
testDemo.setId(null); |
|
||||
} |
|
||||
} |
|
||||
return toAjax(testDemoMapper.insertOrUpdateBatch(list)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 删除批量方法 |
|
||||
*/ |
|
||||
@DeleteMapping() |
|
||||
// @DS("slave")
|
|
||||
public R<Void> remove() { |
|
||||
return toAjax(testDemoMapper.delete(new LambdaQueryWrapper<TestDemo>() |
|
||||
.eq(TestDemo::getOrderNum, -1L))); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,147 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.core.utils.MapstructUtils; |
|
||||
import org.dromara.common.core.utils.ValidatorUtils; |
|
||||
import org.dromara.common.core.validate.AddGroup; |
|
||||
import org.dromara.common.core.validate.EditGroup; |
|
||||
import org.dromara.common.core.validate.QueryGroup; |
|
||||
import org.dromara.common.web.core.BaseController; |
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit; |
|
||||
import org.dromara.common.mybatis.core.page.PageQuery; |
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo; |
|
||||
import org.dromara.common.excel.core.ExcelResult; |
|
||||
import org.dromara.common.excel.utils.ExcelUtil; |
|
||||
import org.dromara.common.log.annotation.Log; |
|
||||
import org.dromara.common.log.enums.BusinessType; |
|
||||
import org.dromara.demo.domain.TestDemo; |
|
||||
import org.dromara.demo.domain.bo.TestDemoBo; |
|
||||
import org.dromara.demo.domain.bo.TestDemoImportVo; |
|
||||
import org.dromara.demo.domain.vo.TestDemoVo; |
|
||||
import org.dromara.demo.service.ITestDemoService; |
|
||||
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 jakarta.servlet.http.HttpServletResponse; |
|
||||
import jakarta.validation.constraints.NotEmpty; |
|
||||
import jakarta.validation.constraints.NotNull; |
|
||||
|
|
||||
import java.util.*; |
|
||||
import java.util.concurrent.TimeUnit; |
|
||||
|
|
||||
/** |
|
||||
* 测试单表Controller |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
@Validated |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/demo") |
|
||||
public class TestDemoController extends BaseController { |
|
||||
|
|
||||
private final ITestDemoService testDemoService; |
|
||||
|
|
||||
/** |
|
||||
* 查询测试单表列表 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:demo:list") |
|
||||
@GetMapping("/list") |
|
||||
public TableDataInfo<TestDemoVo> list(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) { |
|
||||
return testDemoService.queryPageList(bo, pageQuery); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 自定义分页查询 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:demo:list") |
|
||||
@GetMapping("/page") |
|
||||
public TableDataInfo<TestDemoVo> page(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) { |
|
||||
return testDemoService.customPageList(bo, pageQuery); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 导入数据 |
|
||||
* |
|
||||
* @param file 导入文件 |
|
||||
*/ |
|
||||
@Log(title = "测试单表", businessType = BusinessType.IMPORT) |
|
||||
@SaCheckPermission("demo:demo:import") |
|
||||
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
|
||||
public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception { |
|
||||
ExcelResult<TestDemoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true); |
|
||||
List<TestDemo> list = MapstructUtils.convert(excelResult.getList(), TestDemo.class); |
|
||||
testDemoService.saveBatch(list); |
|
||||
return R.ok(excelResult.getAnalysis()); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 导出测试单表列表 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:demo:export") |
|
||||
@Log(title = "测试单表", businessType = BusinessType.EXPORT) |
|
||||
@PostMapping("/export") |
|
||||
public void export(@Validated TestDemoBo bo, HttpServletResponse response) { |
|
||||
List<TestDemoVo> list = testDemoService.queryList(bo); |
|
||||
// 测试雪花id导出
|
|
||||
// for (TestDemoVo vo : list) {
|
|
||||
// vo.setId(1234567891234567893L);
|
|
||||
// }
|
|
||||
ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 获取测试单表详细信息 |
|
||||
* |
|
||||
* @param id 测试ID |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:demo:query") |
|
||||
@GetMapping("/{id}") |
|
||||
public R<TestDemoVo> getInfo(@NotNull(message = "主键不能为空") |
|
||||
@PathVariable("id") Long id) { |
|
||||
return R.ok(testDemoService.queryById(id)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 新增测试单表 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:demo:add") |
|
||||
@Log(title = "测试单表", businessType = BusinessType.INSERT) |
|
||||
@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "{repeat.submit.message}") |
|
||||
@PostMapping() |
|
||||
public R<Void> add(@RequestBody TestDemoBo bo) { |
|
||||
// 使用校验工具对标 @Validated(AddGroup.class) 注解
|
|
||||
// 用于在非 Controller 的地方校验对象
|
|
||||
ValidatorUtils.validate(bo, AddGroup.class); |
|
||||
return toAjax(testDemoService.insertByBo(bo)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 修改测试单表 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:demo:edit") |
|
||||
@Log(title = "测试单表", businessType = BusinessType.UPDATE) |
|
||||
@RepeatSubmit |
|
||||
@PutMapping() |
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TestDemoBo bo) { |
|
||||
return toAjax(testDemoService.updateByBo(bo)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 删除测试单表 |
|
||||
* |
|
||||
* @param ids 测试ID串 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:demo:remove") |
|
||||
@Log(title = "测试单表", businessType = BusinessType.DELETE) |
|
||||
@DeleteMapping("/{ids}") |
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空") |
|
||||
@PathVariable Long[] ids) { |
|
||||
return toAjax(testDemoService.deleteWithValidByIds(Arrays.asList(ids), true)); |
|
||||
} |
|
||||
} |
|
||||
@ -1,55 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.demo.domain.TestDemoEncrypt; |
|
||||
import org.dromara.demo.mapper.TestDemoEncryptMapper; |
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||
import org.springframework.beans.factory.annotation.Value; |
|
||||
import org.springframework.validation.annotation.Validated; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
import java.util.HashMap; |
|
||||
import java.util.Map; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 测试数据库加解密功能 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@Validated |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/encrypt") |
|
||||
public class TestEncryptController { |
|
||||
|
|
||||
@Autowired |
|
||||
private TestDemoEncryptMapper mapper; |
|
||||
@Value("${mybatis-encryptor.enable}") |
|
||||
private Boolean encryptEnable; |
|
||||
|
|
||||
/** |
|
||||
* 测试数据库加解密 |
|
||||
* |
|
||||
* @param key 测试key |
|
||||
* @param value 测试value |
|
||||
*/ |
|
||||
@GetMapping() |
|
||||
public R<Map<String, TestDemoEncrypt>> test(String key, String value) { |
|
||||
if (!encryptEnable) { |
|
||||
throw new RuntimeException("加密功能未开启!"); |
|
||||
} |
|
||||
Map<String, TestDemoEncrypt> map = new HashMap<>(2); |
|
||||
TestDemoEncrypt demo = new TestDemoEncrypt(); |
|
||||
demo.setTestKey(key); |
|
||||
demo.setValue(value); |
|
||||
mapper.insert(demo); |
|
||||
map.put("加密", demo); |
|
||||
TestDemoEncrypt testDemo = mapper.selectById(demo.getId()); |
|
||||
map.put("解密", testDemo); |
|
||||
return R.ok(map); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
} |
|
||||
@ -1,160 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import cn.hutool.core.collection.CollUtil; |
|
||||
import jakarta.servlet.http.HttpServletResponse; |
|
||||
import lombok.AllArgsConstructor; |
|
||||
import lombok.Data; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.dromara.common.excel.core.ExcelResult; |
|
||||
import org.dromara.common.excel.utils.ExcelUtil; |
|
||||
import org.dromara.demo.domain.vo.ExportDemoVo; |
|
||||
import org.dromara.demo.listener.ExportDemoListener; |
|
||||
import org.dromara.demo.service.IExportExcelService; |
|
||||
import org.springframework.http.MediaType; |
|
||||
import org.springframework.web.bind.annotation.*; |
|
||||
import org.springframework.web.multipart.MultipartFile; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
import java.util.HashMap; |
|
||||
import java.util.List; |
|
||||
import java.util.Map; |
|
||||
|
|
||||
/** |
|
||||
* 测试Excel功能 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/excel") |
|
||||
public class TestExcelController { |
|
||||
|
|
||||
private final IExportExcelService exportExcelService; |
|
||||
|
|
||||
/** |
|
||||
* 单列表多数据 |
|
||||
*/ |
|
||||
@GetMapping("/exportTemplateOne") |
|
||||
public void exportTemplateOne(HttpServletResponse response) { |
|
||||
Map<String, String> map = new HashMap<>(); |
|
||||
map.put("title", "单列表多数据"); |
|
||||
map.put("test1", "数据测试1"); |
|
||||
map.put("test2", "数据测试2"); |
|
||||
map.put("test3", "数据测试3"); |
|
||||
map.put("test4", "数据测试4"); |
|
||||
map.put("testTest", "666"); |
|
||||
List<TestObj> list = new ArrayList<>(); |
|
||||
list.add(new TestObj("单列表测试1", "列表测试1", "列表测试2", "列表测试3", "列表测试4")); |
|
||||
list.add(new TestObj("单列表测试2", "列表测试5", "列表测试6", "列表测试7", "列表测试8")); |
|
||||
list.add(new TestObj("单列表测试3", "列表测试9", "列表测试10", "列表测试11", "列表测试12")); |
|
||||
ExcelUtil.exportTemplate(CollUtil.newArrayList(map, list), "单列表.xlsx", "excel/单列表.xlsx", response); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 多列表多数据 |
|
||||
*/ |
|
||||
@GetMapping("/exportTemplateMuliti") |
|
||||
public void exportTemplateMuliti(HttpServletResponse response) { |
|
||||
Map<String, String> map = new HashMap<>(); |
|
||||
map.put("title1", "标题1"); |
|
||||
map.put("title2", "标题2"); |
|
||||
map.put("title3", "标题3"); |
|
||||
map.put("title4", "标题4"); |
|
||||
map.put("author", "Lion Li"); |
|
||||
List<TestObj1> list1 = new ArrayList<>(); |
|
||||
list1.add(new TestObj1("list1测试1", "list1测试2", "list1测试3")); |
|
||||
list1.add(new TestObj1("list1测试4", "list1测试5", "list1测试6")); |
|
||||
list1.add(new TestObj1("list1测试7", "list1测试8", "list1测试9")); |
|
||||
List<TestObj1> list2 = new ArrayList<>(); |
|
||||
list2.add(new TestObj1("list2测试1", "list2测试2", "list2测试3")); |
|
||||
list2.add(new TestObj1("list2测试4", "list2测试5", "list2测试6")); |
|
||||
List<TestObj1> list3 = new ArrayList<>(); |
|
||||
list3.add(new TestObj1("list3测试1", "list3测试2", "list3测试3")); |
|
||||
List<TestObj1> list4 = new ArrayList<>(); |
|
||||
list4.add(new TestObj1("list4测试1", "list4测试2", "list4测试3")); |
|
||||
list4.add(new TestObj1("list4测试4", "list4测试5", "list4测试6")); |
|
||||
list4.add(new TestObj1("list4测试7", "list4测试8", "list4测试9")); |
|
||||
list4.add(new TestObj1("list4测试10", "list4测试11", "list4测试12")); |
|
||||
Map<String, Object> multiListMap = new HashMap<>(); |
|
||||
multiListMap.put("map", map); |
|
||||
multiListMap.put("data1", list1); |
|
||||
multiListMap.put("data2", list2); |
|
||||
multiListMap.put("data3", list3); |
|
||||
multiListMap.put("data4", list4); |
|
||||
ExcelUtil.exportTemplateMultiList(multiListMap, "多列表.xlsx", "excel/多列表.xlsx", response); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 导出下拉框 |
|
||||
* |
|
||||
* @param response / |
|
||||
*/ |
|
||||
@GetMapping("/exportWithOptions") |
|
||||
public void exportWithOptions(HttpServletResponse response) { |
|
||||
exportExcelService.exportWithOptions(response); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 多个sheet导出 |
|
||||
*/ |
|
||||
@GetMapping("/exportTemplateMultiSheet") |
|
||||
public void exportTemplateMultiSheet(HttpServletResponse response) { |
|
||||
List<TestObj1> list1 = new ArrayList<>(); |
|
||||
list1.add(new TestObj1("list1测试1", "list1测试2", "list1测试3")); |
|
||||
list1.add(new TestObj1("list1测试4", "list1测试5", "list1测试6")); |
|
||||
List<TestObj1> list2 = new ArrayList<>(); |
|
||||
list2.add(new TestObj1("list2测试1", "list2测试2", "list2测试3")); |
|
||||
list2.add(new TestObj1("list2测试4", "list2测试5", "list2测试6")); |
|
||||
List<TestObj1> list3 = new ArrayList<>(); |
|
||||
list3.add(new TestObj1("list3测试1", "list3测试2", "list3测试3")); |
|
||||
list3.add(new TestObj1("list3测试4", "list3测试5", "list3测试6")); |
|
||||
List<TestObj1> list4 = new ArrayList<>(); |
|
||||
list4.add(new TestObj1("list4测试1", "list4测试2", "list4测试3")); |
|
||||
list4.add(new TestObj1("list4测试4", "list4测试5", "list4测试6")); |
|
||||
|
|
||||
List<Map<String, Object>> list = new ArrayList<>(); |
|
||||
Map<String, Object> sheetMap1 = new HashMap<>(); |
|
||||
sheetMap1.put("data1", list1); |
|
||||
Map<String, Object> sheetMap2 = new HashMap<>(); |
|
||||
sheetMap2.put("data2", list2); |
|
||||
Map<String, Object> sheetMap3 = new HashMap<>(); |
|
||||
sheetMap3.put("data3", list3); |
|
||||
Map<String, Object> sheetMap4 = new HashMap<>(); |
|
||||
sheetMap4.put("data4", list4); |
|
||||
|
|
||||
list.add(sheetMap1); |
|
||||
list.add(sheetMap2); |
|
||||
list.add(sheetMap3); |
|
||||
list.add(sheetMap4); |
|
||||
ExcelUtil.exportTemplateMultiSheet(list, "多sheet列表", "excel/多sheet列表.xlsx", response); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 导入表格 |
|
||||
*/ |
|
||||
@PostMapping(value = "/importWithOptions", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
|
||||
public List<ExportDemoVo> importWithOptions(@RequestPart("file") MultipartFile file) throws Exception { |
|
||||
// 处理解析结果
|
|
||||
ExcelResult<ExportDemoVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), ExportDemoVo.class, new ExportDemoListener()); |
|
||||
return excelResult.getList(); |
|
||||
} |
|
||||
|
|
||||
@Data |
|
||||
@AllArgsConstructor |
|
||||
static class TestObj1 { |
|
||||
private String test1; |
|
||||
private String test2; |
|
||||
private String test3; |
|
||||
} |
|
||||
|
|
||||
@Data |
|
||||
@AllArgsConstructor |
|
||||
static class TestObj { |
|
||||
private String name; |
|
||||
private String list1; |
|
||||
private String list2; |
|
||||
private String list3; |
|
||||
private String list4; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,71 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.core.utils.MessageUtils; |
|
||||
import lombok.Data; |
|
||||
import org.hibernate.validator.constraints.Range; |
|
||||
import org.springframework.validation.annotation.Validated; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
import jakarta.validation.constraints.NotBlank; |
|
||||
import jakarta.validation.constraints.NotNull; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 测试国际化 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
@Validated |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/i18n") |
|
||||
public class TestI18nController { |
|
||||
|
|
||||
/** |
|
||||
* 通过code获取国际化内容 |
|
||||
* code为 messages.properties 中的 key |
|
||||
* <p> |
|
||||
* 测试使用 user.register.success |
|
||||
* |
|
||||
* @param code 国际化code |
|
||||
*/ |
|
||||
@GetMapping() |
|
||||
public R<Void> get(String code) { |
|
||||
return R.ok(MessageUtils.message(code)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Validator 校验国际化 |
|
||||
* 不传值 分别查看异常返回 |
|
||||
* <p> |
|
||||
* 测试使用 not.null |
|
||||
*/ |
|
||||
@GetMapping("/test1") |
|
||||
public R<Void> test1(@NotBlank(message = "{not.null}") String str) { |
|
||||
return R.ok(str); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Bean 校验国际化 |
|
||||
* 不传值 分别查看异常返回 |
|
||||
* <p> |
|
||||
* 测试使用 not.null |
|
||||
*/ |
|
||||
@GetMapping("/test2") |
|
||||
public R<TestI18nBo> test2(@Validated TestI18nBo bo) { |
|
||||
return R.ok(bo); |
|
||||
} |
|
||||
|
|
||||
@Data |
|
||||
public static class TestI18nBo { |
|
||||
|
|
||||
@NotBlank(message = "{not.null}") |
|
||||
private String name; |
|
||||
|
|
||||
@NotNull(message = "{not.null}") |
|
||||
@Range(min = 0, max = 100, message = "{length.not.valid}") |
|
||||
private Integer age; |
|
||||
} |
|
||||
} |
|
||||
@ -1,76 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.web.core.BaseController; |
|
||||
import org.dromara.common.sensitive.annotation.Sensitive; |
|
||||
import org.dromara.common.sensitive.core.SensitiveStrategy; |
|
||||
import lombok.Data; |
|
||||
import org.dromara.common.sensitive.core.SensitiveService; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
/** |
|
||||
* 测试数据脱敏控制器 |
|
||||
* <p> |
|
||||
* 默认管理员不过滤 |
|
||||
* 需自行根据业务重写实现 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @version 3.6.0 |
|
||||
* @see SensitiveService |
|
||||
*/ |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/sensitive") |
|
||||
public class TestSensitiveController extends BaseController { |
|
||||
|
|
||||
/** |
|
||||
* 测试数据脱敏 |
|
||||
*/ |
|
||||
@GetMapping("/test") |
|
||||
public R<TestSensitive> test() { |
|
||||
TestSensitive testSensitive = new TestSensitive(); |
|
||||
testSensitive.setIdCard("210397198608215431"); |
|
||||
testSensitive.setPhone("17640125371"); |
|
||||
testSensitive.setAddress("北京市朝阳区某某四合院1203室"); |
|
||||
testSensitive.setEmail("17640125371@163.com"); |
|
||||
testSensitive.setBankCard("6226456952351452853"); |
|
||||
return R.ok(testSensitive); |
|
||||
} |
|
||||
|
|
||||
@Data |
|
||||
static class TestSensitive { |
|
||||
|
|
||||
/** |
|
||||
* 身份证 |
|
||||
*/ |
|
||||
@Sensitive(strategy = SensitiveStrategy.ID_CARD) |
|
||||
private String idCard; |
|
||||
|
|
||||
/** |
|
||||
* 电话 |
|
||||
*/ |
|
||||
@Sensitive(strategy = SensitiveStrategy.PHONE, roleKey = "common") |
|
||||
private String phone; |
|
||||
|
|
||||
/** |
|
||||
* 地址 |
|
||||
*/ |
|
||||
@Sensitive(strategy = SensitiveStrategy.ADDRESS, perms = "system:user:query") |
|
||||
private String address; |
|
||||
|
|
||||
/** |
|
||||
* 邮箱 |
|
||||
*/ |
|
||||
@Sensitive(strategy = SensitiveStrategy.EMAIL, roleKey = "common", perms = "system:user:query1") |
|
||||
private String email; |
|
||||
|
|
||||
/** |
|
||||
* 银行卡 |
|
||||
*/ |
|
||||
@Sensitive(strategy = SensitiveStrategy.BANK_CARD, roleKey = "common1", perms = "system:user:query") |
|
||||
private String bankCard; |
|
||||
|
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,107 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.core.validate.AddGroup; |
|
||||
import org.dromara.common.core.validate.EditGroup; |
|
||||
import org.dromara.common.core.validate.QueryGroup; |
|
||||
import org.dromara.common.web.core.BaseController; |
|
||||
import org.dromara.common.excel.utils.ExcelUtil; |
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit; |
|
||||
import org.dromara.common.log.annotation.Log; |
|
||||
import org.dromara.common.log.enums.BusinessType; |
|
||||
import org.dromara.demo.domain.bo.TestTreeBo; |
|
||||
import org.dromara.demo.domain.vo.TestTreeVo; |
|
||||
import org.dromara.demo.service.ITestTreeService; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.springframework.validation.annotation.Validated; |
|
||||
import org.springframework.web.bind.annotation.*; |
|
||||
|
|
||||
import jakarta.servlet.http.HttpServletResponse; |
|
||||
import jakarta.validation.constraints.NotEmpty; |
|
||||
import jakarta.validation.constraints.NotNull; |
|
||||
import java.util.Arrays; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* 测试树表Controller |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
@Validated |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/tree") |
|
||||
public class TestTreeController extends BaseController { |
|
||||
|
|
||||
private final ITestTreeService testTreeService; |
|
||||
|
|
||||
/** |
|
||||
* 查询测试树表列表 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:tree:list") |
|
||||
@GetMapping("/list") |
|
||||
public R<List<TestTreeVo>> list(@Validated(QueryGroup.class) TestTreeBo bo) { |
|
||||
List<TestTreeVo> list = testTreeService.queryList(bo); |
|
||||
return R.ok(list); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 导出测试树表列表 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:tree:export") |
|
||||
@Log(title = "测试树表", businessType = BusinessType.EXPORT) |
|
||||
@GetMapping("/export") |
|
||||
public void export(@Validated TestTreeBo bo, HttpServletResponse response) { |
|
||||
List<TestTreeVo> list = testTreeService.queryList(bo); |
|
||||
ExcelUtil.exportExcel(list, "测试树表", TestTreeVo.class, response); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 获取测试树表详细信息 |
|
||||
* |
|
||||
* @param id 测试树ID |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:tree:query") |
|
||||
@GetMapping("/{id}") |
|
||||
public R<TestTreeVo> getInfo(@NotNull(message = "主键不能为空") |
|
||||
@PathVariable("id") Long id) { |
|
||||
return R.ok(testTreeService.queryById(id)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 新增测试树表 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:tree:add") |
|
||||
@Log(title = "测试树表", businessType = BusinessType.INSERT) |
|
||||
@RepeatSubmit |
|
||||
@PostMapping() |
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody TestTreeBo bo) { |
|
||||
return toAjax(testTreeService.insertByBo(bo)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 修改测试树表 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:tree:edit") |
|
||||
@Log(title = "测试树表", businessType = BusinessType.UPDATE) |
|
||||
@RepeatSubmit |
|
||||
@PutMapping() |
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TestTreeBo bo) { |
|
||||
return toAjax(testTreeService.updateByBo(bo)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 删除测试树表 |
|
||||
* |
|
||||
* @param ids 测试树ID串 |
|
||||
*/ |
|
||||
@SaCheckPermission("demo:tree:remove") |
|
||||
@Log(title = "测试树表", businessType = BusinessType.DELETE) |
|
||||
@DeleteMapping("/{ids}") |
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空") |
|
||||
@PathVariable Long[] ids) { |
|
||||
return toAjax(testTreeService.deleteWithValidByIds(Arrays.asList(ids), true)); |
|
||||
} |
|
||||
} |
|
||||
@ -1,33 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
|
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.websocket.dto.WebSocketMessageDto; |
|
||||
import org.dromara.common.websocket.utils.WebSocketUtils; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
/** |
|
||||
* WebSocket 演示案例 |
|
||||
* |
|
||||
* @author zendwang |
|
||||
*/ |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/websocket") |
|
||||
@Slf4j |
|
||||
public class WeSocketController { |
|
||||
|
|
||||
/** |
|
||||
* 发布消息 |
|
||||
* |
|
||||
* @param dto 发送内容 |
|
||||
*/ |
|
||||
@GetMapping("/send") |
|
||||
public R<Void> send(WebSocketMessageDto dto) throws InterruptedException { |
|
||||
WebSocketUtils.publishMessage(dto); |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
} |
|
||||
@ -1 +0,0 @@ |
|||||
package org.dromara.demo.controller; |
|
||||
@ -1,92 +0,0 @@ |
|||||
package org.dromara.demo.controller.queue; |
|
||||
|
|
||||
import cn.dev33.satoken.annotation.SaIgnore; |
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.redis.utils.QueueUtils; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.redisson.api.RBoundedBlockingQueue; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
/** |
|
||||
* 有界队列 演示案例 |
|
||||
* <p> |
|
||||
* 轻量级队列 重量级数据量 请使用 MQ |
|
||||
* <p> |
|
||||
* 集群测试通过 同一个数据只会被消费一次 做好事务补偿 |
|
||||
* 集群测试流程 在其中一台发送数据 两端分别调用获取接口 一次获取一条 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @version 3.6.0 |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/queue/bounded") |
|
||||
public class BoundedQueueController { |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 添加队列数据 |
|
||||
* |
|
||||
* @param queueName 队列名 |
|
||||
* @param capacity 容量 |
|
||||
*/ |
|
||||
@GetMapping("/add") |
|
||||
public R<Void> add(String queueName, int capacity) { |
|
||||
// 用完了一定要销毁 否则会一直存在
|
|
||||
boolean b = QueueUtils.destroyBoundedQueue(queueName); |
|
||||
log.info("通道: {} , 删除: {}", queueName, b); |
|
||||
// 初始化设置一次即可
|
|
||||
if (QueueUtils.trySetBoundedQueueCapacity(queueName, capacity)) { |
|
||||
log.info("通道: {} , 设置容量: {}", queueName, capacity); |
|
||||
} else { |
|
||||
log.info("通道: {} , 设置容量失败", queueName); |
|
||||
return R.fail("操作失败"); |
|
||||
} |
|
||||
for (int i = 0; i < 11; i++) { |
|
||||
String data = "data-" + i; |
|
||||
boolean flag = QueueUtils.addBoundedQueueObject(queueName, data); |
|
||||
if (flag == false) { |
|
||||
log.info("通道: {} , 发送数据: {} 失败, 通道已满", queueName, data); |
|
||||
} else { |
|
||||
log.info("通道: {} , 发送数据: {}", queueName, data); |
|
||||
} |
|
||||
} |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 删除队列数据 |
|
||||
* |
|
||||
* @param queueName 队列名 |
|
||||
*/ |
|
||||
@GetMapping("/remove") |
|
||||
public R<Void> remove(String queueName) { |
|
||||
String data = "data-" + 5; |
|
||||
if (QueueUtils.removeBoundedQueueObject(queueName, data)) { |
|
||||
log.info("通道: {} , 删除数据: {}", queueName, data); |
|
||||
} else { |
|
||||
return R.fail("操作失败"); |
|
||||
} |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 获取队列数据 |
|
||||
* |
|
||||
* @param queueName 队列名 |
|
||||
*/ |
|
||||
@GetMapping("/get") |
|
||||
public R<Void> get(String queueName) { |
|
||||
String data; |
|
||||
do { |
|
||||
data = QueueUtils.getBoundedQueueObject(queueName); |
|
||||
log.info("通道: {} , 获取数据: {}", queueName, data); |
|
||||
} while (data != null); |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,97 +0,0 @@ |
|||||
package org.dromara.demo.controller.queue; |
|
||||
|
|
||||
import cn.dev33.satoken.annotation.SaIgnore; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.redis.utils.QueueUtils; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
import java.util.concurrent.CompletableFuture; |
|
||||
import java.util.concurrent.TimeUnit; |
|
||||
|
|
||||
/** |
|
||||
* 延迟队列 演示案例 |
|
||||
* <p> |
|
||||
* 轻量级队列 重量级数据量 请使用 MQ |
|
||||
* 例如: 创建订单30分钟后过期处理 |
|
||||
* <p> |
|
||||
* 集群测试通过 同一个数据只会被消费一次 做好事务补偿 |
|
||||
* 集群测试流程 两台集群分别开启订阅 在其中一台发送数据 观察接收消息的规律 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @version 3.6.0 |
|
||||
*/ |
|
||||
@SaIgnore |
|
||||
@Slf4j |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/queue/delayed") |
|
||||
public class DelayedQueueController { |
|
||||
|
|
||||
/** |
|
||||
* 订阅队列 |
|
||||
* |
|
||||
* @param queueName 队列名 |
|
||||
*/ |
|
||||
@GetMapping("/subscribe") |
|
||||
public R<Void> subscribe(String queueName) { |
|
||||
log.info("通道: {} 监听中......", queueName); |
|
||||
// 项目初始化设置一次即可
|
|
||||
QueueUtils.subscribeBlockingQueue(queueName, (String orderNum) -> { |
|
||||
// 观察接收时间
|
|
||||
log.info("通道: {}, 收到数据: {}", queueName, orderNum); |
|
||||
return CompletableFuture.runAsync(() -> { |
|
||||
// 异步处理数据逻辑 不要在上方处理业务逻辑
|
|
||||
log.info("数据处理: {}", orderNum); |
|
||||
}); |
|
||||
}, true); |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 添加队列数据 |
|
||||
* |
|
||||
* @param queueName 队列名 |
|
||||
* @param orderNum 订单号 |
|
||||
* @param time 延迟时间(秒) |
|
||||
*/ |
|
||||
@GetMapping("/add") |
|
||||
public R<Void> add(String queueName, String orderNum, Long time) { |
|
||||
QueueUtils.addDelayedQueueObject(queueName, orderNum, time, TimeUnit.SECONDS); |
|
||||
// 观察发送时间
|
|
||||
log.info("通道: {} , 发送数据: {}", queueName, orderNum); |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 删除队列数据 |
|
||||
* |
|
||||
* @param queueName 队列名 |
|
||||
* @param orderNum 订单号 |
|
||||
*/ |
|
||||
@GetMapping("/remove") |
|
||||
public R<Void> remove(String queueName, String orderNum) { |
|
||||
if (QueueUtils.removeDelayedQueueObject(queueName, orderNum)) { |
|
||||
log.info("通道: {} , 删除数据: {}", queueName, orderNum); |
|
||||
} else { |
|
||||
return R.fail("操作失败"); |
|
||||
} |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 销毁队列 |
|
||||
* |
|
||||
* @param queueName 队列名 |
|
||||
*/ |
|
||||
@GetMapping("/destroy") |
|
||||
public R<Void> destroy(String queueName) { |
|
||||
// 用完了一定要销毁 否则会一直存在
|
|
||||
QueueUtils.destroyDelayedQueue(queueName); |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,22 +0,0 @@ |
|||||
package org.dromara.demo.controller.queue; |
|
||||
|
|
||||
import lombok.Data; |
|
||||
import lombok.NoArgsConstructor; |
|
||||
|
|
||||
/** |
|
||||
* 实体类 注意不允许使用内部类 否则会找不到类 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @version 3.6.0 |
|
||||
*/ |
|
||||
@Data |
|
||||
@NoArgsConstructor |
|
||||
public class PriorityDemo implements Comparable<PriorityDemo> { |
|
||||
private String name; |
|
||||
private Integer orderNum; |
|
||||
|
|
||||
@Override |
|
||||
public int compareTo(PriorityDemo other) { |
|
||||
return Integer.compare(getOrderNum(), other.getOrderNum()); |
|
||||
} |
|
||||
} |
|
||||
@ -1,89 +0,0 @@ |
|||||
package org.dromara.demo.controller.queue; |
|
||||
|
|
||||
import cn.hutool.core.util.RandomUtil; |
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.redis.utils.QueueUtils; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.web.bind.annotation.RestController; |
|
||||
|
|
||||
/** |
|
||||
* 优先队列 演示案例 |
|
||||
* <p> |
|
||||
* 轻量级队列 重量级数据量 请使用 MQ |
|
||||
* <p> |
|
||||
* 集群测试通过 同一个消息只会被消费一次 做好事务补偿 |
|
||||
* 集群测试流程 在其中一台发送数据 两端分别调用获取接口 一次获取一条 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @version 3.6.0 |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/demo/queue/priority") |
|
||||
public class PriorityQueueController { |
|
||||
|
|
||||
/** |
|
||||
* 添加队列数据 |
|
||||
* |
|
||||
* @param queueName 队列名 |
|
||||
*/ |
|
||||
@GetMapping("/add") |
|
||||
public R<Void> add(String queueName) { |
|
||||
// 用完了一定要销毁 否则会一直存在
|
|
||||
boolean b = QueueUtils.destroyPriorityQueue(queueName); |
|
||||
log.info("通道: {} , 删除: {}", queueName, b); |
|
||||
|
|
||||
for (int i = 0; i < 10; i++) { |
|
||||
int randomNum = RandomUtil.randomInt(10); |
|
||||
PriorityDemo data = new PriorityDemo(); |
|
||||
data.setName("data-" + i); |
|
||||
data.setOrderNum(randomNum); |
|
||||
if (QueueUtils.addPriorityQueueObject(queueName, data)) { |
|
||||
log.info("通道: {} , 发送数据: {}", queueName, data); |
|
||||
} else { |
|
||||
log.info("通道: {} , 发送数据: {}, 发送失败", queueName, data); |
|
||||
} |
|
||||
} |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 删除队列数据 |
|
||||
* |
|
||||
* @param queueName 队列名 |
|
||||
* @param name 对象名 |
|
||||
* @param orderNum 排序号 |
|
||||
*/ |
|
||||
@GetMapping("/remove") |
|
||||
public R<Void> remove(String queueName, String name, Integer orderNum) { |
|
||||
PriorityDemo data = new PriorityDemo(); |
|
||||
data.setName(name); |
|
||||
data.setOrderNum(orderNum); |
|
||||
if (QueueUtils.removePriorityQueueObject(queueName, data)) { |
|
||||
log.info("通道: {} , 删除数据: {}", queueName, data); |
|
||||
} else { |
|
||||
return R.fail("操作失败"); |
|
||||
} |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 获取队列数据 |
|
||||
* |
|
||||
* @param queueName 队列名 |
|
||||
*/ |
|
||||
@GetMapping("/get") |
|
||||
public R<Void> get(String queueName) { |
|
||||
PriorityDemo data; |
|
||||
do { |
|
||||
data = QueueUtils.getPriorityQueueObject(queueName); |
|
||||
log.info("通道: {} , 获取数据: {}", queueName, data); |
|
||||
} while (data != null); |
|
||||
return R.ok("操作成功"); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,68 +0,0 @@ |
|||||
package org.dromara.demo.domain; |
|
||||
|
|
||||
import com.baomidou.mybatisplus.annotation.*; |
|
||||
import org.dromara.common.tenant.core.TenantEntity; |
|
||||
import lombok.Data; |
|
||||
import lombok.EqualsAndHashCode; |
|
||||
|
|
||||
import java.io.Serial; |
|
||||
|
|
||||
/** |
|
||||
* 测试单表对象 test_demo |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
@Data |
|
||||
@EqualsAndHashCode(callSuper = true) |
|
||||
@TableName("test_demo") |
|
||||
public class TestDemo extends TenantEntity { |
|
||||
|
|
||||
@Serial |
|
||||
private static final long serialVersionUID = 1L; |
|
||||
|
|
||||
/** |
|
||||
* 主键 |
|
||||
*/ |
|
||||
@TableId(value = "id") |
|
||||
private Long id; |
|
||||
|
|
||||
/** |
|
||||
* 部门id |
|
||||
*/ |
|
||||
private Long deptId; |
|
||||
|
|
||||
/** |
|
||||
* 用户id |
|
||||
*/ |
|
||||
private Long userId; |
|
||||
|
|
||||
/** |
|
||||
* 排序号 |
|
||||
*/ |
|
||||
@OrderBy(asc = false, sort = 1) |
|
||||
private Integer orderNum; |
|
||||
|
|
||||
/** |
|
||||
* key键 |
|
||||
*/ |
|
||||
private String testKey; |
|
||||
|
|
||||
/** |
|
||||
* 值 |
|
||||
*/ |
|
||||
private String value; |
|
||||
|
|
||||
/** |
|
||||
* 版本 |
|
||||
*/ |
|
||||
@Version |
|
||||
private Long version; |
|
||||
|
|
||||
/** |
|
||||
* 删除标志 |
|
||||
*/ |
|
||||
@TableLogic |
|
||||
private Long delFlag; |
|
||||
|
|
||||
} |
|
||||
@ -1,29 +0,0 @@ |
|||||
package org.dromara.demo.domain; |
|
||||
|
|
||||
import com.baomidou.mybatisplus.annotation.TableName; |
|
||||
import org.dromara.common.encrypt.annotation.EncryptField; |
|
||||
import org.dromara.common.encrypt.enumd.AlgorithmType; |
|
||||
import lombok.Data; |
|
||||
import lombok.EqualsAndHashCode; |
|
||||
|
|
||||
@Data |
|
||||
@EqualsAndHashCode(callSuper = true) |
|
||||
@TableName("test_demo") |
|
||||
public class TestDemoEncrypt extends TestDemo { |
|
||||
|
|
||||
/** |
|
||||
* key键 |
|
||||
*/ |
|
||||
// @EncryptField(algorithm=AlgorithmType.SM2, privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgZSlOvw8FBiH+aFJWLYZP/VRjg9wjfRarTkGBZd/T3N+gCgYIKoEcz1UBgi2hRANCAAR5DGuQwJqkxnbCsP+iPSDoHWIF4RwcR5EsSvT8QPxO1wRkR2IhCkzvRb32x2CUgJFdvoqVqfApFDPZzShqzBwX", publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEeQxrkMCapMZ2wrD/oj0g6B1iBeEcHEeRLEr0/ED8TtcEZEdiIQpM70W99sdglICRXb6KlanwKRQz2c0oaswcFw==")
|
|
||||
@EncryptField(algorithm = AlgorithmType.RSA, 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") |
|
||||
private String testKey; |
|
||||
|
|
||||
/** |
|
||||
* 值 |
|
||||
*/ |
|
||||
// @EncryptField // 什么也不写走默认yml配置
|
|
||||
// @EncryptField(algorithm = AlgorithmType.SM4, password = "10rfylhtccpuyke5")
|
|
||||
@EncryptField(algorithm = AlgorithmType.AES, password = "10rfylhtccpuyke5") |
|
||||
private String value; |
|
||||
|
|
||||
} |
|
||||
@ -1,65 +0,0 @@ |
|||||
package org.dromara.demo.domain; |
|
||||
|
|
||||
import com.baomidou.mybatisplus.annotation.TableId; |
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic; |
|
||||
import com.baomidou.mybatisplus.annotation.TableName; |
|
||||
import com.baomidou.mybatisplus.annotation.Version; |
|
||||
import org.dromara.common.tenant.core.TenantEntity; |
|
||||
import lombok.Data; |
|
||||
import lombok.EqualsAndHashCode; |
|
||||
|
|
||||
import java.io.Serial; |
|
||||
|
|
||||
/** |
|
||||
* 测试树表对象 test_tree |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
@Data |
|
||||
@EqualsAndHashCode(callSuper = true) |
|
||||
@TableName("test_tree") |
|
||||
public class TestTree extends TenantEntity { |
|
||||
|
|
||||
@Serial |
|
||||
private static final long serialVersionUID = 1L; |
|
||||
|
|
||||
/** |
|
||||
* 主键 |
|
||||
*/ |
|
||||
@TableId(value = "id") |
|
||||
private Long id; |
|
||||
|
|
||||
/** |
|
||||
* 父ID |
|
||||
*/ |
|
||||
private Long parentId; |
|
||||
|
|
||||
/** |
|
||||
* 部门id |
|
||||
*/ |
|
||||
private Long deptId; |
|
||||
|
|
||||
/** |
|
||||
* 用户id |
|
||||
*/ |
|
||||
private Long userId; |
|
||||
|
|
||||
/** |
|
||||
* 树节点名 |
|
||||
*/ |
|
||||
private String treeName; |
|
||||
|
|
||||
/** |
|
||||
* 版本 |
|
||||
*/ |
|
||||
@Version |
|
||||
private Long version; |
|
||||
|
|
||||
/** |
|
||||
* 删除标志 |
|
||||
*/ |
|
||||
@TableLogic |
|
||||
private Long delFlag; |
|
||||
|
|
||||
} |
|
||||
@ -1,62 +0,0 @@ |
|||||
package org.dromara.demo.domain.bo; |
|
||||
|
|
||||
import org.dromara.common.core.validate.AddGroup; |
|
||||
import org.dromara.common.core.validate.EditGroup; |
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity; |
|
||||
import org.dromara.demo.domain.TestDemo; |
|
||||
import io.github.linpeilie.annotations.AutoMapper; |
|
||||
import lombok.Data; |
|
||||
import lombok.EqualsAndHashCode; |
|
||||
|
|
||||
import jakarta.validation.constraints.NotBlank; |
|
||||
import jakarta.validation.constraints.NotNull; |
|
||||
|
|
||||
/** |
|
||||
* 测试单表业务对象 test_demo |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
|
|
||||
@Data |
|
||||
@EqualsAndHashCode(callSuper = true) |
|
||||
@AutoMapper(target = TestDemo.class, reverseConvertGenerate = false) |
|
||||
public class TestDemoBo extends BaseEntity { |
|
||||
|
|
||||
/** |
|
||||
* 主键 |
|
||||
*/ |
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class}) |
|
||||
private Long id; |
|
||||
|
|
||||
/** |
|
||||
* 部门id |
|
||||
*/ |
|
||||
@NotNull(message = "部门id不能为空", groups = {AddGroup.class, EditGroup.class}) |
|
||||
private Long deptId; |
|
||||
|
|
||||
/** |
|
||||
* 用户id |
|
||||
*/ |
|
||||
@NotNull(message = "用户id不能为空", groups = {AddGroup.class, EditGroup.class}) |
|
||||
private Long userId; |
|
||||
|
|
||||
/** |
|
||||
* 排序号 |
|
||||
*/ |
|
||||
@NotNull(message = "排序号不能为空", groups = {AddGroup.class, EditGroup.class}) |
|
||||
private Integer orderNum; |
|
||||
|
|
||||
/** |
|
||||
* key键 |
|
||||
*/ |
|
||||
@NotBlank(message = "key键不能为空", groups = {AddGroup.class, EditGroup.class}) |
|
||||
private String testKey; |
|
||||
|
|
||||
/** |
|
||||
* 值 |
|
||||
*/ |
|
||||
@NotBlank(message = "值不能为空", groups = {AddGroup.class, EditGroup.class}) |
|
||||
private String value; |
|
||||
|
|
||||
} |
|
||||
@ -1,53 +0,0 @@ |
|||||
package org.dromara.demo.domain.bo; |
|
||||
|
|
||||
import com.alibaba.excel.annotation.ExcelProperty; |
|
||||
import lombok.Data; |
|
||||
|
|
||||
import jakarta.validation.constraints.NotBlank; |
|
||||
import jakarta.validation.constraints.NotNull; |
|
||||
|
|
||||
/** |
|
||||
* 测试单表业务对象 test_demo |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
@Data |
|
||||
public class TestDemoImportVo { |
|
||||
|
|
||||
/** |
|
||||
* 部门id |
|
||||
*/ |
|
||||
@NotNull(message = "部门id不能为空") |
|
||||
@ExcelProperty(value = "部门id") |
|
||||
private Long deptId; |
|
||||
|
|
||||
/** |
|
||||
* 用户id |
|
||||
*/ |
|
||||
@NotNull(message = "用户id不能为空") |
|
||||
@ExcelProperty(value = "用户id") |
|
||||
private Long userId; |
|
||||
|
|
||||
/** |
|
||||
* 排序号 |
|
||||
*/ |
|
||||
@NotNull(message = "排序号不能为空") |
|
||||
@ExcelProperty(value = "排序号") |
|
||||
private Long orderNum; |
|
||||
|
|
||||
/** |
|
||||
* key键 |
|
||||
*/ |
|
||||
@NotBlank(message = "key键不能为空") |
|
||||
@ExcelProperty(value = "key键") |
|
||||
private String testKey; |
|
||||
|
|
||||
/** |
|
||||
* 值 |
|
||||
*/ |
|
||||
@NotBlank(message = "值不能为空") |
|
||||
@ExcelProperty(value = "值") |
|
||||
private String value; |
|
||||
|
|
||||
} |
|
||||
@ -1,54 +0,0 @@ |
|||||
package org.dromara.demo.domain.bo; |
|
||||
|
|
||||
import org.dromara.common.core.validate.AddGroup; |
|
||||
import org.dromara.common.core.validate.EditGroup; |
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity; |
|
||||
import org.dromara.demo.domain.TestTree; |
|
||||
import io.github.linpeilie.annotations.AutoMapper; |
|
||||
import jakarta.validation.constraints.NotBlank; |
|
||||
import jakarta.validation.constraints.NotNull; |
|
||||
import lombok.Data; |
|
||||
import lombok.EqualsAndHashCode; |
|
||||
|
|
||||
/** |
|
||||
* 测试树表业务对象 test_tree |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
|
|
||||
@Data |
|
||||
@EqualsAndHashCode(callSuper = true) |
|
||||
@AutoMapper(target = TestTree.class, reverseConvertGenerate = false) |
|
||||
public class TestTreeBo extends BaseEntity { |
|
||||
|
|
||||
/** |
|
||||
* 主键 |
|
||||
*/ |
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class}) |
|
||||
private Long id; |
|
||||
|
|
||||
/** |
|
||||
* 父ID |
|
||||
*/ |
|
||||
private Long parentId; |
|
||||
|
|
||||
/** |
|
||||
* 部门id |
|
||||
*/ |
|
||||
@NotNull(message = "部门id不能为空", groups = {AddGroup.class, EditGroup.class}) |
|
||||
private Long deptId; |
|
||||
|
|
||||
/** |
|
||||
* 用户id |
|
||||
*/ |
|
||||
@NotNull(message = "用户id不能为空", groups = {AddGroup.class, EditGroup.class}) |
|
||||
private Long userId; |
|
||||
|
|
||||
/** |
|
||||
* 树节点名 |
|
||||
*/ |
|
||||
@NotBlank(message = "树节点名不能为空", groups = {AddGroup.class, EditGroup.class}) |
|
||||
private String treeName; |
|
||||
|
|
||||
} |
|
||||
@ -1 +0,0 @@ |
|||||
package org.dromara.demo.domain; |
|
||||
@ -1,118 +0,0 @@ |
|||||
package org.dromara.demo.domain.vo; |
|
||||
|
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
|
||||
import com.alibaba.excel.annotation.ExcelProperty; |
|
||||
import jakarta.validation.constraints.NotEmpty; |
|
||||
import jakarta.validation.constraints.NotNull; |
|
||||
import lombok.AllArgsConstructor; |
|
||||
import lombok.Data; |
|
||||
import lombok.NoArgsConstructor; |
|
||||
import org.dromara.common.core.enums.UserStatus; |
|
||||
import org.dromara.common.core.validate.AddGroup; |
|
||||
import org.dromara.common.core.validate.EditGroup; |
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat; |
|
||||
import org.dromara.common.excel.annotation.ExcelEnumFormat; |
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert; |
|
||||
import org.dromara.common.excel.convert.ExcelEnumConvert; |
|
||||
|
|
||||
/** |
|
||||
* 带有下拉选的Excel导出 |
|
||||
* |
|
||||
* @author Emil.Zhang |
|
||||
*/ |
|
||||
@Data |
|
||||
@ExcelIgnoreUnannotated |
|
||||
@AllArgsConstructor |
|
||||
@NoArgsConstructor |
|
||||
public class ExportDemoVo { |
|
||||
|
|
||||
private static final long serialVersionUID = 1L; |
|
||||
|
|
||||
/** |
|
||||
* 用户昵称 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "用户名", index = 0) |
|
||||
@NotEmpty(message = "用户名不能为空", groups = AddGroup.class) |
|
||||
private String nickName; |
|
||||
|
|
||||
/** |
|
||||
* 用户类型 |
|
||||
* </p> |
|
||||
* 使用ExcelEnumFormat注解需要进行下拉选的部分 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "用户类型", index = 1, converter = ExcelEnumConvert.class) |
|
||||
@ExcelEnumFormat(enumClass = UserStatus.class, textField = "info") |
|
||||
@NotEmpty(message = "用户类型不能为空", groups = AddGroup.class) |
|
||||
private String userStatus; |
|
||||
|
|
||||
/** |
|
||||
* 性别 |
|
||||
* <p> |
|
||||
* 使用ExcelDictFormat注解需要进行下拉选的部分 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "性别", index = 2, converter = ExcelDictConvert.class) |
|
||||
@ExcelDictFormat(dictType = "sys_user_sex") |
|
||||
@NotEmpty(message = "性别不能为空", groups = AddGroup.class) |
|
||||
private String gender; |
|
||||
|
|
||||
/** |
|
||||
* 手机号 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "手机号", index = 3) |
|
||||
@NotEmpty(message = "手机号不能为空", groups = AddGroup.class) |
|
||||
private String phoneNumber; |
|
||||
|
|
||||
/** |
|
||||
* Email |
|
||||
*/ |
|
||||
@ExcelProperty(value = "Email", index = 4) |
|
||||
@NotEmpty(message = "Email不能为空", groups = AddGroup.class) |
|
||||
private String email; |
|
||||
|
|
||||
/** |
|
||||
* 省 |
|
||||
* <p> |
|
||||
* 级联下拉,仅判断是否选了 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "省", index = 5) |
|
||||
@NotNull(message = "省不能为空", groups = AddGroup.class) |
|
||||
private String province; |
|
||||
|
|
||||
/** |
|
||||
* 数据库中的省ID |
|
||||
* </p> |
|
||||
* 处理完毕后再判断是否市正确的值 |
|
||||
*/ |
|
||||
@NotNull(message = "请勿手动输入", groups = EditGroup.class) |
|
||||
private Integer provinceId; |
|
||||
|
|
||||
/** |
|
||||
* 市 |
|
||||
* <p> |
|
||||
* 级联下拉 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "市", index = 6) |
|
||||
@NotNull(message = "市不能为空", groups = AddGroup.class) |
|
||||
private String city; |
|
||||
|
|
||||
/** |
|
||||
* 数据库中的市ID |
|
||||
*/ |
|
||||
@NotNull(message = "请勿手动输入", groups = EditGroup.class) |
|
||||
private Integer cityId; |
|
||||
|
|
||||
/** |
|
||||
* 县 |
|
||||
* <p> |
|
||||
* 级联下拉 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "县", index = 7) |
|
||||
@NotNull(message = "县不能为空", groups = AddGroup.class) |
|
||||
private String area; |
|
||||
|
|
||||
/** |
|
||||
* 数据库中的县ID |
|
||||
*/ |
|
||||
@NotNull(message = "请勿手动输入", groups = EditGroup.class) |
|
||||
private Integer areaId; |
|
||||
} |
|
||||
@ -1,104 +0,0 @@ |
|||||
package org.dromara.demo.domain.vo; |
|
||||
|
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
|
||||
import com.alibaba.excel.annotation.ExcelProperty; |
|
||||
import org.dromara.common.translation.annotation.Translation; |
|
||||
import org.dromara.common.translation.constant.TransConstant; |
|
||||
import org.dromara.demo.domain.TestDemo; |
|
||||
import io.github.linpeilie.annotations.AutoMapper; |
|
||||
import lombok.Data; |
|
||||
|
|
||||
import java.io.Serial; |
|
||||
import java.io.Serializable; |
|
||||
import java.util.Date; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 测试单表视图对象 test_demo |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
@Data |
|
||||
@ExcelIgnoreUnannotated |
|
||||
@AutoMapper(target = TestDemo.class) |
|
||||
public class TestDemoVo implements Serializable { |
|
||||
|
|
||||
@Serial |
|
||||
private static final long serialVersionUID = 1L; |
|
||||
|
|
||||
/** |
|
||||
* 主键 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "主键") |
|
||||
private Long id; |
|
||||
|
|
||||
/** |
|
||||
* 部门id |
|
||||
*/ |
|
||||
@ExcelProperty(value = "部门id") |
|
||||
private Long deptId; |
|
||||
|
|
||||
/** |
|
||||
* 用户id |
|
||||
*/ |
|
||||
@ExcelProperty(value = "用户id") |
|
||||
private Long userId; |
|
||||
|
|
||||
/** |
|
||||
* 排序号 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "排序号") |
|
||||
private Integer orderNum; |
|
||||
|
|
||||
/** |
|
||||
* key键 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "key键") |
|
||||
private String testKey; |
|
||||
|
|
||||
/** |
|
||||
* 值 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "值") |
|
||||
private String value; |
|
||||
|
|
||||
/** |
|
||||
* 创建时间 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "创建时间") |
|
||||
private Date createTime; |
|
||||
|
|
||||
/** |
|
||||
* 创建人 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "创建人") |
|
||||
private Long createBy; |
|
||||
|
|
||||
/** |
|
||||
* 创建人账号 |
|
||||
*/ |
|
||||
@Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "createBy") |
|
||||
@ExcelProperty(value = "创建人账号") |
|
||||
private String createByName; |
|
||||
|
|
||||
/** |
|
||||
* 更新时间 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "更新时间") |
|
||||
private Date updateTime; |
|
||||
|
|
||||
/** |
|
||||
* 更新人 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "更新人") |
|
||||
private Long updateBy; |
|
||||
|
|
||||
/** |
|
||||
* 更新人账号 |
|
||||
*/ |
|
||||
@Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "updateBy") |
|
||||
@ExcelProperty(value = "更新人账号") |
|
||||
private String updateByName; |
|
||||
|
|
||||
} |
|
||||
@ -1,64 +0,0 @@ |
|||||
package org.dromara.demo.domain.vo; |
|
||||
|
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
|
||||
import com.alibaba.excel.annotation.ExcelProperty; |
|
||||
import org.dromara.demo.domain.TestTree; |
|
||||
import io.github.linpeilie.annotations.AutoMapper; |
|
||||
import lombok.Data; |
|
||||
|
|
||||
import java.io.Serial; |
|
||||
import java.io.Serializable; |
|
||||
import java.util.Date; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 测试树表视图对象 test_tree |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
@Data |
|
||||
@ExcelIgnoreUnannotated |
|
||||
@AutoMapper(target = TestTree.class) |
|
||||
public class TestTreeVo implements Serializable { |
|
||||
|
|
||||
@Serial |
|
||||
private static final long serialVersionUID = 1L; |
|
||||
|
|
||||
/** |
|
||||
* 主键 |
|
||||
*/ |
|
||||
private Long id; |
|
||||
|
|
||||
/** |
|
||||
* 父id |
|
||||
*/ |
|
||||
@ExcelProperty(value = "父id") |
|
||||
private Long parentId; |
|
||||
|
|
||||
/** |
|
||||
* 部门id |
|
||||
*/ |
|
||||
@ExcelProperty(value = "部门id") |
|
||||
private Long deptId; |
|
||||
|
|
||||
/** |
|
||||
* 用户id |
|
||||
*/ |
|
||||
@ExcelProperty(value = "用户id") |
|
||||
private Long userId; |
|
||||
|
|
||||
/** |
|
||||
* 树节点名 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "树节点名") |
|
||||
private String treeName; |
|
||||
|
|
||||
/** |
|
||||
* 创建时间 |
|
||||
*/ |
|
||||
@ExcelProperty(value = "创建时间") |
|
||||
private Date createTime; |
|
||||
|
|
||||
|
|
||||
} |
|
||||
@ -1,68 +0,0 @@ |
|||||
package org.dromara.demo.listener; |
|
||||
|
|
||||
import cn.hutool.core.util.NumberUtil; |
|
||||
import com.alibaba.excel.context.AnalysisContext; |
|
||||
import org.dromara.common.core.utils.ValidatorUtils; |
|
||||
import org.dromara.common.core.validate.AddGroup; |
|
||||
import org.dromara.common.core.validate.EditGroup; |
|
||||
import org.dromara.common.excel.core.DefaultExcelListener; |
|
||||
import org.dromara.common.excel.core.DropDownOptions; |
|
||||
import org.dromara.demo.domain.vo.ExportDemoVo; |
|
||||
|
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* Excel带下拉框的解析处理器 |
|
||||
* |
|
||||
* @author Emil.Zhang |
|
||||
*/ |
|
||||
public class ExportDemoListener extends DefaultExcelListener<ExportDemoVo> { |
|
||||
|
|
||||
public ExportDemoListener() { |
|
||||
// 显示使用构造函数,否则将导致空指针
|
|
||||
super(true); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void invoke(ExportDemoVo data, AnalysisContext context) { |
|
||||
// 先校验必填
|
|
||||
ValidatorUtils.validate(data, AddGroup.class); |
|
||||
|
|
||||
// 处理级联下拉的部分
|
|
||||
String province = data.getProvince(); |
|
||||
String city = data.getCity(); |
|
||||
String area = data.getArea(); |
|
||||
// 本行用户选择的省
|
|
||||
List<String> thisRowSelectedProvinceOption = DropDownOptions.analyzeOptionValue(province); |
|
||||
if (thisRowSelectedProvinceOption.size() == 2) { |
|
||||
String provinceIdStr = thisRowSelectedProvinceOption.get(1); |
|
||||
if (NumberUtil.isNumber(provinceIdStr)) { |
|
||||
// 严格要求数据的话可以在这里做与数据库相关的判断
|
|
||||
// 例如判断省信息是否在数据库中存在等,建议结合RedisCache做缓存10s,减少数据库调用
|
|
||||
data.setProvinceId(Integer.parseInt(provinceIdStr)); |
|
||||
} |
|
||||
} |
|
||||
// 本行用户选择的市
|
|
||||
List<String> thisRowSelectedCityOption = DropDownOptions.analyzeOptionValue(city); |
|
||||
if (thisRowSelectedCityOption.size() == 2) { |
|
||||
String cityIdStr = thisRowSelectedCityOption.get(1); |
|
||||
if (NumberUtil.isNumber(cityIdStr)) { |
|
||||
data.setCityId(Integer.parseInt(cityIdStr)); |
|
||||
} |
|
||||
} |
|
||||
// 本行用户选择的县
|
|
||||
List<String> thisRowSelectedAreaOption = DropDownOptions.analyzeOptionValue(area); |
|
||||
if (thisRowSelectedAreaOption.size() == 2) { |
|
||||
String areaIdStr = thisRowSelectedAreaOption.get(1); |
|
||||
if (NumberUtil.isNumber(areaIdStr)) { |
|
||||
data.setAreaId(Integer.parseInt(areaIdStr)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 处理完毕以后判断是否符合规则
|
|
||||
ValidatorUtils.validate(data, EditGroup.class); |
|
||||
|
|
||||
// 添加到处理结果中
|
|
||||
getExcelResult().getList().add(data); |
|
||||
} |
|
||||
} |
|
||||
@ -1,13 +0,0 @@ |
|||||
package org.dromara.demo.mapper; |
|
||||
|
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
|
||||
import org.dromara.demo.domain.TestDemoEncrypt; |
|
||||
|
|
||||
/** |
|
||||
* 测试加密功能 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
*/ |
|
||||
public interface TestDemoEncryptMapper extends BaseMapperPlus<TestDemoEncrypt, TestDemoEncrypt> { |
|
||||
|
|
||||
} |
|
||||
@ -1,60 +0,0 @@ |
|||||
package org.dromara.demo.mapper; |
|
||||
|
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper; |
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants; |
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|
||||
import org.apache.ibatis.annotations.Param; |
|
||||
import org.dromara.common.mybatis.annotation.DataColumn; |
|
||||
import org.dromara.common.mybatis.annotation.DataPermission; |
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
|
||||
import org.dromara.demo.domain.TestDemo; |
|
||||
import org.dromara.demo.domain.vo.TestDemoVo; |
|
||||
|
|
||||
import java.io.Serializable; |
|
||||
import java.util.Collection; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* 测试单表Mapper接口 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
public interface TestDemoMapper extends BaseMapperPlus<TestDemo, TestDemoVo> { |
|
||||
|
|
||||
@DataPermission({ |
|
||||
@DataColumn(key = "deptName", value = "dept_id"), |
|
||||
@DataColumn(key = "userName", value = "user_id") |
|
||||
}) |
|
||||
Page<TestDemoVo> customPageList(@Param("page") Page<TestDemo> page, @Param("ew") Wrapper<TestDemo> wrapper); |
|
||||
|
|
||||
@Override |
|
||||
@DataPermission({ |
|
||||
@DataColumn(key = "deptName", value = "dept_id"), |
|
||||
@DataColumn(key = "userName", value = "user_id") |
|
||||
}) |
|
||||
List<TestDemo> selectList(IPage<TestDemo> page, @Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper); |
|
||||
|
|
||||
@Override |
|
||||
@DataPermission({ |
|
||||
@DataColumn(key = "deptName", value = "dept_id"), |
|
||||
@DataColumn(key = "userName", value = "user_id") |
|
||||
}) |
|
||||
List<TestDemo> selectList(@Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper); |
|
||||
|
|
||||
@Override |
|
||||
@DataPermission(value = { |
|
||||
@DataColumn(key = "deptName", value = "dept_id"), |
|
||||
@DataColumn(key = "userName", value = "user_id") |
|
||||
}, joinStr = "AND") |
|
||||
List<TestDemo> selectByIds(@Param(Constants.COLL) Collection<? extends Serializable> idList); |
|
||||
|
|
||||
@Override |
|
||||
@DataPermission({ |
|
||||
@DataColumn(key = "deptName", value = "dept_id"), |
|
||||
@DataColumn(key = "userName", value = "user_id") |
|
||||
}) |
|
||||
int updateById(@Param(Constants.ENTITY) TestDemo entity); |
|
||||
|
|
||||
} |
|
||||
@ -1,21 +0,0 @@ |
|||||
package org.dromara.demo.mapper; |
|
||||
|
|
||||
import org.dromara.common.mybatis.annotation.DataColumn; |
|
||||
import org.dromara.common.mybatis.annotation.DataPermission; |
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
|
||||
import org.dromara.demo.domain.TestTree; |
|
||||
import org.dromara.demo.domain.vo.TestTreeVo; |
|
||||
|
|
||||
/** |
|
||||
* 测试树表Mapper接口 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
@DataPermission({ |
|
||||
@DataColumn(key = "deptName", value = "dept_id"), |
|
||||
@DataColumn(key = "userName", value = "user_id") |
|
||||
}) |
|
||||
public interface TestTreeMapper extends BaseMapperPlus<TestTree, TestTreeVo> { |
|
||||
|
|
||||
} |
|
||||
@ -1 +0,0 @@ |
|||||
package org.dromara.demo.mapper; |
|
||||
@ -1,18 +0,0 @@ |
|||||
package org.dromara.demo.service; |
|
||||
|
|
||||
import jakarta.servlet.http.HttpServletResponse; |
|
||||
|
|
||||
/** |
|
||||
* 导出下拉框Excel示例 |
|
||||
* |
|
||||
* @author Emil.Zhang |
|
||||
*/ |
|
||||
public interface IExportExcelService { |
|
||||
|
|
||||
/** |
|
||||
* 导出下拉框 |
|
||||
* |
|
||||
* @param response / |
|
||||
*/ |
|
||||
void exportWithOptions(HttpServletResponse response); |
|
||||
} |
|
||||
@ -1,71 +0,0 @@ |
|||||
package org.dromara.demo.service; |
|
||||
|
|
||||
import org.dromara.common.mybatis.core.page.PageQuery; |
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo; |
|
||||
import org.dromara.demo.domain.TestDemo; |
|
||||
import org.dromara.demo.domain.bo.TestDemoBo; |
|
||||
import org.dromara.demo.domain.vo.TestDemoVo; |
|
||||
|
|
||||
import java.util.Collection; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* 测试单表Service接口 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
public interface ITestDemoService { |
|
||||
|
|
||||
/** |
|
||||
* 查询单个 |
|
||||
* |
|
||||
* @return |
|
||||
*/ |
|
||||
TestDemoVo queryById(Long id); |
|
||||
|
|
||||
/** |
|
||||
* 查询列表 |
|
||||
*/ |
|
||||
TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery); |
|
||||
|
|
||||
/** |
|
||||
* 自定义分页查询 |
|
||||
*/ |
|
||||
TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery); |
|
||||
|
|
||||
/** |
|
||||
* 查询列表 |
|
||||
*/ |
|
||||
List<TestDemoVo> queryList(TestDemoBo bo); |
|
||||
|
|
||||
/** |
|
||||
* 根据新增业务对象插入测试单表 |
|
||||
* |
|
||||
* @param bo 测试单表新增业务对象 |
|
||||
* @return |
|
||||
*/ |
|
||||
Boolean insertByBo(TestDemoBo bo); |
|
||||
|
|
||||
/** |
|
||||
* 根据编辑业务对象修改测试单表 |
|
||||
* |
|
||||
* @param bo 测试单表编辑业务对象 |
|
||||
* @return |
|
||||
*/ |
|
||||
Boolean updateByBo(TestDemoBo bo); |
|
||||
|
|
||||
/** |
|
||||
* 校验并删除数据 |
|
||||
* |
|
||||
* @param ids 主键集合 |
|
||||
* @param isValid 是否校验,true-删除前校验,false-不校验 |
|
||||
* @return |
|
||||
*/ |
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
|
||||
|
|
||||
/** |
|
||||
* 批量保存 |
|
||||
*/ |
|
||||
Boolean saveBatch(List<TestDemo> list); |
|
||||
} |
|
||||
@ -1,52 +0,0 @@ |
|||||
package org.dromara.demo.service; |
|
||||
|
|
||||
import org.dromara.demo.domain.bo.TestTreeBo; |
|
||||
import org.dromara.demo.domain.vo.TestTreeVo; |
|
||||
|
|
||||
import java.util.Collection; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* 测试树表Service接口 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
public interface ITestTreeService { |
|
||||
/** |
|
||||
* 查询单个 |
|
||||
* |
|
||||
* @return |
|
||||
*/ |
|
||||
TestTreeVo queryById(Long id); |
|
||||
|
|
||||
/** |
|
||||
* 查询列表 |
|
||||
*/ |
|
||||
List<TestTreeVo> queryList(TestTreeBo bo); |
|
||||
|
|
||||
/** |
|
||||
* 根据新增业务对象插入测试树表 |
|
||||
* |
|
||||
* @param bo 测试树表新增业务对象 |
|
||||
* @return |
|
||||
*/ |
|
||||
Boolean insertByBo(TestTreeBo bo); |
|
||||
|
|
||||
/** |
|
||||
* 根据编辑业务对象修改测试树表 |
|
||||
* |
|
||||
* @param bo 测试树表编辑业务对象 |
|
||||
* @return |
|
||||
*/ |
|
||||
Boolean updateByBo(TestTreeBo bo); |
|
||||
|
|
||||
/** |
|
||||
* 校验并删除数据 |
|
||||
* |
|
||||
* @param ids 主键集合 |
|
||||
* @param isValid 是否校验,true-删除前校验,false-不校验 |
|
||||
* @return |
|
||||
*/ |
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
|
||||
} |
|
||||
@ -1,222 +0,0 @@ |
|||||
package org.dromara.demo.service.impl; |
|
||||
|
|
||||
import cn.hutool.core.util.StrUtil; |
|
||||
import jakarta.servlet.http.HttpServletResponse; |
|
||||
import lombok.Data; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.dromara.common.core.enums.UserStatus; |
|
||||
import org.dromara.common.core.utils.StreamUtils; |
|
||||
import org.dromara.common.excel.core.DropDownOptions; |
|
||||
import org.dromara.common.excel.utils.ExcelUtil; |
|
||||
import org.dromara.demo.domain.vo.ExportDemoVo; |
|
||||
import org.dromara.demo.service.IExportExcelService; |
|
||||
import org.springframework.stereotype.Service; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
import java.util.List; |
|
||||
import java.util.Map; |
|
||||
import java.util.stream.Collectors; |
|
||||
|
|
||||
/** |
|
||||
* 导出下拉框Excel示例 |
|
||||
* |
|
||||
* @author Emil.Zhang |
|
||||
*/ |
|
||||
@Service |
|
||||
@RequiredArgsConstructor |
|
||||
public class ExportExcelServiceImpl implements IExportExcelService { |
|
||||
|
|
||||
@Override |
|
||||
public void exportWithOptions(HttpServletResponse response) { |
|
||||
// 创建表格数据,业务中一般通过数据库查询
|
|
||||
List<ExportDemoVo> excelDataList = new ArrayList<>(); |
|
||||
for (int i = 0; i < 3; i++) { |
|
||||
// 模拟数据库中的一条数据
|
|
||||
ExportDemoVo everyRowData = new ExportDemoVo(); |
|
||||
everyRowData.setNickName("用户-" + i); |
|
||||
everyRowData.setUserStatus(UserStatus.OK.getCode()); |
|
||||
everyRowData.setGender("1"); |
|
||||
everyRowData.setPhoneNumber(String.format("175%08d", i)); |
|
||||
everyRowData.setEmail(String.format("175%08d", i) + "@163.com"); |
|
||||
everyRowData.setProvinceId(i); |
|
||||
everyRowData.setCityId(i); |
|
||||
everyRowData.setAreaId(i); |
|
||||
excelDataList.add(everyRowData); |
|
||||
} |
|
||||
|
|
||||
// 通过@ExcelIgnoreUnannotated配合@ExcelProperty合理显示需要的列
|
|
||||
// 并通过@DropDown注解指定下拉值,或者通过创建ExcelOptions来指定下拉框
|
|
||||
// 使用ExcelOptions时建议指定列index,防止出现下拉列解析不对齐
|
|
||||
|
|
||||
// 首先从数据库中查询下拉框内的可选项
|
|
||||
// 这里模拟查询结果
|
|
||||
List<DemoCityData> provinceList = getProvinceList(), |
|
||||
cityList = getCityList(provinceList), |
|
||||
areaList = getAreaList(cityList); |
|
||||
int provinceIndex = 5, cityIndex = 6, areaIndex = 7; |
|
||||
|
|
||||
DropDownOptions provinceToCity = DropDownOptions.buildLinkedOptions( |
|
||||
provinceList, |
|
||||
provinceIndex, |
|
||||
cityList, |
|
||||
cityIndex, |
|
||||
DemoCityData::getId, |
|
||||
DemoCityData::getPid, |
|
||||
everyOptions -> DropDownOptions.createOptionValue( |
|
||||
everyOptions.getName(), |
|
||||
everyOptions.getId() |
|
||||
) |
|
||||
); |
|
||||
|
|
||||
DropDownOptions cityToArea = DropDownOptions.buildLinkedOptions( |
|
||||
cityList, |
|
||||
cityIndex, |
|
||||
areaList, |
|
||||
areaIndex, |
|
||||
DemoCityData::getId, |
|
||||
DemoCityData::getPid, |
|
||||
everyOptions -> DropDownOptions.createOptionValue( |
|
||||
everyOptions.getName(), |
|
||||
everyOptions.getId() |
|
||||
) |
|
||||
); |
|
||||
|
|
||||
// 把所有的下拉框存储
|
|
||||
List<DropDownOptions> options = new ArrayList<>(); |
|
||||
options.add(provinceToCity); |
|
||||
options.add(cityToArea); |
|
||||
|
|
||||
// 到此为止所有的下拉框可选项已全部配置完毕
|
|
||||
|
|
||||
// 接下来需要将Excel中的展示数据转换为对应的下拉选
|
|
||||
List<ExportDemoVo> outList = StreamUtils.toList(excelDataList, everyRowData -> { |
|
||||
// 只需要处理没有使用@ExcelDictFormat注解的下拉框
|
|
||||
// 一般来说,可以直接在数据库查询即查询出省市县信息,这里通过模拟操作赋值
|
|
||||
everyRowData.setProvince(buildOptions(provinceList, everyRowData.getProvinceId())); |
|
||||
everyRowData.setCity(buildOptions(cityList, everyRowData.getCityId())); |
|
||||
everyRowData.setArea(buildOptions(areaList, everyRowData.getAreaId())); |
|
||||
return everyRowData; |
|
||||
}); |
|
||||
|
|
||||
ExcelUtil.exportExcel(outList, "下拉框示例", ExportDemoVo.class, response, options); |
|
||||
} |
|
||||
|
|
||||
private String buildOptions(List<DemoCityData> cityDataList, Integer id) { |
|
||||
Map<Integer, List<DemoCityData>> groupByIdMap = |
|
||||
cityDataList.stream().collect(Collectors.groupingBy(DemoCityData::getId)); |
|
||||
if (groupByIdMap.containsKey(id)) { |
|
||||
DemoCityData demoCityData = groupByIdMap.get(id).get(0); |
|
||||
return DropDownOptions.createOptionValue(demoCityData.getName(), demoCityData.getId()); |
|
||||
} else { |
|
||||
return StrUtil.EMPTY; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 模拟查询数据库操作 |
|
||||
* |
|
||||
* @return / |
|
||||
*/ |
|
||||
private List<DemoCityData> getProvinceList() { |
|
||||
List<DemoCityData> provinceList = new ArrayList<>(); |
|
||||
|
|
||||
// 实际业务中一般采用数据库读取的形式,这里直接拼接创建
|
|
||||
provinceList.add(new DemoCityData(0, null, "安徽省")); |
|
||||
provinceList.add(new DemoCityData(1, null, "江苏省")); |
|
||||
|
|
||||
return provinceList; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 模拟查找数据库操作,需要连带查询出省的数据 |
|
||||
* |
|
||||
* @param provinceList 模拟的父省数据 |
|
||||
* @return / |
|
||||
*/ |
|
||||
private List<DemoCityData> getCityList(List<DemoCityData> provinceList) { |
|
||||
List<DemoCityData> cityList = new ArrayList<>(); |
|
||||
|
|
||||
// 实际业务中一般采用数据库读取的形式,这里直接拼接创建
|
|
||||
cityList.add(new DemoCityData(0, 0, "合肥市")); |
|
||||
cityList.add(new DemoCityData(1, 0, "芜湖市")); |
|
||||
cityList.add(new DemoCityData(2, 1, "南京市")); |
|
||||
cityList.add(new DemoCityData(3, 1, "无锡市")); |
|
||||
cityList.add(new DemoCityData(4, 1, "徐州市")); |
|
||||
|
|
||||
selectParentData(provinceList, cityList); |
|
||||
|
|
||||
return cityList; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 模拟查找数据库操作,需要连带查询出市的数据 |
|
||||
* |
|
||||
* @param cityList 模拟的父市数据 |
|
||||
* @return / |
|
||||
*/ |
|
||||
private List<DemoCityData> getAreaList(List<DemoCityData> cityList) { |
|
||||
List<DemoCityData> areaList = new ArrayList<>(); |
|
||||
|
|
||||
// 实际业务中一般采用数据库读取的形式,这里直接拼接创建
|
|
||||
areaList.add(new DemoCityData(0, 0, "瑶海区")); |
|
||||
areaList.add(new DemoCityData(1, 0, "庐江区")); |
|
||||
areaList.add(new DemoCityData(2, 1, "南宁县")); |
|
||||
areaList.add(new DemoCityData(3, 1, "镜湖区")); |
|
||||
areaList.add(new DemoCityData(4, 2, "玄武区")); |
|
||||
areaList.add(new DemoCityData(5, 2, "秦淮区")); |
|
||||
areaList.add(new DemoCityData(6, 3, "宜兴市")); |
|
||||
areaList.add(new DemoCityData(7, 3, "新吴区")); |
|
||||
areaList.add(new DemoCityData(8, 4, "鼓楼区")); |
|
||||
areaList.add(new DemoCityData(9, 4, "丰县")); |
|
||||
|
|
||||
selectParentData(cityList, areaList); |
|
||||
|
|
||||
return areaList; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 模拟数据库的查询父数据操作 |
|
||||
* |
|
||||
* @param parentList / |
|
||||
* @param sonList / |
|
||||
*/ |
|
||||
private void selectParentData(List<DemoCityData> parentList, List<DemoCityData> sonList) { |
|
||||
Map<Integer, List<DemoCityData>> parentGroupByIdMap = |
|
||||
parentList.stream().collect(Collectors.groupingBy(DemoCityData::getId)); |
|
||||
|
|
||||
sonList.forEach(everySon -> { |
|
||||
if (parentGroupByIdMap.containsKey(everySon.getPid())) { |
|
||||
everySon.setPData(parentGroupByIdMap.get(everySon.getPid()).get(0)); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 模拟的数据库省市县 |
|
||||
*/ |
|
||||
@Data |
|
||||
private static class DemoCityData { |
|
||||
/** |
|
||||
* 数据库id字段 |
|
||||
*/ |
|
||||
private Integer id; |
|
||||
/** |
|
||||
* 数据库pid字段 |
|
||||
*/ |
|
||||
private Integer pid; |
|
||||
/** |
|
||||
* 数据库name字段 |
|
||||
*/ |
|
||||
private String name; |
|
||||
/** |
|
||||
* MyBatisPlus连带查询父数据 |
|
||||
*/ |
|
||||
private DemoCityData pData; |
|
||||
|
|
||||
public DemoCityData(Integer id, Integer pid, String name) { |
|
||||
this.id = id; |
|
||||
this.pid = pid; |
|
||||
this.name = name; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,116 +0,0 @@ |
|||||
package org.dromara.demo.service.impl; |
|
||||
|
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.dromara.common.core.exception.ServiceException; |
|
||||
import org.dromara.common.core.utils.MapstructUtils; |
|
||||
import org.dromara.common.core.utils.StringUtils; |
|
||||
import org.dromara.common.mybatis.core.page.PageQuery; |
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo; |
|
||||
import org.dromara.demo.domain.TestDemo; |
|
||||
import org.dromara.demo.domain.bo.TestDemoBo; |
|
||||
import org.dromara.demo.domain.vo.TestDemoVo; |
|
||||
import org.dromara.demo.mapper.TestDemoMapper; |
|
||||
import org.dromara.demo.service.ITestDemoService; |
|
||||
import org.springframework.stereotype.Service; |
|
||||
|
|
||||
import java.util.Collection; |
|
||||
import java.util.List; |
|
||||
import java.util.Map; |
|
||||
|
|
||||
/** |
|
||||
* 测试单表Service业务层处理 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
@RequiredArgsConstructor |
|
||||
@Service |
|
||||
public class TestDemoServiceImpl implements ITestDemoService { |
|
||||
|
|
||||
private final TestDemoMapper baseMapper; |
|
||||
|
|
||||
@Override |
|
||||
public TestDemoVo queryById(Long id) { |
|
||||
return baseMapper.selectVoById(id); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery) { |
|
||||
LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo); |
|
||||
Page<TestDemoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
|
||||
return TableDataInfo.build(result); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 自定义分页查询 |
|
||||
*/ |
|
||||
@Override |
|
||||
public TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery) { |
|
||||
LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo); |
|
||||
Page<TestDemoVo> result = baseMapper.customPageList(pageQuery.build(), lqw); |
|
||||
return TableDataInfo.build(result); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public List<TestDemoVo> queryList(TestDemoBo bo) { |
|
||||
return baseMapper.selectVoList(buildQueryWrapper(bo)); |
|
||||
} |
|
||||
|
|
||||
private LambdaQueryWrapper<TestDemo> buildQueryWrapper(TestDemoBo bo) { |
|
||||
Map<String, Object> params = bo.getParams(); |
|
||||
LambdaQueryWrapper<TestDemo> lqw = Wrappers.lambdaQuery(); |
|
||||
lqw.like(StringUtils.isNotBlank(bo.getTestKey()), TestDemo::getTestKey, bo.getTestKey()); |
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getValue()), TestDemo::getValue, bo.getValue()); |
|
||||
lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null, |
|
||||
TestDemo::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime")); |
|
||||
lqw.orderByAsc(TestDemo::getId); |
|
||||
return lqw; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public Boolean insertByBo(TestDemoBo bo) { |
|
||||
TestDemo add = MapstructUtils.convert(bo, TestDemo.class); |
|
||||
validEntityBeforeSave(add); |
|
||||
boolean flag = baseMapper.insert(add) > 0; |
|
||||
if (flag) { |
|
||||
bo.setId(add.getId()); |
|
||||
} |
|
||||
return flag; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public Boolean updateByBo(TestDemoBo bo) { |
|
||||
TestDemo update = MapstructUtils.convert(bo, TestDemo.class); |
|
||||
validEntityBeforeSave(update); |
|
||||
return baseMapper.updateById(update) > 0; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 保存前的数据校验 |
|
||||
* |
|
||||
* @param entity 实体类数据 |
|
||||
*/ |
|
||||
private void validEntityBeforeSave(TestDemo entity) { |
|
||||
//TODO 做一些数据校验,如唯一约束
|
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
|
||||
if (isValid) { |
|
||||
// 做一些业务上的校验,判断是否需要校验
|
|
||||
List<TestDemo> list = baseMapper.selectByIds(ids); |
|
||||
if (list.size() != ids.size()) { |
|
||||
throw new ServiceException("您没有删除权限!"); |
|
||||
} |
|
||||
} |
|
||||
return baseMapper.deleteByIds(ids) > 0; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public Boolean saveBatch(List<TestDemo> list) { |
|
||||
return baseMapper.insertBatch(list); |
|
||||
} |
|
||||
} |
|
||||
@ -1,88 +0,0 @@ |
|||||
package org.dromara.demo.service.impl; |
|
||||
|
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
|
||||
import org.dromara.common.core.utils.MapstructUtils; |
|
||||
import org.dromara.common.core.utils.StringUtils; |
|
||||
import org.dromara.demo.domain.TestTree; |
|
||||
import org.dromara.demo.domain.bo.TestTreeBo; |
|
||||
import org.dromara.demo.domain.vo.TestTreeVo; |
|
||||
import org.dromara.demo.mapper.TestTreeMapper; |
|
||||
import org.dromara.demo.service.ITestTreeService; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.springframework.stereotype.Service; |
|
||||
|
|
||||
import java.util.Collection; |
|
||||
import java.util.List; |
|
||||
import java.util.Map; |
|
||||
|
|
||||
/** |
|
||||
* 测试树表Service业务层处理 |
|
||||
* |
|
||||
* @author Lion Li |
|
||||
* @date 2021-07-26 |
|
||||
*/ |
|
||||
// @DS("slave") // 切换从库查询
|
|
||||
@RequiredArgsConstructor |
|
||||
@Service |
|
||||
public class TestTreeServiceImpl implements ITestTreeService { |
|
||||
|
|
||||
private final TestTreeMapper baseMapper; |
|
||||
|
|
||||
@Override |
|
||||
public TestTreeVo queryById(Long id) { |
|
||||
return baseMapper.selectVoById(id); |
|
||||
} |
|
||||
|
|
||||
// @DS("slave") // 切换从库查询
|
|
||||
@Override |
|
||||
public List<TestTreeVo> queryList(TestTreeBo bo) { |
|
||||
LambdaQueryWrapper<TestTree> lqw = buildQueryWrapper(bo); |
|
||||
return baseMapper.selectVoList(lqw); |
|
||||
} |
|
||||
|
|
||||
private LambdaQueryWrapper<TestTree> buildQueryWrapper(TestTreeBo bo) { |
|
||||
Map<String, Object> params = bo.getParams(); |
|
||||
LambdaQueryWrapper<TestTree> lqw = Wrappers.lambdaQuery(); |
|
||||
lqw.like(StringUtils.isNotBlank(bo.getTreeName()), TestTree::getTreeName, bo.getTreeName()); |
|
||||
lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null, |
|
||||
TestTree::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime")); |
|
||||
lqw.orderByAsc(TestTree::getId); |
|
||||
return lqw; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public Boolean insertByBo(TestTreeBo bo) { |
|
||||
TestTree add = MapstructUtils.convert(bo, TestTree.class); |
|
||||
validEntityBeforeSave(add); |
|
||||
boolean flag = baseMapper.insert(add) > 0; |
|
||||
if (flag) { |
|
||||
bo.setId(add.getId()); |
|
||||
} |
|
||||
return flag; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public Boolean updateByBo(TestTreeBo bo) { |
|
||||
TestTree update = MapstructUtils.convert(bo, TestTree.class); |
|
||||
validEntityBeforeSave(update); |
|
||||
return baseMapper.updateById(update) > 0; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 保存前的数据校验 |
|
||||
* |
|
||||
* @param entity 实体类数据 |
|
||||
*/ |
|
||||
private void validEntityBeforeSave(TestTree entity) { |
|
||||
//TODO 做一些数据校验,如唯一约束
|
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
|
||||
if (isValid) { |
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
|
||||
} |
|
||||
return baseMapper.deleteByIds(ids) > 0; |
|
||||
} |
|
||||
} |
|
||||
@ -1 +0,0 @@ |
|||||
package org.dromara.demo.service.impl; |
|
||||
@ -1 +0,0 @@ |
|||||
package org.dromara.demo.service; |
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,11 +0,0 @@ |
|||||
<?xml version="1.0" encoding="UTF-8" ?> |
|
||||
<!DOCTYPE mapper |
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|
||||
<mapper namespace="org.dromara.demo.mapper.TestDemoMapper"> |
|
||||
|
|
||||
<select id="customPageList" resultType="org.dromara.demo.domain.vo.TestDemoVo"> |
|
||||
SELECT * FROM test_demo ${ew.customSqlSegment} |
|
||||
</select> |
|
||||
|
|
||||
</mapper> |
|
||||
@ -1,7 +0,0 @@ |
|||||
<?xml version="1.0" encoding="UTF-8" ?> |
|
||||
<!DOCTYPE mapper |
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|
||||
<mapper namespace="org.dromara.demo.mapper.TestTreeMapper"> |
|
||||
|
|
||||
</mapper> |
|
||||
@ -1,3 +0,0 @@ |
|||||
java包使用 `.` 分割 resource 目录使用 `/` 分割 |
|
||||
<br> |
|
||||
此文件目的 防止文件夹粘连找不到 `xml` 文件 |
|
||||
@ -1,34 +0,0 @@ |
|||||
<?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> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-modules</artifactId> |
|
||||
<version>${revision}</version> |
|
||||
</parent> |
|
||||
<modelVersion>4.0.0</modelVersion> |
|
||||
<packaging>jar</packaging> |
|
||||
<artifactId>ruoyi-job</artifactId> |
|
||||
|
|
||||
<description> |
|
||||
任务调度 |
|
||||
</description> |
|
||||
|
|
||||
<dependencies> |
|
||||
|
|
||||
<!-- 通用工具--> |
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-json</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-job</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
</dependencies> |
|
||||
|
|
||||
</project> |
|
||||
|
|
||||
@ -1 +0,0 @@ |
|||||
package org.dromara.job; |
|
||||
@ -1,23 +0,0 @@ |
|||||
package org.dromara.job.snailjob; |
|
||||
|
|
||||
import com.aizuda.snailjob.client.job.core.annotation.JobExecutor; |
|
||||
import com.aizuda.snailjob.client.job.core.dto.JobArgs; |
|
||||
import com.aizuda.snailjob.client.model.ExecuteResult; |
|
||||
import com.aizuda.snailjob.common.core.util.JsonUtil; |
|
||||
import com.aizuda.snailjob.common.log.SnailJobLog; |
|
||||
import org.springframework.stereotype.Component; |
|
||||
|
|
||||
/** |
|
||||
* @author opensnail |
|
||||
* @date 2024-05-17 |
|
||||
*/ |
|
||||
@Component |
|
||||
@JobExecutor(name = "testJobExecutor") |
|
||||
public class TestAnnoJobExecutor { |
|
||||
|
|
||||
public ExecuteResult jobExecute(JobArgs jobArgs) { |
|
||||
SnailJobLog.LOCAL.info("testJobExecutor. jobArgs:{}", JsonUtil.toJsonString(jobArgs)); |
|
||||
SnailJobLog.REMOTE.info("testJobExecutor. jobArgs:{}", JsonUtil.toJsonString(jobArgs)); |
|
||||
return ExecuteResult.success("测试成功"); |
|
||||
} |
|
||||
} |
|
||||
@ -1,19 +0,0 @@ |
|||||
package org.dromara.job.snailjob; |
|
||||
|
|
||||
import com.aizuda.snailjob.client.job.core.dto.JobArgs; |
|
||||
import com.aizuda.snailjob.client.job.core.executor.AbstractJobExecutor; |
|
||||
import com.aizuda.snailjob.client.model.ExecuteResult; |
|
||||
import org.springframework.stereotype.Component; |
|
||||
|
|
||||
/** |
|
||||
* @author opensnail |
|
||||
* @date 2024-05-17 |
|
||||
*/ |
|
||||
@Component |
|
||||
public class TestClassJobExecutor extends AbstractJobExecutor { |
|
||||
|
|
||||
@Override |
|
||||
protected ExecuteResult doJobExecute(JobArgs jobArgs) { |
|
||||
return ExecuteResult.success("TestJobExecutor测试成功"); |
|
||||
} |
|
||||
} |
|
||||
@ -1,3 +0,0 @@ |
|||||
# 工作流说明 |
|
||||
|
|
||||
工作流目前在未成熟阶段 后续仍会经历重构 甚至重写(生产使用前请慎重考虑后续是否要更新维护) |
|
||||
@ -1,119 +0,0 @@ |
|||||
<?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> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-modules</artifactId> |
|
||||
<version>${revision}</version> |
|
||||
<relativePath>../pom.xml</relativePath> |
|
||||
</parent> |
|
||||
<modelVersion>4.0.0</modelVersion> |
|
||||
<packaging>jar</packaging> |
|
||||
<artifactId>ruoyi-workflow</artifactId> |
|
||||
|
|
||||
<description> |
|
||||
工作流模块 |
|
||||
</description> |
|
||||
|
|
||||
<dependencies> |
|
||||
|
|
||||
<!--引入flowable依赖--> |
|
||||
<dependency> |
|
||||
<groupId>org.flowable</groupId> |
|
||||
<artifactId>flowable-spring-boot-autoconfigure</artifactId> |
|
||||
<exclusions> |
|
||||
<exclusion> |
|
||||
<groupId>org.flowable</groupId> |
|
||||
<artifactId>flowable-spring-security</artifactId> |
|
||||
</exclusion> |
|
||||
</exclusions> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.flowable</groupId> |
|
||||
<artifactId>flowable-spring-configurator</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.flowable</groupId> |
|
||||
<artifactId>flowable-spring-boot-starter-actuator</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<!-- 绘制flowable流程图 --> |
|
||||
<dependency> |
|
||||
<groupId>org.flowable</groupId> |
|
||||
<artifactId>flowable-image-generator</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<!-- flowable json 转换 --> |
|
||||
<dependency> |
|
||||
<groupId>org.flowable</groupId> |
|
||||
<artifactId>flowable-json-converter</artifactId> |
|
||||
<version>6.8.0</version> |
|
||||
</dependency> |
|
||||
|
|
||||
<!-- svg转png图片工具--> |
|
||||
<dependency> |
|
||||
<groupId>org.apache.xmlgraphics</groupId> |
|
||||
<artifactId>batik-all</artifactId> |
|
||||
<version>1.17</version> |
|
||||
<exclusions> |
|
||||
<exclusion> |
|
||||
<groupId>xalan</groupId> |
|
||||
<artifactId>xalan</artifactId> |
|
||||
</exclusion> |
|
||||
</exclusions> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-websocket</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-mail</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-sms</artifactId> |
|
||||
</dependency> |
|
||||
|
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-mybatis</artifactId> |
|
||||
</dependency> |
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-web</artifactId> |
|
||||
</dependency> |
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-log</artifactId> |
|
||||
</dependency> |
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-idempotent</artifactId> |
|
||||
</dependency> |
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-excel</artifactId> |
|
||||
</dependency> |
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-translation</artifactId> |
|
||||
</dependency> |
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-tenant</artifactId> |
|
||||
</dependency> |
|
||||
<dependency> |
|
||||
<groupId>org.dromara</groupId> |
|
||||
<artifactId>ruoyi-common-security</artifactId> |
|
||||
</dependency> |
|
||||
</dependencies> |
|
||||
|
|
||||
</project> |
|
||||
|
|
||||
@ -1,137 +0,0 @@ |
|||||
package org.dromara.workflow.common.constant; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 工作流常量 |
|
||||
* |
|
||||
* @author may |
|
||||
*/ |
|
||||
public interface FlowConstant { |
|
||||
|
|
||||
String MESSAGE_CURRENT_TASK_IS_NULL = "当前任务不存在或你不是任务办理人!"; |
|
||||
|
|
||||
String MESSAGE_SUSPENDED = "当前任务已挂起不可审批!"; |
|
||||
|
|
||||
/** |
|
||||
* 连线 |
|
||||
*/ |
|
||||
String SEQUENCE_FLOW = "sequenceFlow"; |
|
||||
|
|
||||
/** |
|
||||
* 并行网关 |
|
||||
*/ |
|
||||
String PARALLEL_GATEWAY = "parallelGateway"; |
|
||||
|
|
||||
/** |
|
||||
* 排它网关 |
|
||||
*/ |
|
||||
String EXCLUSIVE_GATEWAY = "exclusiveGateway"; |
|
||||
|
|
||||
/** |
|
||||
* 包含网关 |
|
||||
*/ |
|
||||
String INCLUSIVE_GATEWAY = "inclusiveGateway"; |
|
||||
|
|
||||
/** |
|
||||
* 结束节点 |
|
||||
*/ |
|
||||
String END_EVENT = "endEvent"; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 流程委派标识 |
|
||||
*/ |
|
||||
String PENDING = "PENDING"; |
|
||||
|
|
||||
/** |
|
||||
* 候选人标识 |
|
||||
*/ |
|
||||
String CANDIDATE = "candidate"; |
|
||||
|
|
||||
/** |
|
||||
* 会签任务总数 |
|
||||
*/ |
|
||||
String NUMBER_OF_INSTANCES = "nrOfInstances"; |
|
||||
|
|
||||
/** |
|
||||
* 正在执行的会签总数 |
|
||||
*/ |
|
||||
String NUMBER_OF_ACTIVE_INSTANCES = "nrOfActiveInstances"; |
|
||||
|
|
||||
/** |
|
||||
* 已完成的会签任务总数 |
|
||||
*/ |
|
||||
String NUMBER_OF_COMPLETED_INSTANCES = "nrOfCompletedInstances"; |
|
||||
|
|
||||
/** |
|
||||
* 循环的索引值,可以使用elementIndexVariable属性修改loopCounter的变量名 |
|
||||
*/ |
|
||||
String LOOP_COUNTER = "loopCounter"; |
|
||||
|
|
||||
String ZIP = "ZIP"; |
|
||||
|
|
||||
/** |
|
||||
* 业务与流程实例关联对象 |
|
||||
*/ |
|
||||
String BUSINESS_INSTANCE_DTO = "businessInstanceDTO"; |
|
||||
|
|
||||
/** |
|
||||
* 流程定义配置 |
|
||||
*/ |
|
||||
String WF_DEFINITION_CONFIG_VO = "wfDefinitionConfigVo"; |
|
||||
|
|
||||
/** |
|
||||
* 节点配置 |
|
||||
*/ |
|
||||
String WF_NODE_CONFIG_VO = "wfNodeConfigVo"; |
|
||||
|
|
||||
/** |
|
||||
* 流程发起人 |
|
||||
*/ |
|
||||
String INITIATOR = "initiator"; |
|
||||
|
|
||||
/** |
|
||||
* 流程实例id |
|
||||
*/ |
|
||||
String PROCESS_INSTANCE_ID = "processInstanceId"; |
|
||||
|
|
||||
/** |
|
||||
* 业务id |
|
||||
*/ |
|
||||
String BUSINESS_KEY = "businessKey"; |
|
||||
|
|
||||
/** |
|
||||
* 流程定义id |
|
||||
*/ |
|
||||
String PROCESS_DEFINITION_ID = "processDefinitionId"; |
|
||||
|
|
||||
/** |
|
||||
* 开启跳过表达式变量 |
|
||||
*/ |
|
||||
String FLOWABLE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED"; |
|
||||
|
|
||||
/** |
|
||||
* 模型标识key命名规范正则表达式 |
|
||||
*/ |
|
||||
String MODEL_KEY_PATTERN = "^[a-zA-Z][a-zA-Z0-9_]{0,254}$"; |
|
||||
|
|
||||
/** |
|
||||
* 用户任务 |
|
||||
*/ |
|
||||
String USER_TASK = "userTask"; |
|
||||
|
|
||||
/** |
|
||||
* 会签 |
|
||||
*/ |
|
||||
String MULTI_INSTANCE = "multiInstance"; |
|
||||
|
|
||||
/** |
|
||||
* 是 |
|
||||
*/ |
|
||||
String TRUE = "0"; |
|
||||
|
|
||||
/** |
|
||||
* 否 |
|
||||
*/ |
|
||||
String FALSE = "1"; |
|
||||
} |
|
||||
@ -1,54 +0,0 @@ |
|||||
package org.dromara.workflow.common.enums; |
|
||||
|
|
||||
import cn.hutool.core.util.StrUtil; |
|
||||
import lombok.AllArgsConstructor; |
|
||||
import lombok.Getter; |
|
||||
import org.apache.commons.lang3.StringUtils; |
|
||||
|
|
||||
import java.util.Arrays; |
|
||||
|
|
||||
/** |
|
||||
* 任务状态枚举 |
|
||||
* |
|
||||
* @author may |
|
||||
*/ |
|
||||
@Getter |
|
||||
@AllArgsConstructor |
|
||||
public enum FormTypeEnum { |
|
||||
/** |
|
||||
* 自定义表单 |
|
||||
*/ |
|
||||
STATIC("static", "自定义表单"), |
|
||||
/** |
|
||||
* 动态表单 |
|
||||
*/ |
|
||||
DYNAMIC("dynamic", "动态表单"); |
|
||||
|
|
||||
/** |
|
||||
* 类型 |
|
||||
*/ |
|
||||
private final String type; |
|
||||
|
|
||||
/** |
|
||||
* 描述 |
|
||||
*/ |
|
||||
private final String desc; |
|
||||
|
|
||||
/** |
|
||||
* 表单类型 |
|
||||
* |
|
||||
* @param formType 表单类型 |
|
||||
*/ |
|
||||
public static String findByType(String formType) { |
|
||||
if (StringUtils.isBlank(formType)) { |
|
||||
return StrUtil.EMPTY; |
|
||||
} |
|
||||
|
|
||||
return Arrays.stream(FormTypeEnum.values()) |
|
||||
.filter(statusEnum -> statusEnum.getType().equals(formType)) |
|
||||
.findFirst() |
|
||||
.map(FormTypeEnum::getDesc) |
|
||||
.orElse(StrUtil.EMPTY); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -1,51 +0,0 @@ |
|||||
package org.dromara.workflow.common.enums; |
|
||||
|
|
||||
import lombok.AllArgsConstructor; |
|
||||
import lombok.Getter; |
|
||||
|
|
||||
import java.util.Map; |
|
||||
import java.util.concurrent.ConcurrentHashMap; |
|
||||
|
|
||||
/** |
|
||||
* 消息类型枚举 |
|
||||
* |
|
||||
* @author may |
|
||||
*/ |
|
||||
@Getter |
|
||||
@AllArgsConstructor |
|
||||
public enum MessageTypeEnum { |
|
||||
/** |
|
||||
* 站内信 |
|
||||
*/ |
|
||||
SYSTEM_MESSAGE("1", "站内信"), |
|
||||
/** |
|
||||
* 邮箱 |
|
||||
*/ |
|
||||
EMAIL_MESSAGE("2", "邮箱"), |
|
||||
/** |
|
||||
* 短信 |
|
||||
*/ |
|
||||
SMS_MESSAGE("3", "短信"); |
|
||||
|
|
||||
private final String code; |
|
||||
|
|
||||
private final String desc; |
|
||||
|
|
||||
private final static Map<String, MessageTypeEnum> MESSAGE_TYPE_ENUM_MAP = new ConcurrentHashMap<>(MessageTypeEnum.values().length); |
|
||||
|
|
||||
static { |
|
||||
for (MessageTypeEnum messageType : MessageTypeEnum.values()) { |
|
||||
MESSAGE_TYPE_ENUM_MAP.put(messageType.code, messageType); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 根据消息类型 code 获取 MessageTypeEnum |
|
||||
* @param code 消息类型code |
|
||||
* @return MessageTypeEnum |
|
||||
*/ |
|
||||
public static MessageTypeEnum getByCode(String code) { |
|
||||
return MESSAGE_TYPE_ENUM_MAP.get(code); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -1,94 +0,0 @@ |
|||||
package org.dromara.workflow.common.enums; |
|
||||
|
|
||||
import cn.hutool.core.util.StrUtil; |
|
||||
import lombok.AllArgsConstructor; |
|
||||
import lombok.Getter; |
|
||||
import org.apache.commons.lang3.StringUtils; |
|
||||
|
|
||||
import java.util.Arrays; |
|
||||
|
|
||||
/** |
|
||||
* 任务状态枚举 |
|
||||
* |
|
||||
* @author may |
|
||||
*/ |
|
||||
@Getter |
|
||||
@AllArgsConstructor |
|
||||
public enum TaskStatusEnum { |
|
||||
/** |
|
||||
* 撤销 |
|
||||
*/ |
|
||||
CANCEL("cancel", "撤销"), |
|
||||
/** |
|
||||
* 通过 |
|
||||
*/ |
|
||||
PASS("pass", "通过"), |
|
||||
/** |
|
||||
* 待审核 |
|
||||
*/ |
|
||||
WAITING("waiting", "待审核"), |
|
||||
/** |
|
||||
* 作废 |
|
||||
*/ |
|
||||
INVALID("invalid", "作废"), |
|
||||
/** |
|
||||
* 退回 |
|
||||
*/ |
|
||||
BACK("back", "退回"), |
|
||||
/** |
|
||||
* 终止 |
|
||||
*/ |
|
||||
TERMINATION("termination", "终止"), |
|
||||
/** |
|
||||
* 转办 |
|
||||
*/ |
|
||||
TRANSFER("transfer", "转办"), |
|
||||
/** |
|
||||
* 委托 |
|
||||
*/ |
|
||||
PENDING("pending", "委托"), |
|
||||
/** |
|
||||
* 抄送 |
|
||||
*/ |
|
||||
COPY("copy", "抄送"), |
|
||||
/** |
|
||||
* 加签 |
|
||||
*/ |
|
||||
SIGN("sign", "加签"), |
|
||||
/** |
|
||||
* 减签 |
|
||||
*/ |
|
||||
SIGN_OFF("sign_off", "减签"), |
|
||||
/** |
|
||||
* 超时 |
|
||||
*/ |
|
||||
TIMEOUT("timeout", "超时"); |
|
||||
|
|
||||
/** |
|
||||
* 状态 |
|
||||
*/ |
|
||||
private final String status; |
|
||||
|
|
||||
/** |
|
||||
* 描述 |
|
||||
*/ |
|
||||
private final String desc; |
|
||||
|
|
||||
/** |
|
||||
* 任务业务状态 |
|
||||
* |
|
||||
* @param status 状态 |
|
||||
*/ |
|
||||
public static String findByStatus(String status) { |
|
||||
if (StringUtils.isBlank(status)) { |
|
||||
return StrUtil.EMPTY; |
|
||||
} |
|
||||
|
|
||||
return Arrays.stream(TaskStatusEnum.values()) |
|
||||
.filter(statusEnum -> statusEnum.getStatus().equals(status)) |
|
||||
.findFirst() |
|
||||
.map(TaskStatusEnum::getDesc) |
|
||||
.orElse(StrUtil.EMPTY); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -1,148 +0,0 @@ |
|||||
package org.dromara.workflow.controller; |
|
||||
|
|
||||
import jakarta.servlet.http.HttpServletResponse; |
|
||||
import jakarta.validation.constraints.NotBlank; |
|
||||
import jakarta.validation.constraints.NotEmpty; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.dromara.common.core.domain.R; |
|
||||
import org.dromara.common.core.validate.AddGroup; |
|
||||
import org.dromara.common.core.validate.EditGroup; |
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit; |
|
||||
import org.dromara.common.log.annotation.Log; |
|
||||
import org.dromara.common.log.enums.BusinessType; |
|
||||
import org.dromara.common.mybatis.core.page.PageQuery; |
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo; |
|
||||
import org.dromara.common.web.core.BaseController; |
|
||||
import org.dromara.workflow.domain.bo.ModelBo; |
|
||||
import org.dromara.workflow.domain.vo.ModelVo; |
|
||||
import org.dromara.workflow.service.IActModelService; |
|
||||
import org.flowable.engine.RepositoryService; |
|
||||
import org.flowable.engine.repository.Model; |
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||
import org.springframework.transaction.annotation.Transactional; |
|
||||
import org.springframework.validation.annotation.Validated; |
|
||||
import org.springframework.web.bind.annotation.*; |
|
||||
|
|
||||
import java.util.Arrays; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* 模型管理 控制层 |
|
||||
* |
|
||||
* @author may |
|
||||
*/ |
|
||||
@Validated |
|
||||
@RequiredArgsConstructor |
|
||||
@RestController |
|
||||
@RequestMapping("/workflow/model") |
|
||||
public class ActModelController extends BaseController { |
|
||||
|
|
||||
@Autowired(required = false) |
|
||||
private RepositoryService repositoryService; |
|
||||
private final IActModelService actModelService; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 分页查询模型 |
|
||||
* |
|
||||
* @param modelBo 模型参数 |
|
||||
*/ |
|
||||
@GetMapping("/list") |
|
||||
public TableDataInfo<Model> page(ModelBo modelBo, PageQuery pageQuery) { |
|
||||
return actModelService.page(modelBo, pageQuery); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 新增模型 |
|
||||
* |
|
||||
* @param modelBo 模型请求对象 |
|
||||
*/ |
|
||||
@Log(title = "模型管理", businessType = BusinessType.INSERT) |
|
||||
@RepeatSubmit() |
|
||||
@PostMapping("/save") |
|
||||
public R<Void> saveNewModel(@Validated(AddGroup.class) @RequestBody ModelBo modelBo) { |
|
||||
return toAjax(actModelService.saveNewModel(modelBo)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 查询模型 |
|
||||
* |
|
||||
* @param id 模型id |
|
||||
*/ |
|
||||
@GetMapping("/getInfo/{id}") |
|
||||
public R<ModelVo> getInfo(@NotBlank(message = "模型id不能为空") @PathVariable String id) { |
|
||||
return R.ok(actModelService.getInfo(id)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 修改模型信息 |
|
||||
* |
|
||||
* @param modelBo 模型数据 |
|
||||
*/ |
|
||||
@Log(title = "模型管理", businessType = BusinessType.UPDATE) |
|
||||
@RepeatSubmit() |
|
||||
@PutMapping(value = "/update") |
|
||||
public R<Void> update(@RequestBody ModelBo modelBo) { |
|
||||
return toAjax(actModelService.update(modelBo)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 编辑XMl模型 |
|
||||
* |
|
||||
* @param modelBo 模型数据 |
|
||||
*/ |
|
||||
@Log(title = "模型管理", businessType = BusinessType.UPDATE) |
|
||||
@RepeatSubmit() |
|
||||
@PutMapping(value = "/editModelXml") |
|
||||
public R<Void> editModel(@Validated(EditGroup.class) @RequestBody ModelBo modelBo) { |
|
||||
return toAjax(actModelService.editModelXml(modelBo)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 删除流程模型 |
|
||||
* |
|
||||
* @param ids 模型id |
|
||||
*/ |
|
||||
@Log(title = "模型管理", businessType = BusinessType.DELETE) |
|
||||
@RepeatSubmit() |
|
||||
@DeleteMapping("/{ids}") |
|
||||
@Transactional(rollbackFor = Exception.class) |
|
||||
public R<Void> delete(@NotEmpty(message = "主键不能为空") @PathVariable String[] ids) { |
|
||||
Arrays.stream(ids).parallel().forEachOrdered(repositoryService::deleteModel); |
|
||||
return R.ok(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 模型部署 |
|
||||
* |
|
||||
* @param id 模型id |
|
||||
*/ |
|
||||
@Log(title = "模型管理", businessType = BusinessType.INSERT) |
|
||||
@RepeatSubmit() |
|
||||
@PostMapping("/modelDeploy/{id}") |
|
||||
public R<Void> deploy(@NotBlank(message = "模型id不能为空") @PathVariable("id") String id) { |
|
||||
return toAjax(actModelService.modelDeploy(id)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 导出模型zip压缩包 |
|
||||
* |
|
||||
* @param modelIds 模型id |
|
||||
* @param response 相应 |
|
||||
*/ |
|
||||
@GetMapping("/export/zip/{modelIds}") |
|
||||
public void exportZip(@NotEmpty(message = "模型id不能为空") @PathVariable List<String> modelIds, |
|
||||
HttpServletResponse response) { |
|
||||
actModelService.exportZip(modelIds, response); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 复制模型 |
|
||||
* |
|
||||
* @param modelBo 模型数据 |
|
||||
*/ |
|
||||
@PostMapping("/copyModel") |
|
||||
public R<Void> copyModel(@RequestBody ModelBo modelBo) { |
|
||||
return toAjax(actModelService.copyModel(modelBo)); |
|
||||
} |
|
||||
} |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue