Merge remote-tracking branch 'remote/master'

# Conflicts:
#	eladmin-system/src/main/java/me/zhengjie/modules/quartz/task/TestTask.java
pull/725/head
Emil.Zhang 2022-07-08 15:31:33 +08:00
commit 7f5640cb1f
29 changed files with 142 additions and 106 deletions

View File

@ -9,7 +9,7 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<properties> <properties>
<hutool.version>5.3.4</hutool.version> <hutool.version>5.7.22</hutool.version>
</properties> </properties>
<artifactId>eladmin-common</artifactId> <artifactId>eladmin-common</artifactId>

View File

@ -15,8 +15,8 @@
*/ */
package me.zhengjie.config; package me.zhengjie.config;
import cn.hutool.core.collection.CollUtil;
import com.fasterxml.classmate.TypeResolver; import com.fasterxml.classmate.TypeResolver;
import com.google.common.base.Predicates;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -29,14 +29,18 @@ import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.PathSelectors;
import springfox.documentation.schema.AlternateTypeRule; import springfox.documentation.schema.AlternateTypeRule;
import springfox.documentation.schema.AlternateTypeRuleConvention; import springfox.documentation.schema.AlternateTypeRuleConvention;
import springfox.documentation.service.*; import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static springfox.documentation.schema.AlternateTypeRules.newRule; import static springfox.documentation.schema.AlternateTypeRules.newRule;
/** /**
@ -62,7 +66,7 @@ public class SwaggerConfig {
.pathMapping("/") .pathMapping("/")
.apiInfo(apiInfo()) .apiInfo(apiInfo())
.select() .select()
.paths(Predicates.not(PathSelectors.regex("/error.*"))) .paths(PathSelectors.regex("^(?!/error).*"))
.paths(PathSelectors.any()) .paths(PathSelectors.any())
.build() .build()
//添加登陆认证 //添加登陆认证
@ -98,7 +102,7 @@ public class SwaggerConfig {
private SecurityContext getContextByPath() { private SecurityContext getContextByPath() {
return SecurityContext.builder() return SecurityContext.builder()
.securityReferences(defaultAuth()) .securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!/auth).*$")) .operationSelector(o->o.requestMappingPattern().matches("^(?!/auth).*$"))
.build(); .build();
} }
@ -128,7 +132,7 @@ class SwaggerDataConfig {
@Override @Override
public List<AlternateTypeRule> rules() { public List<AlternateTypeRule> rules() {
return newArrayList(newRule(resolver.resolve(Pageable.class), resolver.resolve(Page.class))); return CollUtil.newArrayList(newRule(resolver.resolve(Pageable.class), resolver.resolve(Page.class)));
} }
}; };
} }

View File

@ -21,7 +21,9 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@ -142,4 +144,13 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB
} }
SpringContextHolder.addCallback = false; SpringContextHolder.addCallback = false;
} }
/**
* @Service bean
* @return /
*/
public static List<String> getAllServiceBeanName() {
return new ArrayList<>(Arrays.asList(applicationContext
.getBeanNamesForAnnotation(Service.class)));
}
} }

View File

@ -15,16 +15,17 @@
*/ */
package me.zhengjie.utils; package me.zhengjie.utils;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.BadRequestException;
import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator;
/** /**
* *
*
* @author Zheng Jie * @author Zheng Jie
* @date 2018-11-23 * @date 2018-11-23
*/ */
public class ValidationUtil{ public class ValidationUtil {
/** /**
* *
@ -36,10 +37,10 @@ public class ValidationUtil{
} }
} }
/** /**
* *
*/ */
public static boolean isEmail(String email) { public static boolean isEmail(String email) {
return new EmailValidator().isValid(email, null); return Validator.isEmail(email);
} }
} }

View File

@ -1,6 +1,6 @@
package me.zhengjie.utils; package me.zhengjie.utils;
import org.junit.Test; import org.junit.jupiter.api.Test;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;

View File

@ -1,8 +1,9 @@
package me.zhengjie.utils; package me.zhengjie.utils;
import org.junit.Test; import org.junit.jupiter.api.Test;
import static org.junit.Assert.*;
import static me.zhengjie.utils.EncryptUtils.*; import static me.zhengjie.utils.EncryptUtils.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class EncryptUtilsTest { public class EncryptUtilsTest {

View File

@ -1,10 +1,10 @@
package me.zhengjie.utils; package me.zhengjie.utils;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockMultipartFile; import org.springframework.mock.web.MockMultipartFile;
import static org.junit.Assert.*;
import static me.zhengjie.utils.FileUtil.*; import static me.zhengjie.utils.FileUtil.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class FileUtilTest { public class FileUtilTest {

View File

@ -1,13 +1,18 @@
package me.zhengjie.utils; package me.zhengjie.utils;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.Date;
import static me.zhengjie.utils.StringUtils.*; import static me.zhengjie.utils.StringUtils.getIp;
import static org.junit.Assert.*; import static me.zhengjie.utils.StringUtils.getWeekDay;
import static me.zhengjie.utils.StringUtils.toCamelCase;
import static me.zhengjie.utils.StringUtils.toCapitalizeCamelCase;
import static me.zhengjie.utils.StringUtils.toUnderScoreCase;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class StringUtilsTest { public class StringUtilsTest {
@ -40,4 +45,4 @@ public class StringUtilsTest {
public void testGetIP() { public void testGetIP() {
assertEquals("127.0.0.1", getIp(new MockHttpServletRequest())); assertEquals("127.0.0.1", getIp(new MockHttpServletRequest()));
} }
} }

View File

@ -13,7 +13,7 @@
<name>代码生成模块</name> <name>代码生成模块</name>
<properties> <properties>
<configuration.version>1.9</configuration.version> <configuration.version>1.10</configuration.version>
</properties> </properties>
<dependencies> <dependencies>

View File

@ -288,7 +288,8 @@ public class GenUtil {
// 主键存在字典 // 主键存在字典
if (StringUtils.isNotBlank(column.getDictName())) { if (StringUtils.isNotBlank(column.getDictName())) {
genMap.put("hasDict", true); genMap.put("hasDict", true);
dicts.add(column.getDictName()); if(!dicts.contains(column.getDictName()))
dicts.add(column.getDictName());
} }
// 存储字段类型 // 存储字段类型

View File

@ -17,6 +17,7 @@ package me.zhengjie.service.impl;
import cn.hutool.core.lang.Dict; import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.zhengjie.domain.Log; import me.zhengjie.domain.Log;
@ -94,6 +95,12 @@ public class LogServiceImpl implements LogService {
log.setMethod(methodName); log.setMethod(methodName);
log.setUsername(username); log.setUsername(username);
log.setParams(getParameter(method, joinPoint.getArgs())); log.setParams(getParameter(method, joinPoint.getArgs()));
// 记录登录用户,隐藏密码信息
if(log.getDescription().equals("用户登录")){
JSONObject obj = JSONUtil.parseObj(log.getParams());
log.setUsername(obj.get("username").toString());
log.setParams(JSONUtil.toJsonStr(Dict.create().set("username", log.getUsername())));
}
log.setBrowser(browser); log.setBrowser(browser);
logRepository.save(log); logRepository.save(log);
} }

View File

@ -13,7 +13,7 @@
<name>核心模块</name> <name>核心模块</name>
<properties> <properties>
<jjwt.version>0.11.1</jjwt.version> <jjwt.version>0.11.2</jjwt.version>
<!-- oshi监控需要指定jna版本, 问题详见 https://github.com/oshi/oshi/issues/1040 --> <!-- oshi监控需要指定jna版本, 问题详见 https://github.com/oshi/oshi/issues/1040 -->
<jna.version>5.8.0</jna.version> <jna.version>5.8.0</jna.version>
</properties> </properties>
@ -84,7 +84,7 @@
<dependency> <dependency>
<groupId>com.github.oshi</groupId> <groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId> <artifactId>oshi-core</artifactId>
<version>5.7.1</version> <version>6.1.4</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -54,7 +54,7 @@ public class ConfigurerAdapter implements WebMvcConfigurer {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration(); CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); config.setAllowCredentials(true);
config.addAllowedOrigin("*"); config.addAllowedOriginPattern("*");
config.addAllowedHeader("*"); config.addAllowedHeader("*");
config.addAllowedMethod("*"); config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config); source.registerCorsConfiguration("/**", config);

View File

@ -51,8 +51,8 @@ public class AsyncTaskExecutePool implements AsyncConfigurer {
executor.setQueueCapacity(AsyncTaskProperties.queueCapacity); executor.setQueueCapacity(AsyncTaskProperties.queueCapacity);
//活跃时间 //活跃时间
executor.setKeepAliveSeconds(AsyncTaskProperties.keepAliveSeconds); executor.setKeepAliveSeconds(AsyncTaskProperties.keepAliveSeconds);
//线程名字前缀 //线程工厂
executor.setThreadNamePrefix("el-async-"); executor.setThreadFactory(new TheadFactoryName("el-async"));
// setRejectedExecutionHandler当pool已经达到max size的时候如何处理新任务 // setRejectedExecutionHandler当pool已经达到max size的时候如何处理新任务
// CallerRunsPolicy不在新线程中执行任务而是由调用者所在的线程来执行 // CallerRunsPolicy不在新线程中执行任务而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

View File

@ -15,8 +15,8 @@
*/ */
package me.zhengjie.config.thread; package me.zhengjie.config.thread;
import me.zhengjie.utils.StringUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -33,24 +33,25 @@ public class TheadFactoryName implements ThreadFactory {
private final AtomicInteger threadNumber = new AtomicInteger(1); private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix; private final String namePrefix;
private final static String DEF_NAME = "el-pool-";
public TheadFactoryName() { public TheadFactoryName() {
this("el-pool"); this(DEF_NAME);
} }
private TheadFactoryName(String name){ public TheadFactoryName(String name){
SecurityManager s = System.getSecurityManager(); SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup(); Thread.currentThread().getThreadGroup();
//此时namePrefix就是 name + 第几个用这个工厂创建线程池的 //此时namePrefix就是 name + 第几个用这个工厂创建线程池的
this.namePrefix = name + this.namePrefix = (StringUtils.isNotBlank(name) ? name : DEF_NAME) + "-" + POOL_NUMBER.getAndIncrement();
POOL_NUMBER.getAndIncrement();
} }
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
//此时线程的名字 就是 namePrefix + -thread- + 这个线程池中第几个执行的线程 //此时线程的名字 就是 namePrefix + -exec- + 这个线程池中第几个执行的线程
Thread t = new Thread(group, r, Thread t = new Thread(group, r,
namePrefix + "-thread-"+threadNumber.getAndIncrement(), namePrefix + "-exec-"+threadNumber.getAndIncrement(),
0); 0);
if (t.isDaemon()) { if (t.isDaemon()) {
t.setDaemon(false); t.setDaemon(false);

View File

@ -16,6 +16,7 @@
package me.zhengjie.config.thread; package me.zhengjie.config.thread;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -26,14 +27,20 @@ import java.util.concurrent.TimeUnit;
*/ */
public class ThreadPoolExecutorUtil { public class ThreadPoolExecutorUtil {
public static ThreadPoolExecutor getPoll(){ public static ExecutorService getPoll(){
return getPoll(null);
}
public static ExecutorService getPoll(String threadName){
return new ThreadPoolExecutor( return new ThreadPoolExecutor(
AsyncTaskProperties.corePoolSize, AsyncTaskProperties.corePoolSize,
AsyncTaskProperties.maxPoolSize, AsyncTaskProperties.maxPoolSize,
AsyncTaskProperties.keepAliveSeconds, AsyncTaskProperties.keepAliveSeconds,
TimeUnit.SECONDS, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(AsyncTaskProperties.queueCapacity), new ArrayBlockingQueue<>(AsyncTaskProperties.queueCapacity),
new TheadFactoryName() new TheadFactoryName(threadName),
// 队列与线程池中线程都满了时使用调用者所在的线程来执行
new ThreadPoolExecutor.CallerRunsPolicy()
); );
} }
} }

View File

@ -24,6 +24,7 @@ import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.quartz.domain.QuartzJob; import me.zhengjie.modules.quartz.domain.QuartzJob;
import me.zhengjie.modules.quartz.service.QuartzJobService; import me.zhengjie.modules.quartz.service.QuartzJobService;
import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria; import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria;
import me.zhengjie.utils.SpringContextHolder;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -84,6 +85,8 @@ public class QuartzJobController {
if (resources.getId() != null) { if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
} }
// 验证Bean是不是合法的合法的定时任务 Bean 需要用 @Service 定义
checkBean(resources.getBeanName());
quartzJobService.create(resources); quartzJobService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED); return new ResponseEntity<>(HttpStatus.CREATED);
} }
@ -93,6 +96,8 @@ public class QuartzJobController {
@PutMapping @PutMapping
@PreAuthorize("@el.check('timing:edit')") @PreAuthorize("@el.check('timing:edit')")
public ResponseEntity<Object> updateQuartzJob(@Validated(QuartzJob.Update.class) @RequestBody QuartzJob resources){ public ResponseEntity<Object> updateQuartzJob(@Validated(QuartzJob.Update.class) @RequestBody QuartzJob resources){
// 验证Bean是不是合法的合法的定时任务 Bean 需要用 @Service 定义
checkBean(resources.getBeanName());
quartzJobService.update(resources); quartzJobService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT); return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} }
@ -123,4 +128,12 @@ public class QuartzJobController {
quartzJobService.delete(ids); quartzJobService.delete(ids);
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
private void checkBean(String beanName){
// 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类
// 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数执行任意sql命令。
if(!SpringContextHolder.getAllServiceBeanName().contains(beanName)){
throw new BadRequestException("非法的 Bean请重新输入");
}
}
} }

View File

@ -19,6 +19,7 @@ import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig; import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine; import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil; import cn.hutool.extra.template.TemplateUtil;
import me.zhengjie.config.thread.ThreadPoolExecutorUtil;
import me.zhengjie.domain.vo.EmailVo; import me.zhengjie.domain.vo.EmailVo;
import me.zhengjie.modules.quartz.domain.QuartzJob; import me.zhengjie.modules.quartz.domain.QuartzJob;
import me.zhengjie.modules.quartz.domain.QuartzLog; import me.zhengjie.modules.quartz.domain.QuartzLog;
@ -32,7 +33,6 @@ import me.zhengjie.utils.ThrowableUtil;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.quartz.QuartzJobBean; import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
@ -42,15 +42,15 @@ import java.util.concurrent.*;
* @author / * @author /
* @date 2019-01-07 * @date 2019-01-07
*/ */
@Async
public class ExecutionJob extends QuartzJobBean { public class ExecutionJob extends QuartzJobBean {
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Logger logger = LoggerFactory.getLogger(this.getClass());
// 此处仅供参考,可根据任务执行情况自定义线程池参数
private final static ExecutorService executor = ThreadPoolExecutorUtil.getPoll("el-quartz-job");
@Override @Override
public void executeInternal(JobExecutionContext context) { public void executeInternal(JobExecutionContext context) {
// 创建单个线程
ExecutorService executor = Executors.newSingleThreadExecutor();
// 获取任务 // 获取任务
QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY); QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY);
// 获取spring bean // 获取spring bean
@ -112,7 +112,6 @@ public class ExecutionJob extends QuartzJobBean {
} }
} finally { } finally {
quartzLogRepository.save(log); quartzLogRepository.save(log);
executor.shutdown();
} }
} }

View File

@ -21,6 +21,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import me.zhengjie.annotation.Log;
import me.zhengjie.annotation.rest.AnonymousDeleteMapping; import me.zhengjie.annotation.rest.AnonymousDeleteMapping;
import me.zhengjie.annotation.rest.AnonymousGetMapping; import me.zhengjie.annotation.rest.AnonymousGetMapping;
import me.zhengjie.annotation.rest.AnonymousPostMapping; import me.zhengjie.annotation.rest.AnonymousPostMapping;
@ -70,6 +71,7 @@ public class AuthorizationController {
@Resource @Resource
private LoginProperties loginProperties; private LoginProperties loginProperties;
@Log("用户登录")
@ApiOperation("登录授权") @ApiOperation("登录授权")
@AnonymousPostMapping(value = "/login") @AnonymousPostMapping(value = "/login")
public ResponseEntity<Object> login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception { public ResponseEntity<Object> login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception {

View File

@ -49,13 +49,13 @@ public interface MenuRepository extends JpaRepository<Menu, Long>, JpaSpecificat
* @param pid / * @param pid /
* @return / * @return /
*/ */
List<Menu> findByPid(long pid); List<Menu> findByPidOrderByMenuSort(long pid);
/** /**
* *
* @return / * @return /
*/ */
List<Menu> findByPidIsNull(); List<Menu> findByPidIsNullOrderByMenuSort();
/** /**
* ID * ID

View File

@ -43,7 +43,7 @@ public class DataServiceImpl implements DataService {
private final DeptService deptService; private final DeptService deptService;
/** /**
* *
* @param user / * @param user /
* @return / * @return /
*/ */

View File

@ -189,7 +189,7 @@ public class MenuServiceImpl implements MenuService {
public Set<Menu> getChildMenus(List<Menu> menuList, Set<Menu> menuSet) { public Set<Menu> getChildMenus(List<Menu> menuList, Set<Menu> menuSet) {
for (Menu menu : menuList) { for (Menu menu : menuList) {
menuSet.add(menu); menuSet.add(menu);
List<Menu> menus = menuRepository.findByPid(menu.getId()); List<Menu> menus = menuRepository.findByPidOrderByMenuSort(menu.getId());
if(menus!=null && menus.size()!=0){ if(menus!=null && menus.size()!=0){
getChildMenus(menus, menuSet); getChildMenus(menus, menuSet);
} }
@ -213,9 +213,9 @@ public class MenuServiceImpl implements MenuService {
public List<MenuDto> getMenus(Long pid) { public List<MenuDto> getMenus(Long pid) {
List<Menu> menus; List<Menu> menus;
if(pid != null && !pid.equals(0L)){ if(pid != null && !pid.equals(0L)){
menus = menuRepository.findByPid(pid); menus = menuRepository.findByPidOrderByMenuSort(pid);
} else { } else {
menus = menuRepository.findByPidIsNull(); menus = menuRepository.findByPidIsNullOrderByMenuSort();
} }
return menuMapper.toDto(menus); return menuMapper.toDto(menus);
} }
@ -223,10 +223,10 @@ public class MenuServiceImpl implements MenuService {
@Override @Override
public List<MenuDto> getSuperior(MenuDto menuDto, List<Menu> menus) { public List<MenuDto> getSuperior(MenuDto menuDto, List<Menu> menus) {
if(menuDto.getPid() == null){ if(menuDto.getPid() == null){
menus.addAll(menuRepository.findByPidIsNull()); menus.addAll(menuRepository.findByPidIsNullOrderByMenuSort());
return menuMapper.toDto(menus); return menuMapper.toDto(menus);
} }
menus.addAll(menuRepository.findByPid(menuDto.getPid())); menus.addAll(menuRepository.findByPidOrderByMenuSort(menuDto.getPid()));
return getSuperior(findById(menuDto.getPid()), menus); return getSuperior(findById(menuDto.getPid()), menus);
} }

View File

@ -15,9 +15,8 @@
*/ */
package me.zhengjie.modules.system.service.impl; package me.zhengjie.modules.system.service.impl;
import cn.hutool.core.date.BetweenFormater; import cn.hutool.core.date.BetweenFormatter.Level;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.service.MonitorService; import me.zhengjie.modules.system.service.MonitorService;
import me.zhengjie.utils.ElAdminConstant; import me.zhengjie.utils.ElAdminConstant;
import me.zhengjie.utils.FileUtil; import me.zhengjie.utils.FileUtil;
@ -149,9 +148,15 @@ public class MonitorServiceImpl implements MonitorService {
cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU"); cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU");
// CPU信息 // CPU信息
long[] prevTicks = processor.getSystemCpuLoadTicks(); long[] prevTicks = processor.getSystemCpuLoadTicks();
// 等待1秒... // 默认等待300毫秒...
Util.sleep(1000); long time = 300;
Util.sleep(time);
long[] ticks = processor.getSystemCpuLoadTicks(); long[] ticks = processor.getSystemCpuLoadTicks();
while (Arrays.toString(prevTicks).equals(Arrays.toString(ticks)) && time < 1000){
time += 25;
Util.sleep(25);
ticks = processor.getSystemCpuLoadTicks();
}
long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()]; long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()]; long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
long sys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()]; long sys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
@ -177,7 +182,7 @@ public class MonitorServiceImpl implements MonitorService {
long time = ManagementFactory.getRuntimeMXBean().getStartTime(); long time = ManagementFactory.getRuntimeMXBean().getStartTime();
Date date = new Date(time); Date date = new Date(time);
// 计算项目运行时间 // 计算项目运行时间
String formatBetween = DateUtil.formatBetween(date, new Date(),BetweenFormater.Level.HOUR); String formatBetween = DateUtil.formatBetween(date, new Date(), Level.HOUR);
// 系统信息 // 系统信息
systemInfo.put("os", os.toString()); systemInfo.put("os", os.toString());
systemInfo.put("day", formatBetween); systemInfo.put("day", formatBetween);

View File

@ -119,6 +119,10 @@ public class UserServiceImpl implements UserService {
redisUtils.del(CacheKey.MENU_USER + resources.getId()); redisUtils.del(CacheKey.MENU_USER + resources.getId());
redisUtils.del(CacheKey.ROLE_AUTH + resources.getId()); redisUtils.del(CacheKey.ROLE_AUTH + resources.getId());
} }
// 修改部门会影响 数据权限
if (!Objects.equals(resources.getDept(),user.getDept())) {
redisUtils.del(CacheKey.DATA_USER + resources.getId());
}
// 如果用户被禁用,则清除用户登录信息 // 如果用户被禁用,则清除用户登录信息
if(!resources.getEnabled()){ if(!resources.getEnabled()){
onlineUserService.kickOutForUsername(resources.getUsername()); onlineUserService.kickOutForUsername(resources.getUsername());

View File

@ -5,4 +5,4 @@
| __| | | (_| | (_| | | | | | | | | | | | __| | | (_| | (_| | | | | | | | | | |
\___|_| \__,_|\__,_|_| |_| |_|_|_| |_| \___|_| \__,_|\__,_|_| |_| |_|_|_| |_|
:: Spring Boot :: (v2.2.10.RELEASE) :: Spring Boot :: (v2.6.4)

View File

@ -55,7 +55,7 @@ public class ${className} implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
</#if> </#if>
</#if> </#if>
@Column(name = "${column.columnName}"<#if column.columnKey = 'UNI'>,unique = true</#if><#if column.istNotNull && column.columnKey != 'PRI'>,nullable = false</#if>) @Column(name = "`${column.columnName}`"<#if column.columnKey = 'UNI'>,unique = true</#if><#if column.istNotNull && column.columnKey != 'PRI'>,nullable = false</#if>)
<#if column.istNotNull && column.columnKey != 'PRI'> <#if column.istNotNull && column.columnKey != 'PRI'>
<#if column.columnType = 'String'> <#if column.columnType = 'String'>
@NotBlank @NotBlank
@ -82,4 +82,4 @@ public class ${className} implements Serializable {
public void copy(${className} source){ public void copy(${className} source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
} }
} }

View File

@ -1,11 +1,8 @@
package me.zhengjie; package me.zhengjie;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class EladminSystemApplicationTests { public class EladminSystemApplicationTests {

View File

@ -14,8 +14,8 @@
<properties> <properties>
<mail.version>1.4.7</mail.version> <mail.version>1.4.7</mail.version>
<qiniu.version>[7.2.0, 7.2.99]</qiniu.version> <qiniu.version>7.9.3</qiniu.version>
<alipay.version>4.9.153.ALL</alipay.version> <alipay.version>4.22.57.ALL</alipay.version>
</properties> </properties>
<dependencies> <dependencies>
@ -47,4 +47,4 @@
<version>${alipay.version}</version> <version>${alipay.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

52
pom.xml
View File

@ -23,7 +23,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.10.RELEASE</version> <version>2.6.4</version>
</parent> </parent>
<properties> <properties>
@ -35,9 +35,9 @@
<log4jdbc.version>1.16</log4jdbc.version> <log4jdbc.version>1.16</log4jdbc.version>
<swagger.version>2.9.2</swagger.version> <swagger.version>2.9.2</swagger.version>
<fastjson.version>1.2.83</fastjson.version> <fastjson.version>1.2.83</fastjson.version>
<druid.version>1.1.24</druid.version> <druid.version>1.2.8</druid.version>
<commons-pool2.version>2.5.0</commons-pool2.version> <commons-pool2.version>2.11.1</commons-pool2.version>
<mapstruct.version>1.3.1.Final</mapstruct.version> <mapstruct.version>1.4.2.Final</mapstruct.version>
</properties> </properties>
<dependencies> <dependencies>
@ -80,6 +80,7 @@
</dependency> </dependency>
<!--spring boot 集成redis所需common-pool2--> <!--spring boot 集成redis所需common-pool2-->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
@ -98,37 +99,14 @@
</dependency> </dependency>
<!-- Swagger UI 相关 --> <!-- Swagger UI 相关 -->
<!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-spring-boot-starter -->
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>com.github.xiaoymin</groupId>
<artifactId>springfox-swagger2</artifactId> <artifactId>knife4j-spring-boot-starter</artifactId>
<version>${swagger.version}</version> <version>3.0.3</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency> </dependency>
<!--Mysql依赖包--> <!--Mysql依赖包-->
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
@ -144,13 +122,13 @@
</dependency> </dependency>
<!-- ip2region IP库 --> <!-- ip2region IP库 -->
<!-- https://mvnrepository.com/artifact/net.dreamlu/mica-ip2region -->
<dependency> <dependency>
<groupId>net.dreamlu</groupId> <groupId>net.dreamlu</groupId>
<artifactId>mica-ip2region</artifactId> <artifactId>mica-ip2region</artifactId>
<version>2.5.6</version> <version>2.6.3</version>
</dependency> </dependency>
<!--lombok插件--> <!--lombok插件-->
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
@ -162,12 +140,12 @@
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId> <artifactId>poi</artifactId>
<version>3.17</version> <version>5.2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId> <artifactId>poi-ooxml</artifactId>
<version>3.17</version> <version>5.2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>xerces</groupId> <groupId>xerces</groupId>
@ -211,7 +189,7 @@
<dependency> <dependency>
<groupId>nl.basjes.parse.useragent</groupId> <groupId>nl.basjes.parse.useragent</groupId>
<artifactId>yauaa</artifactId> <artifactId>yauaa</artifactId>
<version>5.23</version> <version>6.11</version>
</dependency> </dependency>
</dependencies> </dependencies>