mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 17:12:28 +08:00
Compare commits
52 Commits
v3.6.3
...
v3.6.3last
| Author | SHA1 | Date | |
|---|---|---|---|
| 857fb53fa1 | |||
| 9db6c1a7ac | |||
| fd0461644e | |||
| 10263720d4 | |||
| 7548f3aa60 | |||
| ad3d2eb3fc | |||
| d0406fcd83 | |||
| 9159b55096 | |||
| faebdee755 | |||
| 2fc672dfab | |||
| 4dc4e87900 | |||
| 13d00a8bb4 | |||
| fb95cf7f2f | |||
| 78f048fda5 | |||
| 200adb8490 | |||
| f1496b5084 | |||
| 7b06715bff | |||
| 3091d5b6f0 | |||
| c117abb2d4 | |||
| dbc3f13c65 | |||
| ea6927a2a7 | |||
| b69a716b04 | |||
| 7e71fa26d7 | |||
| 4fed40ff7d | |||
| ee4ff35c90 | |||
| c9b92decaf | |||
| eed3bc346d | |||
| 6edef14f07 | |||
| ab49983759 | |||
| 5a09a6fb4a | |||
| ac93bf7d6b | |||
| c9c6dd5c1d | |||
| e3e1cd6b0d | |||
| f3cf90bd28 | |||
| 70847d17f1 | |||
| 2cfc39b23f | |||
| c8676b3040 | |||
| 73bd04d04a | |||
| 0ca4badb77 | |||
| 80b92ca132 | |||
| 58865bef28 | |||
| 9fd40d0973 | |||
| 266ebd9122 | |||
| fee729e16c | |||
| 10a3e9c6ba | |||
| 990f79fdfe | |||
| 6360aee0ff | |||
| 685b81e5ec | |||
| e38e395436 | |||
| 39af6e25ee | |||
| acf0713385 | |||
| cee872000a |
7
.github/ISSUE_TEMPLATE.md
vendored
7
.github/ISSUE_TEMPLATE.md
vendored
@ -1,8 +1,9 @@
|
||||
##### 版本号:
|
||||
|
||||
##### 分支: master?还是springboot3?
|
||||
|
||||
##### 前端版本:vue3版?还是 vue2版?
|
||||
|
||||
##### 前端版本: vue3版?还是 vue2版?
|
||||
|
||||
##### 问题描述:
|
||||
|
||||
@ -13,9 +14,9 @@
|
||||
|
||||
|
||||
#### 友情提示(为了提高issue处理效率):
|
||||
- 未按格式要求发帖,会被直接删掉;
|
||||
- 描述过于简单或模糊,导致无法处理的,会被直接删掉;
|
||||
- 未按格式要求发帖、描述过于简抽象的,会被直接删掉;
|
||||
- 请自己初判问题描述是否清楚,是否方便我们调查处理;
|
||||
- 针对问题请说明是Online在线功能(需说明用的主题模板),还是生成的代码功能;
|
||||
- springboot3_sas分支采用 `Spring Authorization Server` 替换 `Shiro`,目前是beta版不稳定,生产项目不要使用;
|
||||
|
||||
|
||||
|
||||
@ -76,7 +76,7 @@ Docker starts the project
|
||||
- [Docker starts the monomer background](https://help.jeecg.com/java/setup/docker/up.html)
|
||||
- [Docker starts the Vue3 front-end](http://help.jeecg.com/publish/docker.html)
|
||||
- [Docker starts the micro-service background](https://help.jeecg.com/java/springcloud/docker.html)
|
||||
|
||||
- [ChatGPT AI Config](https://help.jeecg.com/java/chatgpt.html)
|
||||
|
||||
|
||||
|
||||
@ -87,7 +87,7 @@ Technical documentation
|
||||
- Doc: [http://help.jeecg.com](http://help.jeecg.com)
|
||||
- Newbie guide: [Quick start](http://www.jeecg.com/doc/quickstart) | [video](https://space.bilibili.com/454617261/channel/series) | [Q&A ](http://www.jeecg.com/doc/qa) | [help](http://jeecg.com/doc/help) | [1 minute experience](https://my.oschina.net/jeecg/blog/3083313)
|
||||
- Microservice Development: [Monomer upgrade to microservice](https://help.jeecg.com/java/springcloud/switchcloud/monomer.html)
|
||||
- QQ group : ⑧825232878、⑦791696430、⑥730954414(full)、683903138(full)、⑤860162132(full)、④774126647(full)、③816531124(full)、②769925425(full)、①284271917(full)
|
||||
- QQ group : ⑨808791225、⑧825232878、⑦791696430、⑥730954414(full)、683903138(full)、⑤860162132(full)、④774126647(full)、③816531124(full)、②769925425(full)、①284271917(full)
|
||||
- Demo : [Vue3](http://boot3.jeecg.com) | [Vue2](http://boot.jeecg.com) | [APP](http://jeecg.com/appIndex)
|
||||
> [please click obtain account password to obtain](http://jeecg.com/doc/demo)
|
||||
|
||||
@ -441,6 +441,10 @@ Technical Architecture:
|
||||
|
||||
### Effect of system
|
||||
|
||||
##### ChatGPT AI Dialog
|
||||
> Go to the JeecgBoot background home page and click "AI Assistant" in the middle of the right side of the home page. The AI Assistant dialog screen is displayed.
|
||||

|
||||
|
||||
|
||||
##### PC
|
||||

|
||||
|
||||
12
README.md
12
README.md
@ -69,7 +69,7 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
||||
- [通过IDEA启动前后端项目](https://help.jeecg.com/java/setup/idea/startup.html)
|
||||
- [Vue3前端项目快速启动](http://help.jeecg.com/setup/startup.html)
|
||||
- [单体快速切换为微服务版](https://help.jeecg.com/java/springcloud/switchcloud/monomer.html)
|
||||
|
||||
- [ChatGPT AI助手配置文档](https://help.jeecg.com/java/chatgpt.html)
|
||||
|
||||
Docker快速启动项目
|
||||
-----------------------------------
|
||||
@ -89,7 +89,7 @@ Docker快速启动项目
|
||||
- 在线演示 : [Vue3演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex) | [敲敲云零代码](https://qiaoqiaoyun.com)
|
||||
> 演示系统的登录账号密码,请点击 [获取账号密码](http://jeecg.com/doc/demo) 获取
|
||||
>
|
||||
- QQ交流群 : ⑧825232878、⑦791696430(满)、⑥730954414(满)、683903138(满)、⑤860162132(满)、④774126647(满)、③816531124(满)、②769925425(满)、①284271917(满)
|
||||
- QQ交流群 : ⑨808791225、⑧825232878、⑦791696430(满)、⑥730954414(满)、683903138(满)、⑤860162132(满)、④774126647(满)、③816531124(满)、②769925425(满)、①284271917(满)
|
||||
> ` 提醒:【QQ群是自助服务群,建议给帮助您解决问题的同学发送指定红包,表示感谢!】 `
|
||||
|
||||
|
||||
@ -196,8 +196,8 @@ Star走势图
|
||||
* 17.支持SAAS服务模式,提供SaaS多租户架构方案。
|
||||
* 18.分布式文件服务,集成minio、阿里OSS等优秀的第三方,提供便捷的文件上传与管理,同时也支持本地存储。
|
||||
* 19.主流数据库兼容,一套代码完全兼容Mysql、Postgresql、Oracle、Sqlserver、MariaDB、达梦等主流数据库。
|
||||
* 20.集成工作流activiti、flowable,并实现了只需在页面配置流程转向,可极大的简化bpm工作流的开发;用bpm的流程设计器画出了流程走向,一个工作流基本就完成了,只需写很少量的java代码;
|
||||
* 21.低代码能力:在线流程设计,采用开源Activiti流程引擎,实现在线画流程,自定义表单,表单挂靠,业务流转
|
||||
* 20.集成工作流flowable、activiti,并实现了只需在页面配置流程转向,可极大的简化bpm工作流的开发;用bpm的流程设计器画出了流程走向,一个工作流基本就完成了,只需写很少量的java代码;
|
||||
* 21.低代码能力:在线流程设计,采用开源flowable、activiti流程引擎,实现在线画流程,自定义表单,表单挂靠,业务流转
|
||||
* 22.多数据源:及其简易的使用方式,在线配置数据源配置,便捷的从其他数据抓取数据;
|
||||
* 23.提供单点登录CAS集成方案,项目中已经提供完善的对接代码
|
||||
* 24.低代码能力:表单设计器,支持用户自定义表单布局,支持单表,一对多表单、支持select、radio、checkbox、textarea、date、popup、列表、宏等控件
|
||||
@ -477,6 +477,10 @@ JeecgBoot企业版本默认集成了activiti和flowable两套方案,大家在
|
||||
### 系统效果
|
||||
|
||||
|
||||
##### ChatGPT AI交互
|
||||
> 进入JeecgBoot后台首页,点击首页右侧中间“AI助手”,弹出AI助手对话界面。
|
||||

|
||||
|
||||
|
||||
##### PC端
|
||||

|
||||
|
||||
@ -8648,4 +8648,8 @@ INSERT INTO `tmp_report_data_income` VALUES ('中石油控股或有控股权', 3
|
||||
INSERT INTO `tmp_report_data_income` VALUES ('中石油参股', 72062.45, 0.00, 0.00, 0.00, 0.00, 0.00, 72062.75);
|
||||
INSERT INTO `tmp_report_data_income` VALUES ('非中石油', 1486526.90, 212070.72, 0.00, 0.00, 0.00, 226415.09, 1698597.62);
|
||||
|
||||
-- 修复设置用户生日格式报错
|
||||
ALTER TABLE sys_user
|
||||
MODIFY COLUMN birthday date NULL DEFAULT NULL COMMENT '生日';
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
@ -82,7 +82,7 @@
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.version}</version>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
@ -183,9 +183,14 @@
|
||||
</dependency>
|
||||
|
||||
<!-- knife4j -->
|
||||
<dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<version>3.0.3</version>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
|
||||
<version>${knife4j-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@ -158,6 +158,9 @@ public class AutoLogAspect {
|
||||
if(value!=null && value.toString().length()>length){
|
||||
return false;
|
||||
}
|
||||
if(value instanceof MultipartFile){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@ -348,8 +348,11 @@ public class CommonUtils {
|
||||
|
||||
//返回 host domain
|
||||
String baseDomainPath = null;
|
||||
int length = 80;
|
||||
if(length == serverPort){
|
||||
//update-begin---author:wangshuai---date:2024-03-15---for:【QQYUN-8561】企业微信登陆请求接口设置上下文不一致,导致接口404---
|
||||
int httpPort = 80;
|
||||
int httpsPort = 443;
|
||||
if(httpPort == serverPort || httpsPort == serverPort){
|
||||
//update-end---author:wangshuai---date:2024-03-15---for:【QQYUN-8561】企业微信登陆请求接口设置上下文不一致,导致接口404---~
|
||||
baseDomainPath = scheme + "://" + serverName + contextPath ;
|
||||
}else{
|
||||
baseDomainPath = scheme + "://" + serverName + ":" + serverPort + contextPath ;
|
||||
|
||||
@ -1,55 +1,6 @@
|
||||
package org.jeecg.common.util.sqlInjection.parse;
|
||||
|
||||
import net.sf.jsqlparser.expression.AllValue;
|
||||
import net.sf.jsqlparser.expression.AnalyticExpression;
|
||||
import net.sf.jsqlparser.expression.AnyComparisonExpression;
|
||||
import net.sf.jsqlparser.expression.ArrayConstructor;
|
||||
import net.sf.jsqlparser.expression.ArrayExpression;
|
||||
import net.sf.jsqlparser.expression.BinaryExpression;
|
||||
import net.sf.jsqlparser.expression.CaseExpression;
|
||||
import net.sf.jsqlparser.expression.CastExpression;
|
||||
import net.sf.jsqlparser.expression.CollateExpression;
|
||||
import net.sf.jsqlparser.expression.ConnectByRootOperator;
|
||||
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
|
||||
import net.sf.jsqlparser.expression.DateValue;
|
||||
import net.sf.jsqlparser.expression.DoubleValue;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.ExpressionVisitor;
|
||||
import net.sf.jsqlparser.expression.ExtractExpression;
|
||||
import net.sf.jsqlparser.expression.Function;
|
||||
import net.sf.jsqlparser.expression.HexValue;
|
||||
import net.sf.jsqlparser.expression.IntervalExpression;
|
||||
import net.sf.jsqlparser.expression.JdbcNamedParameter;
|
||||
import net.sf.jsqlparser.expression.JdbcParameter;
|
||||
import net.sf.jsqlparser.expression.JsonAggregateFunction;
|
||||
import net.sf.jsqlparser.expression.JsonExpression;
|
||||
import net.sf.jsqlparser.expression.JsonFunction;
|
||||
import net.sf.jsqlparser.expression.JsonFunctionExpression;
|
||||
import net.sf.jsqlparser.expression.KeepExpression;
|
||||
import net.sf.jsqlparser.expression.LongValue;
|
||||
import net.sf.jsqlparser.expression.MySQLGroupConcat;
|
||||
import net.sf.jsqlparser.expression.NextValExpression;
|
||||
import net.sf.jsqlparser.expression.NotExpression;
|
||||
import net.sf.jsqlparser.expression.NullValue;
|
||||
import net.sf.jsqlparser.expression.NumericBind;
|
||||
import net.sf.jsqlparser.expression.OracleHierarchicalExpression;
|
||||
import net.sf.jsqlparser.expression.OracleHint;
|
||||
import net.sf.jsqlparser.expression.OracleNamedFunctionParameter;
|
||||
import net.sf.jsqlparser.expression.Parenthesis;
|
||||
import net.sf.jsqlparser.expression.RowConstructor;
|
||||
import net.sf.jsqlparser.expression.RowGetExpression;
|
||||
import net.sf.jsqlparser.expression.SignedExpression;
|
||||
import net.sf.jsqlparser.expression.StringValue;
|
||||
import net.sf.jsqlparser.expression.TimeKeyExpression;
|
||||
import net.sf.jsqlparser.expression.TimeValue;
|
||||
import net.sf.jsqlparser.expression.TimestampValue;
|
||||
import net.sf.jsqlparser.expression.TimezoneExpression;
|
||||
import net.sf.jsqlparser.expression.TryCastExpression;
|
||||
import net.sf.jsqlparser.expression.UserVariable;
|
||||
import net.sf.jsqlparser.expression.ValueListExpression;
|
||||
import net.sf.jsqlparser.expression.VariableAssignment;
|
||||
import net.sf.jsqlparser.expression.WhenClause;
|
||||
import net.sf.jsqlparser.expression.XMLSerializeExpr;
|
||||
import net.sf.jsqlparser.expression.*;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
|
||||
@ -215,6 +166,23 @@ public class ConstAnalyzer implements ExpressionVisitor, ItemsListVisitor {
|
||||
expr.getBetweenExpressionEnd().accept(this);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 用于处理 OverlapsCondition 类型的表达式
|
||||
// * @param overlapsCondition
|
||||
// */
|
||||
// @Override
|
||||
// public void visit(OverlapsCondition overlapsCondition) {
|
||||
// constFlag.set(false);
|
||||
// }
|
||||
// /**
|
||||
// * 用于处理 SafeCastExpression 类型的表达式。
|
||||
// * @param safeCastExpression
|
||||
// */
|
||||
// @Override
|
||||
// public void visit(SafeCastExpression safeCastExpression) {
|
||||
// constFlag.set(false);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void visit(EqualsTo expr) {
|
||||
visitBinaryExpression(expr);
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
package org.jeecg.config;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.SpringApplicationRunListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 启动程序修改DruidWallConfig配置
|
||||
* 允许SELECT语句的WHERE子句是一个永真条件
|
||||
* @author eightmonth@qq.com
|
||||
* @date 2024/4/8 11:37
|
||||
*/
|
||||
public class DruidWallConfigRegister implements SpringApplicationRunListener {
|
||||
|
||||
public SpringApplication application;
|
||||
|
||||
private String[] args;
|
||||
|
||||
|
||||
/**
|
||||
* 必备,否则启动报错
|
||||
* @param application
|
||||
* @param args
|
||||
*/
|
||||
public DruidWallConfigRegister(SpringApplication application, String[] args) {
|
||||
this.application = application;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextLoaded(ConfigurableApplicationContext context) {
|
||||
ConfigurableEnvironment env = context.getEnvironment();
|
||||
Map<String, Object> props = new HashMap<>();
|
||||
props.put("spring.datasource.dynamic.druid.wall.selectWhereAlwayTrueCheck", false);
|
||||
|
||||
MutablePropertySources propertySources = env.getPropertySources();
|
||||
|
||||
PropertySource<Map<String, Object>> propertySource = new MapPropertySource("jeecg-datasource-config", props);
|
||||
|
||||
propertySources.addLast(propertySource);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
package org.jeecg.config;
|
||||
|
||||
|
||||
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.springframework.beans.BeansException;
|
||||
@ -19,15 +18,13 @@ import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.ParameterBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.oas.annotations.EnableOpenApi;
|
||||
import springfox.documentation.schema.ModelRef;
|
||||
import springfox.documentation.service.*;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
|
||||
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
@ -39,8 +36,7 @@ import java.util.stream.Collectors;
|
||||
* @Author scott
|
||||
*/
|
||||
@Configuration
|
||||
@EnableSwagger2 //开启 Swagger2
|
||||
@EnableKnife4j //开启 knife4j,可以不写
|
||||
@EnableSwagger2WebMvc
|
||||
@Import(BeanValidatorPluginsConfiguration.class)
|
||||
public class Swagger2Config implements WebMvcConfigurer {
|
||||
|
||||
@ -152,7 +148,7 @@ public class Swagger2Config implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
|
||||
if (bean instanceof WebMvcRequestHandlerProvider) {
|
||||
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
|
||||
}
|
||||
return bean;
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
package org.jeecg.config.shiro;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 免认证注解,认证系统结合spring MVC的@RequestMapping获取请求路径进行免登录配置
|
||||
* @author eightmonth@qq.com
|
||||
* @date 2024/2/28 9:58
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface IgnoreAuth {
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package org.jeecg.config.shiro;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
|
||||
@ -17,15 +18,18 @@ import org.jeecg.config.shiro.filters.CustomShiroFilterFactoryBean;
|
||||
import org.jeecg.config.shiro.filters.JwtFilter;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.*;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.filter.DelegatingFilterProxy;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.JedisCluster;
|
||||
@ -33,6 +37,7 @@ import redis.clients.jedis.JedisCluster;
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@ -53,7 +58,6 @@ public class ShiroConfig {
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
@Autowired(required = false)
|
||||
private RedisProperties redisProperties;
|
||||
|
||||
/**
|
||||
* Filter Chain定义说明
|
||||
*
|
||||
@ -148,7 +152,7 @@ public class ShiroConfig {
|
||||
//大屏模板例子
|
||||
filterChainDefinitionMap.put("/test/bigScreen/**", "anon");
|
||||
filterChainDefinitionMap.put("/bigscreen/template1/**", "anon");
|
||||
filterChainDefinitionMap.put("/bigscreen/template1/**", "anon");
|
||||
filterChainDefinitionMap.put("/bigscreen/template2/**", "anon");
|
||||
//filterChainDefinitionMap.put("/test/jeecgDemo/rabbitMqClientTest/**", "anon"); //MQ测试
|
||||
//filterChainDefinitionMap.put("/test/jeecgDemo/html", "anon"); //模板页面
|
||||
//filterChainDefinitionMap.put("/test/jeecgDemo/redis/**", "anon"); //redis测试
|
||||
|
||||
@ -8,6 +8,7 @@ import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.shiro.JwtToken;
|
||||
import org.jeecg.config.shiro.ignore.InMemoryIgnoreAuth;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@ -47,6 +48,10 @@ public class JwtFilter extends BasicHttpAuthenticationFilter {
|
||||
@Override
|
||||
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
|
||||
try {
|
||||
// 判断当前路径是不是注解了@IngoreAuth路径,如果是,则放开验证
|
||||
if (InMemoryIgnoreAuth.contains(((HttpServletRequest) request).getServletPath())) {
|
||||
return true;
|
||||
}
|
||||
executeLogin(request, response);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
|
||||
@ -0,0 +1,104 @@
|
||||
package org.jeecg.config.shiro.ignore;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.jeecg.config.shiro.IgnoreAuth;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 在spring boot初始化时,根据@RestController注解获取当前spring容器中的bean
|
||||
* @author eightmonth@qq.com
|
||||
* @date 2024/4/18 11:35
|
||||
*/
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class IgnoreAuthPostProcessor implements ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
List<String> ignoreAuthUrls = new ArrayList<>();
|
||||
if (event.getApplicationContext().getParent() == null) {
|
||||
// 只处理根应用上下文的事件,避免在子上下文中重复处理
|
||||
Map<String, Object> restControllers = applicationContext.getBeansWithAnnotation(RestController.class);
|
||||
for (Object restController : restControllers.values()) {
|
||||
// 如 online系统的controller并不是spring 默认生成
|
||||
if (restController instanceof Advised) {
|
||||
ignoreAuthUrls.addAll(postProcessRestController(restController));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(ignoreAuthUrls)) {
|
||||
InMemoryIgnoreAuth.set(ignoreAuthUrls);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> postProcessRestController(Object restController) {
|
||||
List<String> ignoreAuthUrls = new ArrayList<>();
|
||||
Class<?> clazz = ((Advised) restController).getTargetClass();
|
||||
RequestMapping base = clazz.getAnnotation(RequestMapping.class);
|
||||
String[] baseUrl = Objects.nonNull(base) ? base.value() : new String[]{};
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
|
||||
for (Method method : methods) {
|
||||
if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(RequestMapping.class)) {
|
||||
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
|
||||
String[] uri = requestMapping.value();
|
||||
ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
|
||||
} else if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(GetMapping.class)) {
|
||||
GetMapping requestMapping = method.getAnnotation(GetMapping.class);
|
||||
String[] uri = requestMapping.value();
|
||||
ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
|
||||
} else if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(PostMapping.class)) {
|
||||
PostMapping requestMapping = method.getAnnotation(PostMapping.class);
|
||||
String[] uri = requestMapping.value();
|
||||
ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
|
||||
} else if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(PutMapping.class)) {
|
||||
PutMapping requestMapping = method.getAnnotation(PutMapping.class);
|
||||
String[] uri = requestMapping.value();
|
||||
ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
|
||||
} else if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(DeleteMapping.class)) {
|
||||
DeleteMapping requestMapping = method.getAnnotation(DeleteMapping.class);
|
||||
String[] uri = requestMapping.value();
|
||||
ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
|
||||
} else if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(PatchMapping.class)) {
|
||||
PatchMapping requestMapping = method.getAnnotation(PatchMapping.class);
|
||||
String[] uri = requestMapping.value();
|
||||
ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
|
||||
}
|
||||
}
|
||||
|
||||
return ignoreAuthUrls;
|
||||
}
|
||||
|
||||
private List<String> rebuildUrl(String[] bases, String[] uris) {
|
||||
List<String> urls = new ArrayList<>();
|
||||
if (bases.length > 0) {
|
||||
for (String base : bases) {
|
||||
for (String uri : uris) {
|
||||
urls.add(prefix(base) + prefix(uri));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Arrays.stream(uris).forEach(uri -> {
|
||||
urls.add(prefix(uri));
|
||||
});
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
private String prefix(String seg) {
|
||||
return seg.startsWith("/") ? seg : "/"+seg;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package org.jeecg.config.shiro.ignore;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 使用内存存储通过@IgnoreAuth注解的url,配合JwtFilter进行免登录校验
|
||||
* PS:无法使用ThreadLocal进行存储,因为ThreadLocal装载时,JwtFilter已经初始化完毕,导致该类获取ThreadLocal为空
|
||||
* @author eightmonth@qq.com
|
||||
* @date 2024/4/18 15:02
|
||||
*/
|
||||
public class InMemoryIgnoreAuth {
|
||||
private static final List<String> IGNORE_AUTH_LIST = new ArrayList<>();
|
||||
|
||||
public InMemoryIgnoreAuth() {}
|
||||
|
||||
public static void set(List<String> list) {
|
||||
IGNORE_AUTH_LIST.addAll(list);
|
||||
}
|
||||
|
||||
public static List<String> get() {
|
||||
return IGNORE_AUTH_LIST;
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
IGNORE_AUTH_LIST.clear();
|
||||
}
|
||||
|
||||
public static boolean contains(String url) {
|
||||
for (String ignoreAuth : IGNORE_AUTH_LIST) {
|
||||
if (url.endsWith(ignoreAuth)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.SpringApplicationRunListener=\
|
||||
org.jeecg.config.DruidWallConfigRegister
|
||||
@ -29,15 +29,15 @@
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
<artifactId>jeewx-api</artifactId>
|
||||
</dependency>
|
||||
<!-- 积木报表 -->
|
||||
<!-- 积木报表设计 -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.jimureport</groupId>
|
||||
<artifactId>jimureport-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- 积木仪表盘 -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.jimureport</groupId>
|
||||
<artifactId>jimureport-drag</artifactId>
|
||||
<version>2.0.1</version>
|
||||
</dependency>
|
||||
<!-- 积木报表 mongo redis 支持包
|
||||
<dependency>
|
||||
|
||||
@ -79,6 +79,7 @@ public enum RangeDateEnum {
|
||||
//本周
|
||||
calendar1.set(Calendar.DAY_OF_WEEK, 2);
|
||||
|
||||
calendar2.set(Calendar.DAY_OF_WEEK,2);
|
||||
calendar2.add(Calendar.WEEK_OF_MONTH,1);
|
||||
calendar2.add(Calendar.DAY_OF_WEEK,-1);
|
||||
} else if(SZ.key.equals(key)){
|
||||
|
||||
@ -365,7 +365,8 @@ public class SysDepartController {
|
||||
//}
|
||||
//});
|
||||
//step.2 组装导出数据
|
||||
List<SysDepartExportVo> sysDepartExportVos = sysDepartService.getExportDepart(sysDepart.getTenantId());
|
||||
Integer tenantId = sysDepart == null ? null : sysDepart.getTenantId();
|
||||
List<SysDepartExportVo> sysDepartExportVos = sysDepartService.getExportDepart(tenantId);
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "部门列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysDepartExportVo.class);
|
||||
|
||||
@ -223,7 +223,7 @@ public interface ISysDepartService extends IService<SysDepart>{
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
List<SysDepartExportVo> getExportDepart(int tenantId);
|
||||
List<SysDepartExportVo> getExportDepart(Integer tenantId);
|
||||
|
||||
/**
|
||||
* 导出系统部门excel
|
||||
|
||||
@ -1220,7 +1220,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<SysDepartExportVo> getExportDepart(int tenantId) {
|
||||
public List<SysDepartExportVo> getExportDepart(Integer tenantId) {
|
||||
//获取父级部门
|
||||
List<SysDepartExportVo> parentDepart = departMapper.getSysDepartList("", tenantId);
|
||||
//子部门
|
||||
|
||||
@ -21,6 +21,7 @@ import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.system.vo.DictModelMany;
|
||||
import org.jeecg.common.system.vo.DictQuery;
|
||||
import org.jeecg.common.util.CommonUtils;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.SqlInjectionUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
@ -67,6 +68,9 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ISysBaseAPI sysBaseAPI;
|
||||
@Lazy
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Override
|
||||
public boolean duplicateCheckData(DuplicateCheckVo duplicateCheckVo) {
|
||||
@ -80,7 +84,8 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
|
||||
// 2.SQL注入check(只限制非法串改数据库)
|
||||
//关联表字典(举例:sys_user,realname,id)
|
||||
SqlInjectionUtil.filterContent(table, fieldName);
|
||||
SqlInjectionUtil.filterContent(table);
|
||||
SqlInjectionUtil.filterContent(fieldName);
|
||||
|
||||
String checkSql = table + SymbolConstant.COMMA + fieldName + SymbolConstant.COMMA;
|
||||
// 【QQYUN-6533】表字典白名单check
|
||||
@ -264,7 +269,8 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
|
||||
// 1.SQL注入校验(只限制非法串改数据库)
|
||||
SqlInjectionUtil.specialFilterContentForDictSql(table);
|
||||
SqlInjectionUtil.filterContent(text, code);
|
||||
SqlInjectionUtil.filterContent(text);
|
||||
SqlInjectionUtil.filterContent(code);
|
||||
SqlInjectionUtil.specialFilterContentForDictSql(filterSql);
|
||||
|
||||
String str = table+","+text+","+code;
|
||||
@ -565,16 +571,17 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
}
|
||||
|
||||
//下拉搜索组件 支持传入排序信息 查询排序
|
||||
if(oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)){
|
||||
filterSql += sqlWhere + sqlAnd + condition + sqlAnd + keywordSql;
|
||||
}else if(oConvertUtils.isNotEmpty(condition)){
|
||||
filterSql += sqlWhere + sqlAnd + condition;
|
||||
}else if(oConvertUtils.isNotEmpty(keywordSql)){
|
||||
filterSql += sqlWhere + sqlAnd + keywordSql;
|
||||
} else if (tableHasWhere){
|
||||
filterSql += sqlWhere;
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240327 for:[QQYUN-8514]Online表单中 下拉搜索框 搜索时报sql错误,生成的SQL多了一个 “and" ------------
|
||||
if (oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)) {
|
||||
filterSql += sqlWhere + (tableHasWhere ? sqlAnd : " ") + condition + sqlAnd + keywordSql;
|
||||
} else if (oConvertUtils.isNotEmpty(condition)) {
|
||||
filterSql += sqlWhere + (tableHasWhere ? sqlAnd : " ") + condition;
|
||||
} else if (oConvertUtils.isNotEmpty(keywordSql)) {
|
||||
filterSql += sqlWhere + (tableHasWhere ? sqlAnd : " ") + keywordSql;
|
||||
} else if (tableHasWhere) {
|
||||
filterSql += sqlWhere;
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240327 for:[QQYUN-8514]Online表单中 下拉搜索框 搜索时报sql错误,生成的SQL多了一个 “and" ------------
|
||||
// 增加排序逻辑
|
||||
if (oConvertUtils.isNotEmpty(orderField)) {
|
||||
filterSql += " order by " + orderField + " " + orderType;
|
||||
@ -818,6 +825,8 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
sysDict.setId(id);
|
||||
baseMapper.updateById(sysDict);
|
||||
this.updateDictItem(id,sysDictVo.getDictItemsList());
|
||||
// 删除字典缓存
|
||||
redisUtil.removeAll(CacheConstant.SYS_DICT_CACHE + "::" + dict.getDictCode());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -217,7 +217,7 @@
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
const ids = selectedRowKeys.value.filter(item => !item.includes('loading'))
|
||||
const ids = selectedRowKeys.value.filter(item => !item.includes('loadChild'))
|
||||
await batchDelete${entityName}({id: ids}, importSuccess);
|
||||
}
|
||||
/**
|
||||
|
||||
@ -261,7 +261,7 @@
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
const ids = selectedRowKeys.value.filter((item) => !item.includes('loading'));
|
||||
const ids = selectedRowKeys.value.filter((item) => !item.includes('loadChild'));
|
||||
await batchDelete${entityName}({ id: ids }, success);
|
||||
}
|
||||
|
||||
|
||||
@ -842,7 +842,7 @@ export const superQuerySchema = {
|
||||
fields: {
|
||||
<#list sub.colums as subCol>
|
||||
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#if subCol.isShowList =='Y' && subCol.fieldName !='id' && po.fieldName !='delFlag'>
|
||||
<#if subCol.isShowList =='Y' && subCol.fieldName !='id' && subCol.fieldName !='delFlag'>
|
||||
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
${superQueryFieldListForVue3(subCol,subCol_index)},
|
||||
</#if>
|
||||
|
||||
@ -783,7 +783,7 @@ export const superQuerySchema = {
|
||||
fields: {
|
||||
<#list sub.colums as subCol>
|
||||
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#if subCol.isShowList =='Y' && subCol.fieldName !='id' && po.fieldName !='delFlag'>
|
||||
<#if subCol.isShowList =='Y' && subCol.fieldName !='id' && subCol.fieldName !='delFlag'>
|
||||
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
${superQueryFieldListForVue3(subCol,subCol_index)},
|
||||
</#if>
|
||||
|
||||
@ -776,7 +776,7 @@ export const superQuerySchema = {
|
||||
fields: {
|
||||
<#list sub.colums as subCol>
|
||||
<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
<#if subCol.isShowList =='Y' && subCol.fieldName !='id' && po.fieldName !='delFlag'>
|
||||
<#if subCol.isShowList =='Y' && subCol.fieldName !='id' && subCol.fieldName !='delFlag'>
|
||||
<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
|
||||
${superQueryFieldListForVue3(subCol,subCol_index)},
|
||||
</#if>
|
||||
|
||||
@ -43,11 +43,10 @@
|
||||
<version>${dm8.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--支持 mysql5.7、mysql8、MariaDB10.3.16-->
|
||||
<!-- flyway支持 mysql5.7、mysql8、MariaDB10.3.16 -->
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
<version>7.15.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package org.jeecg;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.shiro.ignore.InMemoryIgnoreAuth;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
|
||||
@ -0,0 +1,136 @@
|
||||
package org.jeecg.config.flyway;
|
||||
|
||||
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.flywaydb.core.api.FlywayException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 初始化flyway配置 修改之后支持多数据源,当出现异常时打印日志,不影响项目启动
|
||||
*
|
||||
* @author: wangshuai
|
||||
* @date: 2024/3/12 10:03
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class FlywayConfig {
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
/**
|
||||
* 是否开启flyway
|
||||
*/
|
||||
@Value("${spring.flyway.enabled:false}")
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* 编码格式,默认UTF-8
|
||||
*/
|
||||
@Value("${spring.flyway.encoding:UTF-8}")
|
||||
private String encoding;
|
||||
|
||||
/**
|
||||
* 迁移sql脚本文件存放路径,官方默认db/migration
|
||||
*/
|
||||
@Value("${spring.flyway.locations:}")
|
||||
private String locations;
|
||||
|
||||
/**
|
||||
* 迁移sql脚本文件名称的前缀,默认V
|
||||
*/
|
||||
@Value("${spring.flyway.sql-migration-prefix:V}")
|
||||
private String sqlMigrationPrefix;
|
||||
|
||||
/**
|
||||
* 迁移sql脚本文件名称的分隔符,默认2个下划线__
|
||||
*/
|
||||
@Value("${spring.flyway.sql-migration-separator:__}")
|
||||
private String sqlMigrationSeparator;
|
||||
|
||||
/**
|
||||
* 文本前缀
|
||||
*/
|
||||
@Value("${spring.flyway.placeholder-prefix:#(}")
|
||||
private String placeholderPrefix;
|
||||
|
||||
/**
|
||||
* 文本后缀
|
||||
*/
|
||||
@Value("${spring.flyway.placeholder-suffix:)}")
|
||||
private String placeholderSuffix;
|
||||
|
||||
/**
|
||||
* 迁移sql脚本文件名称的后缀
|
||||
*/
|
||||
@Value("${spring.flyway.sql-migration-suffixes:.sql}")
|
||||
private String sqlMigrationSuffixes;
|
||||
|
||||
/**
|
||||
* 迁移时是否进行校验,默认true
|
||||
*/
|
||||
@Value("${spring.flyway.validate-on-migrate:true}")
|
||||
private Boolean validateOnMigrate;
|
||||
|
||||
/**
|
||||
* 当迁移发现数据库非空且存在没有元数据的表时,自动执行基准迁移,新建schema_version表
|
||||
*/
|
||||
@Value("${spring.flyway.baseline-on-migrate:true}")
|
||||
private Boolean baselineOnMigrate;
|
||||
|
||||
/**
|
||||
* 是否关闭要清除已有库下的表功能,生产环境必须为true,否则会删库,非常重要!!!
|
||||
*/
|
||||
@Value("${spring.flyway.clean-disabled:true}")
|
||||
private Boolean cleanDisabled;
|
||||
|
||||
@Bean
|
||||
public void migrate() {
|
||||
if(!enabled){
|
||||
return;
|
||||
}
|
||||
|
||||
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
|
||||
Map<String, DataSource> dataSources = ds.getDataSources();
|
||||
dataSources.forEach((k, v) -> {
|
||||
if("master".equals(k)){
|
||||
String databaseType = environment.getProperty("spring.datasource.dynamic.datasource." + k + ".url");
|
||||
if (databaseType != null && databaseType.contains("mysql")) {
|
||||
try {
|
||||
Flyway flyway = Flyway.configure()
|
||||
.dataSource(v)
|
||||
.locations(locations)
|
||||
.encoding(encoding)
|
||||
.sqlMigrationPrefix(sqlMigrationPrefix)
|
||||
.sqlMigrationSeparator(sqlMigrationSeparator)
|
||||
.placeholderPrefix(placeholderPrefix)
|
||||
.placeholderSuffix(placeholderSuffix)
|
||||
.sqlMigrationSuffixes(sqlMigrationSuffixes)
|
||||
.validateOnMigrate(validateOnMigrate)
|
||||
.baselineOnMigrate(baselineOnMigrate)
|
||||
.cleanDisabled(cleanDisabled)
|
||||
.load();
|
||||
flyway.migrate();
|
||||
log.info("【升级提示】平台集成了MySQL库的Flyway,数据库版本自动升级! ");
|
||||
} catch (FlywayException e) {
|
||||
log.error("【升级提示】flyway执行sql脚本失败", e);
|
||||
}
|
||||
} else {
|
||||
log.warn("【升级提示】平台只集成了MySQL库的Flyway,实现了数据库版本自动升级! 其他类型的数据库,您可以考虑手工升级~");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,9 @@ spring:
|
||||
resource:
|
||||
static-locations: classpath:/static/,classpath:/public/
|
||||
autoconfigure:
|
||||
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
|
||||
exclude:
|
||||
- com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
|
||||
- org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
|
||||
datasource:
|
||||
druid:
|
||||
stat-view-servlet:
|
||||
@ -261,7 +263,7 @@ jeecg:
|
||||
password:
|
||||
type: STANDALONE
|
||||
enabled: true
|
||||
# ChartGPT对接配置
|
||||
# ai-chat
|
||||
ai-chat:
|
||||
# 是否开启;必须。
|
||||
enabled: false
|
||||
|
||||
@ -118,7 +118,9 @@ spring:
|
||||
resource:
|
||||
static-locations: classpath:/static/,classpath:/public/
|
||||
autoconfigure:
|
||||
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
|
||||
exclude:
|
||||
- com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
|
||||
- org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
|
||||
datasource:
|
||||
druid:
|
||||
stat-view-servlet:
|
||||
|
||||
@ -118,7 +118,9 @@ spring:
|
||||
resource:
|
||||
static-locations: classpath:/static/,classpath:/public/
|
||||
autoconfigure:
|
||||
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
|
||||
exclude:
|
||||
- com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
|
||||
- org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
|
||||
datasource:
|
||||
druid:
|
||||
stat-view-servlet:
|
||||
|
||||
@ -73,9 +73,14 @@
|
||||
<!-- Swagger API文档 -->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
|
||||
<version>${knife4j-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
package org.jeecg.handler.swagger;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.swagger.web.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -18,6 +20,11 @@ import java.util.List;
|
||||
@RequestMapping("/swagger-resources")
|
||||
public class SwaggerResourceController {
|
||||
private MySwaggerResourceProvider swaggerResourceProvider;
|
||||
/**
|
||||
* 生产环境,关闭swagger文档
|
||||
*/
|
||||
@Value("${knife4j.production:#{null}}")
|
||||
private Boolean production;
|
||||
|
||||
@Autowired
|
||||
public SwaggerResourceController(MySwaggerResourceProvider swaggerResourceProvider) {
|
||||
@ -36,6 +43,10 @@ public class SwaggerResourceController {
|
||||
|
||||
@RequestMapping
|
||||
public ResponseEntity<List<SwaggerResource>> swaggerResources() {
|
||||
// 是否开启生产环境屏蔽swagger
|
||||
if (production != null && production) {
|
||||
return new ResponseEntity<>(new ArrayList<>(), HttpStatus.OK);
|
||||
}
|
||||
return new ResponseEntity<>(swaggerResourceProvider.get(), HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
@ -49,6 +49,12 @@
|
||||
<artifactId>jeecg-cloud-test-rabbitmq</artifactId>
|
||||
<version>${jeecgboot.version}</version>
|
||||
</dependency>-->
|
||||
<!-- rocketmq例子-->
|
||||
<!--<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-cloud-test-rocketmq</artifactId>
|
||||
<version>${jeecgboot.version}</version>
|
||||
</dependency>-->
|
||||
<!-- 分布式事务例子
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
|
||||
@ -16,6 +16,7 @@ import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
@ -35,6 +36,7 @@ public class JeecgSystemCloudApplication extends SpringBootServletInitializer im
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||
|
||||
return application.sources(JeecgSystemCloudApplication.class);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
<?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.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-cloud-test</artifactId>
|
||||
<version>3.6.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<description>消息队列测试模块</description>
|
||||
<artifactId>jeecg-cloud-test-rocketmq</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- rocketmq消息队列-->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-starter-rocketmq</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,28 @@
|
||||
package org.jeecg.modules.test.rocketmq.constant;
|
||||
|
||||
/**
|
||||
* 微服务单元测试常量定义
|
||||
* @author: zyf
|
||||
* @date: 2022/04/21
|
||||
*/
|
||||
public interface CloudConstant {
|
||||
|
||||
|
||||
/**
|
||||
* MQ测试队列名字
|
||||
*/
|
||||
public final static String MQ_JEECG_PLACE_ORDER = "jeecg_place_order";
|
||||
public final static String MQ_JEECG_PLACE_ORDER_TIME = "jeecg_place_order_time";
|
||||
|
||||
/**
|
||||
* MQ测试消息总线
|
||||
*/
|
||||
public final static String MQ_DEMO_BUS_EVENT = "demoBusEvent";
|
||||
|
||||
/**
|
||||
* 分布式锁lock key
|
||||
*/
|
||||
public final static String REDISSON_DEMO_LOCK_KEY1 = "demoLockKey1";
|
||||
public final static String REDISSON_DEMO_LOCK_KEY2 = "demoLockKey2";
|
||||
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package org.jeecg.modules.test.rocketmq.controller;
|
||||
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.jeecg.boot.starter.rabbitmq.client.RabbitMqClient;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.base.BaseMap;
|
||||
import org.jeecg.modules.test.rocketmq.constant.CloudConstant;
|
||||
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 javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* RocketMqClient发送消息
|
||||
* @author: zyf
|
||||
* @date: 2022/04/21
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/test")
|
||||
@Api(tags = "【微服务】MQ单元测试")
|
||||
public class JeecgMqTestController {
|
||||
|
||||
@Autowired
|
||||
private RabbitMqClient rabbitMqClient;
|
||||
|
||||
|
||||
/**
|
||||
* 测试方法:快速点击发送MQ消息
|
||||
* 观察三个接受者如何分配处理消息:HelloReceiver1、HelloReceiver2、HelloReceiver3,会均衡分配
|
||||
*
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/rocketmq")
|
||||
@ApiOperation(value = "测试rocketmq", notes = "测试rocketmq")
|
||||
public Result<?> rabbitMqClientTest(HttpServletRequest req) {
|
||||
//rabbitmq消息队列测试
|
||||
BaseMap map = new BaseMap();
|
||||
map.put("orderId", RandomUtil.randomNumbers(10));
|
||||
rabbitMqClient.sendMessage(CloudConstant.MQ_JEECG_PLACE_ORDER, map);
|
||||
rabbitMqClient.sendMessage(CloudConstant.MQ_JEECG_PLACE_ORDER_TIME, map,2);
|
||||
return Result.OK("MQ发送消息成功");
|
||||
}
|
||||
|
||||
@GetMapping(value = "/rocketmq2")
|
||||
@ApiOperation(value = "rocketmq消息总线测试", notes = "rocketmq消息总线测试")
|
||||
public Result<?> rabbitmq2(HttpServletRequest req) {
|
||||
|
||||
//rabbitmq消息总线测试
|
||||
BaseMap params = new BaseMap();
|
||||
params.put("orderId", "123456");
|
||||
rabbitMqClient.publishEvent(CloudConstant.MQ_DEMO_BUS_EVENT, params);
|
||||
return Result.OK("MQ发送消息成功");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package org.jeecg.modules.test.rocketmq.event;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.boot.starter.rabbitmq.event.EventObj;
|
||||
import org.jeecg.boot.starter.rabbitmq.event.JeecgBusEventHandler;
|
||||
import org.jeecg.common.base.BaseMap;
|
||||
import org.jeecg.modules.test.rocketmq.constant.CloudConstant;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 消息处理器【发布订阅】
|
||||
* @author: zyf
|
||||
* @date: 2022/04/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Component(CloudConstant.MQ_DEMO_BUS_EVENT)
|
||||
public class DemoBusEvent implements JeecgBusEventHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void onMessage(EventObj obj) {
|
||||
if (ObjectUtil.isNotEmpty(obj)) {
|
||||
BaseMap baseMap = obj.getBaseMap();
|
||||
String orderId = baseMap.get("orderId");
|
||||
log.info("业务处理----订单ID:" + orderId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.jeecg.modules.test.rocketmq.listener;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.jeecg.common.base.BaseMap;
|
||||
import org.jeecg.modules.test.rocketmq.constant.CloudConstant;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 定义接收者(可以定义N个接受者,消息会均匀的发送到N个接收者中)
|
||||
*
|
||||
* RabbitMq接受者1
|
||||
* (@RabbitListener声明类上,一个类只能监听一个队列)
|
||||
* @author: zyf
|
||||
* @date: 2022/04/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RocketMQMessageListener(topic = CloudConstant.MQ_JEECG_PLACE_ORDER, consumerGroup = "helloReceiver1")
|
||||
public class HelloReceiver1 implements RocketMQListener<BaseMap> {
|
||||
|
||||
public void onMessage(BaseMap baseMap) {
|
||||
log.info("helloReceiver1接收消息:" + baseMap);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.jeecg.modules.test.rocketmq.listener;//package org.jeecg.modules.cloud.rabbitmq;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.jeecg.common.base.BaseMap;
|
||||
import org.jeecg.modules.test.rocketmq.constant.CloudConstant;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 定义接收者(可以定义N个接受者,消息会均匀的发送到N个接收者中)
|
||||
*
|
||||
* RabbitMq接受者2
|
||||
* (@RabbitListener声明类上,一个类只能监听一个队列)
|
||||
* @author: zyf
|
||||
* @date: 2022/04/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RocketMQMessageListener(topic = CloudConstant.MQ_JEECG_PLACE_ORDER, consumerGroup = "helloReceiver2")
|
||||
public class HelloReceiver2 implements RocketMQListener<BaseMap> {
|
||||
|
||||
public void onMessage(BaseMap baseMap) {
|
||||
log.info("helloReceiver2接收消息:" + baseMap);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.jeecg.modules.test.rocketmq.listener;//package org.jeecg.modules.cloud.rabbitmq;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.jeecg.common.base.BaseMap;
|
||||
import org.jeecg.modules.test.rocketmq.constant.CloudConstant;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 定义接收者(可以定义N个接受者,消息会均匀的发送到N个接收者中)
|
||||
*
|
||||
* RabbitMq接受者3【我是处理人3】
|
||||
* (@RabbitListener声明类方法上,一个类可以多监听多个队列)
|
||||
* @author: zyf
|
||||
* @date: 2022/04/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RocketMQMessageListener(topic = CloudConstant.MQ_JEECG_PLACE_ORDER, consumerGroup = "helloReceiver3")
|
||||
public class HelloReceiver3 implements RocketMQListener<BaseMap> {
|
||||
|
||||
public void onMessage(BaseMap baseMap) {
|
||||
log.info("helloReceiver3接收消息:" + baseMap);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package org.jeecg.modules.test.rocketmq.listener;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.jeecg.common.base.BaseMap;
|
||||
import org.jeecg.modules.test.rocketmq.constant.CloudConstant;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 定义接收者(可以定义N个接受者,消息会均匀的发送到N个接收者中)
|
||||
* @author: zyf
|
||||
* @date: 2022/04/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RocketMQMessageListener(topic = CloudConstant.MQ_JEECG_PLACE_ORDER_TIME, consumerGroup = "helloTimeReceiver")
|
||||
public class HelloTimeReceiver implements RocketMQListener<BaseMap> {
|
||||
|
||||
public void onMessage(BaseMap baseMap) {
|
||||
log.info("helloTimeReceiver接收消息:" + baseMap);
|
||||
}
|
||||
|
||||
}
|
||||
@ -24,5 +24,6 @@
|
||||
<module>jeecg-cloud-test-more</module>
|
||||
<module>jeecg-cloud-test-rabbitmq</module>
|
||||
<module>jeecg-cloud-test-seata</module>
|
||||
<module>jeecg-cloud-test-rocketmq</module>
|
||||
</modules>
|
||||
</project>
|
||||
68
pom.xml
68
pom.xml
@ -40,8 +40,7 @@
|
||||
<xxl-job-core.version>2.2.0</xxl-job-core.version>
|
||||
<fastjson.version>1.2.83</fastjson.version>
|
||||
<pegdown.version>1.6.0</pegdown.version>
|
||||
<knife4j-spring-boot-starter.version>3.0.3</knife4j-spring-boot-starter.version>
|
||||
<knife4j-spring-ui.version>2.0.9</knife4j-spring-ui.version>
|
||||
<knife4j-spring-boot-starter.version>4.4.0</knife4j-spring-boot-starter.version>
|
||||
<!-- 数据库驱动 -->
|
||||
<postgresql.version>42.2.25</postgresql.version>
|
||||
<ojdbc6.version>11.2.0.3</ojdbc6.version>
|
||||
@ -54,11 +53,12 @@
|
||||
<!-- 持久层 -->
|
||||
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
|
||||
<dynamic-datasource-spring-boot-starter.version>4.1.3</dynamic-datasource-spring-boot-starter.version>
|
||||
<druid.version>1.2.19</druid.version>
|
||||
<minidao.version>1.9.5</minidao.version>
|
||||
<druid.version>1.2.22</druid.version>
|
||||
<minidao.version>1.9.10</minidao.version>
|
||||
|
||||
<!-- 积木报表-->
|
||||
<jimureport-spring-boot-starter.version>1.7.2-beta</jimureport-spring-boot-starter.version>
|
||||
<jimureport-spring-boot-starter.version>1.7.4</jimureport-spring-boot-starter.version>
|
||||
<commons-io.version>2.11.0</commons-io.version>
|
||||
<commons.version>2.6</commons.version>
|
||||
<aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version>
|
||||
<aliyun.oss.version>3.11.2</aliyun.oss.version>
|
||||
@ -66,10 +66,10 @@
|
||||
<shiro.version>1.12.0</shiro.version>
|
||||
<java-jwt.version>3.11.0</java-jwt.version>
|
||||
<shiro-redis.version>3.2.2</shiro-redis.version>
|
||||
<codegenerate.version>1.4.5</codegenerate.version>
|
||||
<codegenerate.version>1.4.7</codegenerate.version>
|
||||
<autopoi-web.version>1.4.7</autopoi-web.version>
|
||||
<minio.version>8.0.3</minio.version>
|
||||
<justauth-spring-boot-starter.version>1.3.4</justauth-spring-boot-starter.version>
|
||||
<justauth-spring-boot-starter.version>1.4.0</justauth-spring-boot-starter.version>
|
||||
<dom4j.version>1.6.1</dom4j.version>
|
||||
<qiniu-java-sdk.version>7.4.0</qiniu-java-sdk.version>
|
||||
<!-- Log4j2爆雷漏洞 -->
|
||||
@ -225,6 +225,12 @@
|
||||
<artifactId>jeecg-boot-starter-rabbitmq</artifactId>
|
||||
<version>${jeecgboot.version}</version>
|
||||
</dependency>
|
||||
<!--rocketmq-->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-starter-rocketmq</artifactId>
|
||||
<version>${jeecgboot.version}</version>
|
||||
</dependency>
|
||||
<!--分库分表shardingsphere-->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
@ -365,6 +371,18 @@
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<groupId>commons-lang</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<groupId>commons-collections</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<groupId>commons-io</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- minidao -->
|
||||
@ -372,6 +390,16 @@
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
<artifactId>minidao-spring-boot-starter</artifactId>
|
||||
<version>${minidao.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>druid</artifactId>
|
||||
<groupId>com.alibaba</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>jsqlparser</artifactId>
|
||||
<groupId>com.github.jsqlparser</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- 积木报表-->
|
||||
<dependency>
|
||||
@ -383,6 +411,14 @@
|
||||
<artifactId>autopoi-web</artifactId>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>druid</artifactId>
|
||||
<groupId>com.alibaba</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>jsqlparser</artifactId>
|
||||
<groupId>com.github.jsqlparser</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -390,11 +426,25 @@
|
||||
<artifactId>jimureport-nosql-starter</artifactId>
|
||||
<version>1.6.0</version>
|
||||
</dependency>
|
||||
<!-- 积木仪表盘-->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.jimureport</groupId>
|
||||
<artifactId>jimureport-drag</artifactId>
|
||||
<version>2.0.1</version>
|
||||
</dependency>
|
||||
<!-- chatgpt -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-starter-chatgpt</artifactId>
|
||||
<version>${jeecgboot.version}</version>
|
||||
<version>${jeecgboot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--flyway 支持 mysql5.7+、MariaDB10.3.16-->
|
||||
<!--mysql5.6,需要把版本号改成5.2.1-->
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
<version>7.15.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
@ -545,4 +595,4 @@
|
||||
</modules>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
</project>
|
||||
|
||||
Reference in New Issue
Block a user