Browse Source

commit code

master
刘力 3 years ago
parent
commit
f3eb49bd4b
  1. 18
      common/src/main/java/com/storeroom/config/RsaProperties.java
  2. 12
      system/pom.xml
  3. 6
      system/src/main/java/com/storeroom/AppRun.java
  4. 47
      system/src/main/java/com/storeroom/config/ConfigurerAdapter.java
  5. 15
      system/src/main/java/com/storeroom/config/WebSocketConfig.java
  6. 51
      system/src/main/java/com/storeroom/config/thread/AsyncTaskExecutePool.java
  7. 20
      system/src/main/java/com/storeroom/config/thread/AsyncTaskProperties.java
  8. 44
      system/src/main/java/com/storeroom/config/thread/TheadFactoryName.java
  9. 22
      system/src/main/java/com/storeroom/config/thread/ThreadPoolExecutorUtil.java
  10. 6
      system/src/main/java/com/storeroom/modules/security/config/ConfigBeanConfiguration.java
  11. 125
      system/src/main/java/com/storeroom/modules/security/controller/AuthorizationController.java
  12. 3
      system/src/main/java/com/storeroom/modules/security/security/JwtAccessDeniedHandler.java
  13. 7
      system/src/main/java/com/storeroom/modules/security/security/JwtAuthenticationEntryPoint.java
  14. 6
      system/src/main/java/com/storeroom/modules/security/service/dto/AuthUserDto.java
  15. 188
      system/src/main/java/com/storeroom/modules/system/controller/UserController.java
  16. 17
      system/src/main/java/com/storeroom/modules/system/repository/DictDetailRepository.java
  17. 3
      system/src/main/java/com/storeroom/modules/system/repository/DictRepository.java
  18. 102
      system/src/main/java/com/storeroom/modules/system/service/DeptService.java
  19. 66
      system/src/main/java/com/storeroom/modules/system/service/JobService.java
  20. 102
      system/src/main/java/com/storeroom/modules/system/service/MenuService.java
  21. 24
      system/src/main/java/com/storeroom/modules/system/service/dto/JobQueryCriteria.java
  22. 73
      system/src/main/java/com/storeroom/modules/system/service/impl/DataServiceImpl.java
  23. 267
      system/src/main/java/com/storeroom/modules/system/service/impl/DeptServiceImpl.java
  24. 80
      system/src/main/java/com/storeroom/modules/system/service/impl/DictDetailServiceImpl.java
  25. 104
      system/src/main/java/com/storeroom/modules/system/service/impl/DictServiceImpl.java
  26. 106
      system/src/main/java/com/storeroom/modules/system/service/impl/JobServiceImpl.java
  27. 339
      system/src/main/java/com/storeroom/modules/system/service/impl/MenuServiceImpl.java
  28. 68
      system/src/main/resources/application-dev.yml
  29. 43
      system/src/main/resources/application.yml
  30. 8
      system/src/main/resources/banner.txt
  31. 27
      system/src/main/resources/generator.properties
  32. 4
      system/src/main/resources/log4jdbc.log4j2.properties
  33. 45
      system/src/main/resources/logback.xml

18
common/src/main/java/com/storeroom/config/RsaProperties.java

@ -0,0 +1,18 @@
package com.storeroom.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Data
@Component
public class RsaProperties {
public static String privateKey;
@Value("${rsa.private_key}")
public void setPrivateKey(String privateKey) {
RsaProperties.privateKey = privateKey;
}
}

12
system/pom.xml

@ -24,11 +24,6 @@
<version>1.0</version>
</dependency>
<!-- Spring boot websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- jwt -->
<dependency>
@ -66,6 +61,13 @@
<version>5.3.6</version>
</dependency>
<!-- Spring boot websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>

6
system/src/main/java/AppRun.java → system/src/main/java/com/storeroom/AppRun.java

@ -1,3 +1,5 @@
package com.storeroom;
import com.storeroom.annotaion.rest.AnonymousGetMapping;
import com.storeroom.utils.SpringContextHolder;
import io.swagger.annotations.Api;
@ -17,8 +19,8 @@ import org.springframework.web.bind.annotation.RestController;
@EnableJpaAuditing(auditorAwareRef = "auditorAware")
public class AppRun {
public static void main(String[] args){
SpringApplication.run(AppRun.class,args);
public static void main(String[] args) {
SpringApplication.run(AppRun.class, args);
}

47
system/src/main/java/com/storeroom/config/ConfigurerAdapter.java

@ -0,0 +1,47 @@
package com.storeroom.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class ConfigurerAdapter implements WebMvcConfigurer {
/** 文件配置 */
private final FileProperties properties;
public ConfigurerAdapter(FileProperties properties) {
this.properties = properties;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
FileProperties.YsPath path = properties.getPath();
String avatarUtl = "file:" + path.getAvatar().replace("\\","/");
String pathUtl = "file:" + path.getPath().replace("\\","/");
registry.addResourceHandler("/avatar/**").addResourceLocations(avatarUtl).setCachePeriod(0);
registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0);
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0);
}
}

15
system/src/main/java/com/storeroom/config/WebSocketConfig.java

@ -0,0 +1,15 @@
package com.storeroom.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}

51
system/src/main/java/com/storeroom/config/thread/AsyncTaskExecutePool.java

@ -0,0 +1,51 @@
package com.storeroom.config.thread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Slf4j
@Configuration
public class AsyncTaskExecutePool implements AsyncConfigurer {
/** 注入配置类 */
private final AsyncTaskProperties config;
public AsyncTaskExecutePool(AsyncTaskProperties config) {
this.config = config;
}
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(config.getCorePoolSize());
//最大线程数
executor.setMaxPoolSize(config.getMaxPoolSize());
//队列容量
executor.setQueueCapacity(config.getQueueCapacity());
//活跃时间
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
//线程名字前缀
executor.setThreadNamePrefix("yxk-async-");
// setRejectedExecutionHandler当pool已经达到max size的时候如何处理新任务
// CallerRunsPolicy不在新线程中执行任务而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (throwable, method, objects) -> {
log.error("===="+throwable.getMessage()+"====", throwable);
log.error("exception method:"+method.getName());
};
}
}

20
system/src/main/java/com/storeroom/config/thread/AsyncTaskProperties.java

@ -0,0 +1,20 @@
package com.storeroom.config.thread;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "task.pool")
public class AsyncTaskProperties {
private int corePoolSize;
private int maxPoolSize;
private int keepAliveSeconds;
private int queueCapacity;
}

44
system/src/main/java/com/storeroom/config/thread/TheadFactoryName.java

@ -0,0 +1,44 @@
package com.storeroom.config.thread;
import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
@Component
public class TheadFactoryName implements ThreadFactory {
private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public TheadFactoryName() {
this("yxk-pool");
}
private TheadFactoryName(String name){
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
//此时namePrefix就是 name + 第几个用这个工厂创建线程池的
this.namePrefix = name +
POOL_NUMBER.getAndIncrement();
}
@Override
public Thread newThread(Runnable r) {
//此时线程的名字 就是 namePrefix + -thread- + 这个线程池中第几个执行的线程
Thread t = new Thread(group, r,
namePrefix + "-thread-"+threadNumber.getAndIncrement(),
0);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
}
}

22
system/src/main/java/com/storeroom/config/thread/ThreadPoolExecutorUtil.java

@ -0,0 +1,22 @@
package com.storeroom.config.thread;
import com.storeroom.utils.SpringContextHolder;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExecutorUtil {
public static ThreadPoolExecutor getPoll(){
AsyncTaskProperties properties = SpringContextHolder.getBean(AsyncTaskProperties.class);
return new ThreadPoolExecutor(
properties.getCorePoolSize(),
properties.getMaxPoolSize(),
properties.getKeepAliveSeconds(),
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(properties.getQueueCapacity()),
new TheadFactoryName()
);
}
}

6
system/src/main/java/com/storeroom/modules/security/config/ConfigBeanConfiguration.java

@ -2,7 +2,7 @@ package com.storeroom.modules.security.config;
import com.storeroom.modules.security.config.bean.LoginProperties;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import com.storeroom.modules.security.config.bean.SecurityProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -11,13 +11,13 @@ import org.springframework.context.annotation.Configuration;
public class ConfigBeanConfiguration {
@Bean
@ConfigurationProperties(prefix="login",ignoreUnknownFields=true)
@ConfigurationProperties(prefix="login")
public LoginProperties loginProperties(){
return new LoginProperties();
}
@Bean
@ConfigurationProperties(prefix = "jwt",ignoreUnknownFields = true)
@ConfigurationProperties(prefix = "jwt")
public SecurityProperties securityProperties(){
return new SecurityProperties();
}

125
system/src/main/java/com/storeroom/modules/security/controller/AuthorizationController.java

@ -0,0 +1,125 @@
package com.storeroom.modules.security.controller;
import cn.hutool.core.util.IdUtil;
import com.storeroom.annotaion.rest.AnonymousDeleteMapping;
import com.storeroom.annotaion.rest.AnonymousGetMapping;
import com.storeroom.annotaion.rest.AnonymousPostMapping;
import com.storeroom.config.RsaProperties;
import com.storeroom.exception.BaseException;
import com.storeroom.exception.constant.ResponseStatus;
import com.storeroom.modules.security.config.bean.LoginCodeEnum;
import com.storeroom.modules.security.config.bean.LoginProperties;
import com.storeroom.modules.security.config.bean.SecurityProperties;
import com.storeroom.modules.security.security.TokenProvider;
import com.storeroom.modules.security.service.OnlineUserService;
import com.storeroom.modules.security.service.dto.AuthUserDto;
import com.storeroom.modules.security.service.dto.JwtUserDto;
import com.storeroom.utils.*;
import com.storeroom.utils.enums.DataStatusEnum;
import com.wf.captcha.base.Captcha;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
@Api(tags = "系统:系统授权接口")
public class AuthorizationController {
private final SecurityProperties properties;
private final RedisUtils redisUtils;
private final OnlineUserService onlineUserService;
private final TokenProvider tokenProvider;
private final AuthenticationManagerBuilder authenticationManagerBuilder;
@Resource
private LoginProperties loginProperties;
@ApiOperation("登录授权")
@AnonymousPostMapping(value = "/login")
public ApiResponse<Object> login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception {
// 密码解密
String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, authUser.getPassword());
// 查询验证码
String code = (String) redisUtils.get(authUser.getUuid());
// 清除验证码
redisUtils.del(authUser.getUuid());
if (StringUtils.isBlank(code)) {
throw new BaseException("验证码不存在或已过期");
}
if (StringUtils.isBlank(authUser.getCode()) || !authUser.getCode().equalsIgnoreCase(code)) {
throw new BaseException("验证码错误");
}
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(authUser.getUsername(), password);
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
String token = tokenProvider.createToken(authentication);
final JwtUserDto jwtUserDto = (JwtUserDto) authentication.getPrincipal();
// 保存在线信息
onlineUserService.save(jwtUserDto, token, request);
// 返回 token 用户信息
Map<String, Object> authInfo = new HashMap<String, Object>(2) {{
put("token", properties.getTokenStartWith() + token);
put("user", jwtUserDto);
}};
if (loginProperties.isSingleLogin()) {
//踢掉之前已经登录的token
onlineUserService.checkLoginOnUser(authUser.getUsername(), token);
}
return ApiResponse.success(authInfo);
}
@ApiOperation("获取用户信息")
@GetMapping(value = "/info")
public ApiResponse<Object> getUserInfo() {
return ApiResponse.success(SecurityUtils.getCurrentUser());
}
@ApiOperation("获取验证码")
@AnonymousGetMapping(value = "/code")
public ApiResponse<Object> getCode() {
// 获取运算的结果
Captcha captcha = loginProperties.getCaptcha();
String uuid = properties.getCodeKey() + IdUtil.simpleUUID();
//当验证码类型为 arithmetic时且长度 >= 2 captcha.text()的结果有几率为浮点型
String captchaValue = captcha.text();
if (captcha.getCharType() - 1 == LoginCodeEnum.arithmetic.ordinal() && captchaValue.contains(".")) {
captchaValue = captchaValue.split("\\.")[0];
}
// 保存
redisUtils.set(uuid, captchaValue, loginProperties.getLoginCode().getExpiration(), TimeUnit.MINUTES);
// 验证码信息
Map<String, Object> imgResult = new HashMap<String, Object>(2) {{
put("img", captcha.toBase64());
put("uuid", uuid);
}};
return ApiResponse.success(imgResult);
}
@ApiOperation("退出登录")
@AnonymousDeleteMapping(value = "/logout")
public ApiResponse<Object> logout(HttpServletRequest request) {
onlineUserService.logout(tokenProvider.getToken(request));
return ApiResponse.success(ResponseStatus.SUCCESS);
}
}

3
system/src/main/java/com/storeroom/modules/security/security/JwtAccessDeniedHandler.java

@ -11,8 +11,9 @@ import java.io.IOException;
@Component
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
//当前用户在没有权限的情况下访问受保护的REST资源时将调用此方法发送403 Forbidden响应
response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage());
}

7
system/src/main/java/com/storeroom/modules/security/security/JwtAuthenticationEntryPoint.java

@ -13,7 +13,10 @@ import java.io.IOException;
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException == null ? "Unauthorized" : authException.getMessage());
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws IOException {
// 当用户尝试访问安全的REST资源而不提供任何凭据时将调用此方法发送401 响应
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException==null?"Unauthorized":authException.getMessage());
}
}

6
system/src/main/java/com/storeroom/modules/security/service/dto/AuthUserDto.java

@ -1,7 +1,13 @@
package com.storeroom.modules.security.service.dto;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
@Getter
@Setter
public class AuthUserDto {
@NotBlank

188
system/src/main/java/com/storeroom/modules/system/controller/UserController.java

@ -0,0 +1,188 @@
package com.storeroom.modules.system.controller;
import cn.hutool.core.collection.CollectionUtil;
import com.storeroom.config.RsaProperties;
import com.storeroom.exception.BaseException;
import com.storeroom.modules.system.domain.Dept;
import com.storeroom.modules.system.domain.User;
import com.storeroom.modules.system.domain.vo.UserPassVo;
import com.storeroom.modules.system.service.DataService;
import com.storeroom.modules.system.service.DeptService;
import com.storeroom.modules.system.service.RoleService;
import com.storeroom.modules.system.service.UserService;
import com.storeroom.modules.system.service.dto.RoleSmallDto;
import com.storeroom.modules.system.service.dto.UserDto;
import com.storeroom.modules.system.service.dto.UserQueryCriteria;
import com.storeroom.utils.PageUtil;
import com.storeroom.utils.RsaUtils;
import com.storeroom.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Api(tags = "系统:用户管理")
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
private final PasswordEncoder passwordEncoder;
private final UserService userService;
private final DataService dataService;
private final DeptService deptService;
private final RoleService roleService;
@ApiOperation("导出用户数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('user:list')")
public void exportUser(HttpServletResponse response, UserQueryCriteria criteria) throws IOException {
userService.download(userService.queryAll(criteria), response);
}
@ApiOperation("查询用户")
@GetMapping
@PreAuthorize("@el.check('user:list')")
public ResponseEntity<Object> queryUser(UserQueryCriteria criteria, Pageable pageable){
if (!ObjectUtils.isEmpty(criteria.getDeptId())) {
criteria.getDeptIds().add(criteria.getDeptId());
// 先查找是否存在子节点
List<Dept> data = deptService.findByPid(criteria.getDeptId());
// 然后把子节点的ID都加入到集合中
criteria.getDeptIds().addAll(deptService.getDeptChildren(data));
}
// 数据权限
List<Long> dataScopes = dataService.getDeptIds(userService.findByName(SecurityUtils.getCurrentUsername()));
// criteria.getDeptIds() 不为空并且数据权限不为空则取交集
if (!CollectionUtils.isEmpty(criteria.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)){
// 取交集
criteria.getDeptIds().retainAll(dataScopes);
if(!CollectionUtil.isEmpty(criteria.getDeptIds())){
return new ResponseEntity<>(userService.queryAll(criteria,pageable), HttpStatus.OK);
}
} else {
// 否则取并集
criteria.getDeptIds().addAll(dataScopes);
return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK);
}
return new ResponseEntity<>(PageUtil.toPage(null,0),HttpStatus.OK);
}
//@Log("新增用户")
@ApiOperation("新增用户")
@PostMapping
@PreAuthorize("@el.check('user:add')")
public ResponseEntity<Object> createUser(@Validated @RequestBody User resources){
checkLevel(resources);
// 默认密码 123456
resources.setPassword(passwordEncoder.encode("123456"));
userService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
//@Log("修改用户")
@ApiOperation("修改用户")
@PutMapping
@PreAuthorize("@el.check('user:edit')")
public ResponseEntity<Object> updateUser(@Validated(User.Update.class) @RequestBody User resources) throws Exception {
checkLevel(resources);
userService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
//@Log("修改用户:个人中心")
@ApiOperation("修改用户:个人中心")
@PutMapping(value = "center")
public ResponseEntity<Object> centerUser(@Validated(User.Update.class) @RequestBody User resources){
if(!resources.getId().equals(SecurityUtils.getCurrentUserId())){
throw new BaseException("不能修改他人资料");
}
userService.updateCenter(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
//@Log("删除用户")
@ApiOperation("删除用户")
@DeleteMapping
@PreAuthorize("@el.check('user:del')")
public ResponseEntity<Object> deleteUser(@RequestBody Set<Long> ids){
for (Long id : ids) {
Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
Integer optLevel = Collections.min(roleService.findByUsersId(id).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
if (currentLevel > optLevel) {
throw new BaseException("角色权限不足,不能删除:" + userService.findById(id).getUsername());
}
}
userService.delete(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
@ApiOperation("修改密码")
@PostMapping(value = "/updatePass")
public ResponseEntity<Object> updateUserPass(@RequestBody UserPassVo passVo) throws Exception {
String oldPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getOldPass());
String newPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getNewPass());
UserDto user = userService.findByName(SecurityUtils.getCurrentUsername());
if(!passwordEncoder.matches(oldPass, user.getPassword())){
throw new BaseException("修改失败,旧密码错误");
}
if(passwordEncoder.matches(newPass, user.getPassword())){
throw new BaseException("新密码不能与旧密码相同");
}
userService.updatePass(user.getUsername(),passwordEncoder.encode(newPass));
return new ResponseEntity<>(HttpStatus.OK);
}
@ApiOperation("修改头像")
@PostMapping(value = "/updateAvatar")
public ResponseEntity<Object> updateUserAvatar(@RequestParam MultipartFile avatar){
return new ResponseEntity<>(userService.updateAvatar(avatar), HttpStatus.OK);
}
//@Log("修改邮箱")
// @ApiOperation("修改邮箱")
// @PostMapping(value = "/updateEmail/{code}")
// public ResponseEntity<Object> updateUserEmail(@PathVariable String code,@RequestBody User user) throws Exception {
// String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,user.getPassword());
// UserDto userDto = userService.findByName(SecurityUtils.getCurrentUsername());
// if(!passwordEncoder.matches(password, userDto.getPassword())){
// throw new BaseException("密码错误");
// }
// verificationCodeService.validated(CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey() + user.getEmail(), code);
// userService.updateEmail(userDto.getUsername(),user.getEmail());
// return new ResponseEntity<>(HttpStatus.OK);
// }
/**
* 如果当前用户的角色级别低于创建用户的角色级别则抛出权限不足的错误
* @param resources /
*/
private void checkLevel(User resources) {
Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
Integer optLevel = roleService.findByRoles(resources.getRoles());
if (currentLevel > optLevel) {
throw new BaseException("角色权限不足");
}
}
}

17
system/src/main/java/com/storeroom/modules/system/repository/DictDetailRepository.java

@ -0,0 +1,17 @@
package com.storeroom.modules.system.repository;
import com.storeroom.modules.system.domain.DictDetail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List;
public interface DictDetailRepository extends JpaRepository<DictDetail, Long>, JpaSpecificationExecutor<DictDetail> {
/**
* 根据字典名称查询
* @param name /
* @return /
*/
List<DictDetail> findByDictName(String name);
}

3
system/src/main/java/com/storeroom/modules/system/repository/DictRepository.java

@ -1,6 +1,7 @@
package com.storeroom.modules.system.repository;
import cn.hutool.core.lang.Dict;
import com.storeroom.modules.system.domain.Dict;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

102
system/src/main/java/com/storeroom/modules/system/service/DeptService.java

@ -1,4 +1,106 @@
package com.storeroom.modules.system.service;
import com.storeroom.modules.system.domain.Dept;
import com.storeroom.modules.system.service.dto.DeptDto;
import com.storeroom.modules.system.service.dto.DeptQueryCriteria;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Set;
public interface DeptService {
/**
* 查询所有数据
* @param criteria 条件
* @param isQuery /
* @throws Exception /
* @return /
*/
List<DeptDto> queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception;
/**
* 根据ID查询
* @param id /
* @return /
*/
DeptDto findById(Long id);
/**
* 创建
* @param resources /
*/
void create(Dept resources);
/**
* 编辑
* @param resources /
*/
void update(Dept resources);
/**
* 删除
* @param deptDtos /
*
*/
void delete(Set<DeptDto> deptDtos);
/**
* 根据PID查询
* @param pid /
* @return /
*/
List<Dept> findByPid(long pid);
/**
* 根据角色ID查询
* @param id /
* @return /
*/
Set<Dept> findByRoleId(Long id);
/**
* 导出数据
* @param queryAll 待导出的数据
* @param response /
* @throws IOException /
*/
void download(List<DeptDto> queryAll, HttpServletResponse response) throws IOException;
/**
* 获取待删除的部门
* @param deptList /
* @param deptDtos /
* @return /
*/
Set<DeptDto> getDeleteDepts(List<Dept> deptList, Set<DeptDto> deptDtos);
/**
* 根据ID获取同级与上级数据
* @param deptDto /
* @param depts /
* @return /
*/
List<DeptDto> getSuperior(DeptDto deptDto, List<Dept> depts);
/**
* 构建树形数据
* @param deptDtos /
* @return /
*/
Object buildTree(List<DeptDto> deptDtos);
/**
* 获取
* @param deptList
* @return
*/
List<Long> getDeptChildren(List<Dept> deptList);
/**
* 验证是否被角色或用户关联
* @param deptDtos /
*/
void verification(Set<DeptDto> deptDtos);
}

66
system/src/main/java/com/storeroom/modules/system/service/JobService.java

@ -1,4 +1,70 @@
package com.storeroom.modules.system.service;
import com.storeroom.modules.system.domain.Job;
import com.storeroom.modules.system.service.dto.JobDto;
import com.storeroom.modules.system.service.dto.JobQueryCriteria;
import org.springframework.data.domain.Pageable;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface JobService {
/**
* 根据ID查询
* @param id /
* @return /
*/
JobDto findById(Long id);
/**
* 创建
* @param resources /
* @return /
*/
void create(Job resources);
/**
* 编辑
* @param resources /
*/
void update(Job resources);
/**
* 删除
* @param ids /
*/
void delete(Set<Long> ids);
/**
* 分页查询
* @param criteria 条件
* @param pageable 分页参数
* @return /
*/
Map<String,Object> queryAll(JobQueryCriteria criteria, Pageable pageable);
/**
* 查询全部数据
* @param criteria /
* @return /
*/
List<JobDto> queryAll(JobQueryCriteria criteria);
/**
* 导出数据
* @param queryAll 待导出的数据
* @param response /
* @throws IOException /
*/
void download(List<JobDto> queryAll, HttpServletResponse response) throws IOException;
/**
* 验证是否被用户关联
* @param ids /
*/
void verification(Set<Long> ids);
}

102
system/src/main/java/com/storeroom/modules/system/service/MenuService.java

@ -1,4 +1,106 @@
package com.storeroom.modules.system.service;
import com.storeroom.modules.system.domain.Menu;
import com.storeroom.modules.system.service.dto.MenuDto;
import com.storeroom.modules.system.service.dto.MenuQueryCriteria;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Set;
public interface MenuService {
/**
* 查询全部数据
* @param criteria 条件
* @param isQuery /
* @throws Exception /
* @return /
*/
List<MenuDto> queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception;
/**
* 根据ID查询
* @param id /
* @return /
*/
MenuDto findById(long id);
/**
* 创建
* @param resources /
*/
void create(Menu resources);
/**
* 编辑
* @param resources /
*/
void update(Menu resources);
/**
* 获取所有子节点包含自身ID
* @param menuList /
* @param menuSet /
* @return /
*/
Set<Menu> getChildMenus(List<Menu> menuList, Set<Menu> menuSet);
/**
* 构建菜单树
* @param menuDtos 原始数据
* @return /
*/
List<MenuDto> buildTree(List<MenuDto> menuDtos);
/**
* 构建菜单树
* @param menuDtos /
* @return /
*/
Object buildMenus(List<MenuDto> menuDtos);
/**
* 根据ID查询
* @param id /
* @return /
*/
Menu findOne(Long id);
/**
* 删除
* @param menuSet /
*/
void delete(Set<Menu> menuSet);
/**
* 导出
* @param queryAll 待导出的数据
* @param response /
* @throws IOException /
*/
void download(List<MenuDto> queryAll, HttpServletResponse response) throws IOException;
/**
* 懒加载菜单数据
* @param pid /
* @return /
*/
List<MenuDto> getMenus(Long pid);
/**
* 根据ID获取同级与上级数据
* @param menuDto /
* @param objects /
* @return /
*/
List<MenuDto> getSuperior(MenuDto menuDto, List<Menu> objects);
/**
* 根据当前用户获取菜单
* @param currentUserId /
* @return /
*/
List<MenuDto> findByUser(Long currentUserId);
}

24
system/src/main/java/com/storeroom/modules/system/service/dto/JobQueryCriteria.java

@ -0,0 +1,24 @@
package com.storeroom.modules.system.service.dto;
import com.storeroom.annotaion.Query;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.sql.Timestamp;
import java.util.List;
@Data
@NoArgsConstructor
public class JobQueryCriteria {
@Query(type = Query.Type.INNER_LIKE)
private String name;
@Query
private Boolean enabled;
@Query(type = Query.Type.BETWEEN)
private List<Timestamp> createTime;
}

73
system/src/main/java/com/storeroom/modules/system/service/impl/DataServiceImpl.java

@ -0,0 +1,73 @@
package com.storeroom.modules.system.service.impl;
import com.storeroom.modules.system.domain.Dept;
import com.storeroom.modules.system.service.DataService;
import com.storeroom.modules.system.service.DeptService;
import com.storeroom.modules.system.service.RoleService;
import com.storeroom.modules.system.service.dto.RoleSmallDto;
import com.storeroom.modules.system.service.dto.UserDto;
import com.storeroom.utils.enums.DataScopeEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "data")
public class DataServiceImpl implements DataService {
private final RoleService roleService;
private final DeptService deptService;
/**
* 用户角色改变时需清理缓存
* @param user /
* @return /
*/
@Override
@Cacheable(key = "'user:' + #p0.id")
public List<Long> getDeptIds(UserDto user) {
// 用于存储部门id
Set<Long> deptIds = new HashSet<>();
// 查询用户角色
List<RoleSmallDto> roleSet = roleService.findByUsersId(user.getId());
// 获取对应的部门ID
for (RoleSmallDto role : roleSet) {
DataScopeEnum dataScopeEnum = DataScopeEnum.find(role.getDataScope());
switch (Objects.requireNonNull(dataScopeEnum)) {
case THIS_LEVEL:
deptIds.add(user.getDept().getId());
break;
case CUSTOMIZE:
deptIds.addAll(getCustomize(deptIds, role));
break;
default:
return new ArrayList<>(deptIds);
}
}
return new ArrayList<>(deptIds);
}
/**
* 获取自定义的数据权限
* @param deptIds 部门ID
* @param role 角色
* @return 数据权限ID
*/
public Set<Long> getCustomize(Set<Long> deptIds, RoleSmallDto role){
Set<Dept> depts = deptService.findByRoleId(role.getId());
for (Dept dept : depts) {
deptIds.add(dept.getId());
List<Dept> deptChildren = deptService.findByPid(dept.getId());
if (deptChildren != null && deptChildren.size() != 0) {
deptIds.addAll(deptService.getDeptChildren(deptChildren));
}
}
return deptIds;
}
}

267
system/src/main/java/com/storeroom/modules/system/service/impl/DeptServiceImpl.java

@ -0,0 +1,267 @@
package com.storeroom.modules.system.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.storeroom.exception.BaseException;
import com.storeroom.modules.system.domain.Dept;
import com.storeroom.modules.system.domain.User;
import com.storeroom.modules.system.repository.DeptRepository;
import com.storeroom.modules.system.repository.RoleRepository;
import com.storeroom.modules.system.repository.UserRepository;
import com.storeroom.modules.system.service.DeptService;
import com.storeroom.modules.system.service.dto.DeptDto;
import com.storeroom.modules.system.service.dto.DeptQueryCriteria;
import com.storeroom.modules.system.service.mapstruct.DeptMapper;
import com.storeroom.utils.*;
import com.storeroom.utils.enums.DataScopeEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "dept")
public class DeptServiceImpl implements DeptService {
private final DeptRepository deptRepository;
private final DeptMapper deptMapper;
private final UserRepository userRepository;
private final RedisUtils redisUtils;
private final RoleRepository roleRepository;
@Override
public List<DeptDto> queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception {
Sort sort = Sort.by(Sort.Direction.ASC, "deptSort");
String dataScopeType = SecurityUtils.getDataScopeType();
if (isQuery) {
if(dataScopeType.equals(DataScopeEnum.ALL.getValue())){
criteria.setPidIsNull(true);
}
List<Field> fields = QueryHelp.getAllFields(criteria.getClass(), new ArrayList<>());
List<String> fieldNames = new ArrayList<String>(){{ add("pidIsNull");add("enabled");}};
for (Field field : fields) {
//设置对象的访问权限保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(criteria);
if(fieldNames.contains(field.getName())){
continue;
}
if (ObjectUtil.isNotNull(val)) {
criteria.setPidIsNull(null);
break;
}
}
}
List<DeptDto> list = deptMapper.toDto(deptRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort));
// 如果为空就代表为自定义权限或者本级权限就需要去重不理解可以注释掉看查询结果
if(StringUtils.isBlank(dataScopeType)){
return deduplication(list);
}
return list;
}
@Override
@Cacheable(key = "'id:' + #p0")
public DeptDto findById(Long id) {
Dept dept = deptRepository.findById(id).orElseGet(Dept::new);
ValidationUtil.isNull(dept.getId(),"Dept","id",id);
return deptMapper.toDto(dept);
}
@Override
public List<Dept> findByPid(long pid) {
return deptRepository.findByPid(pid);
}
@Override
public Set<Dept> findByRoleId(Long id) {
return deptRepository.findByRoleId(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Dept resources) {
deptRepository.save(resources);
// 计算子节点数目
resources.setSubCount(0);
// 清理缓存
updateSubCnt(resources.getPid());
// 清理自定义角色权限的datascope缓存
delCaches(resources.getPid());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Dept resources) {
// 旧的部门
Long oldPid = findById(resources.getId()).getPid();
Long newPid = resources.getPid();
if(resources.getPid() != null && resources.getId().equals(resources.getPid())) {
throw new BaseException("上级不能为自己");
}
Dept dept = deptRepository.findById(resources.getId()).orElseGet(Dept::new);
ValidationUtil.isNull( dept.getId(),"Dept","id",resources.getId());
resources.setId(dept.getId());
deptRepository.save(resources);
// 更新父节点中子节点数目
updateSubCnt(oldPid);
updateSubCnt(newPid);
// 清理缓存
delCaches(resources.getId());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<DeptDto> deptDtos) {
for (DeptDto deptDto : deptDtos) {
// 清理缓存
delCaches(deptDto.getId());
deptRepository.deleteById(deptDto.getId());
updateSubCnt(deptDto.getPid());
}
}
@Override
public void download(List<DeptDto> deptDtos, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (DeptDto deptDTO : deptDtos) {
Map<String,Object> map = new LinkedHashMap<>();
map.put("部门名称", deptDTO.getName());
map.put("部门状态", deptDTO.getEnabled() ? "启用" : "停用");
map.put("创建日期", deptDTO.getCreateTime());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
@Override
public Set<DeptDto> getDeleteDepts(List<Dept> menuList, Set<DeptDto> deptDtos) {
for (Dept dept : menuList) {
deptDtos.add(deptMapper.toDto(dept));
List<Dept> depts = deptRepository.findByPid(dept.getId());
if(depts!=null && depts.size()!=0){
getDeleteDepts(depts, deptDtos);
}
}
return deptDtos;
}
@Override
public List<Long> getDeptChildren(List<Dept> deptList) {
List<Long> list = new ArrayList<>();
deptList.forEach(dept -> {
if (dept!=null && dept.getEnabled()) {
List<Dept> depts = deptRepository.findByPid(dept.getId());
if (depts.size() != 0) {
list.addAll(getDeptChildren(depts));
}
list.add(dept.getId());
}
}
);
return list;
}
@Override
public List<DeptDto> getSuperior(DeptDto deptDto, List<Dept> depts) {
if(deptDto.getPid() == null){
depts.addAll(deptRepository.findByPidIsNull());
return deptMapper.toDto(depts);
}
depts.addAll(deptRepository.findByPid(deptDto.getPid()));
return getSuperior(findById(deptDto.getPid()), depts);
}
@Override
public Object buildTree(List<DeptDto> deptDtos) {
Set<DeptDto> trees = new LinkedHashSet<>();
Set<DeptDto> depts= new LinkedHashSet<>();
List<String> deptNames = deptDtos.stream().map(DeptDto::getName).collect(Collectors.toList());
boolean isChild;
for (DeptDto deptDTO : deptDtos) {
isChild = false;
if (deptDTO.getPid() == null) {
trees.add(deptDTO);
}
for (DeptDto it : deptDtos) {
if (it.getPid() != null && deptDTO.getId().equals(it.getPid())) {
isChild = true;
if (deptDTO.getChildren() == null) {
deptDTO.setChildren(new ArrayList<>());
}
deptDTO.getChildren().add(it);
}
}
if(isChild) {
depts.add(deptDTO);
} else if(deptDTO.getPid() != null && !deptNames.contains(findById(deptDTO.getPid()).getName())) {
depts.add(deptDTO);
}
}
if (CollectionUtil.isEmpty(trees)) {
trees = depts;
}
Map<String,Object> map = new HashMap<>(2);
map.put("totalElements",deptDtos.size());
map.put("content",CollectionUtil.isEmpty(trees)? deptDtos :trees);
return map;
}
@Override
public void verification(Set<DeptDto> deptDtos) {
Set<Long> deptIds = deptDtos.stream().map(DeptDto::getId).collect(Collectors.toSet());
if(userRepository.countByDepts(deptIds) > 0){
throw new BaseException("所选部门存在用户关联,请解除后再试!");
}
if(roleRepository.countByDepts(deptIds) > 0){
throw new BaseException("所选部门存在角色关联,请解除后再试!");
}
}
private void updateSubCnt(Long deptId){
if(deptId != null){
int count = deptRepository.countByPid(deptId);
deptRepository.updateSubCntById(count, deptId);
}
}
private List<DeptDto> deduplication(List<DeptDto> list) {
List<DeptDto> deptDtos = new ArrayList<>();
for (DeptDto deptDto : list) {
boolean flag = true;
for (DeptDto dto : list) {
if (dto.getId().equals(deptDto.getPid())) {
flag = false;
break;
}
}
if (flag){
deptDtos.add(deptDto);
}
}
return deptDtos;
}
/**
* 清理缓存
* @param id /
*/
public void delCaches(Long id){
List<User> users = userRepository.findByRoleDeptId(id);
// 删除数据权限
redisUtils.delByKeys(CacheKey.DATA_USER, users.stream().map(User::getId).collect(Collectors.toSet()));
redisUtils.del(CacheKey.DEPT_ID + id);
}
}

80
system/src/main/java/com/storeroom/modules/system/service/impl/DictDetailServiceImpl.java

@ -0,0 +1,80 @@
package com.storeroom.modules.system.service.impl;
import com.storeroom.modules.system.domain.Dict;
import com.storeroom.modules.system.domain.DictDetail;
import com.storeroom.modules.system.repository.DictDetailRepository;
import com.storeroom.modules.system.repository.DictRepository;
import com.storeroom.modules.system.service.DictDetailService;
import com.storeroom.modules.system.service.dto.DictDetailDto;
import com.storeroom.modules.system.service.dto.DictDetailQueryCriteria;
import com.storeroom.modules.system.service.mapstruct.DictDetailMapper;
import com.storeroom.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "dict")
public class DictDetailServiceImpl implements DictDetailService {
private final DictRepository dictRepository;
private final DictDetailRepository dictDetailRepository;
private final DictDetailMapper dictDetailMapper;
private final RedisUtils redisUtils;
@Override
public Map<String,Object> queryAll(DictDetailQueryCriteria criteria, Pageable pageable) {
Page<DictDetail> page = dictDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(dictDetailMapper::toDto));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(DictDetail resources) {
dictDetailRepository.save(resources);
// 清理缓存
delCaches(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(DictDetail resources) {
DictDetail dictDetail = dictDetailRepository.findById(resources.getId()).orElseGet(DictDetail::new);
ValidationUtil.isNull( dictDetail.getId(),"DictDetail","id",resources.getId());
resources.setId(dictDetail.getId());
dictDetailRepository.save(resources);
// 清理缓存
delCaches(resources);
}
@Override
@Cacheable(key = "'name:' + #p0")
public List<DictDetailDto> getDictByName(String name) {
return dictDetailMapper.toDto(dictDetailRepository.findByDictName(name));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
DictDetail dictDetail = dictDetailRepository.findById(id).orElseGet(DictDetail::new);
// 清理缓存
delCaches(dictDetail);
dictDetailRepository.deleteById(id);
}
public void delCaches(DictDetail dictDetail){
Dict dict = dictRepository.findById(dictDetail.getDict().getId()).orElseGet(Dict::new);
redisUtils.del(CacheKey.DICT_NAME + dict.getName());
}
}

104
system/src/main/java/com/storeroom/modules/system/service/impl/DictServiceImpl.java

@ -0,0 +1,104 @@
package com.storeroom.modules.system.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.storeroom.modules.system.domain.Dict;
import com.storeroom.modules.system.repository.DictRepository;
import com.storeroom.modules.system.service.DictService;
import com.storeroom.modules.system.service.dto.DictDetailDto;
import com.storeroom.modules.system.service.dto.DictDto;
import com.storeroom.modules.system.service.dto.DictQueryCriteria;
import com.storeroom.modules.system.service.mapstruct.DictMapper;
import com.storeroom.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "dict")
public class DictServiceImpl implements DictService {
private final DictRepository dictRepository;
private final DictMapper dictMapper;
private final RedisUtils redisUtils;
@Override
public Map<String, Object> queryAll(DictQueryCriteria dict, Pageable pageable){
Page<Dict> page = dictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb), pageable);
return PageUtil.toPage(page.map(dictMapper::toDto));
}
@Override
public List<DictDto> queryAll(DictQueryCriteria dict) {
List<Dict> list = dictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb));
return dictMapper.toDto(list);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Dict resources) {
dictRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Dict resources) {
// 清理缓存
delCaches(resources);
Dict dict = dictRepository.findById(resources.getId()).orElseGet(Dict::new);
ValidationUtil.isNull( dict.getId(),"Dict","id",resources.getId());
dict.setName(resources.getName());
dict.setDescription(resources.getDescription());
dictRepository.save(dict);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<Long> ids) {
// 清理缓存
List<Dict> dicts = dictRepository.findByIdIn(ids);
for (Dict dict : dicts) {
delCaches(dict);
}
dictRepository.deleteByIdIn(ids);
}
@Override
public void download(List<DictDto> dictDtos, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (DictDto dictDTO : dictDtos) {
if(CollectionUtil.isNotEmpty(dictDTO.getDictDetails())){
for (DictDetailDto dictDetail : dictDTO.getDictDetails()) {
Map<String,Object> map = new LinkedHashMap<>();
map.put("字典名称", dictDTO.getName());
map.put("字典描述", dictDTO.getDescription());
map.put("字典标签", dictDetail.getLabel());
map.put("字典值", dictDetail.getValue());
map.put("创建日期", dictDetail.getCreateTime());
list.add(map);
}
} else {
Map<String,Object> map = new LinkedHashMap<>();
map.put("字典名称", dictDTO.getName());
map.put("字典描述", dictDTO.getDescription());
map.put("字典标签", null);
map.put("字典值", null);
map.put("创建日期", dictDTO.getCreateTime());
list.add(map);
}
}
FileUtil.downloadExcel(list, response);
}
public void delCaches(Dict dict){
redisUtils.del(CacheKey.DICT_NAME + dict.getName());
}
}

106
system/src/main/java/com/storeroom/modules/system/service/impl/JobServiceImpl.java

@ -0,0 +1,106 @@
package com.storeroom.modules.system.service.impl;
import com.storeroom.exception.BaseException;
import com.storeroom.modules.system.domain.Job;
import com.storeroom.modules.system.repository.JobRepository;
import com.storeroom.modules.system.repository.UserRepository;
import com.storeroom.modules.system.service.JobService;
import com.storeroom.modules.system.service.dto.JobDto;
import com.storeroom.modules.system.service.dto.JobQueryCriteria;
import com.storeroom.modules.system.service.mapstruct.JobMapper;
import com.storeroom.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "job")
public class JobServiceImpl implements JobService {
private final JobRepository jobRepository;
private final JobMapper jobMapper;
private final RedisUtils redisUtils;
private final UserRepository userRepository;
@Override
public Map<String,Object> queryAll(JobQueryCriteria criteria, Pageable pageable) {
Page<Job> page = jobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(jobMapper::toDto).getContent(),page.getTotalElements());
}
@Override
public List<JobDto> queryAll(JobQueryCriteria criteria) {
List<Job> list = jobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder));
return jobMapper.toDto(list);
}
@Override
@Cacheable(key = "'id:' + #p0")
public JobDto findById(Long id) {
Job job = jobRepository.findById(id).orElseGet(Job::new);
ValidationUtil.isNull(job.getId(),"Job","id",id);
return jobMapper.toDto(job);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Job resources) {
Job job = jobRepository.findByName(resources.getName());
if(job != null){
throw new BaseException("name",resources.getName());
}
jobRepository.save(resources);
}
@Override
@CacheEvict(key = "'id:' + #p0.id")
@Transactional(rollbackFor = Exception.class)
public void update(Job resources) {
Job job = jobRepository.findById(resources.getId()).orElseGet(Job::new);
Job old = jobRepository.findByName(resources.getName());
if(old != null && !old.getId().equals(resources.getId())){
throw new BaseException("name",resources.getName());
}
ValidationUtil.isNull( job.getId(),"Job","id",resources.getId());
resources.setId(job.getId());
jobRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<Long> ids) {
jobRepository.deleteAllByIdIn(ids);
// 删除缓存
redisUtils.delByKeys(CacheKey.JOB_ID, ids);
}
@Override
public void download(List<JobDto> jobDtos, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (JobDto jobDTO : jobDtos) {
Map<String,Object> map = new LinkedHashMap<>();
map.put("岗位名称", jobDTO.getName());
map.put("岗位状态", jobDTO.getEnabled() ? "启用" : "停用");
map.put("创建日期", jobDTO.getCreateTime());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
@Override
public void verification(Set<Long> ids) {
if(userRepository.countByJobs(ids) > 0){
throw new BaseException("所选的岗位中存在用户关联,请解除关联再试!");
}
}
}

339
system/src/main/java/com/storeroom/modules/system/service/impl/MenuServiceImpl.java

@ -0,0 +1,339 @@
package com.storeroom.modules.system.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.storeroom.exception.BaseException;
import com.storeroom.modules.system.domain.Menu;
import com.storeroom.modules.system.domain.Role;
import com.storeroom.modules.system.domain.User;
import com.storeroom.modules.system.domain.vo.MenuMetaVo;
import com.storeroom.modules.system.domain.vo.MenuVo;
import com.storeroom.modules.system.repository.MenuRepository;
import com.storeroom.modules.system.repository.UserRepository;
import com.storeroom.modules.system.service.MenuService;
import com.storeroom.modules.system.service.RoleService;
import com.storeroom.modules.system.service.dto.MenuDto;
import com.storeroom.modules.system.service.dto.MenuQueryCriteria;
import com.storeroom.modules.system.service.dto.RoleSmallDto;
import com.storeroom.modules.system.service.mapstruct.MenuMapper;
import com.storeroom.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "menu")
public class MenuServiceImpl implements MenuService {
private final MenuRepository menuRepository;
private final UserRepository userRepository;
private final MenuMapper menuMapper;
private final RoleService roleService;
private final RedisUtils redisUtils;
@Override
public List<MenuDto> queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception {
Sort sort = Sort.by(Sort.Direction.ASC, "menuSort");
if(Boolean.TRUE.equals(isQuery)){
criteria.setPidIsNull(true);
List<Field> fields = QueryHelp.getAllFields(criteria.getClass(), new ArrayList<>());
for (Field field : fields) {
//设置对象的访问权限保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(criteria);
if("pidIsNull".equals(field.getName())){
continue;
}
if (ObjectUtil.isNotNull(val)) {
criteria.setPidIsNull(null);
break;
}
}
}
return menuMapper.toDto(menuRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort));
}
@Override
@Cacheable(key = "'id:' + #p0")
public MenuDto findById(long id) {
Menu menu = menuRepository.findById(id).orElseGet(Menu::new);
ValidationUtil.isNull(menu.getId(),"Menu","id",id);
return menuMapper.toDto(menu);
}
/**
* 用户角色改变时需清理缓存
* @param currentUserId /
* @return /
*/
@Override
@Cacheable(key = "'user:' + #p0")
public List<MenuDto> findByUser(Long currentUserId) {
List<RoleSmallDto> roles = roleService.findByUsersId(currentUserId);
Set<Long> roleIds = roles.stream().map(RoleSmallDto::getId).collect(Collectors.toSet());
LinkedHashSet<Menu> menus = menuRepository.findByRoleIdsAndTypeNot(roleIds, 2);
return menus.stream().map(menuMapper::toDto).collect(Collectors.toList());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Menu resources) {
if(menuRepository.findByTitle(resources.getTitle()) != null){
throw new BaseException("title",resources.getTitle());
}
if(StringUtils.isNotBlank(resources.getComponentName())){
if(menuRepository.findByComponentName(resources.getComponentName()) != null){
throw new BaseException("componentName",resources.getComponentName());
}
}
if(resources.getPid().equals(0L)){
resources.setPid(null);
}
if(resources.getIFrame()){
String http = "http://", https = "https://";
if (!(resources.getPath().toLowerCase().startsWith(http)||resources.getPath().toLowerCase().startsWith(https))) {
throw new BaseException("外链必须以http://或者https://开头");
}
}
menuRepository.save(resources);
// 计算子节点数目
resources.setSubCount(0);
// 更新父节点菜单数目
updateSubCnt(resources.getPid());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Menu resources) {
if(resources.getId().equals(resources.getPid())) {
throw new BaseException("上级不能为自己");
}
Menu menu = menuRepository.findById(resources.getId()).orElseGet(Menu::new);
ValidationUtil.isNull(menu.getId(),"Permission","id",resources.getId());
if(resources.getIFrame()){
String http = "http://", https = "https://";
if (!(resources.getPath().toLowerCase().startsWith(http)||resources.getPath().toLowerCase().startsWith(https))) {
throw new BaseException("外链必须以http://或者https://开头");
}
}
Menu menu1 = menuRepository.findByTitle(resources.getTitle());
if(menu1 != null && !menu1.getId().equals(menu.getId())){
throw new BaseException("title",resources.getTitle());
}
if(resources.getPid().equals(0L)){
resources.setPid(null);
}
// 记录的父节点ID
Long oldPid = menu.getPid();
Long newPid = resources.getPid();
if(StringUtils.isNotBlank(resources.getComponentName())){
menu1 = menuRepository.findByComponentName(resources.getComponentName());
if(menu1 != null && !menu1.getId().equals(menu.getId())){
throw new BaseException("componentName",resources.getComponentName());
}
}
menu.setTitle(resources.getTitle());
menu.setComponent(resources.getComponent());
menu.setPath(resources.getPath());
menu.setIcon(resources.getIcon());
menu.setIFrame(resources.getIFrame());
menu.setPid(resources.getPid());
menu.setMenuSort(resources.getMenuSort());
menu.setCache(resources.getCache());
menu.setHidden(resources.getHidden());
menu.setComponentName(resources.getComponentName());
menu.setPermission(resources.getPermission());
menu.setType(resources.getType());
menuRepository.save(menu);
// 计算父级菜单节点数目
updateSubCnt(oldPid);
updateSubCnt(newPid);
// 清理缓存
delCaches(resources.getId());
}
@Override
public Set<Menu> getChildMenus(List<Menu> menuList, Set<Menu> menuSet) {
for (Menu menu : menuList) {
menuSet.add(menu);
List<Menu> menus = menuRepository.findByPid(menu.getId());
if(menus!=null && menus.size()!=0){
getChildMenus(menus, menuSet);
}
}
return menuSet;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<Menu> menuSet) {
for (Menu menu : menuSet) {
// 清理缓存
delCaches(menu.getId());
roleService.untiedMenu(menu.getId());
menuRepository.deleteById(menu.getId());
updateSubCnt(menu.getPid());
}
}
@Override
public List<MenuDto> getMenus(Long pid) {
List<Menu> menus;
if(pid != null && !pid.equals(0L)){
menus = menuRepository.findByPid(pid);
} else {
menus = menuRepository.findByPidIsNull();
}
return menuMapper.toDto(menus);
}
@Override
public List<MenuDto> getSuperior(MenuDto menuDto, List<Menu> menus) {
if(menuDto.getPid() == null){
menus.addAll(menuRepository.findByPidIsNull());
return menuMapper.toDto(menus);
}
menus.addAll(menuRepository.findByPid(menuDto.getPid()));
return getSuperior(findById(menuDto.getPid()), menus);
}
@Override
public List<MenuDto> buildTree(List<MenuDto> menuDtos) {
List<MenuDto> trees = new ArrayList<>();
Set<Long> ids = new HashSet<>();
for (MenuDto menuDTO : menuDtos) {
if (menuDTO.getPid() == null) {
trees.add(menuDTO);
}
for (MenuDto it : menuDtos) {
if (menuDTO.getId().equals(it.getPid())) {
if (menuDTO.getChildren() == null) {
menuDTO.setChildren(new ArrayList<>());
}
menuDTO.getChildren().add(it);
ids.add(it.getId());
}
}
}
if(trees.size() == 0){
trees = menuDtos.stream().filter(s -> !ids.contains(s.getId())).collect(Collectors.toList());
}
return trees;
}
@Override
public List<MenuVo> buildMenus(List<MenuDto> menuDtos) {
List<MenuVo> list = new LinkedList<>();
menuDtos.forEach(menuDTO -> {
if (menuDTO!=null){
List<MenuDto> menuDtoList = menuDTO.getChildren();
MenuVo menuVo = new MenuVo();
menuVo.setName(ObjectUtil.isNotEmpty(menuDTO.getComponentName()) ? menuDTO.getComponentName() : menuDTO.getTitle());
// 一级目录需要加斜杠不然会报警告
menuVo.setPath(menuDTO.getPid() == null ? "/" + menuDTO.getPath() :menuDTO.getPath());
menuVo.setHidden(menuDTO.getHidden());
// 如果不是外链
if(!menuDTO.getIFrame()){
if(menuDTO.getPid() == null){
menuVo.setComponent(StringUtils.isEmpty(menuDTO.getComponent())?"Layout":menuDTO.getComponent());
// 如果不是一级菜单并且菜单类型为目录则代表是多级菜单
}else if(menuDTO.getType() == 0){
menuVo.setComponent(StringUtils.isEmpty(menuDTO.getComponent())?"ParentView":menuDTO.getComponent());
}else if(StringUtils.isNoneBlank(menuDTO.getComponent())){
menuVo.setComponent(menuDTO.getComponent());
}
}
menuVo.setMeta(new MenuMetaVo(menuDTO.getTitle(),menuDTO.getIcon(),!menuDTO.getCache()));
if(CollectionUtil.isNotEmpty(menuDtoList)){
menuVo.setAlwaysShow(true);
menuVo.setRedirect("noredirect");
menuVo.setChildren(buildMenus(menuDtoList));
// 处理是一级菜单并且没有子菜单的情况
} else if(menuDTO.getPid() == null){
MenuVo menuVo1 = new MenuVo();
menuVo1.setMeta(menuVo.getMeta());
// 非外链
if(!menuDTO.getIFrame()){
menuVo1.setPath("index");
menuVo1.setName(menuVo.getName());
menuVo1.setComponent(menuVo.getComponent());
} else {
menuVo1.setPath(menuDTO.getPath());
}
menuVo.setName(null);
menuVo.setMeta(null);
menuVo.setComponent("Layout");
List<MenuVo> list1 = new ArrayList<>();
list1.add(menuVo1);
menuVo.setChildren(list1);
}
list.add(menuVo);
}
}
);
return list;
}
@Override
public Menu findOne(Long id) {
Menu menu = menuRepository.findById(id).orElseGet(Menu::new);
ValidationUtil.isNull(menu.getId(),"Menu","id",id);
return menu;
}
@Override
public void download(List<MenuDto> menuDtos, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (MenuDto menuDTO : menuDtos) {
Map<String,Object> map = new LinkedHashMap<>();
map.put("菜单标题", menuDTO.getTitle());
map.put("菜单类型", menuDTO.getType() == null ? "目录" : menuDTO.getType() == 1 ? "菜单" : "按钮");
map.put("权限标识", menuDTO.getPermission());
map.put("外链菜单", menuDTO.getIFrame() ? "是" : "否");
map.put("菜单可见", menuDTO.getHidden() ? "否" : "是");
map.put("是否缓存", menuDTO.getCache() ? "是" : "否");
map.put("创建日期", menuDTO.getCreateTime());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
private void updateSubCnt(Long menuId){
if(menuId != null){
int count = menuRepository.countByPid(menuId);
menuRepository.updateSubCntById(count, menuId);
}
}
/**
* 清理缓存
* @param id 菜单ID
*/
public void delCaches(Long id){
List<User> users = userRepository.findByMenuId(id);
redisUtils.del(CacheKey.MENU_ID + id);
redisUtils.delByKeys(CacheKey.MENU_USER, users.stream().map(User::getId).collect(Collectors.toSet()));
// 清除 Role 缓存
List<Role> roles = roleService.findInMenuId(new ArrayList<Long>(){{
add(id);
}});
redisUtils.delByKeys(CacheKey.ROLE_ID, roles.stream().map(Role::getId).collect(Collectors.toSet()));
}
}

68
system/src/main/resources/application-dev.yml

@ -45,3 +45,71 @@ spring:
wall:
config:
multi-statement-allow: true
# 登录相关配置
login:
# 登录缓存
cache-enable: true
# 是否限制单用户登录
single-login: false
# 验证码
login-code:
# 验证码类型配置 查看 LoginProperties 类
code-type: arithmetic
# 登录图形验证码有效时间/分钟
expiration: 2
# 验证码高度
width: 111
# 验证码宽度
height: 36
# 内容长度
length: 2
# 字体名称,为空则使用默认字体
font-name:
# 字体大小
font-size: 25
#jwt
jwt:
header: Authorization
# 令牌前缀
token-start-with: Bearer
# 必须使用最少88位的Base64对该令牌进行编码
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
token-validity-in-seconds: 14400000
# 在线用户key
online-key: online-token-
# 验证码
code-key: code-key-
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
detect: 1800000
# 续期时间范围,默认1小时,单位毫秒
renew: 3600000
#是否开启 swagger-ui
swagger:
enabled: true
# IP 本地解析
ip:
local-parsing: true
# 文件存储路径
file:
mac:
path: ~/file/
avatar: ~/avatar/
linux:
path: /home/yxk_App/file/
avatar: /home/yxk_App/avatar/
windows:
path: D:\yxk_App\file\
avatar: D:\yxk_App\avatar\
# 文件大小 /M
maxSize: 100
avatarMaxSize: 5

43
system/src/main/resources/application.yml

@ -43,23 +43,7 @@ task:
# 队列容量
queue-capacity: 50
#jwt
jwt:
header: Authorization
# 令牌前缀
token-start-with: Bearer
# 必须使用最少88位的Base64对该令牌进行编码
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
token-validity-in-seconds: 14400000
# 在线用户key
online-key: online-token-
# 验证码
code-key: code-key-
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
detect: 1800000
# 续期时间范围,默认1小时,单位毫秒
renew: 3600000
code:
expriration: 300
@ -72,21 +56,18 @@ swagger:
ip:
local-parsing: true
# 文件存储路径
file:
mac:
path: ~/file/
avatar: ~/avatar/
linux:
path: /home/yxk_App/file/
avatar: /home/yxk_App/avatar/
windows:
path: D:\yxk_App\file\
avatar: D:\yxk_App\avatar\
# 文件大小 /M
maxSize: 100
avatarMaxSize: 5
#密码加密传输 此处为私钥
rsa:
private_key: MIICWwIBAAKBgQDyhGeZ23kNfDysndtEMHQgX+3YcKPNny2YFtlfvYTpHmVClbaiZK+g2VetX/mhkiSQtyp5OwSy+dm6WVX7QOvUO7iPNs2Hl+33d6rzzMhROs46rCTBpukgdaT0N6SC8NWkBF9ogoDzhEGNKIV0AGHRPWmL75ghflUPD2VflmAnywIDAQABAoGAPL47MMdPD7ihfd7gD7lPLNi6Oy8jaBpJkkGO2rMeekFZvY7AOvabIt+tXUifvv9a10B5i/njWGzKQymjJpaBOp+JswuBKEq8ZFqeyQJWsrj1zJC+HaCImP1frvgdtWIu1tldVE44X7jIQSFAd26JJsPslMntj/iE7VBkzQRYhjkCQQD/3+zu4OJP5XdSq4Y+HzIJ7u2JS8u/SxRQYQh1E6/yydgyWE96cze4jZQQTvxBRsOrXvBlVJdT+QmcV0YnlyMtAkEA8qLOBevOgH5qq1nLRMYU6zb0k5OiAaiI+Oq1mZn0kjcisyFZopAs2FH07DVlh+tzbGdzt4Q3PjLSEqhVFU4x1wJARljoKRzG27R4w8/IjpfBCB4aTF78W1Fm+lpTGu0YuKVpvR2ubDn1HdY+2OT+UWwFK75kVVeWa03SqJsN/KB+2QJAKD9XO2Y1F91gZlH7xMmyuJ2iDkTD79B8AAY232bJSeO5bstOagfOWIenv/LPh69Hsyip6jwVScz2ScAAdQtGewJACeSyLWjPnQ4ZgWrJyz6dyPgGKprDzQ00UMlvH3F2KJ9Ll99yfBah++GQXPfzjhD2ouWAQ+GaiS/RdSNDX1RoFg==
# 内存用户缓存配置
user-cache:
# 最小回收数(当缓存数量达到此值时进行回收)
min-evictable-size: 512
# 最小回收间隔
min-evictable-interval: 1800000
# 最小存活时间 (ms)
min-idle-time: 3600000

8
system/src/main/resources/banner.txt

@ -0,0 +1,8 @@
██ ██ ██ ██ ██ ██ ████████ ██ ███████
░░██ ██ ░░██ ██ ░██ ██ ██░░░░░░ ░██ ░██░░░░██
░░████ ░░██ ██ ░██ ██ ░██ ██████ ██████ ██████ █████ ░██ ░██ ██████ ██████ ██████████
░░██ ░░███ ░████ ░█████████░░░██░ ██░░░░██░░██░░█ ██░░░██ ░███████ ██░░░░██ ██░░░░██░░██░░██░░██
░██ ██░██ ░██░██ ░░░░░░░░██ ░██ ░██ ░██ ░██ ░ ░███████ ░██░░░██ ░██ ░██░██ ░██ ░██ ░██ ░██
░██ ██ ░░██ ░██░░██ ░██ ░██ ░██ ░██ ░██ ░██░░░░ ░██ ░░██ ░██ ░██░██ ░██ ░██ ░██ ░██
░██ ██ ░░██░██ ░░██ ████████ ░░██ ░░██████ ░███ ░░██████ ░██ ░░██░░██████ ░░██████ ███ ░██ ░██
░░ ░░ ░░ ░░ ░░ ░░░░░░░░ ░░ ░░░░░░ ░░░ ░░░░░░ ░░ ░░ ░░░░░░ ░░░░░░ ░░░ ░░ ░░

27
system/src/main/resources/generator.properties

@ -0,0 +1,27 @@
#数据库类型转Java类型
tinyint=Integer
smallint=Integer
mediumint=Integer
int=Integer
integer=Integer
bigint=Long
float=Float
double=Double
decimal=BigDecimal
bit=Boolean
char=String
varchar=String
tinytext=String
text=String
mediumtext=String
longtext=String
date=Timestamp
datetime=Timestamp
timestamp=Timestamp

4
system/src/main/resources/log4jdbc.log4j2.properties

@ -0,0 +1,4 @@
# If you use SLF4J. First, you need to tell log4jdbc-log4j2 that you want to use the SLF4J logger
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.auto.load.popular.drivers=false
log4jdbc.drivers=com.mysql.cj.jdbc.Driver

45
system/src/main/resources/logback.xml

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" debug="false">
<contextName>yxk-storeroom</contextName>
<property name="log.charset" value="utf-8" />
<property name="log.pattern" value="%contextName- %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %msg%n" />
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
<charset>${log.charset}</charset>
</encoder>
</appender>
<!--普通日志输出到控制台-->
<root level="info">
<appender-ref ref="console" />
</root>
<!--监控sql日志输出,如需监控 Sql 打印,请设置为 INFO -->
<logger name="jdbc.sqlonly" level="ERROR" additivity="false">
<appender-ref ref="console" />
</logger>
<logger name="jdbc.resultset" level="ERROR" additivity="false">
<appender-ref ref="console" />
</logger>
<!-- 如想看到表格数据,将OFF改为INFO -->
<logger name="jdbc.resultsettable" level="OFF" additivity="false">
<appender-ref ref="console" />
</logger>
<logger name="jdbc.connection" level="OFF" additivity="false">
<appender-ref ref="console" />
</logger>
<logger name="jdbc.sqltiming" level="OFF" additivity="false">
<appender-ref ref="console" />
</logger>
<logger name="jdbc.audit" level="OFF" additivity="false">
<appender-ref ref="console" />
</logger>
</configuration>
Loading…
Cancel
Save