init
This commit is contained in:
commit
af3b160551
|
@ -0,0 +1,173 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.dc</groupId>
|
||||||
|
<artifactId>welfare-api</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.3.4.RELEASE</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- springWeb -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- spring test -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>5.3.23</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- validation -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- redis 缓存操作 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>io.lettuce</groupId>
|
||||||
|
<artifactId>lettuce-core</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>redis.clients</groupId>
|
||||||
|
<artifactId>jedis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- spring security -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!--Token生成与解析-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt</artifactId>
|
||||||
|
<version>0.9.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringBoot 拦截器 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- pagehelper 分页插件 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.pagehelper</groupId>
|
||||||
|
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||||
|
<version>1.3.0</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.mybatis</groupId>
|
||||||
|
<artifactId>mybatis</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.mybatis</groupId>
|
||||||
|
<artifactId>mybatis-spring</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--mybatisplus-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
<version>3.3.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- mysql -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 阿里JSON解析器 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>1.2.74</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- redis 缓存操作 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- hutool -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.0.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<!-- 此包一般在Servlet容器中都有提供 -->
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- commons -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.10</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Excel -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi-ooxml</artifactId>
|
||||||
|
<version>3.17</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.org;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
|
@EnableScheduling
|
||||||
|
@SpringBootApplication
|
||||||
|
public class WelfareApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(WelfareApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,181 @@
|
||||||
|
package com.org.oss.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import com.org.oss.entity.SysOss;
|
||||||
|
import com.org.oss.service.SysOssService;
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.controller.BaseController;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import com.org.utils.page.TableDataInfo;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.tomcat.util.codec.binary.Base64;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sys/oss")
|
||||||
|
public class SysOssController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysOssService sysOssService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
*
|
||||||
|
* @return RestResponse
|
||||||
|
*/
|
||||||
|
@GetMapping("/list")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:oss:list')")
|
||||||
|
@Log(title = "系统文件分页查询", businessType = BusinessType.SELECT)
|
||||||
|
public TableDataInfo getList(SysOss sysOss) {
|
||||||
|
log.info("SysOssController - getList sysOss:{}", sysOss);
|
||||||
|
|
||||||
|
startPage();
|
||||||
|
List<SysOss> list = sysOssService.queryList(sysOss);
|
||||||
|
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
*
|
||||||
|
* @param file file
|
||||||
|
* @return RestResponse
|
||||||
|
*/
|
||||||
|
@RequestMapping("/upload")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:oss:edit')")
|
||||||
|
@Log(title = "系统文件上传", businessType = BusinessType.INSERT)
|
||||||
|
public Object upload(@RequestParam(value = "file", required = false) MultipartFile file,
|
||||||
|
@RequestParam(value = "sourceId", required = false) String sourceId,
|
||||||
|
@RequestParam(value = "fileType", required = false) String fileType) throws IOException {
|
||||||
|
if (null == file || file.isEmpty()) throw new CustomException("上传文件不能为空");
|
||||||
|
|
||||||
|
return sysOssService.upload(file, sourceId, fileType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传图片-指定图片大小
|
||||||
|
*
|
||||||
|
* @param file file
|
||||||
|
* @return RestResponse
|
||||||
|
*/
|
||||||
|
@RequestMapping("/uploadImg")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:oss:edit')")
|
||||||
|
@Log(title = "系统文件上传", businessType = BusinessType.INSERT)
|
||||||
|
public Object uploadImg(@RequestParam(value = "file", required = false) MultipartFile file,
|
||||||
|
@RequestParam(value = "sourceId", required = false) String sourceId,
|
||||||
|
@RequestParam(value = "fileType", required = false) String fileType,
|
||||||
|
@RequestParam(value = "fileSize", required = false) Long fileSize) throws IOException {
|
||||||
|
if (null == file || file.isEmpty()) throw new CustomException("上传文件不能为空");
|
||||||
|
|
||||||
|
if (null == fileSize) return sysOssService.upload(file, sourceId, fileType);
|
||||||
|
return sysOssService.uploadImg(file, sourceId, fileType, fileSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传-图片Base64
|
||||||
|
*
|
||||||
|
* @param base64
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@PostMapping("/upload/base64")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:oss:edit')")
|
||||||
|
@Log(title = "系统文件上传-图片Base64", businessType = BusinessType.INSERT)
|
||||||
|
public Object uploadBase64(@RequestBody String base64) throws IOException {
|
||||||
|
if(StringUtils.isEmpty(base64)) throw new CustomException("上传文件Base64不能为空");
|
||||||
|
|
||||||
|
base64 = base64.substring(base64.indexOf(",")+1);
|
||||||
|
byte[] data = Base64.decodeBase64(base64);
|
||||||
|
|
||||||
|
String fileName = String.format("%s.%s", IdUtil.simpleUUID(), "png") ;
|
||||||
|
MultipartFile file = new MockMultipartFile(fileName, fileName, "application/x-png", data);
|
||||||
|
|
||||||
|
return sysOssService.upload(file, "", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文件上传记录
|
||||||
|
*
|
||||||
|
* @param ids ids
|
||||||
|
* @return RestResponse
|
||||||
|
*/
|
||||||
|
@PostMapping("/delete")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:oss:edit')")
|
||||||
|
@Log(title = "系统文件删除", businessType = BusinessType.DELETE)
|
||||||
|
public AjaxResult delete(@RequestBody Integer[] ids) {
|
||||||
|
log.info("SysOssController - delete ids:{}", ids);
|
||||||
|
|
||||||
|
sysOssService.delete(ids);
|
||||||
|
|
||||||
|
return AjaxResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件全路径数组删除上传文件
|
||||||
|
*
|
||||||
|
* @param urls
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/deleteByUrl")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:oss:edit')")
|
||||||
|
@Log(title = "系统文件删除", businessType = BusinessType.DELETE)
|
||||||
|
public AjaxResult deleteByUrl(@RequestBody String[] urls) {
|
||||||
|
log.info("SysOssController - deleteByUrl urls:{}", urls);
|
||||||
|
|
||||||
|
sysOssService.deleteByUrl(urls);
|
||||||
|
|
||||||
|
return AjaxResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件
|
||||||
|
*
|
||||||
|
* @param dateDir
|
||||||
|
* @param fileName
|
||||||
|
*/
|
||||||
|
@GetMapping(value = "/show/{dateDir}/{fileName}")
|
||||||
|
public void show(@PathVariable("dateDir") String dateDir, @PathVariable("fileName") String fileName) {
|
||||||
|
log.info("SysOssController - show dateDir:{}", dateDir);
|
||||||
|
log.info("SysOssController - show fileName:{}", fileName);
|
||||||
|
|
||||||
|
sysOssService.show(dateDir, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件ID获取文件
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
@GetMapping(value = "/show")
|
||||||
|
public void show(@RequestParam String id) {
|
||||||
|
log.info("SysOssController - show id:{}", id);
|
||||||
|
|
||||||
|
sysOssService.show(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* COS工作流回调
|
||||||
|
* @param callbackStr
|
||||||
|
* @return
|
||||||
|
|
||||||
|
@PostMapping("/cos/callback")
|
||||||
|
public String cosCallback(@RequestBody String callbackStr){
|
||||||
|
log.info("SysOssController - cosCallback callbackStr:{}", callbackStr);
|
||||||
|
|
||||||
|
sysOssService.cosCallback(callbackStr);
|
||||||
|
|
||||||
|
return "ok";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.org.oss.controller;
|
||||||
|
|
||||||
|
import com.org.system.controller.BaseController;
|
||||||
|
import com.org.utils.upload.CommonUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("common")
|
||||||
|
public class commonController extends BaseController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用下载接口
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
*/
|
||||||
|
@GetMapping("/download")
|
||||||
|
public void fileDownload(String fileName){
|
||||||
|
log.info("commonController - fileDownload fileName:{}", fileName);
|
||||||
|
|
||||||
|
CommonUtil.download(fileName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.org.oss.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.org.system.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class SysOss extends BaseEntity {
|
||||||
|
|
||||||
|
/** 附件ID **/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 来源ID **/
|
||||||
|
private String sourceId;
|
||||||
|
|
||||||
|
/** 附件名称 **/
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
/** 附件新名称 **/
|
||||||
|
private String newName;
|
||||||
|
|
||||||
|
/** 附件类型 **/
|
||||||
|
private String fileType;
|
||||||
|
|
||||||
|
/** 附件存放地址 **/
|
||||||
|
private String realPath;
|
||||||
|
|
||||||
|
/** URL地址 **/
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.org.oss.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.org.oss.entity.SysOss;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysOssMapper extends BaseMapper<SysOss> {
|
||||||
|
|
||||||
|
@Select("SELECT * FROM sys_oss WHERE url = #{fileUrl}")
|
||||||
|
SysOss findByUrl(@Param("fileUrl") String fileUrl);
|
||||||
|
|
||||||
|
@Select("SELECT * FROM sys_oss WHERE real_path = #{realPath}")
|
||||||
|
SysOss findByRealPath(@Param("realPath") String realPath);
|
||||||
|
|
||||||
|
@Select("select * from sys_oss where real_path like concat('%', #{suffix})")
|
||||||
|
List<SysOss> findByRealPathSuffix(@Param("suffix") String suffix);
|
||||||
|
}
|
|
@ -0,0 +1,288 @@
|
||||||
|
package com.org.oss.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.org.oss.entity.SysOss;
|
||||||
|
import com.org.oss.mapper.SysOssMapper;
|
||||||
|
import com.org.system.enums.YesOrNoState;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import com.org.utils.SecurityUtil;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import com.org.utils.upload.UpLoadUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SysOssService extends ServiceImpl<SysOssMapper, SysOss> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
*
|
||||||
|
* @param sysOss
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysOss> queryList(SysOss sysOss){
|
||||||
|
log.info("SysOssService - queryList sysOss:{}", sysOss);
|
||||||
|
LambdaQueryWrapper<SysOss> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
if(StringUtils.isNotEmpty(sysOss.getFileName())) queryWrapper.like(SysOss::getFileName, sysOss.getFileName());
|
||||||
|
|
||||||
|
return list(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @param sourceId
|
||||||
|
* @param fileType
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public AjaxResult upload(MultipartFile file, String sourceId, String fileType) throws IOException {
|
||||||
|
log.info("SysOssService - upload file:{}", file);
|
||||||
|
log.info("SysOssService - upload sourceId:{}", sourceId);
|
||||||
|
log.info("SysOssService - upload fileType:{}", fileType);
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||||
|
String url = UpLoadUtil.uploadSuffix(file.getBytes(), suffix);
|
||||||
|
String[] urlArr = url.split("/");
|
||||||
|
String fileName = urlArr[urlArr.length - 1];
|
||||||
|
|
||||||
|
// String realPath = url.replace(UpLoadUtil.domain, "");
|
||||||
|
String realPath = url.replace(UpLoadUtil.proxyServer, "");
|
||||||
|
realPath = UpLoadUtil.diskPath + realPath;
|
||||||
|
|
||||||
|
// 保存文件信息
|
||||||
|
SysOss sysOss = new SysOss();
|
||||||
|
sysOss.setSourceId(sourceId);
|
||||||
|
sysOss.setFileName(file.getOriginalFilename());
|
||||||
|
sysOss.setNewName(fileName);
|
||||||
|
sysOss.setFileType(fileType);
|
||||||
|
sysOss.setRealPath(realPath);
|
||||||
|
sysOss.setUrl(url);
|
||||||
|
// 富文本上传图片 没带token 增加是否登录判断
|
||||||
|
if (SecurityUtil.isLogin()) sysOss.setCreateBy(SecurityUtil.getUserId());
|
||||||
|
sysOss.setCreateTime(new Date());
|
||||||
|
sysOss.setIsDelete(YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
save(sysOss);
|
||||||
|
// 返回兼容UEditor的参数
|
||||||
|
return AjaxResult.success().put("url", url)
|
||||||
|
.put("name", sysOss.getFileName())
|
||||||
|
.put("id", sysOss.getId())
|
||||||
|
.put("uid", sysOss.getId())
|
||||||
|
.put("createTime", sysOss.getCreateTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文件上传记录
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
*/
|
||||||
|
public void delete(Integer[] ids){
|
||||||
|
log.info("SysOssService - delete ids:{}", ids);
|
||||||
|
|
||||||
|
for (Integer id : ids) {
|
||||||
|
try {
|
||||||
|
SysOss oss = getById(id);
|
||||||
|
log.info("SysOssService - delete oss:{}", oss);
|
||||||
|
|
||||||
|
FileUtil.del(oss.getRealPath());
|
||||||
|
} catch (Exception err) {
|
||||||
|
log.error("删除文件出现错误:" + id, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeByIds(Arrays.asList(ids));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件全路径数组删除上传文件
|
||||||
|
*
|
||||||
|
* @param urls
|
||||||
|
*/
|
||||||
|
public void deleteByUrl(String[] urls){
|
||||||
|
log.info("SysOssService - deleteByUrl urls:{}", urls);
|
||||||
|
|
||||||
|
for (String url : urls) {
|
||||||
|
try {
|
||||||
|
LambdaQueryWrapper<SysOss> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysOss::getUrl, url);
|
||||||
|
|
||||||
|
SysOss sysOss = getOne(queryWrapper);
|
||||||
|
log.info("SysOssService - deleteByUrl sysOss:{}", sysOss);
|
||||||
|
|
||||||
|
FileUtil.del(sysOss.getRealPath());
|
||||||
|
removeById(sysOss.getId());
|
||||||
|
} catch (Exception err) {
|
||||||
|
log.error("删除文件出现错误:" + url, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(String dateDir, String fileName){
|
||||||
|
log.info("SysOssService - show dateDir:{}", dateDir);
|
||||||
|
log.info("SysOssService - show fileName:{}", fileName);
|
||||||
|
|
||||||
|
fileName = UpLoadUtil.diskPath + "/" + dateDir + "/" + fileName;
|
||||||
|
log.info("SysOssService - show fileName:{}", fileName);
|
||||||
|
|
||||||
|
SysOss oss = findByRealPath(fileName);
|
||||||
|
|
||||||
|
// 如果是视频文件 则走视频文件方法
|
||||||
|
if(fileName.toLowerCase().endsWith("mp4") || fileName.toLowerCase().endsWith("flv")
|
||||||
|
|| fileName.toLowerCase().endsWith("avi") || fileName.toLowerCase().endsWith("rm")
|
||||||
|
|| fileName.toLowerCase().endsWith("rmvb") || fileName.toLowerCase().endsWith("wmv")
|
||||||
|
|| fileName.toLowerCase().endsWith("m3u8")) {
|
||||||
|
UpLoadUtil.getVideo(fileName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpLoadUtil.getFile(fileName, oss.getFileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(String id){
|
||||||
|
log.info("SysOssService - show id:{}", id);
|
||||||
|
|
||||||
|
SysOss oss = getById(id);
|
||||||
|
if(oss == null || StringUtils.isEmpty(oss.getId())) return ;
|
||||||
|
|
||||||
|
String fileName = oss.getRealPath();
|
||||||
|
log.info("SysOssService - show fileName:{}", fileName);
|
||||||
|
|
||||||
|
// 如果是视频文件 则走视频文件方法
|
||||||
|
if(fileName.toLowerCase().endsWith("mp4") || fileName.toLowerCase().endsWith("flv")
|
||||||
|
|| fileName.toLowerCase().endsWith("avi") || fileName.toLowerCase().endsWith("rm")
|
||||||
|
||fileName.toLowerCase().endsWith("rmvb") || fileName.toLowerCase().endsWith("wmv")) {
|
||||||
|
UpLoadUtil.getVideo(fileName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpLoadUtil.getFile(fileName, oss.getFileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过url获取sysOss
|
||||||
|
* @param fileUrl
|
||||||
|
*/
|
||||||
|
public SysOss findByUrl(String fileUrl) {
|
||||||
|
log.info("SysOssService - findByUrl fileUrl:{}", fileUrl);
|
||||||
|
SysOss sysOss = baseMapper.findByUrl(fileUrl);
|
||||||
|
log.info("SysOssService - findByUrl sysOss:{}", sysOss);
|
||||||
|
|
||||||
|
if (sysOss == null || StringUtils.isNull(sysOss.getId())) throw new CustomException("文件未找到!");
|
||||||
|
|
||||||
|
return sysOss;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过url获取sysOss
|
||||||
|
* @param realPath
|
||||||
|
*/
|
||||||
|
public SysOss findByRealPath(String realPath) {
|
||||||
|
log.info("SysOssService - findByRealPath realPath:{}", realPath);
|
||||||
|
SysOss sysOss = baseMapper.findByRealPath(realPath);
|
||||||
|
log.info("SysOssService - findByRealPath sysOss:{}", sysOss);
|
||||||
|
|
||||||
|
if (sysOss == null || StringUtils.isNull(sysOss.getId())) throw new CustomException("文件未找到!");
|
||||||
|
|
||||||
|
return sysOss;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public AjaxResult uploadImg(MultipartFile file, String sourceId, String fileType, long fileSize) throws IOException {
|
||||||
|
log.info("SysOssService - uploadImg file:{}", file);
|
||||||
|
log.info("SysOssService - uploadImg sourceId:{}", sourceId);
|
||||||
|
log.info("SysOssService - uploadImg fileType:{}", fileType);
|
||||||
|
log.info("SysOssService - uploadImg fileSize:{}", fileSize);
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
/*//压缩图片到指定大小以内
|
||||||
|
byte[] bytes = PicUtils.compressPicForScale(file.getBytes(), fileSize);
|
||||||
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
|
||||||
|
String suffix = ".jpg";*/
|
||||||
|
// 上传文件
|
||||||
|
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||||
|
String url = UpLoadUtil.uploadSuffix(file.getBytes(), suffix);
|
||||||
|
String[] urlArr = url.split("/");
|
||||||
|
String fileName = urlArr[urlArr.length - 1];
|
||||||
|
|
||||||
|
String realPath = url.replace(UpLoadUtil.proxyServer, "");
|
||||||
|
realPath = UpLoadUtil.diskPath + realPath;
|
||||||
|
// String realPath = url.replace(UpLoadUtil.domain, "");
|
||||||
|
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
String suffix1 = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
|
||||||
|
originalFilename = originalFilename.substring(0, originalFilename.lastIndexOf(".")) + suffix1;
|
||||||
|
|
||||||
|
// 保存文件信息
|
||||||
|
SysOss sysOss = new SysOss();
|
||||||
|
sysOss.setSourceId(sourceId);
|
||||||
|
sysOss.setFileName(originalFilename);
|
||||||
|
sysOss.setNewName(fileName);
|
||||||
|
sysOss.setFileType(fileType);
|
||||||
|
sysOss.setRealPath(realPath);
|
||||||
|
sysOss.setUrl(url);
|
||||||
|
sysOss.setCreateBy(SecurityUtil.getUserId());
|
||||||
|
sysOss.setCreateTime(new Date());
|
||||||
|
sysOss.setIsDelete(YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
save(sysOss);
|
||||||
|
// 返回兼容UEditor的参数
|
||||||
|
return AjaxResult.success().put("url", url)
|
||||||
|
.put("name", sysOss.getFileName())
|
||||||
|
.put("id", sysOss.getId())
|
||||||
|
.put("uid", sysOss.getId())
|
||||||
|
.put("createTime", sysOss.getCreateTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* COS工作流回调
|
||||||
|
* @param callbackStr
|
||||||
|
|
||||||
|
public void cosCallback(String callbackStr) {
|
||||||
|
log.info("SysOssService - cosCallback callbackStr:{}", callbackStr);
|
||||||
|
|
||||||
|
JSONObject jsonObject = JSONUtil.parseObj(callbackStr);
|
||||||
|
JSONObject workflowExecution = jsonObject.getJSONObject("WorkflowExecution");
|
||||||
|
|
||||||
|
String state = workflowExecution.getStr("State");
|
||||||
|
log.info("SysOssService - cosCallback state:{}", state);
|
||||||
|
|
||||||
|
if(!"Success".equals(state)) return;
|
||||||
|
|
||||||
|
String object = workflowExecution.getStr("Object");
|
||||||
|
log.info("SysOssService - cosCallback object:{}", object);
|
||||||
|
|
||||||
|
if(Validator.isNotEmpty(object)){
|
||||||
|
String url = object;
|
||||||
|
String bakUrl = String.format("%s_bak%s", object.substring(0, object.lastIndexOf(".")), object.substring(object.lastIndexOf(".")));
|
||||||
|
String transcodingUrl = String.format("%s_transcoding%s", object.substring(0, object.lastIndexOf(".")), object.substring(object.lastIndexOf(".")));
|
||||||
|
|
||||||
|
log.info("SysOssService - cosCallback url:{}", url);
|
||||||
|
log.info("SysOssService - cosCallback bakUrl:{}", bakUrl);
|
||||||
|
log.info("SysOssService - cosCallback transcodingUrl:{}", transcodingUrl);
|
||||||
|
|
||||||
|
// 备份源视频文件
|
||||||
|
UpLoadUtil.copyObject(url, bakUrl);
|
||||||
|
UpLoadUtil.deleteObject(url);
|
||||||
|
|
||||||
|
// 转移转码后的视频文件
|
||||||
|
UpLoadUtil.copyObject(transcodingUrl, url);
|
||||||
|
UpLoadUtil.deleteObject(transcodingUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.org.system.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface CheckVerify {
|
||||||
|
public String phone() default "";
|
||||||
|
public String type() default "";
|
||||||
|
public String code() default "";
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
package com.org.system.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义导出Excel数据注解
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface Excel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 导出时在excel中排序
|
||||||
|
*/
|
||||||
|
public int sort() default Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出到Excel中的名字.
|
||||||
|
*/
|
||||||
|
public String name() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期格式, 如: yyyy-MM-dd
|
||||||
|
*/
|
||||||
|
public String dateFormat() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
|
||||||
|
*/
|
||||||
|
public String dictType() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取内容转表达式 (如: 0=男,1=女,2=未知)
|
||||||
|
*/
|
||||||
|
public String readConverterExp() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分隔符,读取字符串组内容
|
||||||
|
*/
|
||||||
|
public String separator() default ",";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
|
||||||
|
*/
|
||||||
|
public int scale() default -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
|
||||||
|
*/
|
||||||
|
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出类型(0数字 1字符串)
|
||||||
|
*/
|
||||||
|
public ColumnType cellType() default ColumnType.STRING;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出时在excel中每个列的高度 单位为字符
|
||||||
|
*/
|
||||||
|
public double height() default 14;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出时在excel中每个列的宽 单位为字符
|
||||||
|
*/
|
||||||
|
public double width() default 16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文字后缀,如% 90 变成90%
|
||||||
|
*/
|
||||||
|
public String suffix() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当值为空时,字段的默认值
|
||||||
|
*/
|
||||||
|
public String defaultValue() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提示信息
|
||||||
|
*/
|
||||||
|
public String prompt() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置只能选择不能输入的列内容.
|
||||||
|
*/
|
||||||
|
public String[] combo() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
|
||||||
|
*/
|
||||||
|
public boolean isExport() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 另一个类中的属性名称,支持多级获取,以小数点隔开
|
||||||
|
*/
|
||||||
|
public String targetAttr() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否自动统计数据,在最后追加一行统计数据总和
|
||||||
|
*/
|
||||||
|
public boolean isStatistics() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
|
||||||
|
*/
|
||||||
|
Type type() default Type.ALL;
|
||||||
|
|
||||||
|
public enum Type
|
||||||
|
{
|
||||||
|
ALL(0), EXPORT(1), IMPORT(2);
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
Type(int value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int value()
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ColumnType
|
||||||
|
{
|
||||||
|
NUMERIC(0), STRING(1);
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
ColumnType(int value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int value()
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.org.system.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel注解集
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Excels
|
||||||
|
{
|
||||||
|
Excel[] value();
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.org.system.annotation;
|
||||||
|
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.system.enums.OperatorType;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/** 自定义操作日志记录注解 **/
|
||||||
|
@Target({ ElementType.PARAMETER, ElementType.METHOD })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface Log
|
||||||
|
{
|
||||||
|
/** 模块 **/
|
||||||
|
public String title() default "";
|
||||||
|
|
||||||
|
/** 功能 **/
|
||||||
|
public BusinessType businessType() default BusinessType.OTHER;
|
||||||
|
|
||||||
|
/** 操作人类别 **/
|
||||||
|
public OperatorType operatorType() default OperatorType.MANAGE;
|
||||||
|
|
||||||
|
/** 是否保存请求的参数 **/
|
||||||
|
public boolean isSaveRequestData() default true;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,198 @@
|
||||||
|
package com.org.system.aspectj;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.extra.servlet.ServletUtil;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.config.async.AsyncFactory;
|
||||||
|
import com.org.system.config.async.AsyncManager;
|
||||||
|
import com.org.system.entity.LoginUser;
|
||||||
|
import com.org.system.entity.SysOperLog;
|
||||||
|
import com.org.system.enums.BusinessStatus;
|
||||||
|
import com.org.system.service.TokenService;
|
||||||
|
import com.org.utils.HttpServletUtil;
|
||||||
|
import com.org.utils.SpringUtil;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.Signature;
|
||||||
|
import org.aspectj.lang.annotation.AfterReturning;
|
||||||
|
import org.aspectj.lang.annotation.AfterThrowing;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** 操作日志记录处理 **/
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class LogAspect
|
||||||
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
|
||||||
|
|
||||||
|
// 配置织入点
|
||||||
|
@Pointcut("@annotation(com.org.system.annotation.Log)")
|
||||||
|
public void logPointCut() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理完请求后执行
|
||||||
|
*
|
||||||
|
* @param joinPoint 切点
|
||||||
|
*/
|
||||||
|
@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
|
||||||
|
public void doAfterReturning(JoinPoint joinPoint, Object jsonResult)
|
||||||
|
{
|
||||||
|
handleLog(joinPoint, null, jsonResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拦截异常操作
|
||||||
|
*
|
||||||
|
* @param joinPoint 切点
|
||||||
|
* @param e 异常
|
||||||
|
*/
|
||||||
|
@AfterThrowing(value = "logPointCut()", throwing = "e")
|
||||||
|
public void doAfterThrowing(JoinPoint joinPoint, Exception e) { handleLog(joinPoint, e, null); }
|
||||||
|
|
||||||
|
protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) {
|
||||||
|
try {
|
||||||
|
// 获得注解
|
||||||
|
Log controllerLog = getAnnotationLog(joinPoint);
|
||||||
|
if (controllerLog == null) return;
|
||||||
|
|
||||||
|
// 获取当前的用户
|
||||||
|
LoginUser loginUser = SpringUtil.getBean(TokenService.class).getLoginUser(HttpServletUtil.getRequest());
|
||||||
|
|
||||||
|
// *========数据库日志=========*//
|
||||||
|
SysOperLog operLog = new SysOperLog();
|
||||||
|
operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
|
||||||
|
// 请求的地址
|
||||||
|
operLog.setOperIp(ServletUtil.getClientIP(HttpServletUtil.getRequest(), ""));
|
||||||
|
// 返回参数
|
||||||
|
operLog.setJsonResult(JSON.toJSONString(jsonResult));
|
||||||
|
|
||||||
|
operLog.setOperUrl(HttpServletUtil.getRequest().getRequestURI());
|
||||||
|
|
||||||
|
if (loginUser != null) operLog.setOperName(loginUser.getUser().getUserName());
|
||||||
|
|
||||||
|
if (e != null) {
|
||||||
|
operLog.setStatus(BusinessStatus.FAIL.ordinal());
|
||||||
|
operLog.setErrorMsg(StrUtil.subWithLength(e.getMessage(), 0, 2000));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置方法名称
|
||||||
|
String className = joinPoint.getTarget().getClass().getName();
|
||||||
|
|
||||||
|
String methodName = joinPoint.getSignature().getName();
|
||||||
|
|
||||||
|
operLog.setMethod(className + "." + methodName + "()");
|
||||||
|
|
||||||
|
// 设置请求方式
|
||||||
|
operLog.setRequestMethod(HttpServletUtil.getRequest().getMethod());
|
||||||
|
|
||||||
|
// 处理设置注解上的参数
|
||||||
|
getControllerMethodDescription(joinPoint, controllerLog, operLog);
|
||||||
|
|
||||||
|
operLog.setOperTime(new Date());
|
||||||
|
|
||||||
|
// 保存数据库
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
|
||||||
|
} catch (Exception exp) {
|
||||||
|
// 记录本地异常日志
|
||||||
|
log.error("==前置通知异常==");
|
||||||
|
log.error("异常信息:{}", exp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取注解中对方法的描述信息 用于Controller层注解
|
||||||
|
*
|
||||||
|
* @param log 日志
|
||||||
|
* @param operLog 操作日志
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) throws Exception {
|
||||||
|
// 设置action动作
|
||||||
|
operLog.setBusinessType(log.businessType().ordinal());
|
||||||
|
// 设置标题
|
||||||
|
operLog.setTitle(log.title());
|
||||||
|
// 设置操作人类别
|
||||||
|
operLog.setOperatorType(log.operatorType().ordinal());
|
||||||
|
// 是否需要保存request,参数和值
|
||||||
|
if (log.isSaveRequestData()) {
|
||||||
|
// 获取参数的信息,传入到数据库中。
|
||||||
|
setRequestValue(joinPoint, operLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取请求的参数,放到log中
|
||||||
|
*
|
||||||
|
* @param operLog 操作日志
|
||||||
|
* @throws Exception 异常
|
||||||
|
*/
|
||||||
|
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception {
|
||||||
|
String requestMethod = operLog.getRequestMethod();
|
||||||
|
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
|
||||||
|
String params = argsArrayToString(joinPoint.getArgs());
|
||||||
|
operLog.setOperParam(StrUtil.subWithLength(params, 0, 2000));
|
||||||
|
} else {
|
||||||
|
Map<?, ?> paramsMap = (Map<?, ?>) HttpServletUtil.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
|
||||||
|
operLog.setOperParam(StrUtil.subWithLength(paramsMap.toString(), 0, 2000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否存在注解,如果存在就获取
|
||||||
|
*/
|
||||||
|
private Log getAnnotationLog(JoinPoint joinPoint) throws Exception {
|
||||||
|
Signature signature = joinPoint.getSignature();
|
||||||
|
MethodSignature methodSignature = (MethodSignature) signature;
|
||||||
|
Method method = methodSignature.getMethod();
|
||||||
|
|
||||||
|
if (method != null) {
|
||||||
|
return method.getAnnotation(Log.class);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数拼装
|
||||||
|
*/
|
||||||
|
private String argsArrayToString(Object[] paramsArray) {
|
||||||
|
StringBuilder params = new StringBuilder();
|
||||||
|
if (paramsArray != null && paramsArray.length > 0) {
|
||||||
|
for (int i = 0; i < paramsArray.length; i++) {
|
||||||
|
if (!isFilterObject(paramsArray[i])) {
|
||||||
|
Object jsonObj = null;
|
||||||
|
try {
|
||||||
|
jsonObj = JSON.toJSON(paramsArray[i]);
|
||||||
|
} catch (Exception e){
|
||||||
|
log.error("{}", e);
|
||||||
|
}
|
||||||
|
if(jsonObj != null) params.append(jsonObj.toString()).append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否需要过滤的对象。
|
||||||
|
*
|
||||||
|
* @param o 对象信息。
|
||||||
|
* @return 如果是需要过滤的对象,则返回true;否则返回false。
|
||||||
|
*/
|
||||||
|
public boolean isFilterObject(final Object o) {
|
||||||
|
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.org.system.config.async;
|
||||||
|
|
||||||
|
import cn.hutool.extra.servlet.ServletUtil;
|
||||||
|
import cn.hutool.http.useragent.UserAgent;
|
||||||
|
import cn.hutool.http.useragent.UserAgentUtil;
|
||||||
|
import com.org.system.entity.SysOperLog;
|
||||||
|
import com.org.system.service.SysOperLogService;
|
||||||
|
import com.org.utils.Constants;
|
||||||
|
import com.org.utils.HttpServletUtil;
|
||||||
|
import com.org.utils.SpringUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
/** 异步工厂(产生任务用) **/
|
||||||
|
@Slf4j
|
||||||
|
public class AsyncFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录登录信息
|
||||||
|
*
|
||||||
|
* @param username 用户名
|
||||||
|
* @param status 状态
|
||||||
|
* @param message 消息
|
||||||
|
* @param args 列表
|
||||||
|
* @return 任务task
|
||||||
|
*/
|
||||||
|
public static TimerTask recordLogininfor(final String username, final String status, final String message,
|
||||||
|
final Object... args) {
|
||||||
|
final UserAgent userAgent = UserAgentUtil.parse(HttpServletUtil.getRequest().getHeader("User-Agent"));
|
||||||
|
final String ip = ServletUtil.getClientIP(HttpServletUtil.getRequest(), "");
|
||||||
|
return new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
String address = "";
|
||||||
|
String os = userAgent.getOs().getName(); // 获取客户端操作系统
|
||||||
|
String browser = userAgent.getBrowser().getName(); // 获取客户端浏览器
|
||||||
|
|
||||||
|
// 封装对象
|
||||||
|
SysOperLog sysOperLog = new SysOperLog();
|
||||||
|
sysOperLog.setTitle("用户登陆");
|
||||||
|
sysOperLog.setMethod("/login");
|
||||||
|
sysOperLog.setRequestMethod(HttpServletUtil.getRequest().getMethod());
|
||||||
|
sysOperLog.setOperName(username);
|
||||||
|
sysOperLog.setOperIp(ip);
|
||||||
|
sysOperLog.setOperLocation(address);
|
||||||
|
sysOperLog.setErrorMsg(browser+";"+os+";"+message);
|
||||||
|
sysOperLog.setOperTime(new Date());
|
||||||
|
|
||||||
|
// 日志状态
|
||||||
|
if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status)) sysOperLog.setStatus(Integer.parseInt(Constants.SUCCESS));
|
||||||
|
else if (Constants.LOGIN_FAIL.equals(status)) sysOperLog.setStatus(Integer.parseInt(Constants.FAIL));
|
||||||
|
|
||||||
|
// 插入数据
|
||||||
|
SpringUtil.getBean(SysOperLogService.class).save(sysOperLog);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作日志记录
|
||||||
|
*
|
||||||
|
* @param sysOperLog 操作日志信息
|
||||||
|
* @return 任务task
|
||||||
|
*/
|
||||||
|
public static TimerTask recordOper(final SysOperLog sysOperLog) {
|
||||||
|
return new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// 远程查询操作地点
|
||||||
|
SpringUtil.getBean(SysOperLogService.class).save(sysOperLog);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.org.system.config.async;
|
||||||
|
|
||||||
|
import com.org.utils.HttpServletUtil;
|
||||||
|
import com.org.utils.SpringUtil;
|
||||||
|
import com.org.utils.Threads;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/** 异步任务管理器 **/
|
||||||
|
public class AsyncManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 操作延迟10毫秒
|
||||||
|
*/
|
||||||
|
private final int OPERATE_DELAY_TIME = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步操作任务调度线程池
|
||||||
|
*/
|
||||||
|
private ScheduledExecutorService executor = SpringUtil.getBean("scheduledExecutorService");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单例模式
|
||||||
|
*/
|
||||||
|
private AsyncManager(){}
|
||||||
|
|
||||||
|
private static AsyncManager me = new AsyncManager();
|
||||||
|
|
||||||
|
public static AsyncManager me()
|
||||||
|
{
|
||||||
|
return me;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行任务
|
||||||
|
*
|
||||||
|
* @param task 任务
|
||||||
|
*/
|
||||||
|
public void execute(TimerTask task) {
|
||||||
|
RequestContextHolder.setRequestAttributes(HttpServletUtil.getServletRequestAttributes(), true);
|
||||||
|
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止任务线程池
|
||||||
|
*/
|
||||||
|
public void shutdown()
|
||||||
|
{
|
||||||
|
Threads.shutdownAndAwaitTermination(executor);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.org.system.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class config {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,204 @@
|
||||||
|
package com.org.system.config.redis;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.HashOperations;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.ValueOperations;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/** spring redis 工具类 **/
|
||||||
|
@SuppressWarnings(value = { "unchecked", "rawtypes" })
|
||||||
|
@Component
|
||||||
|
public class RedisCache {
|
||||||
|
@Autowired
|
||||||
|
public RedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存基本的对象,Integer、String、实体类等
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param value 缓存的值
|
||||||
|
*/
|
||||||
|
public <T> void setCacheObject(final String key, final T value) {
|
||||||
|
redisTemplate.opsForValue().set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存基本的对象,Integer、String、实体类等
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param value 缓存的值
|
||||||
|
* @param timeout 时间
|
||||||
|
* @param timeUnit 时间颗粒度
|
||||||
|
*/
|
||||||
|
public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
|
||||||
|
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置有效时间
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param timeout 超时时间
|
||||||
|
* @return true=设置成功;false=设置失败
|
||||||
|
*/
|
||||||
|
public boolean expire(final String key, final long timeout) {
|
||||||
|
return expire(key, timeout, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置有效时间
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param timeout 超时时间
|
||||||
|
* @param unit 时间单位
|
||||||
|
* @return true=设置成功;false=设置失败
|
||||||
|
*/
|
||||||
|
public boolean expire(final String key, final long timeout, final TimeUnit unit) {
|
||||||
|
return redisTemplate.expire(key, timeout, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的基本对象。
|
||||||
|
*
|
||||||
|
* @param key 缓存键值
|
||||||
|
* @return 缓存键值对应的数据
|
||||||
|
*/
|
||||||
|
public <T> T getCacheObject(final String key) {
|
||||||
|
ValueOperations<String, T> operation = redisTemplate.opsForValue();
|
||||||
|
return operation.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除单个对象
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
public boolean deleteObject(final String key) {
|
||||||
|
return redisTemplate.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除集合对象
|
||||||
|
*
|
||||||
|
* @param collection 多个对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public long deleteObject(final Collection collection) {
|
||||||
|
return redisTemplate.delete(collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存List数据
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param dataList 待缓存的List数据
|
||||||
|
* @return 缓存的对象
|
||||||
|
*/
|
||||||
|
public <T> long setCacheList(final String key, final List<T> dataList) {
|
||||||
|
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
|
||||||
|
return count == null ? 0 : count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的list对象
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @return 缓存键值对应的数据
|
||||||
|
*/
|
||||||
|
public <T> List<T> getCacheList(final String key) {
|
||||||
|
return redisTemplate.opsForList().range(key, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存Set
|
||||||
|
*
|
||||||
|
* @param key 缓存键值
|
||||||
|
* @param dataSet 缓存的数据
|
||||||
|
* @return 缓存数据的对象
|
||||||
|
*/
|
||||||
|
public <T> long setCacheSet(final String key, final Set<T> dataSet) {
|
||||||
|
Long count = redisTemplate.opsForSet().add(key, dataSet);
|
||||||
|
return count == null ? 0 : count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的set
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public <T> Set<T> getCacheSet(final String key) {
|
||||||
|
return redisTemplate.opsForSet().members(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存Map
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param dataMap
|
||||||
|
*/
|
||||||
|
public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
|
||||||
|
if (dataMap != null) redisTemplate.opsForHash().putAll(key, dataMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的Map
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public <T> Map<String, T> getCacheMap(final String key) {
|
||||||
|
return redisTemplate.opsForHash().entries(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 往Hash中存入数据
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param hKey Hash键
|
||||||
|
* @param value 值
|
||||||
|
*/
|
||||||
|
public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
|
||||||
|
redisTemplate.opsForHash().put(key, hKey, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Hash中的数据
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param hKey Hash键
|
||||||
|
* @return Hash中的对象
|
||||||
|
*/
|
||||||
|
public <T> T getCacheMapValue(final String key, final String hKey) {
|
||||||
|
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
|
||||||
|
return opsForHash.get(key, hKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取多个Hash中的数据
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param hKeys Hash键集合
|
||||||
|
* @return Hash对象集合
|
||||||
|
*/
|
||||||
|
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
|
||||||
|
return redisTemplate.opsForHash().multiGet(key, hKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的基本对象列表
|
||||||
|
*
|
||||||
|
* @param pattern 字符串前缀
|
||||||
|
* @return 对象列表
|
||||||
|
*/
|
||||||
|
public Collection<String> keys(final String pattern) {
|
||||||
|
return redisTemplate.keys(pattern);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.org.system.config.security;
|
||||||
|
|
||||||
|
import cn.hutool.extra.servlet.ServletUtil;
|
||||||
|
import cn.hutool.http.ContentType;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/** 认证失败处理类 返回未授权 **/
|
||||||
|
@Component
|
||||||
|
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
|
||||||
|
String msg = String.format("请求访问:%s,认证失败,无法访问系统资源", request.getRequestURI());
|
||||||
|
ServletUtil.write(response, JSONObject.toJSONString(AjaxResult.error(HttpStatus.UNAUTHORIZED.value(), msg)), ContentType.JSON.toString(Charset.defaultCharset()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.org.system.config.security;
|
||||||
|
|
||||||
|
import com.org.system.entity.LoginUser;
|
||||||
|
import com.org.system.service.TokenService;
|
||||||
|
import com.org.utils.SecurityUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/** token过滤器 验证token有效性 **/
|
||||||
|
@Component
|
||||||
|
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
LoginUser loginUser = tokenService.getLoginUser(request);
|
||||||
|
|
||||||
|
if (null != loginUser && null == SecurityUtil.getAuthentication()) {
|
||||||
|
tokenService.verifyToken(loginUser);
|
||||||
|
|
||||||
|
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
|
||||||
|
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
||||||
|
}
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.org.system.config.security;
|
||||||
|
|
||||||
|
import cn.hutool.extra.servlet.ServletUtil;
|
||||||
|
import cn.hutool.http.ContentType;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.org.system.config.async.AsyncFactory;
|
||||||
|
import com.org.system.config.async.AsyncManager;
|
||||||
|
import com.org.system.entity.LoginUser;
|
||||||
|
import com.org.system.service.TokenService;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import com.org.utils.Constants;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/** 自定义退出处理类 返回成功 **/
|
||||||
|
@Configuration
|
||||||
|
public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出处理
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
LoginUser loginUser = tokenService.getLoginUser(request);
|
||||||
|
|
||||||
|
if (null != loginUser) {
|
||||||
|
String userName = loginUser.getUsername();
|
||||||
|
|
||||||
|
// 删除用户缓存记录
|
||||||
|
tokenService.delLoginUser(loginUser.getToken());
|
||||||
|
|
||||||
|
// 记录用户退出日志
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
|
||||||
|
}
|
||||||
|
ServletUtil.write(response, JSONObject.toJSONString(AjaxResult.success("退出成功")), ContentType.JSON.toString(Charset.defaultCharset()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.org.system.config.security;
|
||||||
|
|
||||||
|
import cn.hutool.crypto.SecureUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class Md5PasswordEncoder implements PasswordEncoder {
|
||||||
|
|
||||||
|
private String salt;
|
||||||
|
|
||||||
|
public void setSalt(String salt) {
|
||||||
|
this.salt = salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Md5PasswordEncoder instance = new Md5PasswordEncoder();
|
||||||
|
|
||||||
|
private Md5PasswordEncoder() {
|
||||||
|
}
|
||||||
|
//以单例模式构造
|
||||||
|
public static Md5PasswordEncoder getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户密码加盐
|
||||||
|
private String mergePasswordAndSalt(CharSequence password) {
|
||||||
|
if (password == null) password = "";
|
||||||
|
|
||||||
|
if ((salt == null) || "".equals(salt)) {
|
||||||
|
return password.toString();
|
||||||
|
} else {
|
||||||
|
return password + salt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MD5加密
|
||||||
|
*
|
||||||
|
* @param rawPassword 原始密码
|
||||||
|
* @return 加密后的md5密文
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String encode(CharSequence rawPassword) {
|
||||||
|
|
||||||
|
String result = null;
|
||||||
|
try {
|
||||||
|
String passwordAndSalt = mergePasswordAndSalt(rawPassword);
|
||||||
|
|
||||||
|
result = SecureUtil.md5(passwordAndSalt);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码比较
|
||||||
|
*
|
||||||
|
* @param rawPassword 原始密码
|
||||||
|
* @param encodedPassword 加密后的密码
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean matches(CharSequence rawPassword, String encodedPassword) {
|
||||||
|
return encodedPassword.equalsIgnoreCase(encode(rawPassword));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
package com.org.system.config.security;
|
||||||
|
|
||||||
|
import com.org.system.service.CustomUserService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
|
/** spring security配置 **/
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
|
||||||
|
public class SecurityConfig extends WebSecurityConfigurerAdapter
|
||||||
|
{
|
||||||
|
/** 自定义用户认证逻辑 **/
|
||||||
|
@Autowired
|
||||||
|
private CustomUserService customUserService;
|
||||||
|
/** 认证失败处理类 **/
|
||||||
|
@Autowired
|
||||||
|
private AuthenticationEntryPointImpl unauthorizedHandler;
|
||||||
|
|
||||||
|
/** 退出处理类 **/
|
||||||
|
@Autowired
|
||||||
|
private LogoutSuccessHandlerImpl logoutSuccessHandler;
|
||||||
|
|
||||||
|
/** token认证过滤器 **/
|
||||||
|
@Autowired
|
||||||
|
private JwtAuthenticationTokenFilter authenticationTokenFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解决 无法直接注入 AuthenticationManager
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Override
|
||||||
|
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||||
|
return super.authenticationManagerBean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* anyRequest | 匹配所有请求路径
|
||||||
|
* access | SpringEl表达式结果为true时可以访问
|
||||||
|
* anonymous | 匿名可以访问
|
||||||
|
* denyAll | 用户不能访问
|
||||||
|
* fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录)
|
||||||
|
* hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问
|
||||||
|
* hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问
|
||||||
|
* hasAuthority | 如果有参数,参数表示权限,则其权限可以访问
|
||||||
|
* hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
|
||||||
|
* hasRole | 如果有参数,参数表示角色,则其角色可以访问
|
||||||
|
* permitAll | 用户可以任意访问
|
||||||
|
* rememberMe | 允许通过remember-me登录的用户访问
|
||||||
|
* authenticated | 用户登录后可访问
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity httpSecurity) throws Exception
|
||||||
|
{
|
||||||
|
httpSecurity
|
||||||
|
// CSRF禁用,因为不使用session
|
||||||
|
.csrf().disable()
|
||||||
|
// 认证失败处理类
|
||||||
|
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
|
||||||
|
// 基于token,所以不需要session
|
||||||
|
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
|
||||||
|
// 过滤请求
|
||||||
|
.authorizeRequests()
|
||||||
|
|
||||||
|
// 对于登录 login 允许匿名访问
|
||||||
|
.antMatchers("/login").anonymous()
|
||||||
|
.antMatchers("/person/register/invitation").anonymous()
|
||||||
|
.antMatchers("/person/register/add").anonymous()
|
||||||
|
|
||||||
|
// 文件下载接口例外
|
||||||
|
.antMatchers("/sys/oss/show/**").anonymous()
|
||||||
|
.antMatchers("/common/download").anonymous()
|
||||||
|
|
||||||
|
.antMatchers("/sys/ueditor/config").anonymous()
|
||||||
|
|
||||||
|
// 获取短信验证码接口
|
||||||
|
.antMatchers("/sys/sms/getCode").anonymous()
|
||||||
|
|
||||||
|
// 获取数据词典项下拉选
|
||||||
|
.antMatchers("/sys/dictionary/item/mobile/dropDown").anonymous()
|
||||||
|
|
||||||
|
// 获取app版本管理相关信息
|
||||||
|
.antMatchers("/sys/appVersion/getVersionNumByAppType","/sys/appVersion/clearVersionCache").anonymous()
|
||||||
|
|
||||||
|
// COS队列回调
|
||||||
|
// .antMatchers("/sys/oss/cos/callback").anonymous()
|
||||||
|
|
||||||
|
// 除上面外的所有请求全部需要鉴权认证
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
.and()
|
||||||
|
.headers().frameOptions().disable();
|
||||||
|
httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
|
||||||
|
// 添加JWT filter
|
||||||
|
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
|
// 添加CORS filter
|
||||||
|
// httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
|
||||||
|
// httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 强散列哈希加密实现
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); }
|
||||||
|
@Bean
|
||||||
|
public Md5PasswordEncoder passwordEncoder(){ return Md5PasswordEncoder.getInstance(); }
|
||||||
|
|
||||||
|
/** 身份认证接口 **/
|
||||||
|
@Override
|
||||||
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
/** user Details Service验证 **/
|
||||||
|
auth.userDetailsService(customUserService).passwordEncoder(passwordEncoder());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.org.system.config.thread;
|
||||||
|
|
||||||
|
import com.org.utils.Threads;
|
||||||
|
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
/** 线程池配置 **/
|
||||||
|
@Configuration
|
||||||
|
public class ThreadPoolConfig
|
||||||
|
{
|
||||||
|
// 核心线程池大小
|
||||||
|
private int corePoolSize = 50;
|
||||||
|
|
||||||
|
// 最大可创建的线程数
|
||||||
|
private int maxPoolSize = 200;
|
||||||
|
|
||||||
|
// 队列最大长度
|
||||||
|
private int queueCapacity = 1000;
|
||||||
|
|
||||||
|
// 线程池维护线程所允许的空闲时间
|
||||||
|
private int keepAliveSeconds = 300;
|
||||||
|
|
||||||
|
@Bean(name = "threadPoolTaskExecutor")
|
||||||
|
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
|
||||||
|
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||||
|
executor.setMaxPoolSize(maxPoolSize);
|
||||||
|
executor.setCorePoolSize(corePoolSize);
|
||||||
|
executor.setQueueCapacity(queueCapacity);
|
||||||
|
executor.setKeepAliveSeconds(keepAliveSeconds);
|
||||||
|
|
||||||
|
// 线程池对拒绝任务(无线程可用)的处理策略
|
||||||
|
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行周期性或定时任务
|
||||||
|
*/
|
||||||
|
@Bean(name = "scheduledExecutorService")
|
||||||
|
protected ScheduledExecutorService scheduledExecutorService() {
|
||||||
|
return new ScheduledThreadPoolExecutor(corePoolSize,
|
||||||
|
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) {
|
||||||
|
@Override
|
||||||
|
protected void afterExecute(Runnable r, Throwable t) {
|
||||||
|
super.afterExecute(r, t);
|
||||||
|
Threads.printException(r, t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.org.system.config.validation;
|
||||||
|
|
||||||
|
import javax.validation.groups.Default;
|
||||||
|
|
||||||
|
/** 分组校验 新增 **/
|
||||||
|
public interface Insert extends Default {
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.org.system.config.validation;
|
||||||
|
|
||||||
|
import javax.validation.groups.Default;
|
||||||
|
|
||||||
|
/** 分组校验 修改 **/
|
||||||
|
public interface Update extends Default {
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
package com.org.system.config.xss;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.http.HTMLFilter;
|
||||||
|
|
||||||
|
/** 转义和反转义工具类 **/
|
||||||
|
public class EscapeUtil {
|
||||||
|
public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)";
|
||||||
|
|
||||||
|
private static final char[][] TEXT = new char[64][];
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (int i = 0; i < 64; i++) {
|
||||||
|
TEXT[i] = new char[] { (char) i };
|
||||||
|
}
|
||||||
|
|
||||||
|
// special HTML characters
|
||||||
|
TEXT['\''] = "'".toCharArray(); // 单引号
|
||||||
|
TEXT['"'] = """.toCharArray(); // 单引号
|
||||||
|
TEXT['&'] = "&".toCharArray(); // &符
|
||||||
|
TEXT['<'] = "<".toCharArray(); // 小于号
|
||||||
|
TEXT['>'] = ">".toCharArray(); // 大于号
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转义文本中的HTML字符为安全的字符
|
||||||
|
*
|
||||||
|
* @param text 被转义的文本
|
||||||
|
* @return 转义后的文本
|
||||||
|
*/
|
||||||
|
public static String escape(String text) {
|
||||||
|
return encode(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 还原被转义的HTML特殊字符
|
||||||
|
*
|
||||||
|
* @param content 包含转义符的HTML内容
|
||||||
|
* @return 转换后的字符串
|
||||||
|
*/
|
||||||
|
public static String unescape(String content) {
|
||||||
|
return decode(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除所有HTML标签,但是不删除标签内的内容
|
||||||
|
*
|
||||||
|
* @param content 文本
|
||||||
|
* @return 清除标签后的文本
|
||||||
|
*/
|
||||||
|
public static String clean(String content) {
|
||||||
|
return new HTMLFilter().filter(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape编码
|
||||||
|
*
|
||||||
|
* @param text 被编码的文本
|
||||||
|
* @return 编码后的字符
|
||||||
|
*/
|
||||||
|
private static String encode(String text) {
|
||||||
|
int len;
|
||||||
|
if ((text == null) || ((len = text.length()) == 0)) {
|
||||||
|
return StrUtil.EMPTY;
|
||||||
|
}
|
||||||
|
StringBuilder buffer = new StringBuilder(len + (len >> 2));
|
||||||
|
char c;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
c = text.charAt(i);
|
||||||
|
if (c < 64) {
|
||||||
|
buffer.append(TEXT[c]);
|
||||||
|
} else {
|
||||||
|
buffer.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape解码
|
||||||
|
*
|
||||||
|
* @param content 被转义的内容
|
||||||
|
* @return 解码后的字符串
|
||||||
|
*/
|
||||||
|
public static String decode(String content)
|
||||||
|
{
|
||||||
|
if (StrUtil.isEmpty(content)) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder tmp = new StringBuilder(content.length());
|
||||||
|
int lastPos = 0, pos = 0;
|
||||||
|
char ch;
|
||||||
|
while (lastPos < content.length()) {
|
||||||
|
pos = content.indexOf("%", lastPos);
|
||||||
|
if (pos == lastPos) {
|
||||||
|
if (content.charAt(pos + 1) == 'u') {
|
||||||
|
ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16);
|
||||||
|
tmp.append(ch);
|
||||||
|
lastPos = pos + 6;
|
||||||
|
} else {
|
||||||
|
ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16);
|
||||||
|
tmp.append(ch);
|
||||||
|
lastPos = pos + 3;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pos == -1) {
|
||||||
|
tmp.append(content.substring(lastPos));
|
||||||
|
lastPos = content.length();
|
||||||
|
} else {
|
||||||
|
tmp.append(content.substring(lastPos, pos));
|
||||||
|
lastPos = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tmp.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.org.system.config.xss;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import javax.servlet.DispatcherType;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** Filter配置 **/
|
||||||
|
@Configuration
|
||||||
|
public class FilterConfig {
|
||||||
|
@Value("${xss.enabled}")
|
||||||
|
private String enabled;
|
||||||
|
|
||||||
|
@Value("${xss.excludes}")
|
||||||
|
private String excludes;
|
||||||
|
|
||||||
|
@Value("${xss.urlPatterns}")
|
||||||
|
private String urlPatterns;
|
||||||
|
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
@Bean
|
||||||
|
public FilterRegistrationBean xssFilterRegistration()
|
||||||
|
{
|
||||||
|
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||||
|
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||||
|
registration.setFilter(new XssFilter());
|
||||||
|
registration.addUrlPatterns(urlPatterns.split(","));
|
||||||
|
registration.setName("xssFilter");
|
||||||
|
registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
|
||||||
|
Map<String, String> initParameters = new HashMap<String, String>();
|
||||||
|
initParameters.put("excludes", excludes);
|
||||||
|
initParameters.put("enabled", enabled);
|
||||||
|
registration.setInitParameters(initParameters);
|
||||||
|
return registration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
@Bean
|
||||||
|
public FilterRegistrationBean someFilterRegistration()
|
||||||
|
{
|
||||||
|
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||||
|
registration.setFilter(new RepeatableFilter());
|
||||||
|
registration.addUrlPatterns("/*");
|
||||||
|
registration.setName("repeatableFilter");
|
||||||
|
registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
|
||||||
|
return registration;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.org.system.config.xss;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/** 通用http工具封装 **/
|
||||||
|
@Slf4j
|
||||||
|
public class HttpHelper {
|
||||||
|
|
||||||
|
public static String getBodyString(ServletRequest request) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try (InputStream inputStream = request.getInputStream()) {
|
||||||
|
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
|
||||||
|
String line = "";
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
sb.append(line);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("getBodyString出现问题!");
|
||||||
|
log.error("{}", e);
|
||||||
|
} finally {
|
||||||
|
if (reader != null) {
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("{}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.org.system.config.xss;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.*;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/** Repeatable 过滤器 **/
|
||||||
|
public class RepeatableFilter implements Filter
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
ServletRequest requestWrapper = null;
|
||||||
|
if (request instanceof HttpServletRequest && StrUtil.equalsAnyIgnoreCase(request.getContentType(),
|
||||||
|
MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE)) {
|
||||||
|
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
|
||||||
|
}
|
||||||
|
if (null == requestWrapper) {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
} else {
|
||||||
|
chain.doFilter(requestWrapper, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.org.system.config.xss;
|
||||||
|
|
||||||
|
import javax.servlet.ReadListener;
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletRequestWrapper;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
/** 构建可重复读取inputStream的request **/
|
||||||
|
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
|
||||||
|
private final byte[] body;
|
||||||
|
|
||||||
|
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {
|
||||||
|
super(request);
|
||||||
|
request.setCharacterEncoding("UTF-8");
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
|
||||||
|
body = HttpHelper.getBodyString(request).getBytes("UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedReader getReader() throws IOException {
|
||||||
|
return new BufferedReader(new InputStreamReader(getInputStream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServletInputStream getInputStream() throws IOException {
|
||||||
|
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
|
||||||
|
|
||||||
|
return new ServletInputStream() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
return bais.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFinished() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReady() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReadListener(ReadListener readListener) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.org.system.config.xss;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.*;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** 防止XSS攻击的过滤器 **/
|
||||||
|
public class XssFilter implements Filter {
|
||||||
|
/** 排除链接 **/
|
||||||
|
public List<String> excludes = new ArrayList<>();
|
||||||
|
|
||||||
|
/** xss过滤开关 **/
|
||||||
|
public boolean enabled = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
|
String tempExcludes = filterConfig.getInitParameter("excludes");
|
||||||
|
String tempEnabled = filterConfig.getInitParameter("enabled");
|
||||||
|
if (StrUtil.isNotEmpty(tempExcludes)) {
|
||||||
|
String[] url = tempExcludes.split(",");
|
||||||
|
for (int i = 0; url != null && i < url.length; i++) {
|
||||||
|
excludes.add(url[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotEmpty(tempEnabled)) {
|
||||||
|
enabled = Boolean.valueOf(tempEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
HttpServletRequest req = (HttpServletRequest) request;
|
||||||
|
HttpServletResponse resp = (HttpServletResponse) response;
|
||||||
|
if (handleExcludeURL(req, resp)) {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
|
||||||
|
chain.doFilter(xssRequest, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
if (!enabled) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (excludes == null || excludes.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String url = request.getServletPath();
|
||||||
|
for (String pattern : excludes) {
|
||||||
|
Pattern p = Pattern.compile("^" + pattern);
|
||||||
|
Matcher m = p.matcher(url);
|
||||||
|
if (m.find()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.org.system.config.xss;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
|
import javax.servlet.ReadListener;
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletRequestWrapper;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/** XSS过滤处理 **/
|
||||||
|
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||||
|
/**
|
||||||
|
* @param request
|
||||||
|
*/
|
||||||
|
public XssHttpServletRequestWrapper(HttpServletRequest request) {
|
||||||
|
super(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getParameterValues(String name) {
|
||||||
|
String[] values = super.getParameterValues(name);
|
||||||
|
if (values != null) {
|
||||||
|
int length = values.length;
|
||||||
|
String[] escapseValues = new String[length];
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
// 防xss攻击和过滤前后空格
|
||||||
|
escapseValues[i] = EscapeUtil.clean(values[i]).trim();
|
||||||
|
}
|
||||||
|
return escapseValues;
|
||||||
|
}
|
||||||
|
return super.getParameterValues(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServletInputStream getInputStream() throws IOException {
|
||||||
|
// 非json类型,直接返回
|
||||||
|
if (!isJsonRequest()) {
|
||||||
|
return super.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为空,直接返回
|
||||||
|
String json = IOUtils.toString(super.getInputStream(), "utf-8");
|
||||||
|
if (StrUtil.isEmpty(json)) {
|
||||||
|
return super.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
// xss过滤
|
||||||
|
json = EscapeUtil.clean(json).trim();
|
||||||
|
final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8"));
|
||||||
|
return new ServletInputStream() {
|
||||||
|
@Override
|
||||||
|
public boolean isFinished() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReady() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReadListener(ReadListener readListener) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
return bis.read();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是Json请求
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public boolean isJsonRequest() {
|
||||||
|
String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
|
||||||
|
return MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(header)
|
||||||
|
|| MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(header);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.org.system.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import com.github.pagehelper.PageInfo;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import com.org.utils.SqlUtil;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.page.PageDomain;
|
||||||
|
import com.org.utils.page.TableDataInfo;
|
||||||
|
import com.org.utils.page.TableSupport;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
|
import org.springframework.web.bind.annotation.InitBinder;
|
||||||
|
|
||||||
|
import java.beans.PropertyEditorSupport;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/** web层通用数据处理 **/
|
||||||
|
public class BaseController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将前台传递过来的日期格式的字符串,自动转化为Date类型
|
||||||
|
*
|
||||||
|
* @param binder
|
||||||
|
*/
|
||||||
|
@InitBinder
|
||||||
|
public void initBinder(WebDataBinder binder) {
|
||||||
|
// Date 类型转换
|
||||||
|
binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
|
||||||
|
@Override
|
||||||
|
public void setAsText(String text) {
|
||||||
|
setValue(DateUtil.parseDate(text));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置请求分页数据
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected void startPage() {
|
||||||
|
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||||
|
Integer pageNum = pageDomain.getPageNum();
|
||||||
|
Integer pageSize = pageDomain.getPageSize();
|
||||||
|
if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
|
||||||
|
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
|
||||||
|
PageHelper.startPage(pageNum, pageSize, orderBy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应请求分页数据
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
protected TableDataInfo getDataTable(List<?> list) {
|
||||||
|
TableDataInfo rspData = new TableDataInfo();
|
||||||
|
rspData.setCode(HttpStatus.OK.value());
|
||||||
|
rspData.setMsg("查询成功");
|
||||||
|
rspData.setRows(list);
|
||||||
|
rspData.setTotal(new PageInfo(list).getTotal());
|
||||||
|
rspData.setPageNo(TableSupport.buildPageRequest().getPageNum());
|
||||||
|
|
||||||
|
return rspData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应返回结果
|
||||||
|
*
|
||||||
|
* @param rows 影响行数
|
||||||
|
* @return 操作结果
|
||||||
|
*/
|
||||||
|
protected AjaxResult toAjax(int rows) {
|
||||||
|
return rows > 0 ? AjaxResult.success() : AjaxResult.error();
|
||||||
|
}
|
||||||
|
protected AjaxResult toAjax(boolean bz) {
|
||||||
|
return bz == true ? AjaxResult.success() : AjaxResult.error();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面跳转
|
||||||
|
*/
|
||||||
|
public String redirect(String url) {
|
||||||
|
return StringUtils.format("redirect:{}", url);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.org.system.controller;
|
||||||
|
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.config.validation.Update;
|
||||||
|
import com.org.system.entity.SysDataDictionary;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.system.service.SysDataDictionaryService;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.page.TableDataInfo;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sys/dictionary")
|
||||||
|
public class SysDataDictionaryController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysDataDictionaryService sysDataDictionaryService;
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
@PostMapping("/add")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:edit')")
|
||||||
|
@Log(title = "词典分类新增", businessType = BusinessType.INSERT)
|
||||||
|
public AjaxResult add(@RequestBody @Validated SysDataDictionary sysDataDictionary){
|
||||||
|
log.info("SysDataDictionaryController - add sysDataDictionary:{}", sysDataDictionary);
|
||||||
|
|
||||||
|
return toAjax(sysDataDictionaryService.saveOrUpdate(sysDataDictionary));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情
|
||||||
|
@PostMapping("/get")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:get')")
|
||||||
|
@Log(title = "词典分类详情", businessType = BusinessType.UPDATE)
|
||||||
|
public AjaxResult get(@RequestParam Long id){
|
||||||
|
log.info("SysDataDictionaryController - get id:{}", id);
|
||||||
|
|
||||||
|
return AjaxResult.success(sysDataDictionaryService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
@PostMapping("/edit")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:edit')")
|
||||||
|
@Log(title = "词典分类修改", businessType = BusinessType.UPDATE)
|
||||||
|
public AjaxResult edit(@RequestBody @Validated(Update.class) SysDataDictionary sysDataDictionary){
|
||||||
|
log.info("SysDataDictionaryController - edit sysDataDictionary:{}", sysDataDictionary);
|
||||||
|
|
||||||
|
return toAjax(sysDataDictionaryService.saveOrUpdate(sysDataDictionary));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
@PostMapping("/del")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:del')")
|
||||||
|
@Log(title = "词典分类删除", businessType = BusinessType.DELETE)
|
||||||
|
public AjaxResult del(@RequestParam String ids, @RequestParam String deleteReason){
|
||||||
|
log.info("SysDataDictionaryController - del ids:{}", ids);
|
||||||
|
log.info("SysDataDictionaryController - del deleteReason:{}", deleteReason);
|
||||||
|
|
||||||
|
if(StringUtils.isEmpty(ids)) return AjaxResult.success();
|
||||||
|
|
||||||
|
List<Long> idList = Arrays.asList(ids.split(",")).stream().map(idStr -> Long.parseLong(idStr)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
return toAjax(sysDataDictionaryService.del(idList, deleteReason));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表
|
||||||
|
@GetMapping("/pageList")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:list')")
|
||||||
|
@Log(title = "词典分类列表", businessType = BusinessType.SELECT)
|
||||||
|
public TableDataInfo list(SysDataDictionary sysDataDictionary){
|
||||||
|
log.info("SysDataDictionaryController - list sysDataDictionary:{}", sysDataDictionary);
|
||||||
|
|
||||||
|
startPage();
|
||||||
|
List<SysDataDictionary> list = sysDataDictionaryService.findList(sysDataDictionary);
|
||||||
|
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
package com.org.system.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.config.validation.Update;
|
||||||
|
import com.org.system.entity.SysDataDictionaryItem;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.system.service.SysDataDictionaryItemService;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.page.TableDataInfo;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sys/dictionary/item")
|
||||||
|
public class SysDataDictionaryItemController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysDataDictionaryItemService sysDataDictionaryItemService;
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
@PostMapping("/add")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:item:edit')")
|
||||||
|
@Log(title = "词典项新增", businessType = BusinessType.INSERT)
|
||||||
|
public AjaxResult add(@RequestBody @Validated SysDataDictionaryItem sysDataDictionaryItem){
|
||||||
|
log.info("SysDataDictionaryItemController - add sysDataDictionaryItem:{}", sysDataDictionaryItem);
|
||||||
|
|
||||||
|
return toAjax(sysDataDictionaryItemService.saveOrUpdate(sysDataDictionaryItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情
|
||||||
|
@PostMapping("/get")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:item:get')")
|
||||||
|
@Log(title = "词典项详情", businessType = BusinessType.UPDATE)
|
||||||
|
public AjaxResult get(@RequestParam Long id){
|
||||||
|
log.info("SysDataDictionaryItemController - get id:{}", id);
|
||||||
|
|
||||||
|
return AjaxResult.success(sysDataDictionaryItemService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
@PostMapping("/edit")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:item:edit')")
|
||||||
|
@Log(title = "词典项修改", businessType = BusinessType.UPDATE)
|
||||||
|
public AjaxResult edit(@RequestBody @Validated(Update.class) SysDataDictionaryItem sysDataDictionaryItem){
|
||||||
|
log.info("SysDataDictionaryItemController - edit sysDataDictionaryItem:{}", sysDataDictionaryItem);
|
||||||
|
|
||||||
|
return toAjax(sysDataDictionaryItemService.saveOrUpdate(sysDataDictionaryItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
@PostMapping("/del")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:item:del')")
|
||||||
|
@Log(title = "词典项删除", businessType = BusinessType.DELETE)
|
||||||
|
public AjaxResult del(@RequestParam String ids, @RequestParam String deleteReason){
|
||||||
|
log.info("SysDataDictionaryItemController - del ids:{}", ids);
|
||||||
|
log.info("SysDataDictionaryItemController - del deleteReason:{}", deleteReason);
|
||||||
|
|
||||||
|
if(StringUtils.isEmpty(ids)) return AjaxResult.success();
|
||||||
|
|
||||||
|
List<Long> idList = Arrays.asList(ids.split(",")).stream().map(idStr -> Long.parseLong(idStr)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
return toAjax(sysDataDictionaryItemService.del(idList, deleteReason));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表
|
||||||
|
@GetMapping("/pageList")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:item:list')")
|
||||||
|
@Log(title = "词典项列表", businessType = BusinessType.SELECT)
|
||||||
|
public TableDataInfo pageList(SysDataDictionaryItem sysDataDictionaryItem){
|
||||||
|
log.info("SysDataDictionaryItemController - pageList sysDataDictionaryItem:{}", sysDataDictionaryItem);
|
||||||
|
|
||||||
|
startPage();
|
||||||
|
List<SysDataDictionaryItem> list = sysDataDictionaryItemService.findList(sysDataDictionaryItem);
|
||||||
|
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表
|
||||||
|
@GetMapping("/list")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:item:list')")
|
||||||
|
@Log(title = "词典项列表", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult list(SysDataDictionaryItem sysDataDictionaryItem){
|
||||||
|
log.info("SysDataDictionaryItemController - list sysDataDictionaryItem:{}", sysDataDictionaryItem);
|
||||||
|
|
||||||
|
List<SysDataDictionaryItem> list = sysDataDictionaryItemService.findList(sysDataDictionaryItem);
|
||||||
|
|
||||||
|
return AjaxResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询最大词典项值
|
||||||
|
@GetMapping("/findMaxValue")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:dictionary:item:list')")
|
||||||
|
@Log(title = "查询最大词典项值", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult findMaxValue(SysDataDictionaryItem sysDataDictionaryItem){
|
||||||
|
log.info("SysDataDictionaryItemController - findMaxValue sysDataDictionaryItem:{}", sysDataDictionaryItem);
|
||||||
|
|
||||||
|
if(StringUtils.isEmpty(sysDataDictionaryItem.getDictionaryCode())) return AjaxResult.error("词典项标识不能为空");
|
||||||
|
|
||||||
|
Integer maxValue = sysDataDictionaryItemService.findMaxValueByCode(sysDataDictionaryItem.getDictionaryCode());
|
||||||
|
log.info("SysDataDictionaryItemController - findMaxValue sysDataDictionaryItem:{},maxValue:{}", sysDataDictionaryItem, maxValue);
|
||||||
|
|
||||||
|
return AjaxResult.success(maxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 词典项下拉选
|
||||||
|
@GetMapping("/dropDown")
|
||||||
|
@Log(title = "词典项下拉选", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult dropDown(String dictionaryCode){
|
||||||
|
log.info("SysDataDictionaryItemController - dropDown dictionaryCode:{}", dictionaryCode);
|
||||||
|
|
||||||
|
List<Dict> list = sysDataDictionaryItemService.listByCode(dictionaryCode);
|
||||||
|
|
||||||
|
return AjaxResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 词典项下拉选
|
||||||
|
@GetMapping("/mobile/dropDown")
|
||||||
|
@Log(title = "词典项下拉选", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult dropDownNoToken(String dictionaryCode){
|
||||||
|
log.info("SysDataDictionaryItemController - dropDown dictionaryCode:{}", dictionaryCode);
|
||||||
|
|
||||||
|
List<Dict> list = sysDataDictionaryItemService.listByCode(dictionaryCode);
|
||||||
|
|
||||||
|
return AjaxResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.org.system.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.entity.LoginBody;
|
||||||
|
import com.org.system.entity.vo.PersonVo;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.system.service.SysLoginService;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import com.org.utils.Constants;
|
||||||
|
import com.org.utils.SecurityUtil;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** 登录验证 **/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
public class SysLoginController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysLoginService sysLoginService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录方法
|
||||||
|
*
|
||||||
|
* @param loginBody 登录信息
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("/login")
|
||||||
|
@Log(title = "登陆系统", businessType = BusinessType.LOGIN)
|
||||||
|
public AjaxResult login(@RequestBody LoginBody loginBody) {
|
||||||
|
log.info("SysLoginController - login loginBody:{}", loginBody);
|
||||||
|
|
||||||
|
if(loginBody == null) throw new CustomException("未找到登陆信息");
|
||||||
|
|
||||||
|
if(StrUtil.isEmpty(loginBody.getUsername()) || StrUtil.isEmpty(loginBody.getPassword()))
|
||||||
|
throw new CustomException("用户名或密码不能为空");
|
||||||
|
|
||||||
|
// 生成令牌
|
||||||
|
Map<String, String> result = sysLoginService.login(loginBody, true);
|
||||||
|
|
||||||
|
return AjaxResult.success().put(Constants.TOKEN, result.get("token"))
|
||||||
|
.put("identity", result.get("identity"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/getLoginUser")
|
||||||
|
@Log(title = "获取当前登录用户信息", businessType = BusinessType.LOGIN)
|
||||||
|
public AjaxResult getLoginUser(){
|
||||||
|
log.info("SysLoginController - getLoginUser userId:{}", SecurityUtil.getUserId());
|
||||||
|
|
||||||
|
sysLoginService.setLoginUserRole();
|
||||||
|
|
||||||
|
return AjaxResult.success(SecurityUtil.getLoginUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/getUserInfo")
|
||||||
|
@Log(title = "获取当前用户信息", businessType = BusinessType.LOGIN)
|
||||||
|
public AjaxResult getUserInfo(){
|
||||||
|
log.info("SysLoginController - getUserInfo userId:{}", SecurityUtil.getUserId());
|
||||||
|
|
||||||
|
PersonVo personVo = sysLoginService.getUserInfo(SecurityUtil.getUserId());
|
||||||
|
|
||||||
|
return AjaxResult.success(personVo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package com.org.system.controller;
|
||||||
|
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.config.validation.Update;
|
||||||
|
import com.org.system.entity.SysMenu;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.system.service.SysMenuService;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sys/menu")
|
||||||
|
public class SysMenuController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysMenuService sysMenuService;
|
||||||
|
|
||||||
|
// 新增菜单
|
||||||
|
@PostMapping("/add")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:menu:add')")
|
||||||
|
@Log(title = "新增系统菜单", businessType = BusinessType.INSERT)
|
||||||
|
public AjaxResult add(@RequestBody @Validated SysMenu sysMenu){
|
||||||
|
log.info("SysMenuController - add sysMenu:{}", sysMenu);
|
||||||
|
|
||||||
|
return toAjax(sysMenuService.add(sysMenu));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑菜单
|
||||||
|
@PostMapping("/edit")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:menu:edit')")
|
||||||
|
@Log(title = "编辑系统菜单", businessType = BusinessType.UPDATE)
|
||||||
|
public AjaxResult edit(@RequestBody @Validated(Update.class) SysMenu sysMenu){
|
||||||
|
log.info("SysMenuController - edit sysMenu:{}", sysMenu);
|
||||||
|
|
||||||
|
return toAjax(sysMenuService.edit(sysMenu));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除菜单
|
||||||
|
@PostMapping("/del")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:menu:del')")
|
||||||
|
@Log(title = "删除系统菜单", businessType = BusinessType.DELETE)
|
||||||
|
public AjaxResult del(@RequestParam Long id, @RequestParam String deleteReason){
|
||||||
|
log.info("SysMenuController - del id:{}", id);
|
||||||
|
log.info("SysMenuController - del deleteReason:{}", deleteReason);
|
||||||
|
|
||||||
|
return toAjax(sysMenuService.del(id, deleteReason));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 菜单列表
|
||||||
|
@GetMapping("/list")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:menu:list')")
|
||||||
|
@Log(title = "查询系统菜单", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult menuList(SysMenu sysMenu){
|
||||||
|
log.info("SysMenuController - list sysMenu:{}", sysMenu);
|
||||||
|
|
||||||
|
List<SysMenu> list = sysMenuService.queryList(sysMenu);
|
||||||
|
// 由于children属性存在,前端菜单树会加载children,故此处不处理,前端处理树结构,如果没有子节点,会删掉children属性
|
||||||
|
// list = sysMenuService.buildMenuTree(list, 0L);
|
||||||
|
|
||||||
|
return AjaxResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tree")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:menu:list')")
|
||||||
|
@Log(title = "菜单树", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult tree(){
|
||||||
|
List<SysMenu> menuTree = sysMenuService.tree();
|
||||||
|
return AjaxResult.success(menuTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/treeForGrant")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:menu:list')")
|
||||||
|
@Log(title = "角色授权菜单树", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult treeForGrant(){
|
||||||
|
List<SysMenu> menuTree = sysMenuService.treeForGrant();
|
||||||
|
return AjaxResult.success(menuTree);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.org.system.controller;
|
||||||
|
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.entity.SysOperLog;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.system.service.SysOperLogService;
|
||||||
|
import com.org.utils.page.TableDataInfo;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sys/operLog")
|
||||||
|
public class SysOperLogController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysOperLogService sysOssService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
*
|
||||||
|
* @return RestResponse
|
||||||
|
*/
|
||||||
|
@GetMapping("/list")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:operLog:list')")
|
||||||
|
@Log(title = "系统文件分页查询", businessType = BusinessType.SELECT)
|
||||||
|
public TableDataInfo getList(SysOperLog sysOperLog) {
|
||||||
|
log.info("SysOperLogController - getList sysOperLog:{}", sysOperLog);
|
||||||
|
|
||||||
|
startPage();
|
||||||
|
List<SysOperLog> list = sysOssService.queryList(sysOperLog);
|
||||||
|
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package com.org.system.controller;
|
||||||
|
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.config.validation.Update;
|
||||||
|
import com.org.system.entity.SysRole;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.system.params.SysRoleGrantMenuParam;
|
||||||
|
import com.org.system.service.SysRoleService;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import com.org.utils.page.TableDataInfo;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sys/role")
|
||||||
|
public class SysRoleController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysRoleService sysRoleService;
|
||||||
|
|
||||||
|
// 新增角色
|
||||||
|
@PostMapping("/add")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:role:add')")
|
||||||
|
@Log(title = "新增角色", businessType = BusinessType.INSERT)
|
||||||
|
public AjaxResult add(@RequestBody @Validated SysRole sysRole){
|
||||||
|
log.info("SysRoleController - add sysRole:{}", sysRole);
|
||||||
|
|
||||||
|
return toAjax(sysRoleService.saveOrUpdate(sysRole));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑角色
|
||||||
|
@PostMapping("/edit")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:role:edit')")
|
||||||
|
@Log(title = "编辑角色", businessType = BusinessType.UPDATE)
|
||||||
|
public AjaxResult edit(@RequestBody @Validated(Update.class) SysRole sysRole){
|
||||||
|
log.info("SysRoleController - edit sysRole:{}", sysRole);
|
||||||
|
|
||||||
|
return toAjax(sysRoleService.saveOrUpdate(sysRole));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除角色
|
||||||
|
@PostMapping("/del")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:role:del')")
|
||||||
|
@Log(title = "删除角色", businessType = BusinessType.DELETE)
|
||||||
|
public AjaxResult del(@RequestParam Long id){
|
||||||
|
log.info("SysRoleController - del id:{}", id);
|
||||||
|
|
||||||
|
return toAjax(sysRoleService.del(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 角色分页列表
|
||||||
|
@GetMapping("/pageList")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:role:list')")
|
||||||
|
@Log(title = "查询角色", businessType = BusinessType.SELECT)
|
||||||
|
public TableDataInfo pageList(SysRole sysRole){
|
||||||
|
log.info("SysRoleController - pageList sysRole:{}", sysRole);
|
||||||
|
|
||||||
|
startPage();
|
||||||
|
List<SysRole> list = sysRoleService.findList(sysRole);
|
||||||
|
log.info("SysRoleController - pageList list:{}", list);
|
||||||
|
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 角色列表
|
||||||
|
@GetMapping("/list")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:role:list')")
|
||||||
|
@Log(title = "查询角色", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult list(){
|
||||||
|
log.info("SysRoleController - list ");
|
||||||
|
|
||||||
|
List<SysRole> list = sysRoleService.findList(new SysRole());
|
||||||
|
log.info("SysRoleController - list list:{}", list);
|
||||||
|
|
||||||
|
return AjaxResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询角色拥有菜单
|
||||||
|
@PostMapping("/ownMenu")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:role:ownMenu')")
|
||||||
|
@Log(title = "角色拥有菜单", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult ownMenu(Long id){
|
||||||
|
log.info("SysRoleController - ownMenu id:{}", id);
|
||||||
|
|
||||||
|
return AjaxResult.success(sysRoleService.ownMenu(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 角色授权菜单
|
||||||
|
@PostMapping("/grantMenu")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:role:grantMenu')")
|
||||||
|
@Log(title = "角色授权菜单", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult grantMenu(@RequestBody @Validated SysRoleGrantMenuParam sysRoleGrantMenuParam){
|
||||||
|
log.info("SysRoleController - grantMenu id:{}, grantMenuIdList{}", sysRoleGrantMenuParam.getId(), sysRoleGrantMenuParam.getGrantMenuIdList());
|
||||||
|
|
||||||
|
sysRoleService.grantMenu(sysRoleGrantMenuParam.getId(), sysRoleGrantMenuParam.getGrantMenuIdList());
|
||||||
|
return AjaxResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.org.system.controller;
|
||||||
|
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.entity.SysMenu;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.system.service.SysRoleMenuService;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sys/role/menu")
|
||||||
|
public class SysRoleMenuController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysRoleMenuService sysRoleMenuService;
|
||||||
|
|
||||||
|
// @PostMapping("add")
|
||||||
|
// @PreAuthorize("@ss.hasPermi('sys:role:menu:edit')")
|
||||||
|
// @Log(title = "系统角色菜单新增", businessType = BusinessType.INSERT)
|
||||||
|
// public AjaxResult add(@RequestParam Long roleId, @RequestParam String menuIds){
|
||||||
|
// log.info("SysRoleMenuController - add roleId:{}", roleId);
|
||||||
|
// log.info("SysRoleMenuController - add menuIds:{}", menuIds);
|
||||||
|
//
|
||||||
|
// if(StringUtils.isNull(roleId)) return AjaxResult.error("角色ID不能为空");
|
||||||
|
//
|
||||||
|
// List<Long> MenuIdList;
|
||||||
|
// if(StringUtils.isNotNull(menuIds))
|
||||||
|
// MenuIdList = Arrays.asList(menuIds.split(",")).stream().map(menuIdStr -> Long.parseLong(menuIdStr)).collect(Collectors.toList());
|
||||||
|
// else
|
||||||
|
// MenuIdList = new ArrayList<>();
|
||||||
|
//
|
||||||
|
// return toAjax(sysRoleMenuService.save(roleId, MenuIdList));
|
||||||
|
// }
|
||||||
|
|
||||||
|
@GetMapping("/findMenuList")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:role:menu:list')")
|
||||||
|
@Log(title = "系统角色菜单查询-根据角色ID查询菜单", businessType = BusinessType.SELECT)
|
||||||
|
public List<SysMenu> findMenuList(@RequestParam Long roleId){
|
||||||
|
log.info("SysRoleMenuController - findMenu roleId:{}", roleId);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(roleId)) return new ArrayList<>();
|
||||||
|
|
||||||
|
return sysRoleMenuService.findMenuListByRoleId(roleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @GetMapping("/findRoleList")
|
||||||
|
// @PreAuthorize("@ss.hasPermi('sys:role:menu:list')")
|
||||||
|
// @Log(title = "系统角色菜单查询-根据菜单ID查询角色", businessType = BusinessType.SELECT)
|
||||||
|
// public List<SysRole> findRoleList(@RequestParam Long menuId){
|
||||||
|
// log.info("SysRoleMenuController - findRole menuId:{}", menuId);
|
||||||
|
//
|
||||||
|
// if(StringUtils.isNull(menuId)) return new ArrayList<>();
|
||||||
|
//
|
||||||
|
// return sysRoleMenuService.findRoleListByMenuId(menuId);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package com.org.system.controller;
|
||||||
|
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.config.validation.Update;
|
||||||
|
import com.org.system.entity.SysUser;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.system.params.SysUserGrantRoleParam;
|
||||||
|
import com.org.system.service.SysUserService;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.page.TableDataInfo;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sys/user")
|
||||||
|
public class SysUserController extends BaseController{
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysUserService sysUserService;
|
||||||
|
|
||||||
|
@PostMapping("/add")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:add')")
|
||||||
|
@Log(title = "系统用户新增", businessType = BusinessType.INSERT)
|
||||||
|
public AjaxResult add(@RequestBody @Validated SysUser sysUser, @RequestParam String password){
|
||||||
|
sysUser.setPassword(password);
|
||||||
|
log.info("SysUserController - add sysUser:{}", sysUser);
|
||||||
|
|
||||||
|
return toAjax(sysUserService.saveOrUpdate(sysUser));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/edit")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:edit')")
|
||||||
|
@Log(title = "系统用户修改", businessType = BusinessType.UPDATE)
|
||||||
|
public AjaxResult edit(@RequestBody @Validated(Update.class) SysUser sysUser){
|
||||||
|
log.info("SysUserController - edit sysUser:{}", sysUser);
|
||||||
|
|
||||||
|
return toAjax(sysUserService.saveOrUpdate(sysUser));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/del")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:del')")
|
||||||
|
@Log(title = "系统用户删除", businessType = BusinessType.DELETE)
|
||||||
|
public AjaxResult del(String ids, String deleteReason){
|
||||||
|
log.info("SysUserController - del ids:{}", ids);
|
||||||
|
log.info("SysUserController - del deleteReason:{}", deleteReason);
|
||||||
|
|
||||||
|
if(StringUtils.isEmpty(ids)) return AjaxResult.success();
|
||||||
|
|
||||||
|
List<Long> idList = Arrays.asList(ids.split(",")).stream().map(idStr -> Long.parseLong(idStr)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
return toAjax(sysUserService.del(idList, deleteReason));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/pageList")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:list')")
|
||||||
|
@Log(title = "系统用户查询", businessType = BusinessType.SELECT)
|
||||||
|
public TableDataInfo pageList(SysUser sysUser){
|
||||||
|
log.info("SysUserController - pageList sysUser:{}", sysUser);
|
||||||
|
|
||||||
|
startPage();
|
||||||
|
List<SysUser> list = sysUserService.findList(sysUser);
|
||||||
|
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 查询用户拥有角色
|
||||||
|
@PostMapping("/ownRole")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:ownRole')")
|
||||||
|
@Log(title = "用户_拥有角色", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult ownRole(Long id){
|
||||||
|
log.info("SysUserController - ownMenu id:{}", id);
|
||||||
|
|
||||||
|
return AjaxResult.success(sysUserService.ownRole(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户授权角色
|
||||||
|
@PostMapping("/grantRole")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:grantRole')")
|
||||||
|
@Log(title = "用户授权角色", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult grantRole(@RequestBody @Validated SysUserGrantRoleParam param){
|
||||||
|
log.info("SysUserController - grantMenu id:{}, grantRoleIdList{}", param.getId(), param.getGrantRoleIdList());
|
||||||
|
|
||||||
|
sysUserService.grantRole(param.getId(), param.getGrantRoleIdList());
|
||||||
|
return AjaxResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置密码
|
||||||
|
@GetMapping("/resetPwd")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:resetPwd')")
|
||||||
|
@Log(title = "重置密码", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult resetPwd(@RequestParam Long id) {
|
||||||
|
log.info("SysUserController - resetPwd id:{}", id);
|
||||||
|
|
||||||
|
return toAjax(sysUserService.resetPwd(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改密码
|
||||||
|
@GetMapping("/changePwd")
|
||||||
|
// @PreAuthorize("@ss.hasPermi('sys:user:changePwd')")
|
||||||
|
@Log(title = "修改密码", businessType = BusinessType.SELECT)
|
||||||
|
public AjaxResult changePwd(@RequestParam String oldPassword, @RequestParam("password") String password) {
|
||||||
|
log.info("SysUserController - changePwd oldPassword:{}", oldPassword);
|
||||||
|
log.info("SysUserController - changePwd password:{}", password);
|
||||||
|
|
||||||
|
return toAjax(sysUserService.changePwd(oldPassword, password));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.org.system.controller;
|
||||||
|
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.entity.SysRole;
|
||||||
|
import com.org.system.entity.SysUser;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.system.service.SysUserRoleService;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sys/user/role")
|
||||||
|
public class SysUserRoleController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysUserRoleService sysUserRoleService;
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
@PostMapping("/add")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:role:edit')")
|
||||||
|
@Log(title = "系统用户角色新增", businessType = BusinessType.INSERT)
|
||||||
|
public AjaxResult add(@RequestParam Long userId, @RequestParam String roleIds){
|
||||||
|
log.info("SysUserRoleController - add userId:{}", userId);
|
||||||
|
log.info("SysUserRoleController - add roleIds:{}", roleIds);
|
||||||
|
|
||||||
|
if(StringUtils.isEmpty(roleIds)) return AjaxResult.error("角色ID不能为空");
|
||||||
|
|
||||||
|
List<Long> roleIdList = Arrays.asList(roleIds.split(",")).stream().map(roleIdStr -> Long.parseLong(roleIdStr)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
return toAjax(sysUserRoleService.save(userId, roleIdList));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
@PostMapping("/del")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:role:edit')")
|
||||||
|
@Log(title = "系统用户角色删除", businessType = BusinessType.DELETE)
|
||||||
|
public AjaxResult del(@RequestParam Long userId, @RequestParam String roleIds){
|
||||||
|
log.info("SysUserRoleController - del userId:{}", userId);
|
||||||
|
log.info("SysUserRoleController - del roleIds:{}", roleIds);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(roleIds)) return AjaxResult.error("角色ID不能为空");
|
||||||
|
|
||||||
|
List<Long> roleIdList = Arrays.asList(roleIds.split(",")).stream().map(roleIdStr -> Long.parseLong(roleIdStr)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
return toAjax(sysUserRoleService.delByUserIdAndRoleId(userId, roleIdList));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据用户ID查询角色信息
|
||||||
|
@GetMapping("/findRoleList")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:role:list')")
|
||||||
|
@Log(title = "系统用户角色查询-根据角色ID查询角色", businessType = BusinessType.SELECT)
|
||||||
|
public List<SysRole> findRoleList(@RequestParam Long userId){
|
||||||
|
log.info("SysUserRoleController - findRoleList userId:{}", userId);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(userId)) return new ArrayList<>();
|
||||||
|
|
||||||
|
return sysUserRoleService.findRoleListByUserId(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据角色ID查询用户信息
|
||||||
|
@GetMapping("/findUserList")
|
||||||
|
@PreAuthorize("@ss.hasPermi('sys:user:role:list')")
|
||||||
|
@Log(title = "系统用户角色查询-根据角色ID查询用户", businessType = BusinessType.SELECT)
|
||||||
|
public List<SysUser> findUserList(@RequestParam Long roleId){
|
||||||
|
log.info("SysUserRoleController - findUserList roleId:{}", roleId);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(roleId)) return new ArrayList<>();
|
||||||
|
|
||||||
|
return sysUserRoleService.findUserListByRoleId(roleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DatePattern;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class BaseEntity implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 创建者 **/
|
||||||
|
private Long createBy;
|
||||||
|
|
||||||
|
/** 创建时间 **/
|
||||||
|
@JsonFormat(pattern= DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/** 更新者 **/
|
||||||
|
private Long updateBy;
|
||||||
|
|
||||||
|
/** 更新时间 **/
|
||||||
|
@JsonFormat(pattern=DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/** 是否删除 1-是,0-否 **/
|
||||||
|
private Integer isDelete;
|
||||||
|
|
||||||
|
/** 删除者 **/
|
||||||
|
private Long deleteBy;
|
||||||
|
|
||||||
|
/** 删除时间 **/
|
||||||
|
@JsonFormat(pattern=DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
|
||||||
|
private Date deleteTime;
|
||||||
|
|
||||||
|
/** 删除理由 **/
|
||||||
|
private String deleteReason;
|
||||||
|
|
||||||
|
/** 备注 **/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/** 用户登录对象 **/
|
||||||
|
@Data
|
||||||
|
public class LoginBody {
|
||||||
|
/** 帐号 **/
|
||||||
|
private String username;
|
||||||
|
/** 密码 **/
|
||||||
|
private String password;
|
||||||
|
/** 角色编码 默认平台管理员**/
|
||||||
|
private String roleCode;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.org.system.pojo.LoginMenuTreeNode;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录用户身份权限
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class LoginUser implements UserDetails {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 用户唯一标识 **/
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
/** 登录时间 **/
|
||||||
|
private Long loginTime;
|
||||||
|
|
||||||
|
/** 过期时间 **/
|
||||||
|
private Long expireTime;
|
||||||
|
|
||||||
|
/** 登录IP地址 **/
|
||||||
|
private String ipaddr;
|
||||||
|
|
||||||
|
/** 登录地点 **/
|
||||||
|
private String loginLocation;
|
||||||
|
|
||||||
|
/** 浏览器类型 **/
|
||||||
|
private String browser;
|
||||||
|
|
||||||
|
/** 操作系统 **/
|
||||||
|
private String os;
|
||||||
|
|
||||||
|
/** 用户信息 **/
|
||||||
|
private SysUser user;
|
||||||
|
|
||||||
|
/** 所有角色信息 **/
|
||||||
|
private List<SysRole> roleList;
|
||||||
|
|
||||||
|
/** 当前角色编码 **/
|
||||||
|
private String currentRoleCode;
|
||||||
|
|
||||||
|
/** 当前角色信息 **/
|
||||||
|
private SysRole currentRole;
|
||||||
|
|
||||||
|
/** 权限列表 **/
|
||||||
|
private Set<String> permissions;
|
||||||
|
|
||||||
|
/** 登录菜单信息,AntDesign版本菜单 **/
|
||||||
|
private List<LoginMenuTreeNode> menus;
|
||||||
|
|
||||||
|
/** 是否管理员 **/
|
||||||
|
public boolean ifAdmin(){
|
||||||
|
if("admin".equals(this.user.getUserName())) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String getPassword(){ return user.getPassword(); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername(){ return user.getUserName(); }
|
||||||
|
|
||||||
|
public String getName(){ return user.getName(); }
|
||||||
|
|
||||||
|
/** 账户是否未过期,过期无法验证 **/
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonExpired()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 指定用户是否解锁,锁定的用户无法进行身份验证 **/
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonLocked()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 **/
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public boolean isCredentialsNonExpired()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 是否可用 ,禁用的用户不能身份验证 **/
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.org.system.config.validation.Update;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/** 系统词典分类表 **/
|
||||||
|
@Data
|
||||||
|
public class SysDataDictionary extends BaseEntity {
|
||||||
|
|
||||||
|
/** 词典分类ID **/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@NotNull(message = "词典分类ID不能为空", groups = {Update.class})
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 词典标识(键) **/
|
||||||
|
private String dictionaryCode;
|
||||||
|
|
||||||
|
/** 词典名称 **/
|
||||||
|
@NotEmpty(message = "词典名称不能为空")
|
||||||
|
private String dictionaryName;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.org.system.config.validation.Update;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/** 系统词典项表 **/
|
||||||
|
@Data
|
||||||
|
public class SysDataDictionaryItem extends BaseEntity {
|
||||||
|
|
||||||
|
/** 词典项ID **/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@NotNull(message = "词典项ID不能为空", groups = {Update.class})
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 词典标识(键) **/
|
||||||
|
@NotEmpty(message = "词典标识不能为空")
|
||||||
|
private String dictionaryCode;
|
||||||
|
|
||||||
|
/** 词典项目名称 **/
|
||||||
|
@NotEmpty(message = "词典项名称不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 词典项目值 **/
|
||||||
|
@NotNull(message = "词典项值不能为空")
|
||||||
|
private Integer value;
|
||||||
|
|
||||||
|
/** 所属上级值顶级默认-1 **/
|
||||||
|
@NotNull(message = "所属上级不能为空")
|
||||||
|
private Integer parentid;
|
||||||
|
|
||||||
|
/** 备注说明 **/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/** 显示顺序 **/
|
||||||
|
@NotNull(message = "显示顺序不能为空", groups = {Update.class})
|
||||||
|
private Integer sortid;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.org.system.config.validation.Update;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/** 菜单表 **/
|
||||||
|
@Data
|
||||||
|
public class SysMenu extends BaseEntity {
|
||||||
|
|
||||||
|
/** 菜单ID **/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@NotNull(message = "菜单ID不能为空", groups = Update.class)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 菜单名称 **/
|
||||||
|
@NotEmpty(message = "菜单名称不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 菜单编码 **/
|
||||||
|
@NotEmpty(message = "菜单编码不能为空")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/** 上级菜单ID **/
|
||||||
|
@NotNull(message = "上级菜单ID不能为空")
|
||||||
|
private Long pid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 父ids
|
||||||
|
*/
|
||||||
|
private String pids;
|
||||||
|
|
||||||
|
/** 菜单类型 0目录 1菜单 2按钮 3-服务级(待定) **/
|
||||||
|
@NotNull(message = "菜单类型不能为空")
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由地址
|
||||||
|
*/
|
||||||
|
private String router;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组件地址
|
||||||
|
*/
|
||||||
|
private String component;
|
||||||
|
|
||||||
|
/** 权限标识 **/
|
||||||
|
private String permission;
|
||||||
|
|
||||||
|
/** 是否显示 1-是 0-否 **/
|
||||||
|
@NotNull(message = "是否显示不能为空")
|
||||||
|
private Integer visible;
|
||||||
|
|
||||||
|
/** 顺序号 **/
|
||||||
|
private Integer intCode;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private List<SysMenu> children = new ArrayList<>();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DatePattern;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/** 操作日志记录表 oper_log **/
|
||||||
|
@Data
|
||||||
|
public class SysOperLog {
|
||||||
|
/** 日志主键 */
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 操作模块 */
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/** 业务类型(0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据) */
|
||||||
|
private Integer businessType;
|
||||||
|
|
||||||
|
/** 业务类型数组 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Integer[] businessTypes;
|
||||||
|
|
||||||
|
/** 请求方法 */
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
/** 请求方式 */
|
||||||
|
private String requestMethod;
|
||||||
|
|
||||||
|
/** 操作类别(0其它 1后台用户 2手机端用户) */
|
||||||
|
private Integer operatorType;
|
||||||
|
|
||||||
|
/** 操作人员 */
|
||||||
|
private String operName;
|
||||||
|
|
||||||
|
/** 部门名称 */
|
||||||
|
private String deptName;
|
||||||
|
|
||||||
|
/** 请求url */
|
||||||
|
private String operUrl;
|
||||||
|
|
||||||
|
/** 操作地址 */
|
||||||
|
private String operIp;
|
||||||
|
|
||||||
|
/** 操作地点 */
|
||||||
|
private String operLocation;
|
||||||
|
|
||||||
|
/** 请求参数 */
|
||||||
|
private String operParam;
|
||||||
|
|
||||||
|
/** 返回参数 */
|
||||||
|
private String jsonResult;
|
||||||
|
|
||||||
|
/** 操作状态(0正常 1异常) */
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/** 错误消息 */
|
||||||
|
private String errorMsg;
|
||||||
|
|
||||||
|
/** 操作时间 */
|
||||||
|
@JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
|
||||||
|
private Date operTime;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.org.system.config.validation.Update;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/** 系统角色表 **/
|
||||||
|
@Data
|
||||||
|
public class SysRole extends BaseEntity {
|
||||||
|
|
||||||
|
public static final Long PLATFORM_MANAGER_ROLE = 2L;
|
||||||
|
|
||||||
|
// 服务人员
|
||||||
|
public static final Long SERVICE_ROLE = 3L;
|
||||||
|
|
||||||
|
// 供养人员
|
||||||
|
public static final Long SUPPORT_ROLE = 4L;
|
||||||
|
|
||||||
|
// 医养结合护理人员
|
||||||
|
public static final Long TEND_ROLE = 5L;
|
||||||
|
|
||||||
|
public static final String STUDENT_ROLE_CODE = "student";
|
||||||
|
|
||||||
|
/** 角色ID **/
|
||||||
|
@NotNull(message = "角色ID不能为空", groups = {Update.class})
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 角色名称 **/
|
||||||
|
@NotEmpty(message = "角色名称不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编码
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
|
/** 角色所属组织ID **/
|
||||||
|
private Long orgCode;
|
||||||
|
|
||||||
|
/** 父级角色ID **/
|
||||||
|
private Long parentId;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/** 角色菜单 **/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class SysRoleMenu {
|
||||||
|
|
||||||
|
/** 主键ID **/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 角色ID **/
|
||||||
|
@NotNull(message = "角色ID不能为空")
|
||||||
|
private Long roleId;
|
||||||
|
|
||||||
|
/** 菜单ID **/
|
||||||
|
@NotNull(message = "菜单ID不能为空")
|
||||||
|
private Long menuId;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DatePattern;
|
||||||
|
import cn.hutool.core.util.IdcardUtil;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.org.system.config.validation.Update;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class SysUser extends BaseEntity {
|
||||||
|
|
||||||
|
public static final String DEFAULT_PASSWORD = "Aqpx123456";
|
||||||
|
|
||||||
|
/** 用户ID **/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@NotNull(message = "用户ID不能为空", groups = {Update.class})
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 姓名 */
|
||||||
|
@NotEmpty(message = "姓名不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 用户名称 **/
|
||||||
|
@NotEmpty(message = "用户名称不能为空")
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/** 用户昵称 **/
|
||||||
|
private String nickName;
|
||||||
|
|
||||||
|
/** 用户邮箱 **/
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
/** 手机号码 **/
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
/** 微信OpenId **/
|
||||||
|
@JsonIgnore
|
||||||
|
private String wxOpenId;
|
||||||
|
|
||||||
|
/** 用户性别 0-未知 1-男 2-女 **/
|
||||||
|
private int sex;
|
||||||
|
|
||||||
|
/** 用户头像 **/
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
/** 用户密码 **/
|
||||||
|
@JsonIgnore
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/** 用户SALT **/
|
||||||
|
@JsonIgnore
|
||||||
|
private String salt;
|
||||||
|
|
||||||
|
/** 用户状态 0-停用 1-正常 2-注册 **/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/** 最后登录IP **/
|
||||||
|
private String loginIp;
|
||||||
|
|
||||||
|
/** 最后登录时间 **/
|
||||||
|
@JsonFormat(pattern= DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
|
||||||
|
private Date loginDate;
|
||||||
|
|
||||||
|
/** 登录次数 **/
|
||||||
|
private Integer loginCount;
|
||||||
|
public Integer getLoginCount(){ return this.loginCount == null ? 0 : this.loginCount; }
|
||||||
|
|
||||||
|
/** 身份证号码 **/
|
||||||
|
private String idCardNo;
|
||||||
|
|
||||||
|
/** 年龄 */
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Integer age;
|
||||||
|
public int getAge() {
|
||||||
|
if(this.idCardNo == null){ return 0; }
|
||||||
|
// 通过身份证号计算年龄
|
||||||
|
return this.age = IdcardUtil.getAgeByIdCard(this.getIdCardNo());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.org.system.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/** 系统用户角色 **/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class SysUserRole {
|
||||||
|
|
||||||
|
/** 主键ID **/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 用户ID **/
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/** 角色ID **/
|
||||||
|
private Long roleId;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.org.system.entity.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class PersonVo implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 学员id */
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 部门信息 */
|
||||||
|
private Long orgId;
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
private Long personId;
|
||||||
|
|
||||||
|
/** 姓名 */
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/* 用户名 */
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
/** 用户性别 0-未知 1-男 2-女 **/
|
||||||
|
private int sex;
|
||||||
|
|
||||||
|
/** 是否管理员 2:否 1:是 */
|
||||||
|
private Integer isAdmin;
|
||||||
|
|
||||||
|
/* 单位信息 */
|
||||||
|
private String unit;
|
||||||
|
|
||||||
|
/* 部门信息 */
|
||||||
|
private String dept;
|
||||||
|
|
||||||
|
/** 年度学时 */
|
||||||
|
private BigDecimal yearClassHour;
|
||||||
|
|
||||||
|
/** 累计学时 */
|
||||||
|
private BigDecimal sumClassHour;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.org.system.enums;
|
||||||
|
|
||||||
|
/** 操作状态 **/
|
||||||
|
public enum BusinessStatus {
|
||||||
|
/** 成功 **/
|
||||||
|
SUCCESS,
|
||||||
|
|
||||||
|
/** 失败 **/
|
||||||
|
FAIL,
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.org.system.enums;
|
||||||
|
|
||||||
|
/** 业务操作类型 **/
|
||||||
|
public enum BusinessType {
|
||||||
|
/** 其它 **/
|
||||||
|
OTHER,
|
||||||
|
|
||||||
|
/** 新增 **/
|
||||||
|
INSERT,
|
||||||
|
|
||||||
|
/** 修改 **/
|
||||||
|
UPDATE,
|
||||||
|
|
||||||
|
/** 删除 **/
|
||||||
|
DELETE,
|
||||||
|
|
||||||
|
/** 查询 **/
|
||||||
|
SELECT,
|
||||||
|
|
||||||
|
/** 授权 **/
|
||||||
|
GRANT,
|
||||||
|
|
||||||
|
/** 导出 **/
|
||||||
|
EXPORT,
|
||||||
|
|
||||||
|
/** 导入 **/
|
||||||
|
IMPORT,
|
||||||
|
|
||||||
|
/** 强退 **/
|
||||||
|
FORCE,
|
||||||
|
|
||||||
|
/** 生成代码 **/
|
||||||
|
GENCODE,
|
||||||
|
|
||||||
|
/** 清空数据 **/
|
||||||
|
CLEAN,
|
||||||
|
|
||||||
|
/** 登陆 **/
|
||||||
|
LOGIN,
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.org.system.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单类型枚举
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum MenuTypeEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 目录
|
||||||
|
*/
|
||||||
|
DIR(0, "目录"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单
|
||||||
|
*/
|
||||||
|
MENU(1, "菜单"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按钮
|
||||||
|
*/
|
||||||
|
BTN(2, "按钮");
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
MenuTypeEnum(Integer code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.org.system.enums;
|
||||||
|
|
||||||
|
/** 操作人类别 **/
|
||||||
|
public enum OperatorType
|
||||||
|
{
|
||||||
|
/** 其它 **/
|
||||||
|
OTHER,
|
||||||
|
|
||||||
|
/** 后台用户 **/
|
||||||
|
MANAGE,
|
||||||
|
|
||||||
|
/** 手机端用户 **/
|
||||||
|
MOBILE
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.org.system.enums;
|
||||||
|
|
||||||
|
/** 短信类型 **/
|
||||||
|
public enum SmsType {
|
||||||
|
REGISTER("register"), CHANGEMOBILE("changeMobile");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
SmsType(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据value获取枚举
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static SmsType getSmsType(String value) {
|
||||||
|
SmsType[] smsTypeArr = SmsType.values();
|
||||||
|
for (int i = 0; i < smsTypeArr.length; i++) {
|
||||||
|
if (smsTypeArr[i].getValue().equals(value)) {
|
||||||
|
return smsTypeArr[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.org.system.enums;
|
||||||
|
|
||||||
|
/** 删除状态 **/
|
||||||
|
public enum YesOrNoState {
|
||||||
|
YES(1),NO(0);
|
||||||
|
private final int state;
|
||||||
|
|
||||||
|
YesOrNoState(int state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.org.system.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.org.system.entity.SysDataDictionaryItem;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysDataDictionaryItemMapper extends BaseMapper<SysDataDictionaryItem> {
|
||||||
|
|
||||||
|
@Select("select max(sortid) from sys_data_dictionary_item where dictionary_code = #{dictionaryCode}")
|
||||||
|
public Integer findMaxSortidByCode(@Param("dictionaryCode") String dictionaryCode);
|
||||||
|
|
||||||
|
@Select("select max(value) from sys_data_dictionary_item where dictionary_code = #{dictionaryCode}")
|
||||||
|
public Integer findMaxValueByCode(@Param("dictionaryCode") String dictionaryCode);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过名称和code 查询词典项
|
||||||
|
* @param name
|
||||||
|
* @param dictionaryCode
|
||||||
|
* @return 返回一条数据
|
||||||
|
*/
|
||||||
|
@Select("SELECT * FROM sys_data_dictionary_item WHERE name=#{name} AND dictionary_code=#{dictionaryCode} ")
|
||||||
|
SysDataDictionaryItem findByNameAndCode(@Param("name") String name, String dictionaryCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过值和code 查询词典项
|
||||||
|
* @param value
|
||||||
|
* @param dictionaryCode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Select("SELECT * FROM sys_data_dictionary_item WHERE value=#{value} AND dictionary_code=#{dictionaryCode} ")
|
||||||
|
SysDataDictionaryItem findByValueAndCode(@Param("value") int value, String dictionaryCode);
|
||||||
|
|
||||||
|
@Select("select name from sys_data_dictionary_item where dictionary_code = #{dictonaryCode} and value = #{value} and is_delete=0")
|
||||||
|
String findDictonaryBydictonaryCode(@Param("dictonaryCode") String dictonaryCode, @Param("value") Integer value);
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.org.system.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.org.system.entity.SysDataDictionary;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysDataDictionaryMapper extends BaseMapper<SysDataDictionary> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.org.system.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.org.system.entity.SysMenu;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysMenuMapper extends BaseMapper<SysMenu> {
|
||||||
|
|
||||||
|
@Select("select max(int_code) from sys_menu where parent_id = #{parentId}")
|
||||||
|
public Integer findMaxIntCodeByParentId(@Param("parentId") Long parentId);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.org.system.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.org.system.entity.SysOperLog;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysOperLogMapper extends BaseMapper<SysOperLog> {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
//package com.xinmei.system.mapper;
|
||||||
|
//
|
||||||
|
//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
//import com.xinmei.system.entity.SysOrg;
|
||||||
|
//import org.apache.ibatis.annotations.Mapper;
|
||||||
|
//
|
||||||
|
//@Mapper
|
||||||
|
//public interface SysOrgMapper extends BaseMapper<SysOrg> {
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.org.system.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.org.system.entity.SysRole;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysRoleMapper extends BaseMapper<SysRole> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.org.system.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.org.system.entity.SysMenu;
|
||||||
|
import com.org.system.entity.SysRole;
|
||||||
|
import com.org.system.entity.SysRoleMenu;
|
||||||
|
import org.apache.ibatis.annotations.Delete;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysRoleMenuMapper extends BaseMapper<SysRoleMenu> {
|
||||||
|
|
||||||
|
@Delete("delete from sys_role_menu where role_id = #{roleId}")
|
||||||
|
public Integer delByRoleId(@Param("roleId") Long roleId);
|
||||||
|
|
||||||
|
// @Delete("delete from sys_role_menu where menu_id = #{menuId}")
|
||||||
|
// public Integer delByMenuId(@Param("menuId") Long menuId);
|
||||||
|
|
||||||
|
@Delete("delete from sys_role_menu where role_id = #{roleId} and menu_id = #{menuId}")
|
||||||
|
public Integer delByRoleIdAndMenuId(@Param("roleId") Long roleId, @Param("menuId") Long menuId);
|
||||||
|
|
||||||
|
@Select("select menu.* from sys_menu menu left join sys_role_menu rm on menu.id = rm.menu_id where rm.role_id = #{roleId} and menu.is_delete = 0 order by menu.int_code")
|
||||||
|
public List<SysMenu> findMenuListByRoleId(@Param("roleId") Long roleId);
|
||||||
|
|
||||||
|
@Select("select role.* from sys_role role left join sys_role_menu rm on role.id = rm.role_id where rm.menu_id = #{menuId} and role.is_delete = 0")
|
||||||
|
public List<SysRole> findRoleListByMenuId(@Param("menuId") Long menuId);
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.org.system.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.org.system.entity.SysUser;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysUserMapper extends BaseMapper<SysUser> {
|
||||||
|
|
||||||
|
@Select("select * from sys_user where user_name = #{userName} and is_delete = 0")
|
||||||
|
public SysUser findByUserName(@Param("userName") String userName);
|
||||||
|
|
||||||
|
@Select("select * from sys_user where (user_name = #{userName} or phone = #{userName}) and is_delete = 0 order by create_time desc limit 1")
|
||||||
|
public SysUser findByUserNameOrPhone(@Param("userName") String userName);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.org.system.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.org.system.entity.SysRole;
|
||||||
|
import com.org.system.entity.SysUser;
|
||||||
|
import com.org.system.entity.SysUserRole;
|
||||||
|
import org.apache.ibatis.annotations.Delete;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
|
||||||
|
|
||||||
|
@Delete("delete from sys_user_role where user_id = #{userId}")
|
||||||
|
public Integer delByUserId(@Param("userId") Long userId);
|
||||||
|
|
||||||
|
@Delete("delete from sys_user_role where role_id = #{roleId}")
|
||||||
|
public Integer delByRoleId(@Param("roleId") Long roleId);
|
||||||
|
|
||||||
|
@Delete("delete from sys_user_role where user_id = #{userId} and role_id = #{roleId}")
|
||||||
|
public Integer delByUserIdAndRoleId(@Param("userId") Long userId, @Param("roleId") Long roleId);
|
||||||
|
|
||||||
|
@Select("select user.* from sys_user user left join sys_user_role ur on user.id = ur.user_id where ur.role_id = #{roleId} and user.is_delete = 0")
|
||||||
|
public List<SysUser> findUserListByRoleId(@Param("roleId") Long roleId);
|
||||||
|
|
||||||
|
@Select("select role.* from sys_role role left join sys_user_role ur on role.id = ur.role_id where ur.user_id = #{userid} and role.is_delete = 0")
|
||||||
|
public List<SysRole> findRoleListByUserId(@Param("userid") Long userid);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.org.system.params;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统角色分配菜单参数
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysRoleGrantMenuParam {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@NotNull(message = "id不能为空,请检查id参数")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权菜单
|
||||||
|
*/
|
||||||
|
@NotNull(message = "授权菜单不能为空,请检查grantMenuIdList参数")
|
||||||
|
private List<Long> grantMenuIdList;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.org.system.params;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户分配角色参数
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysUserGrantRoleParam {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@NotNull(message = "id不能为空,请检查id参数")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权角色
|
||||||
|
*/
|
||||||
|
@NotNull(message = "授权角色不能为空,请检查grantRoleIdList参数")
|
||||||
|
private List<Long> grantRoleIdList;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.org.system.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录菜单
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class LoginMenuTreeNode implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* id
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 父id
|
||||||
|
*/
|
||||||
|
private Long pid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由名称, 必须设置,且不能重名
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组件
|
||||||
|
*/
|
||||||
|
private String component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重定向地址, 访问这个路由时, 自定进行重定向
|
||||||
|
*/
|
||||||
|
private String redirect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由元信息(路由附带扩展信息)
|
||||||
|
*/
|
||||||
|
private Meta meta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路径
|
||||||
|
*/
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制路由和子路由是否显示在 sidebar
|
||||||
|
*/
|
||||||
|
private boolean hidden;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由元信息内部类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class Meta implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由标题, 用于显示面包屑, 页面标题 *推荐设置
|
||||||
|
*/
|
||||||
|
public String title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标
|
||||||
|
*/
|
||||||
|
public String icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可见
|
||||||
|
*/
|
||||||
|
public boolean show;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如需外部打开,增加:_blank
|
||||||
|
*/
|
||||||
|
public String target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内链打开http链接
|
||||||
|
*/
|
||||||
|
public String link;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import com.org.system.config.security.Md5PasswordEncoder;
|
||||||
|
import com.org.system.entity.LoginUser;
|
||||||
|
import com.org.system.entity.SysUser;
|
||||||
|
import com.org.utils.exception.BaseException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户验证处理
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CustomUserService implements UserDetailsService {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CustomUserService.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysUserService sysUserService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
// SysUser user = sysUserService.findByUserName(username);
|
||||||
|
SysUser user = sysUserService.findByUserNameOrPhone(username);
|
||||||
|
if (user == null) {
|
||||||
|
log.info("登录用户:{} 不存在.", username);
|
||||||
|
// throw new UsernameNotFoundException("登录用户:" + username + " 不存在");
|
||||||
|
throw new InternalAuthenticationServiceException("登录用户:" + username + " 不存在");
|
||||||
|
} else if (1 == user.getIsDelete()) {
|
||||||
|
log.info("登录用户:{} 已被删除.", username);
|
||||||
|
throw new BaseException("对不起,您的账号:" + username + " 已被删除");
|
||||||
|
} else if (0 == user.getStatus()) {
|
||||||
|
log.info("登录用户:{} 已被停用.", username);
|
||||||
|
throw new BaseException("对不起,您的账号:" + username + " 已停用");
|
||||||
|
}
|
||||||
|
Md5PasswordEncoder.getInstance().setSalt(user.getSalt());
|
||||||
|
return createLoginUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserDetails createLoginUser(SysUser user) {
|
||||||
|
// 这里可以查询用户权限放入 LoginUser 内
|
||||||
|
return new LoginUser().setUser(user);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import com.org.system.entity.LoginUser;
|
||||||
|
import com.org.utils.HttpServletUtil;
|
||||||
|
import com.org.utils.SecurityUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/** 自定义权限实现 **/
|
||||||
|
@Service("ss")
|
||||||
|
public class PermissionService {
|
||||||
|
/** 所有权限标识 **/
|
||||||
|
public static final String ALL_PERMISSION = "*:*:*";
|
||||||
|
|
||||||
|
/** 管理员角色权限标识 **/
|
||||||
|
private static final String SUPER_ADMIN = "admin";
|
||||||
|
|
||||||
|
private static final String ROLE_DELIMETER = ",";
|
||||||
|
|
||||||
|
private static final String PERMISSION_DELIMETER = ",";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证用户是否具备某权限
|
||||||
|
*
|
||||||
|
* @param permission 权限字符串
|
||||||
|
* @return 用户是否具备某权限
|
||||||
|
*/
|
||||||
|
public boolean hasPermi(String permission) {
|
||||||
|
if (StringUtils.isEmpty(permission)) return false;
|
||||||
|
|
||||||
|
// LoginUser loginUser = tokenService.getLoginUser(HttpServletUtil.getRequest());
|
||||||
|
LoginUser loginUser = SecurityUtil.getLoginUser();
|
||||||
|
if (null == loginUser || CollectionUtils.isEmpty(loginUser.getPermissions())) return false;
|
||||||
|
|
||||||
|
return hasPermissions(loginUser.getPermissions(), permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证用户是否不具备某权限,与 hasPermi逻辑相反
|
||||||
|
*
|
||||||
|
* @param permission 权限字符串
|
||||||
|
* @return 用户是否不具备某权限
|
||||||
|
*/
|
||||||
|
public boolean lacksPermi(String permission)
|
||||||
|
{
|
||||||
|
return hasPermi(permission) != true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证用户是否具有以下任意一个权限
|
||||||
|
*
|
||||||
|
* @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
|
||||||
|
* @return 用户是否具有以下任意一个权限
|
||||||
|
*/
|
||||||
|
public boolean hasAnyPermi(String permissions) {
|
||||||
|
if (StringUtils.isEmpty(permissions)) return false;
|
||||||
|
|
||||||
|
LoginUser loginUser = tokenService.getLoginUser(HttpServletUtil.getRequest());
|
||||||
|
if (null == loginUser || CollectionUtils.isEmpty(loginUser.getPermissions())) return false;
|
||||||
|
|
||||||
|
Set<String> authorities = loginUser.getPermissions();
|
||||||
|
for (String permission : permissions.split(PERMISSION_DELIMETER)) {
|
||||||
|
if (permission != null && hasPermissions(authorities, permission)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断用户是否拥有某个角色
|
||||||
|
*
|
||||||
|
* @param role 角色字符串
|
||||||
|
* @return 用户是否具备某角色
|
||||||
|
*/
|
||||||
|
/*public boolean hasRole(String role)
|
||||||
|
{
|
||||||
|
if (StringUtils.isEmpty(role))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
|
||||||
|
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (SysRole sysRole : loginUser.getUser().getRoles())
|
||||||
|
{
|
||||||
|
String roleKey = sysRole.getRoleKey();
|
||||||
|
if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证用户是否不具备某角色,与 isRole逻辑相反。
|
||||||
|
*
|
||||||
|
* @param role 角色名称
|
||||||
|
* @return 用户是否不具备某角色
|
||||||
|
*/
|
||||||
|
/*public boolean lacksRole(String role)
|
||||||
|
{
|
||||||
|
return hasRole(role) != true;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证用户是否具有以下任意一个角色
|
||||||
|
*
|
||||||
|
* @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
|
||||||
|
* @return 用户是否具有以下任意一个角色
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
public boolean hasAnyRoles(String roles)
|
||||||
|
{
|
||||||
|
if (StringUtils.isEmpty(roles))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
|
||||||
|
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (String role : roles.split(ROLE_DELIMETER))
|
||||||
|
{
|
||||||
|
if (hasRole(role))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否包含权限
|
||||||
|
*
|
||||||
|
* @param permissions 权限列表
|
||||||
|
* @param permission 权限字符串
|
||||||
|
* @return 用户是否具备某权限
|
||||||
|
*/
|
||||||
|
private boolean hasPermissions(Set<String> permissions, String permission) {
|
||||||
|
return permissions.contains(ALL_PERMISSION) || permissions.contains(permission.trim());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,243 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.org.system.entity.SysDataDictionaryItem;
|
||||||
|
import com.org.system.enums.YesOrNoState;
|
||||||
|
import com.org.system.mapper.SysDataDictionaryItemMapper;
|
||||||
|
import com.org.utils.SecurityUtil;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SysDataDictionaryItemService extends ServiceImpl<SysDataDictionaryItemMapper, SysDataDictionaryItem> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增或修改词典项
|
||||||
|
*
|
||||||
|
* @param sysDataDictionaryItem
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean saveOrUpdate(SysDataDictionaryItem sysDataDictionaryItem){
|
||||||
|
log.info("SysDataDictionaryItemService - saveOrUpdate sysDataDictionaryItem:{}", sysDataDictionaryItem);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(sysDataDictionaryItem.getId())){
|
||||||
|
//校验参数,检查是否存在相同的名称和值
|
||||||
|
checkParam(sysDataDictionaryItem, false);
|
||||||
|
// 新增
|
||||||
|
if(null == sysDataDictionaryItem.getSortid()) sysDataDictionaryItem.setSortid(findMaxSortidByCode(sysDataDictionaryItem.getDictionaryCode()));
|
||||||
|
sysDataDictionaryItem.setCreateBy(SecurityUtil.getUserId());
|
||||||
|
sysDataDictionaryItem.setCreateTime(new Date());
|
||||||
|
sysDataDictionaryItem.setIsDelete(YesOrNoState.NO.getState());
|
||||||
|
log.info("SysDataDictionaryItemService - saveOrUpdate save sysDataDictionaryItem:{}", sysDataDictionaryItem);
|
||||||
|
|
||||||
|
return save(sysDataDictionaryItem);
|
||||||
|
} else {
|
||||||
|
//校验参数,检查是否存在相同的名称和值
|
||||||
|
checkParam(sysDataDictionaryItem, true);
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
SysDataDictionaryItem sysDataDictionaryItemOld = getById(sysDataDictionaryItem.getId());
|
||||||
|
if(sysDataDictionaryItemOld == null || StringUtils.isNull(sysDataDictionaryItemOld.getId()))
|
||||||
|
throw new CustomException("未找到词典项");
|
||||||
|
|
||||||
|
sysDataDictionaryItem.setCreateBy(null);
|
||||||
|
sysDataDictionaryItem.setCreateTime(null);
|
||||||
|
sysDataDictionaryItem.setIsDelete(null);
|
||||||
|
sysDataDictionaryItem.setUpdateBy(SecurityUtil.getUserId());
|
||||||
|
sysDataDictionaryItem.setUpdateTime(new Date());
|
||||||
|
log.info("SysDataDictionaryItemService - saveOrUpdate update sysDataDictionaryItem:{}", sysDataDictionaryItem);
|
||||||
|
|
||||||
|
return updateById(sysDataDictionaryItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验参数,检查是否存在相同的名称
|
||||||
|
*/
|
||||||
|
private void checkParam(SysDataDictionaryItem dictionary, boolean isExcludeSelf) {
|
||||||
|
Long id = dictionary.getId();
|
||||||
|
String name = dictionary.getName();
|
||||||
|
Integer value = dictionary.getValue();
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysDataDictionaryItem> queryWrapperByName = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapperByName.eq(SysDataDictionaryItem::getName, name)
|
||||||
|
.eq(SysDataDictionaryItem::getDictionaryCode, dictionary.getDictionaryCode())
|
||||||
|
.eq(SysDataDictionaryItem::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysDataDictionaryItem> queryWrapperByCode = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapperByCode.eq(SysDataDictionaryItem::getValue, value)
|
||||||
|
.eq(SysDataDictionaryItem::getDictionaryCode, dictionary.getDictionaryCode())
|
||||||
|
.eq(SysDataDictionaryItem::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
//是否排除自己,如果排除自己则不查询自己的id
|
||||||
|
if (isExcludeSelf) {
|
||||||
|
queryWrapperByName.ne(SysDataDictionaryItem::getId, id);
|
||||||
|
queryWrapperByCode.ne(SysDataDictionaryItem::getId, id);
|
||||||
|
}
|
||||||
|
int countByName = this.count(queryWrapperByName);
|
||||||
|
int countByCode = this.count(queryWrapperByCode);
|
||||||
|
|
||||||
|
if (countByName >= 1) {
|
||||||
|
throw new CustomException("名称重复,请检查名称参数");
|
||||||
|
}
|
||||||
|
if (countByCode >= 1) {
|
||||||
|
throw new CustomException("词典项值重复,请检查词典项值参数");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除词典项
|
||||||
|
*
|
||||||
|
* @param idList
|
||||||
|
* @param deleteReason
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean del(List<Long> idList, String deleteReason){
|
||||||
|
log.info("SysDataDictionaryItemService - del idList:{}", idList);
|
||||||
|
log.info("SysDataDictionaryItemService - del deleteReason:{}", deleteReason);
|
||||||
|
|
||||||
|
List<SysDataDictionaryItem> delList = new ArrayList<>();
|
||||||
|
for (Long id : idList) {
|
||||||
|
if(id == null) continue;
|
||||||
|
|
||||||
|
SysDataDictionaryItem sysDataDictionaryItem = getById(id);
|
||||||
|
if(sysDataDictionaryItem == null || sysDataDictionaryItem.getId() == null) continue;
|
||||||
|
|
||||||
|
sysDataDictionaryItem.setIsDelete(YesOrNoState.YES.getState());
|
||||||
|
sysDataDictionaryItem.setDeleteBy(SecurityUtil.getUserId());
|
||||||
|
sysDataDictionaryItem.setDeleteTime(new Date());
|
||||||
|
log.info("SysDataDictionaryItemService - del sysDataDictionaryItem:{}", sysDataDictionaryItem);
|
||||||
|
|
||||||
|
delList.add(sysDataDictionaryItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateBatchById(delList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 词典项查询
|
||||||
|
*
|
||||||
|
* @param sysDataDictionaryItem
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysDataDictionaryItem> findList(SysDataDictionaryItem sysDataDictionaryItem){
|
||||||
|
log.info("SysDataDictionaryItemService - findList sysDataDictionaryItem:{}", sysDataDictionaryItem);
|
||||||
|
|
||||||
|
if(StringUtils.isEmpty(sysDataDictionaryItem.getDictionaryCode())) throw new CustomException("词典标识不能为空");
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysDataDictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysDataDictionaryItem::getIsDelete, YesOrNoState.NO.getState())
|
||||||
|
.eq(SysDataDictionaryItem::getDictionaryCode, sysDataDictionaryItem.getDictionaryCode());
|
||||||
|
|
||||||
|
if(StringUtils.isNotEmpty(sysDataDictionaryItem.getName()))
|
||||||
|
queryWrapper.like(SysDataDictionaryItem::getName, sysDataDictionaryItem.getName());
|
||||||
|
if(StringUtils.isNotNull(sysDataDictionaryItem.getValue()))
|
||||||
|
queryWrapper.like(SysDataDictionaryItem::getValue, sysDataDictionaryItem.getValue());
|
||||||
|
|
||||||
|
//根据排序升序排列,序号越小越在前
|
||||||
|
queryWrapper.orderByAsc(SysDataDictionaryItem::getSortid);
|
||||||
|
|
||||||
|
return list(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据词典标识获取该标识下的词典项最大显示顺序
|
||||||
|
*
|
||||||
|
* @param dictionaryCode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Integer findMaxSortidByCode(String dictionaryCode){
|
||||||
|
log.info("SysDataDictionaryItemService - findMaxSortidByCode dictionaryCode:{}", dictionaryCode);
|
||||||
|
|
||||||
|
Integer sortid = baseMapper.findMaxSortidByCode(dictionaryCode);
|
||||||
|
log.info("SysDataDictionaryItemService - findMaxSortidByCode sortid:{}", sortid);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(sortid)) sortid = 0;
|
||||||
|
sortid++;
|
||||||
|
log.info("SysDataDictionaryItemService - findMaxSortidByCode sortid:{}", sortid);
|
||||||
|
|
||||||
|
return sortid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据词典标识获取该标识下的词典项最大词典项目值
|
||||||
|
*
|
||||||
|
* @param dictionaryCode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Integer findMaxValueByCode(String dictionaryCode){
|
||||||
|
log.info("SysDataDictionaryItemService - findMaxValueByCode dictionaryCode:{}", dictionaryCode);
|
||||||
|
|
||||||
|
Integer value = baseMapper.findMaxValueByCode(dictionaryCode);
|
||||||
|
log.info("SysDataDictionaryItemService - findMaxValueByCode value:{}", value);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(value)) value = 0;
|
||||||
|
value++;
|
||||||
|
log.info("SysDataDictionaryItemService - findMaxValueByCode value:{}", value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<Dict> listByCode(String dictionaryCode) {
|
||||||
|
//构造查询条件
|
||||||
|
LambdaQueryWrapper<SysDataDictionaryItem> queryWrapper = new LambdaQueryWrapper<SysDataDictionaryItem>();
|
||||||
|
queryWrapper.eq(SysDataDictionaryItem::getDictionaryCode, dictionaryCode)
|
||||||
|
.eq(SysDataDictionaryItem::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
//根据排序升序排列,序号越小越在前
|
||||||
|
queryWrapper.orderByAsc(SysDataDictionaryItem::getSortid);
|
||||||
|
//查询dictTypeId下所有的字典项
|
||||||
|
List<SysDataDictionaryItem> results = this.list(queryWrapper);
|
||||||
|
|
||||||
|
//抽取code和value封装到map返回
|
||||||
|
List<Dict> dictList = CollectionUtil.newArrayList();
|
||||||
|
results.forEach(sysDictData -> {
|
||||||
|
Dict dict = Dict.create();
|
||||||
|
dict.put("id", sysDictData.getId());
|
||||||
|
dict.put("name", sysDictData.getName());
|
||||||
|
dict.put("value", sysDictData.getValue());
|
||||||
|
dict.put("parentid", sysDictData.getParentid());
|
||||||
|
dictList.add(dict);
|
||||||
|
});
|
||||||
|
|
||||||
|
return dictList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过课程的
|
||||||
|
* @param dictonaryCode 字典code
|
||||||
|
* @param value 字典value
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String findDictonaryBydictonaryCode(String dictonaryCode,Integer value){
|
||||||
|
log.info("SysDataDictionaryItemService - findDictonaryBydictonaryCode dictonaryCode:{}", dictonaryCode);
|
||||||
|
log.info("SysDataDictionaryItemService - findDictonaryBydictonaryCode value:{}", value);
|
||||||
|
return baseMapper.findDictonaryBydictonaryCode(dictonaryCode,value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SysDataDictionaryItem getByCodeAndName(String dictionaryCode, String name) {
|
||||||
|
LambdaQueryWrapper<SysDataDictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysDataDictionaryItem::getDictionaryCode, dictionaryCode);
|
||||||
|
queryWrapper.eq(SysDataDictionaryItem::getName, name);
|
||||||
|
queryWrapper.eq(SysDataDictionaryItem::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
return baseMapper.selectOne(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SysDataDictionaryItem getByCodeAndValue(String dictionaryCode, String value) {
|
||||||
|
LambdaQueryWrapper<SysDataDictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysDataDictionaryItem::getDictionaryCode, dictionaryCode);
|
||||||
|
queryWrapper.eq(SysDataDictionaryItem::getValue, value);
|
||||||
|
queryWrapper.eq(SysDataDictionaryItem::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
return baseMapper.selectOne(queryWrapper);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.org.system.entity.SysDataDictionary;
|
||||||
|
import com.org.system.enums.YesOrNoState;
|
||||||
|
import com.org.system.mapper.SysDataDictionaryMapper;
|
||||||
|
import com.org.utils.SecurityUtil;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SysDataDictionaryService extends ServiceImpl<SysDataDictionaryMapper, SysDataDictionary> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增或修改词典分类
|
||||||
|
*
|
||||||
|
* @param sysDataDictionary
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean saveOrUpdate(SysDataDictionary sysDataDictionary){
|
||||||
|
log.info("SysDataDictionaryService - saveOrUpdate sysDataDictionary:{}", sysDataDictionary);
|
||||||
|
|
||||||
|
if(sysDataDictionary.getId() == null){
|
||||||
|
//校验参数,检查是否存在相同的名称和编码
|
||||||
|
checkParam(sysDataDictionary, false);
|
||||||
|
// 新增词典分类
|
||||||
|
sysDataDictionary.setDictionaryCode(findDictionaryCode());
|
||||||
|
sysDataDictionary.setCreateBy(SecurityUtil.getUserId());
|
||||||
|
sysDataDictionary.setCreateTime(new Date());
|
||||||
|
sysDataDictionary.setIsDelete(YesOrNoState.NO.getState());
|
||||||
|
log.info("SysDataDictionaryService - saveOrUpdate save sysDataDictionary:{}", sysDataDictionary);
|
||||||
|
|
||||||
|
return save(sysDataDictionary);
|
||||||
|
}else{
|
||||||
|
//校验参数,检查是否存在相同的名称和编码
|
||||||
|
checkParam(sysDataDictionary, true);
|
||||||
|
|
||||||
|
// 修改词典分类
|
||||||
|
SysDataDictionary sysDataDictionaryOld = getById(sysDataDictionary.getId());
|
||||||
|
if(sysDataDictionaryOld == null || sysDataDictionaryOld.getId() == null)
|
||||||
|
throw new CustomException("未找到词典分类");
|
||||||
|
|
||||||
|
sysDataDictionaryOld.setDictionaryName(sysDataDictionary.getDictionaryName());
|
||||||
|
sysDataDictionaryOld.setUpdateBy(SecurityUtil.getUserId());
|
||||||
|
sysDataDictionaryOld.setUpdateTime(new Date());
|
||||||
|
log.info("SysDataDictionaryService - saveOrUpdate save sysDataDictionary:{}", sysDataDictionaryOld);
|
||||||
|
|
||||||
|
return updateById(sysDataDictionaryOld);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验参数,检查是否存在相同的名称
|
||||||
|
*/
|
||||||
|
private void checkParam(SysDataDictionary dictionary, boolean isExcludeSelf) {
|
||||||
|
Long id = dictionary.getId();
|
||||||
|
String name = dictionary.getDictionaryName();
|
||||||
|
String code = dictionary.getDictionaryCode();
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysDataDictionary> queryWrapperByName = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapperByName.eq(SysDataDictionary::getDictionaryName, name)
|
||||||
|
.eq(SysDataDictionary::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysDataDictionary> queryWrapperByCode = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapperByCode.eq(SysDataDictionary::getDictionaryCode, code)
|
||||||
|
.eq(SysDataDictionary::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
//是否排除自己,如果排除自己则不查询自己的id
|
||||||
|
if (isExcludeSelf) {
|
||||||
|
queryWrapperByName.ne(SysDataDictionary::getId, id);
|
||||||
|
queryWrapperByCode.ne(SysDataDictionary::getId, id);
|
||||||
|
}
|
||||||
|
int countByName = this.count(queryWrapperByName);
|
||||||
|
int countByCode = this.count(queryWrapperByCode);
|
||||||
|
|
||||||
|
if (countByName >= 1) {
|
||||||
|
throw new CustomException("名称重复,请检查名称参数");
|
||||||
|
}
|
||||||
|
if (countByCode >= 1) {
|
||||||
|
throw new CustomException("编码重复,请检查编码参数");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除词典分类
|
||||||
|
*
|
||||||
|
* @param idList
|
||||||
|
* @param deleteReason
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean del(List<Long> idList, String deleteReason){
|
||||||
|
log.info("SysDataDictionaryService - del idList:{}", idList);
|
||||||
|
log.info("SysDataDictionaryService - del deleteReason:{}", deleteReason);
|
||||||
|
|
||||||
|
List<SysDataDictionary> delList = new ArrayList<>();
|
||||||
|
for (Long id : idList) {
|
||||||
|
if(id == null) continue;
|
||||||
|
|
||||||
|
SysDataDictionary sysDataDictionary = getById(id);
|
||||||
|
if(sysDataDictionary == null || sysDataDictionary.getId() == null) continue;
|
||||||
|
|
||||||
|
sysDataDictionary.setIsDelete(YesOrNoState.YES.getState());
|
||||||
|
sysDataDictionary.setDeleteBy(SecurityUtil.getUserId());
|
||||||
|
sysDataDictionary.setDeleteTime(new Date());
|
||||||
|
log.info("SysDataDictionaryService - del sysDataDictionary:{}", sysDataDictionary);
|
||||||
|
|
||||||
|
delList.add(sysDataDictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateBatchById(delList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 词典分类查询
|
||||||
|
*
|
||||||
|
* @param sysDataDictionary
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysDataDictionary> findList(SysDataDictionary sysDataDictionary){
|
||||||
|
log.info("SysDataDictionaryService - findList sysDataDictionary:{}", sysDataDictionary);
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysDataDictionary> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysDataDictionary::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
if(StringUtils.isNotEmpty(sysDataDictionary.getDictionaryCode()))
|
||||||
|
queryWrapper.like(SysDataDictionary::getDictionaryCode, sysDataDictionary.getDictionaryCode());
|
||||||
|
if(StringUtils.isNotEmpty(sysDataDictionary.getDictionaryName()))
|
||||||
|
queryWrapper.like(SysDataDictionary::getDictionaryName, sysDataDictionary.getDictionaryName());
|
||||||
|
|
||||||
|
return list(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取词典标识
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String findDictionaryCode(){
|
||||||
|
int count = count();
|
||||||
|
|
||||||
|
return String.format("%04d", count+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.org.system.config.async.AsyncFactory;
|
||||||
|
import com.org.system.config.async.AsyncManager;
|
||||||
|
import com.org.system.entity.*;
|
||||||
|
import com.org.system.entity.vo.PersonVo;
|
||||||
|
import com.org.system.pojo.LoginMenuTreeNode;
|
||||||
|
import com.org.utils.Constants;
|
||||||
|
import com.org.utils.MessageUtil;
|
||||||
|
import com.org.utils.SecurityUtil;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import com.org.utils.exception.UserPasswordNotMatchException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/** 登录校验方法 **/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SysLoginService {
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
@Resource
|
||||||
|
private AuthenticationManager authenticationManager;
|
||||||
|
@Autowired
|
||||||
|
private SysUserService sysUserService;
|
||||||
|
@Autowired
|
||||||
|
private SysUserRoleService sysUserRoleService;
|
||||||
|
@Autowired
|
||||||
|
private SysRoleService sysRoleService;
|
||||||
|
@Autowired
|
||||||
|
private SysRoleMenuService sysRoleMenuService;
|
||||||
|
@Autowired
|
||||||
|
private SysMenuService sysMenuService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录验证
|
||||||
|
*
|
||||||
|
* @param loginBody 登陆用户实体
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public Map<String, String> login(LoginBody loginBody, boolean isCheckState) {
|
||||||
|
|
||||||
|
// todo 这里加验证码
|
||||||
|
// todo 这里加验证码
|
||||||
|
// todo 这里加验证码
|
||||||
|
|
||||||
|
// 用户验证
|
||||||
|
Authentication authentication = null;
|
||||||
|
try {
|
||||||
|
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
||||||
|
authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginBody.getUsername(), loginBody.getPassword()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e instanceof BadCredentialsException) {
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginBody.getUsername(), Constants.LOGIN_FAIL, MessageUtil.message("user.password.not.match")));
|
||||||
|
throw new UserPasswordNotMatchException();
|
||||||
|
} else {
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginBody.getUsername(), Constants.LOGIN_FAIL, e.getMessage()));
|
||||||
|
throw new CustomException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginBody.getUsername(), Constants.LOGIN_SUCCESS, "登陆成功"));
|
||||||
|
|
||||||
|
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
|
||||||
|
loginUser.getUser().setLoginCount(loginUser.getUser().getLoginCount() + 1);
|
||||||
|
sysUserService.updateById(loginUser.getUser());
|
||||||
|
|
||||||
|
// 登录时校验是否存在角色
|
||||||
|
SysUserRole sysUserRole = sysUserRoleService.getByUserIdAndRoleCode(loginUser.getUser().getId(), loginBody.getRoleCode());
|
||||||
|
if(ObjectUtil.isEmpty(sysUserRole)) throw new CustomException("当前用户没有该角色");
|
||||||
|
|
||||||
|
Integer status = loginUser.getUser().getStatus();
|
||||||
|
// 登录时是否校验账号状态
|
||||||
|
if (isCheckState && status != 1) {
|
||||||
|
String msg = status == 2 ? "审核中,请稍后再试": "已停用";
|
||||||
|
throw new CustomException("您的账号" + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
loginUser.setCurrentRoleCode(loginBody.getRoleCode());
|
||||||
|
|
||||||
|
Map<String, String> result = new HashMap<>();
|
||||||
|
|
||||||
|
// 生成token
|
||||||
|
String token = tokenService.createToken(loginUser);
|
||||||
|
result.put("token", token);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置登陆用户当前角色信息
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void setLoginUserRole(){
|
||||||
|
log.info("SysLoginService - setLoginUserRole roleCode:{}", SecurityUtil.getLoginUser().getCurrentRoleCode());
|
||||||
|
|
||||||
|
// 获取当前登录账号的所有角色信息
|
||||||
|
List<SysRole> sysRoleList = null;
|
||||||
|
if(!SecurityUtil.getLoginUser().ifAdmin()) sysRoleList = sysUserRoleService.findRoleListByUserId(SecurityUtil.getUserId());
|
||||||
|
else sysRoleList = sysRoleService.findAll();
|
||||||
|
SecurityUtil.getLoginUser().setRoleList(sysRoleList);
|
||||||
|
|
||||||
|
// 获取当前登录账号的当前角色信息
|
||||||
|
SysRole sysRole = null;
|
||||||
|
for (SysRole role : sysRoleList) { if(SecurityUtil.getLoginUser().getCurrentRoleCode().equals(role.getCode())) sysRole = role; }
|
||||||
|
if(ObjectUtil.isEmpty(sysRole)) throw new CustomException("当前用户没有该角色");
|
||||||
|
SecurityUtil.getLoginUser().setCurrentRole(sysRole);
|
||||||
|
|
||||||
|
|
||||||
|
// 获取当前登录账号当前角色的菜单
|
||||||
|
List<SysMenu> sysMenuList = null;
|
||||||
|
if(!SecurityUtil.getLoginUser().ifAdmin()) sysMenuList = sysRoleMenuService.findMenuListByRoleId(sysRole.getId());
|
||||||
|
else sysMenuList = sysMenuService.findAll();
|
||||||
|
List<LoginMenuTreeNode> loginMenuTreeNodeList = sysMenuService.convertSysMenuToLoginMenu(sysMenuList);
|
||||||
|
SecurityUtil.getLoginUser().setMenus(loginMenuTreeNodeList);
|
||||||
|
|
||||||
|
// 获取当前登录账号当前角色的权限
|
||||||
|
Set<String> permissions = new HashSet<>();
|
||||||
|
if(SecurityUtil.getLoginUser().ifAdmin()){
|
||||||
|
permissions.add(PermissionService.ALL_PERMISSION);
|
||||||
|
} else {
|
||||||
|
for (SysMenu sysMenu : sysMenuList) { if(StringUtils.isNotEmpty(sysMenu.getPermission())) permissions.add(sysMenu.getPermission()); }
|
||||||
|
}
|
||||||
|
SecurityUtil.getLoginUser().setPermissions(permissions);
|
||||||
|
|
||||||
|
tokenService.refreshToken(SecurityUtil.getLoginUser());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersonVo getUserInfo(Long userId) {
|
||||||
|
PersonVo personVo = new PersonVo();
|
||||||
|
/*XmPerson person = xmPersonService.getByUserId(userId);
|
||||||
|
if (person == null) throw new CustomException("未查询到人员信息");
|
||||||
|
PersonVo personVo = new PersonVo();
|
||||||
|
BeanUtils.copyProperties(person, personVo);
|
||||||
|
SysOrg sysOrg = sysOrgService.getById(person.getOrgId());
|
||||||
|
if (sysOrg.getType() == 1) {
|
||||||
|
// 如果组织为单位,则直接返回单位名称
|
||||||
|
personVo.setUnit(sysOrg.getName());
|
||||||
|
} else {
|
||||||
|
// 先查询出部门信息,再查询所属单位
|
||||||
|
SysOrg parentOrg = sysOrgService.findUnitByOrgId(sysOrg.getPid());
|
||||||
|
personVo.setUnit(parentOrg.getName());
|
||||||
|
personVo.setDept(sysOrg.getName());
|
||||||
|
}
|
||||||
|
personVo.setPersonId(person.getId());
|
||||||
|
|
||||||
|
// 学时
|
||||||
|
BigDecimal yearClassHour = studyRecordService.getBaseMapper().getYearSumStudyHours(person.getId());
|
||||||
|
personVo.setYearClassHour(yearClassHour);
|
||||||
|
BigDecimal sumClassHour = studyRecordService.getBaseMapper().getSumStudyHours(person.getId());
|
||||||
|
personVo.setSumClassHour(sumClassHour);*/
|
||||||
|
|
||||||
|
return personVo;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,339 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.org.system.entity.SysMenu;
|
||||||
|
import com.org.system.enums.MenuTypeEnum;
|
||||||
|
import com.org.system.enums.YesOrNoState;
|
||||||
|
import com.org.system.mapper.SysMenuMapper;
|
||||||
|
import com.org.system.pojo.LoginMenuTreeNode;
|
||||||
|
import com.org.utils.SecurityUtil;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SysMenuService extends ServiceImpl<SysMenuMapper, SysMenu> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysUserRoleService sysUserRoleService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysRoleMenuService sysRoleMenuService;
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public boolean add(SysMenu sysMenu) {
|
||||||
|
// 校验参数
|
||||||
|
checkParam(sysMenu, false);
|
||||||
|
|
||||||
|
|
||||||
|
// 设置新的pid
|
||||||
|
String newPids = createNewPids(sysMenu.getPid());
|
||||||
|
sysMenu.setPids(newPids);
|
||||||
|
|
||||||
|
// 设置启用状态
|
||||||
|
sysMenu.setCreateBy(SecurityUtil.getUserId());
|
||||||
|
sysMenu.setCreateTime(new Date());
|
||||||
|
sysMenu.setIsDelete(YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
return this.save(sysMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public boolean edit(SysMenu sysMenu) {
|
||||||
|
|
||||||
|
// 校验参数
|
||||||
|
checkParam(sysMenu, true);
|
||||||
|
|
||||||
|
// 获取修改的菜单的旧数据(库中的)
|
||||||
|
SysMenu oldMenu = getById(sysMenu.getId());
|
||||||
|
if(oldMenu == null || oldMenu.getId() == null) throw new CustomException("未找到菜单");
|
||||||
|
|
||||||
|
// 本菜单旧的pids
|
||||||
|
Long oldPid = oldMenu.getPid();
|
||||||
|
String oldPids = oldMenu.getPids();
|
||||||
|
|
||||||
|
// 生成新的pid和pids
|
||||||
|
Long newPid = sysMenu.getPid();
|
||||||
|
String newPids = this.createNewPids(sysMenu.getPid());
|
||||||
|
|
||||||
|
// 父节点有变化,更新子节点
|
||||||
|
if (!newPid.equals(oldPid)) {
|
||||||
|
// 查找所有叶子节点,包含子节点的子节点
|
||||||
|
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.like(SysMenu::getPids, "[" + oldMenu.getId() + "]");
|
||||||
|
List<SysMenu> list = this.list(queryWrapper);
|
||||||
|
|
||||||
|
list.forEach(child -> {
|
||||||
|
String oldParentCodesPrefix = oldPids + "[" + oldMenu.getId() + "]" + ",";
|
||||||
|
String oldParentCodesSuffix = child.getPids().substring(oldParentCodesPrefix.length());
|
||||||
|
// 子节点pids组成 = 当前菜单新pids + 当前菜单id + 子节点自己的pids后缀
|
||||||
|
String menuParentCodes = newPids + "[" + oldMenu.getId() + "]" + "," + oldParentCodesSuffix;
|
||||||
|
child.setPids(menuParentCodes);
|
||||||
|
});
|
||||||
|
this.updateBatchById(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置新的pids
|
||||||
|
sysMenu.setPids(newPids);
|
||||||
|
return this.updateById(sysMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验参数
|
||||||
|
*/
|
||||||
|
private void checkParam(SysMenu sysMenu, boolean isExcludeSelf) {
|
||||||
|
//菜单类型(字典 0目录 1菜单 2按钮)
|
||||||
|
Integer type = sysMenu.getType();
|
||||||
|
|
||||||
|
String router = sysMenu.getRouter();
|
||||||
|
|
||||||
|
String permission = sysMenu.getPermission();
|
||||||
|
|
||||||
|
if (!MenuTypeEnum.BTN.getCode().equals(type) && ObjectUtil.isEmpty(router)) {
|
||||||
|
throw new CustomException("路由地址为空,请检查router参数");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MenuTypeEnum.BTN.getCode().equals(type)) {
|
||||||
|
if (ObjectUtil.isEmpty(permission)) {
|
||||||
|
throw new CustomException("权限标识为空,请检查permission参数");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是编辑菜单时候,pid和id不能一致,一致会导致无限递归
|
||||||
|
if (isExcludeSelf) {
|
||||||
|
if (sysMenu.getId().equals(sysMenu.getPid())) {
|
||||||
|
throw new CustomException("父级菜单不能为当前节点,请重新选择父级菜单");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是编辑,父id不能为自己的子节点
|
||||||
|
List<Long> childIdListById = this.getChildIdListById(sysMenu.getId());
|
||||||
|
if(ObjectUtil.isNotEmpty(childIdListById)) {
|
||||||
|
if(childIdListById.contains(sysMenu.getPid())) {
|
||||||
|
throw new CustomException("父节点不能为本节点的子节点,请重新选择父节点");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Long id = sysMenu.getId();
|
||||||
|
String name = sysMenu.getName();
|
||||||
|
String code = sysMenu.getCode();
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysMenu> queryWrapperByName = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapperByName.eq(SysMenu::getName, name)
|
||||||
|
.eq(SysMenu::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysMenu> queryWrapperByCode = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapperByCode.eq(SysMenu::getCode, code)
|
||||||
|
.eq(SysMenu::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
if (isExcludeSelf) {
|
||||||
|
queryWrapperByName.ne(SysMenu::getId, id);
|
||||||
|
queryWrapperByCode.ne(SysMenu::getId, id);
|
||||||
|
}
|
||||||
|
int countByName = this.count(queryWrapperByName);
|
||||||
|
int countByCode = this.count(queryWrapperByCode);
|
||||||
|
|
||||||
|
if (countByName >= 1) {
|
||||||
|
throw new CustomException("菜单名称重复,请检查name参数");
|
||||||
|
}
|
||||||
|
if (countByCode >= 1) {
|
||||||
|
throw new CustomException("菜单编码重复,请检查code参数");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 创建pids的值
|
||||||
|
* <p>
|
||||||
|
* 如果pid是0顶级节点,pids就是 [0],
|
||||||
|
* <p>
|
||||||
|
* 如果pid不是顶级节点,pids就是 pid菜单的pids + [pid] + ,
|
||||||
|
*/
|
||||||
|
private String createNewPids(Long pid) {
|
||||||
|
if (pid.equals(0L)) {
|
||||||
|
return "[" + 0 + "]"
|
||||||
|
+ ",";
|
||||||
|
} else {
|
||||||
|
//获取父菜单
|
||||||
|
SysMenu parentMenu = this.getById(pid);
|
||||||
|
return parentMenu.getPids()
|
||||||
|
+ "[" + pid + "]"
|
||||||
|
+ ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据菜单ID删除菜单
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
public boolean del(Long id, String deleteReason){
|
||||||
|
log.info("SysMenuService - del - id:{}", id);
|
||||||
|
|
||||||
|
//级联删除子节点
|
||||||
|
List<Long> childIdList = this.getChildIdListById(id);
|
||||||
|
childIdList.add(id);
|
||||||
|
LambdaUpdateWrapper<SysMenu> updateWrapper = new LambdaUpdateWrapper<>();
|
||||||
|
updateWrapper.in(SysMenu::getId, childIdList)
|
||||||
|
.set(SysMenu::getIsDelete, YesOrNoState.YES.getState())
|
||||||
|
.set(SysMenu::getDeleteBy, SecurityUtil.getUserId())
|
||||||
|
.set(SysMenu::getDeleteTime, new Date())
|
||||||
|
.set(SysMenu::getDeleteReason, deleteReason);
|
||||||
|
boolean flag = this.update(updateWrapper);
|
||||||
|
|
||||||
|
// 删除角色菜单引用
|
||||||
|
sysRoleMenuService.deleteRoleMenuListByMenuIdList(childIdList);
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据节点id获取所有子节点id集合
|
||||||
|
*/
|
||||||
|
private List<Long> getChildIdListById(Long id) {
|
||||||
|
List<Long> childIdList = CollectionUtil.newArrayList();
|
||||||
|
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.like(SysMenu::getPids, "[" + id + "]");
|
||||||
|
this.list(queryWrapper).forEach(sysMenu -> childIdList.add(sysMenu.getId()));
|
||||||
|
return childIdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询菜单列表
|
||||||
|
* @param sysMenu
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysMenu> queryList(SysMenu sysMenu) {
|
||||||
|
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysMenu::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
//根据菜单名称模糊查询
|
||||||
|
if (StringUtils.isNotEmpty(sysMenu.getName())) {
|
||||||
|
queryWrapper.like(SysMenu::getName, sysMenu.getName());
|
||||||
|
}
|
||||||
|
//根据排序升序排列,序号越小越在前
|
||||||
|
queryWrapper.orderByAsc(SysMenu::getIntCode);
|
||||||
|
List<SysMenu> sysMenuList = this.list(queryWrapper);
|
||||||
|
return sysMenuList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SysMenu> findAll(){
|
||||||
|
log.info("SysMenuService - findAll userid:{}", SecurityUtil.getUserId());
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysMenu::getIsDelete, YesOrNoState.NO.getState()).orderByAsc(SysMenu::getIntCode);
|
||||||
|
|
||||||
|
return this.list(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查出并组装树形结构
|
||||||
|
* @param list 所有节点菜单
|
||||||
|
* @param pid 父级id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysMenu> buildMenuTree(List<SysMenu> list, Long pid){
|
||||||
|
//组装数据
|
||||||
|
List<SysMenu> collect = list.stream().filter(sysMenu -> {
|
||||||
|
return pid.equals(sysMenu.getPid());
|
||||||
|
}).map(sysMenu -> {
|
||||||
|
sysMenu.setChildren(getChildren(sysMenu, list));
|
||||||
|
return sysMenu;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
return collect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在所有列表中查询当前项的子项
|
||||||
|
* @param o 当前节点
|
||||||
|
* @param all 所有数据
|
||||||
|
*/
|
||||||
|
private List<SysMenu> getChildren(SysMenu o, List<SysMenu> all){
|
||||||
|
List<SysMenu> children = all.stream().filter((sysMenu) -> {
|
||||||
|
return o.getId().equals(sysMenu.getPid());
|
||||||
|
}).map(sysMenu -> {
|
||||||
|
sysMenu.setChildren(getChildren(sysMenu, all));
|
||||||
|
return sysMenu;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取系统菜单树,用于新增,编辑时选择上级节点
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysMenu> tree() {
|
||||||
|
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysMenu::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
List<SysMenu> allMenu = list(queryWrapper);
|
||||||
|
allMenu = this.buildMenuTree(allMenu, 0L);
|
||||||
|
return allMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取系统菜单树,用于给角色授权时选择
|
||||||
|
*/
|
||||||
|
public List<SysMenu> treeForGrant() {
|
||||||
|
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysMenu::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
//如果是超级管理员给角色授权菜单时可选择所有菜单
|
||||||
|
if (SecurityUtil.getLoginUser().ifAdmin()) {
|
||||||
|
// 不加任何判断条件
|
||||||
|
} else {
|
||||||
|
//非超级管理员则获取自己拥有的菜单,分配给人员,防止越级授权
|
||||||
|
Long userId = SecurityUtil.getUserId();
|
||||||
|
List<Long> roleIdList = sysUserRoleService.getUserRoleIdList(userId);
|
||||||
|
if (ObjectUtil.isNotEmpty(roleIdList)) {
|
||||||
|
List<Long> menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList);
|
||||||
|
if (ObjectUtil.isNotEmpty(menuIdList)) {
|
||||||
|
queryWrapper.in(SysMenu::getId, menuIdList);
|
||||||
|
} else {
|
||||||
|
//如果角色的菜单为空,则查不到菜单
|
||||||
|
return CollectionUtil.newArrayList();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//如果角色为空,则根本没菜单
|
||||||
|
return CollectionUtil.newArrayList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queryWrapper.orderByAsc(SysMenu::getIntCode);
|
||||||
|
List<SysMenu> allMenu = list(queryWrapper);
|
||||||
|
allMenu = this.buildMenuTree(allMenu, 0L);
|
||||||
|
return allMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将SysMenu格式菜单转换为LoginMenuTreeNode菜单
|
||||||
|
*/
|
||||||
|
public List<LoginMenuTreeNode> convertSysMenuToLoginMenu(List<SysMenu> sysMenuList) {
|
||||||
|
List<LoginMenuTreeNode> antDesignMenuTreeNodeList = CollectionUtil.newArrayList();
|
||||||
|
sysMenuList.forEach(sysMenu -> {
|
||||||
|
if(sysMenu.getType() != MenuTypeEnum.BTN.getCode()) {
|
||||||
|
LoginMenuTreeNode loginMenuTreeNode = new LoginMenuTreeNode();
|
||||||
|
loginMenuTreeNode.setComponent(sysMenu.getComponent());
|
||||||
|
loginMenuTreeNode.setId(sysMenu.getId());
|
||||||
|
loginMenuTreeNode.setName(sysMenu.getCode());
|
||||||
|
loginMenuTreeNode.setPath(sysMenu.getRouter());
|
||||||
|
loginMenuTreeNode.setPid(sysMenu.getPid());
|
||||||
|
LoginMenuTreeNode.Meta mateItem = new LoginMenuTreeNode().new Meta();
|
||||||
|
mateItem.setTitle(sysMenu.getName());
|
||||||
|
//是否可见
|
||||||
|
mateItem.setShow(YesOrNoState.YES.getState() == sysMenu.getVisible());
|
||||||
|
loginMenuTreeNode.setMeta(mateItem);
|
||||||
|
antDesignMenuTreeNodeList.add(loginMenuTreeNode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return antDesignMenuTreeNodeList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.org.system.entity.SysOperLog;
|
||||||
|
import com.org.system.mapper.SysOperLogMapper;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SysOperLogService extends ServiceImpl<SysOperLogMapper, SysOperLog> {
|
||||||
|
public List<SysOperLog> queryList(SysOperLog sysOperLog) {
|
||||||
|
log.info("SysOperLogService - queryList sysOperLog:{}", sysOperLog);
|
||||||
|
LambdaQueryWrapper<SysOperLog> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
if(StringUtils.isNotEmpty(sysOperLog.getTitle())) queryWrapper.like(SysOperLog::getTitle, sysOperLog.getTitle());
|
||||||
|
|
||||||
|
return list(queryWrapper);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.org.system.entity.SysMenu;
|
||||||
|
import com.org.system.entity.SysRoleMenu;
|
||||||
|
import com.org.system.mapper.SysRoleMenuMapper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SysRoleMenuService extends ServiceImpl<SysRoleMenuMapper, SysRoleMenu> {
|
||||||
|
|
||||||
|
public List<Long> getRoleMenuIdList(List<Long> roleIdList) {
|
||||||
|
if(ObjectUtil.isNotEmpty(roleIdList)) {
|
||||||
|
LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.in(SysRoleMenu::getRoleId, roleIdList);
|
||||||
|
return this.list(queryWrapper).stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
return CollectionUtil.newArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void grantMenu(Long roleId, List<Long> grantMenuIdList) {
|
||||||
|
//删除所拥有菜单
|
||||||
|
LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysRoleMenu::getRoleId, roleId);
|
||||||
|
this.remove(queryWrapper);
|
||||||
|
//授权菜单
|
||||||
|
grantMenuIdList.forEach(menuId -> {
|
||||||
|
SysRoleMenu sysRoleMenu = new SysRoleMenu();
|
||||||
|
sysRoleMenu.setRoleId(roleId);
|
||||||
|
sysRoleMenu.setMenuId(menuId);
|
||||||
|
this.save(sysRoleMenu);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteRoleMenuListByMenuIdList(List<Long> menuIdList) {
|
||||||
|
LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.in(SysRoleMenu::getMenuId, menuIdList);
|
||||||
|
this.remove(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteRoleMenuListByRoleId(Long roleId) {
|
||||||
|
LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysRoleMenu::getRoleId, roleId);
|
||||||
|
this.remove(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据角色ID获取菜单
|
||||||
|
* @param roleId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysMenu> findMenuListByRoleId(Long roleId) {
|
||||||
|
return baseMapper.findMenuListByRoleId(roleId);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,178 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.org.system.entity.SysRole;
|
||||||
|
import com.org.system.enums.YesOrNoState;
|
||||||
|
import com.org.system.mapper.SysRoleMapper;
|
||||||
|
import com.org.utils.SecurityUtil;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SysRoleService extends ServiceImpl<SysRoleMapper, SysRole> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysRoleMenuService sysRoleMenuService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysUserRoleService sysUserRoleService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增或修改
|
||||||
|
*
|
||||||
|
* @param sysRole
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean saveOrUpdate(SysRole sysRole){
|
||||||
|
log.info("SysRoleService - saveOrUpdate sysRole:{}", sysRole);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(sysRole.getId())){
|
||||||
|
//校验参数,检查是否存在相同的名称和编码
|
||||||
|
checkParam(sysRole, false);
|
||||||
|
// 新增
|
||||||
|
sysRole.setParentId(sysRole.getParentId() == null ? -1 : sysRole.getParentId());
|
||||||
|
sysRole.setCreateBy(SecurityUtil.getUserId());
|
||||||
|
sysRole.setCreateTime(new Date());
|
||||||
|
sysRole.setIsDelete(YesOrNoState.NO.getState());
|
||||||
|
log.info("SysRoleService - saveOrUpdate save sysRole:{}", sysRole);
|
||||||
|
|
||||||
|
return save(sysRole);
|
||||||
|
} else {
|
||||||
|
//校验参数,检查是否存在相同的名称和编码
|
||||||
|
checkParam(sysRole, true);
|
||||||
|
// 修改
|
||||||
|
SysRole sysRoleOld = querySysRole(sysRole.getId());
|
||||||
|
|
||||||
|
sysRoleOld.setName(sysRole.getName());
|
||||||
|
sysRoleOld.setCode(sysRole.getCode());
|
||||||
|
sysRoleOld.setSort(sysRole.getSort());
|
||||||
|
|
||||||
|
sysRoleOld.setOrgCode(sysRole.getOrgCode());
|
||||||
|
sysRoleOld.setParentId(sysRole.getParentId());
|
||||||
|
sysRoleOld.setUpdateBy(SecurityUtil.getUserId());
|
||||||
|
sysRoleOld.setUpdateTime(new Date());
|
||||||
|
log.info("SysRoleService - saveOrUpdate update sysRole:{}", sysRoleOld);
|
||||||
|
|
||||||
|
return updateById(sysRoleOld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验参数,检查是否存在相同的名称
|
||||||
|
*/
|
||||||
|
private void checkParam(SysRole sysRole, boolean isExcludeSelf) {
|
||||||
|
Long id = sysRole.getId();
|
||||||
|
String name = sysRole.getName();
|
||||||
|
String code = sysRole.getCode();
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysRole> queryWrapperByName = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapperByName.eq(SysRole::getName, name)
|
||||||
|
.eq(SysRole::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysRole> queryWrapperByCode = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapperByCode.eq(SysRole::getCode, code)
|
||||||
|
.eq(SysRole::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
//是否排除自己,如果排除自己则不查询自己的id
|
||||||
|
if (isExcludeSelf) {
|
||||||
|
queryWrapperByName.ne(SysRole::getId, id);
|
||||||
|
queryWrapperByCode.ne(SysRole::getId, id);
|
||||||
|
}
|
||||||
|
int countByName = this.count(queryWrapperByName);
|
||||||
|
int countByCode = this.count(queryWrapperByCode);
|
||||||
|
|
||||||
|
if (countByName >= 1) {
|
||||||
|
throw new CustomException("角色名称重复,请检查name参数");
|
||||||
|
}
|
||||||
|
if (countByCode >= 1) {
|
||||||
|
throw new CustomException("角色编码重复,请检查code参数");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取系统角色
|
||||||
|
*/
|
||||||
|
private SysRole querySysRole(Long id) {
|
||||||
|
SysRole sysRole = this.getById(id);
|
||||||
|
if (ObjectUtil.isNull(sysRole)) {
|
||||||
|
throw new CustomException("角色不存在");
|
||||||
|
}
|
||||||
|
return sysRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
public boolean del(Long id){
|
||||||
|
SysRole sysRole = querySysRole(id);
|
||||||
|
|
||||||
|
// 删除角色菜单引用
|
||||||
|
sysRoleMenuService.deleteRoleMenuListByRoleId(sysRole.getId());
|
||||||
|
// 删除用户角色引用
|
||||||
|
sysUserRoleService.delByRoleId(sysRole.getId());
|
||||||
|
|
||||||
|
sysRole.setIsDelete(YesOrNoState.YES.getState());
|
||||||
|
sysRole.setDeleteBy(SecurityUtil.getUserId());
|
||||||
|
sysRole.setDeleteTime(new Date());
|
||||||
|
|
||||||
|
return updateById(sysRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询角色
|
||||||
|
*
|
||||||
|
* @param sysRole
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysRole> findList(SysRole sysRole){
|
||||||
|
log.info("SysRoleService - findList - sysRole:{}", sysRole);
|
||||||
|
|
||||||
|
if(sysRole.getParentId() == null) sysRole.setParentId(-1L);
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysRole::getParentId, sysRole.getParentId())
|
||||||
|
.eq(SysRole::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
if(StringUtils.isNotEmpty(sysRole.getName())) queryWrapper.like(SysRole::getName, sysRole.getName());
|
||||||
|
if(StringUtils.isNotNull(sysRole.getOrgCode())) queryWrapper.eq(SysRole::getOrgCode, sysRole.getOrgCode());
|
||||||
|
|
||||||
|
return list(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有角色信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysRole> findAll(){
|
||||||
|
log.info("SysRoleService - findAll - userId:{}", SecurityUtil.getUserId());
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysRole::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
return list(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Long> ownMenu(Long id) {
|
||||||
|
SysRole sysRole = querySysRole(id);
|
||||||
|
return sysRoleMenuService.getRoleMenuIdList(CollectionUtil.newArrayList(sysRole.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void grantMenu(Long id, List<Long> grantMenuIdList) {
|
||||||
|
this.querySysRole(id);
|
||||||
|
sysRoleMenuService.grantMenu(id, grantMenuIdList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.org.system.entity.SysRole;
|
||||||
|
import com.org.system.entity.SysUser;
|
||||||
|
import com.org.system.entity.SysUserRole;
|
||||||
|
import com.org.system.mapper.SysUserRoleMapper;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SysUserRoleService extends ServiceImpl<SysUserRoleMapper, SysUserRole> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新能用户角色
|
||||||
|
*
|
||||||
|
* @param userId
|
||||||
|
* @param roleIdList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
public boolean save(Long userId, List<Long> roleIdList){
|
||||||
|
log.info("SysUserRoleService - save userId:{}", userId);
|
||||||
|
log.info("SysUserRoleService - save roleIdList:{}", roleIdList);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(userId)) throw new CustomException("用户ID不能为空");
|
||||||
|
if(StringUtils.isNull(roleIdList) || roleIdList.size() == 0) throw new CustomException("角色ID不能为空");
|
||||||
|
|
||||||
|
List<SysUserRole> sysUserRoleList = new ArrayList<>();
|
||||||
|
for (Long roleId : roleIdList) {
|
||||||
|
if(StringUtils.isNull(roleId)) continue;
|
||||||
|
|
||||||
|
sysUserRoleList.add(new SysUserRole().setUserId(userId).setRoleId(roleId));
|
||||||
|
}
|
||||||
|
|
||||||
|
return saveBatch(sysUserRoleList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID删除
|
||||||
|
*
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean delByUserId(Long userId){
|
||||||
|
log.info("SysUserRoleService - delByUserId userId:{}", userId);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(userId)) throw new CustomException("用户ID不能为空");
|
||||||
|
|
||||||
|
return baseMapper.delByUserId(userId) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据角色ID删除
|
||||||
|
*
|
||||||
|
* @param roleId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean delByRoleId(Long roleId){
|
||||||
|
log.info("SysUserRoleService - delByRoleId roleId:{}", roleId);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(roleId)) throw new CustomException("角色ID不能为空");
|
||||||
|
|
||||||
|
return baseMapper.delByRoleId(roleId) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID和角色ID删除
|
||||||
|
*
|
||||||
|
* @param userId
|
||||||
|
* @param roleIdList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
public boolean delByUserIdAndRoleId(Long userId, List<Long> roleIdList){
|
||||||
|
log.info("SysUserRoleService - delByUserIdAndRoleId userId:{}", userId);
|
||||||
|
log.info("SysUserRoleService - delByUserIdAndRoleId roleIdList:{}", roleIdList);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(userId)) throw new CustomException("用户ID不能为空");
|
||||||
|
if(StringUtils.isNull(roleIdList) || roleIdList.size() == 0) throw new CustomException("角色ID不能为空");
|
||||||
|
|
||||||
|
for (Long roleId : roleIdList) {
|
||||||
|
baseMapper.delByUserIdAndRoleId(userId, roleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据角色ID获取用户
|
||||||
|
*
|
||||||
|
* @param roleId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysUser> findUserListByRoleId(Long roleId){
|
||||||
|
log.info("SysUserRoleService - findUserListByRoleId roleId:{}", roleId);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(roleId)) return new ArrayList<>();
|
||||||
|
|
||||||
|
return baseMapper.findUserListByRoleId(roleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID获取角色
|
||||||
|
*
|
||||||
|
* @param userid
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysRole> findRoleListByUserId(Long userid){
|
||||||
|
log.info("SysUserRoleService - findRoleListByUserId roleId:{}", userid);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(userid)) return new ArrayList<>();
|
||||||
|
|
||||||
|
return baseMapper.findRoleListByUserId(userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2021-08-28 新增方法*/
|
||||||
|
|
||||||
|
public List<Long> getUserRoleIdList(Long userId) {
|
||||||
|
LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysUserRole::getUserId, userId);
|
||||||
|
|
||||||
|
return this.list(queryWrapper).stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void grantRole(Long userId, List<Long> grantRoleIdList) {
|
||||||
|
//删除所拥有角色
|
||||||
|
LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysUserRole::getUserId, userId);
|
||||||
|
this.remove(queryWrapper);
|
||||||
|
//授权角色
|
||||||
|
grantRoleIdList.forEach(roleId -> {
|
||||||
|
SysUserRole sysUserRole = new SysUserRole();
|
||||||
|
sysUserRole.setUserId(userId);
|
||||||
|
sysUserRole.setRoleId(roleId);
|
||||||
|
this.save(sysUserRole);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public SysUserRole getByUserIdAndRoleCode(Long userId, String roleCode) {
|
||||||
|
LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysUserRole::getUserId, userId);
|
||||||
|
queryWrapper.inSql(SysUserRole::getRoleId, "select id from sys_role where is_delete = 0 and code = '" + roleCode + "'");
|
||||||
|
queryWrapper.last("limit 1");
|
||||||
|
return this.getOne(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,234 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.crypto.digest.DigestUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.org.system.config.security.Md5PasswordEncoder;
|
||||||
|
import com.org.system.entity.SysUser;
|
||||||
|
import com.org.system.enums.YesOrNoState;
|
||||||
|
import com.org.system.mapper.SysUserMapper;
|
||||||
|
import com.org.utils.SecurityUtil;
|
||||||
|
import com.org.utils.SpringUtil;
|
||||||
|
import com.org.utils.StringUtils;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SysUserService extends ServiceImpl<SysUserMapper, SysUser> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysUserRoleService sysUserRoleService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增或修改系统用户
|
||||||
|
*
|
||||||
|
* @param sysUser
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean saveOrUpdate(SysUser sysUser){
|
||||||
|
log.info("SysUserService - saveOrUpdate sysUser:{}", sysUser);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(sysUser.getId())){
|
||||||
|
// 新增
|
||||||
|
checkParam(sysUser, false);
|
||||||
|
|
||||||
|
sysUser.setSalt(DigestUtil.md5Hex(sysUser.getUserName()));
|
||||||
|
|
||||||
|
Md5PasswordEncoder md5PasswordEncoder = Md5PasswordEncoder.getInstance();
|
||||||
|
md5PasswordEncoder.setSalt(sysUser.getSalt());
|
||||||
|
sysUser.setPassword(md5PasswordEncoder.encode(sysUser.getPassword()));
|
||||||
|
|
||||||
|
sysUser.setStatus(1);
|
||||||
|
sysUser.setCreateBy(SecurityUtil.getUserId());
|
||||||
|
sysUser.setCreateTime(new Date());
|
||||||
|
sysUser.setIsDelete(YesOrNoState.NO.getState());
|
||||||
|
log.info("SysUserService - saveOrUpdate save sysUser:{}", sysUser);
|
||||||
|
|
||||||
|
return save(sysUser);
|
||||||
|
} else {
|
||||||
|
// 修改
|
||||||
|
checkParam(sysUser, true);
|
||||||
|
|
||||||
|
SysUser sysUserOld = getById(sysUser.getId());
|
||||||
|
if(StringUtils.isNull(sysUserOld) || StringUtils.isNull(sysUserOld.getId()))
|
||||||
|
throw new CustomException("未找到要修改的用户");
|
||||||
|
|
||||||
|
// 禁止修改的内容
|
||||||
|
sysUser.setSalt(null);
|
||||||
|
sysUser.setPassword(null);
|
||||||
|
sysUser.setWxOpenId(null);
|
||||||
|
|
||||||
|
sysUser.setUpdateBy(SecurityUtil.getUserId());
|
||||||
|
sysUser.setUpdateTime(new Date());
|
||||||
|
log.info("SysUserService - saveOrUpdate update sysUser:{}", sysUser);
|
||||||
|
|
||||||
|
return updateById(sysUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验参数,检查是否存在相同的账号
|
||||||
|
*/
|
||||||
|
private void checkParam(SysUser sysUser, boolean isExcludeSelf) {
|
||||||
|
Long id = sysUser.getId();
|
||||||
|
String userName = sysUser.getUserName();
|
||||||
|
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysUser::getUserName, userName)
|
||||||
|
.eq(SysUser::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
//是否排除自己,如果是则查询条件排除自己id
|
||||||
|
if (isExcludeSelf) {
|
||||||
|
queryWrapper.ne(SysUser::getId, id);
|
||||||
|
}
|
||||||
|
int countByAccount = this.count(queryWrapper);
|
||||||
|
//大于等于1个则表示重复
|
||||||
|
if (countByAccount >= 1) {
|
||||||
|
throw new CustomException("用户名:" + sysUser.getUserName() + "已存在");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID删除用户
|
||||||
|
*
|
||||||
|
* @param idList
|
||||||
|
* @param deleteReason
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean del(List<Long> idList, String deleteReason){
|
||||||
|
log.info("SysUserService - del idList:{}", idList);
|
||||||
|
log.info("SysUserService - del deleteReason:{}", deleteReason);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(idList) || idList.size() == 0) return true;
|
||||||
|
|
||||||
|
List<SysUser> sysUserList = new ArrayList<>();
|
||||||
|
for (Long id : idList) {
|
||||||
|
SysUser sysUser = getById(id);
|
||||||
|
|
||||||
|
if(StringUtils.isNull(sysUser) || StringUtils.isNull(sysUser.getId())) continue;
|
||||||
|
|
||||||
|
// 删除用户角色引用
|
||||||
|
SpringUtil.getBean(SysUserRoleService.class).delByUserId(sysUser.getId());
|
||||||
|
|
||||||
|
sysUser.setIsDelete(YesOrNoState.YES.getState());
|
||||||
|
sysUser.setDeleteBy(SecurityUtil.getUserId());
|
||||||
|
sysUser.setDeleteTime(new Date());
|
||||||
|
sysUser.setDeleteReason(deleteReason);
|
||||||
|
log.info("SysUserService - del sysUser:{}", sysUser);
|
||||||
|
|
||||||
|
sysUserList.add(sysUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateBatchById(sysUserList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统用户查询
|
||||||
|
*
|
||||||
|
* @param sysUser
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<SysUser> findList(SysUser sysUser){
|
||||||
|
log.info("SysUserService - findList sysUser:{}", sysUser);
|
||||||
|
|
||||||
|
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(SysUser::getIsDelete, YesOrNoState.NO.getState());
|
||||||
|
|
||||||
|
if(StringUtils.isNotEmpty(sysUser.getName())) queryWrapper.like(SysUser::getName, sysUser.getName());
|
||||||
|
if(StringUtils.isNotEmpty(sysUser.getUserName())) queryWrapper.like(SysUser::getUserName, sysUser.getUserName());
|
||||||
|
if(StringUtils.isNotEmpty(sysUser.getPhone())) queryWrapper.like(SysUser::getPhone, sysUser.getPhone());
|
||||||
|
|
||||||
|
return list(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据登录名查询系统用户
|
||||||
|
*
|
||||||
|
* @param userName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SysUser findByUserName(String userName){
|
||||||
|
log.info("SysUserService - findByUserName userName:{}", userName);
|
||||||
|
return baseMapper.findByUserName(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据登录名或电话查询系统用户
|
||||||
|
*
|
||||||
|
* @param userName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SysUser findByUserNameOrPhone(String userName) {
|
||||||
|
log.info("SysUserService - findByUserNameOrPhone userName:{}", userName);
|
||||||
|
return baseMapper.findByUserNameOrPhone(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取系统用户
|
||||||
|
*/
|
||||||
|
private SysUser querySysUser(Long id) {
|
||||||
|
SysUser sysUser = this.getById(id);
|
||||||
|
if (ObjectUtil.isNull(sysUser)) {
|
||||||
|
throw new CustomException("用户不存在");
|
||||||
|
}
|
||||||
|
return sysUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Long> ownRole(Long id) {
|
||||||
|
SysUser sysUser = this.querySysUser(id);
|
||||||
|
return sysUserRoleService.getUserRoleIdList(sysUser.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void grantRole(Long id, List<Long> grantRoleIdList) {
|
||||||
|
this.querySysUser(id);
|
||||||
|
sysUserRoleService.grantRole(id, grantRoleIdList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置密码
|
||||||
|
@Transactional
|
||||||
|
public boolean resetPwd(Long id) {
|
||||||
|
// 修改用户密码
|
||||||
|
SysUser sysUser = this.getById(id);
|
||||||
|
if (ObjectUtil.isNull(sysUser)) {
|
||||||
|
throw new CustomException("未查询到用户信息");
|
||||||
|
}
|
||||||
|
sysUser.setSalt(DigestUtil.md5Hex(sysUser.getUserName()));
|
||||||
|
|
||||||
|
Md5PasswordEncoder md5PasswordEncoder = Md5PasswordEncoder.getInstance();
|
||||||
|
md5PasswordEncoder.setSalt(sysUser.getSalt());
|
||||||
|
sysUser.setPassword(md5PasswordEncoder.encode(SysUser.DEFAULT_PASSWORD));
|
||||||
|
return updateById(sysUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改密码
|
||||||
|
@Transactional
|
||||||
|
public boolean changePwd(String oldPassword, String password) {
|
||||||
|
// 修改用户密码
|
||||||
|
SysUser sysUser = this.getById(SecurityUtil.getUserId());
|
||||||
|
if (ObjectUtil.isNull(sysUser)) {
|
||||||
|
throw new CustomException("未查询到用户信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
Md5PasswordEncoder.getInstance().setSalt(sysUser.getSalt());
|
||||||
|
if(!Md5PasswordEncoder.getInstance().matches(oldPassword, sysUser.getPassword())){
|
||||||
|
throw new CustomException("原密码不正确!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Md5PasswordEncoder md5PasswordEncoder = Md5PasswordEncoder.getInstance();
|
||||||
|
md5PasswordEncoder.setSalt(sysUser.getSalt());
|
||||||
|
sysUser.setPassword(md5PasswordEncoder.encode(password));
|
||||||
|
|
||||||
|
sysUser.setUpdateBy(sysUser.getId());
|
||||||
|
sysUser.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
return updateById(sysUser);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
package com.org.system.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.hutool.extra.servlet.ServletUtil;
|
||||||
|
import cn.hutool.http.useragent.UserAgent;
|
||||||
|
import cn.hutool.http.useragent.UserAgentUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
|
import com.org.system.entity.LoginUser;
|
||||||
|
import com.org.system.config.redis.RedisCache;
|
||||||
|
import com.org.utils.Constants;
|
||||||
|
import com.org.utils.HttpServletUtil;
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/** token验证处理 **/
|
||||||
|
@Service
|
||||||
|
public class TokenService
|
||||||
|
{
|
||||||
|
// 令牌自定义标识
|
||||||
|
@Value("${token.header}")
|
||||||
|
private String header;
|
||||||
|
|
||||||
|
// 令牌秘钥
|
||||||
|
@Value("${token.secret}")
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
// 令牌有效期(默认30分钟)
|
||||||
|
@Value("${token.expireTime}")
|
||||||
|
private int expireTime;
|
||||||
|
|
||||||
|
protected static final long MILLIS_SECOND = 1000;
|
||||||
|
|
||||||
|
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
|
||||||
|
|
||||||
|
private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisCache redisCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户身份信息
|
||||||
|
*
|
||||||
|
* @return 用户信息
|
||||||
|
*/
|
||||||
|
public LoginUser getLoginUser(HttpServletRequest request) {
|
||||||
|
// 获取请求携带的令牌
|
||||||
|
String token = getToken(request);
|
||||||
|
if (StringUtils.isNotEmpty(token)) {
|
||||||
|
Claims claims = parseToken(token);
|
||||||
|
// 解析对应的权限以及用户信息
|
||||||
|
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
|
||||||
|
String userKey = getTokenKey(uuid);
|
||||||
|
LoginUser user = redisCache.getCacheObject(userKey);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置用户身份信息
|
||||||
|
*/
|
||||||
|
public void setLoginUser(LoginUser loginUser) {
|
||||||
|
if (null != loginUser && StringUtils.isNotEmpty(loginUser.getToken())) refreshToken(loginUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除用户身份信息
|
||||||
|
*/
|
||||||
|
public void delLoginUser(String token) {
|
||||||
|
if (StringUtils.isNotEmpty(token)) {
|
||||||
|
String userKey = getTokenKey(token);
|
||||||
|
redisCache.deleteObject(userKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建令牌
|
||||||
|
*
|
||||||
|
* @param loginUser 用户信息
|
||||||
|
* @return 令牌
|
||||||
|
*/
|
||||||
|
public String createToken(LoginUser loginUser) {
|
||||||
|
String token = IdUtil.fastUUID();
|
||||||
|
loginUser.setToken(token);
|
||||||
|
setUserAgent(loginUser);
|
||||||
|
refreshToken(loginUser);
|
||||||
|
|
||||||
|
Map<String, Object> claims = new HashMap<>();
|
||||||
|
claims.put(Constants.LOGIN_USER_KEY, token);
|
||||||
|
return createToken(claims);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证令牌有效期,相差不足20分钟,自动刷新缓存
|
||||||
|
*
|
||||||
|
* @param loginUser
|
||||||
|
* @return 令牌
|
||||||
|
*/
|
||||||
|
public void verifyToken(LoginUser loginUser) {
|
||||||
|
long expireTime = loginUser.getExpireTime();
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) refreshToken(loginUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新令牌有效期
|
||||||
|
*
|
||||||
|
* @param loginUser 登录信息
|
||||||
|
*/
|
||||||
|
public void refreshToken(LoginUser loginUser) {
|
||||||
|
loginUser.setLoginTime(System.currentTimeMillis());
|
||||||
|
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
|
||||||
|
// 根据uuid将loginUser缓存
|
||||||
|
String userKey = getTokenKey(loginUser.getToken());
|
||||||
|
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置用户代理信息
|
||||||
|
*
|
||||||
|
* @param loginUser 登录信息
|
||||||
|
*/
|
||||||
|
public void setUserAgent(LoginUser loginUser) {
|
||||||
|
UserAgent userAgent = UserAgentUtil.parse(HttpServletUtil.getRequest().getHeader("User-Agent"));
|
||||||
|
String ip = ServletUtil.getClientIP(HttpServletUtil.getRequest(), "");
|
||||||
|
loginUser.setIpaddr(ip);
|
||||||
|
loginUser.setLoginLocation("");
|
||||||
|
loginUser.setBrowser(userAgent.getBrowser().getName());
|
||||||
|
loginUser.setOs(userAgent.getOs().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从数据声明生成令牌
|
||||||
|
*
|
||||||
|
* @param claims 数据声明
|
||||||
|
* @return 令牌
|
||||||
|
*/
|
||||||
|
private String createToken(Map<String, Object> claims) {
|
||||||
|
String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从令牌中获取数据声明
|
||||||
|
*
|
||||||
|
* @param token 令牌
|
||||||
|
* @return 数据声明
|
||||||
|
*/
|
||||||
|
private Claims parseToken(String token) {
|
||||||
|
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从令牌中获取用户名
|
||||||
|
*
|
||||||
|
* @param token 令牌
|
||||||
|
* @return 用户名
|
||||||
|
*/
|
||||||
|
public String getUsernameFromToken(String token) {
|
||||||
|
Claims claims = parseToken(token);
|
||||||
|
return claims.getSubject();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取请求token
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return token
|
||||||
|
*/
|
||||||
|
private String getToken(HttpServletRequest request) {
|
||||||
|
String token = request.getHeader(header);
|
||||||
|
if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
|
||||||
|
token = token.replace(Constants.TOKEN_PREFIX, "");
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTokenKey(String uuid) {
|
||||||
|
return Constants.LOGIN_TOKEN_KEY + uuid;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.org.ueditor.controller;
|
||||||
|
|
||||||
|
import com.org.oss.service.SysOssService;
|
||||||
|
import com.org.system.annotation.Log;
|
||||||
|
import com.org.system.enums.BusinessType;
|
||||||
|
import com.org.ueditor.domain.UeditorConfig;
|
||||||
|
import com.org.ueditor.domain.UeditorConfigJson;
|
||||||
|
import com.org.utils.AjaxResult;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("sys/ueditor")
|
||||||
|
public class UeditorContorller {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysOssService sysOssService;
|
||||||
|
|
||||||
|
@Log(title = "富文本上传", businessType = BusinessType.INSERT)
|
||||||
|
@RequestMapping("/config")
|
||||||
|
public Object ueditorConfig(MultipartFile upfile, String action) throws IOException {
|
||||||
|
log.info("UeditorContorller - ueditorConfig action:{}", action);
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case "config":
|
||||||
|
log.info("UeditorContorller - ueditorConfig get config json");
|
||||||
|
return new UeditorConfigJson();
|
||||||
|
case "uploadimage":
|
||||||
|
log.info("UeditorContorller - ueditorConfig uploadimage");
|
||||||
|
|
||||||
|
AjaxResult upload = sysOssService.upload(upfile, "ueditor", "ueditor");
|
||||||
|
|
||||||
|
String url = upload.get("zoomUrl") != null ? upload.get("zoomUrl").toString() : upload.get("url").toString();
|
||||||
|
url = String.format("%s?width=1024", url);
|
||||||
|
return new UeditorConfig("SUCCESS", url, upfile.getSize(), upfile.getContentType(), upfile.getOriginalFilename(), upfile.getOriginalFilename());
|
||||||
|
}
|
||||||
|
return "请求失败";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.org.ueditor.domain;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UeditorConfig {
|
||||||
|
|
||||||
|
/* 状态 */
|
||||||
|
private String state;
|
||||||
|
|
||||||
|
/* 回显路径 */
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
/* 大小 */
|
||||||
|
private long size;
|
||||||
|
|
||||||
|
/* 类型 */
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/* 文件title */
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/* 名称 */
|
||||||
|
private String original;
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
package com.org.ueditor.domain;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UeditorConfigJson {
|
||||||
|
|
||||||
|
/* 上传图片配置项 */
|
||||||
|
/* 执行上传图片的action名称 */
|
||||||
|
private String imageActionName = "uploadimage";
|
||||||
|
/* 提交的图片表单名称 */
|
||||||
|
private String imageFieldName = "upfile";
|
||||||
|
/* 上传大小限制,单位B */
|
||||||
|
private long imageMaxSize = 2048000;
|
||||||
|
/* 上传图片格式显示 */
|
||||||
|
private String[] imageAllowFiles = new String[]{".png", ".jpg", ".jpeg", ".gif", ".bmp"};
|
||||||
|
/* 是否压缩图片;默认是true */
|
||||||
|
private boolean imageCompressEnable = true;
|
||||||
|
/* 图片压缩最长边限制 */
|
||||||
|
private long imageCompressBorder = 1600;
|
||||||
|
/* 插入的图片浮动方式 */
|
||||||
|
private String imageInsertAlign = "none";
|
||||||
|
/* 图片访问路径前缀 */
|
||||||
|
private String imageUrlPrefix = "";
|
||||||
|
/* 上传保存路径;可以自定义保存路径和文件名格式 */
|
||||||
|
/* {filename} 会替换成原文件名;配置这项需要注意中文乱码问题 */
|
||||||
|
/* {rand:6} 会替换成随机数;后面的数字是随机数的位数 */
|
||||||
|
/* {time} 会替换成时间戳 */
|
||||||
|
/* {yyyy} 会替换成四位年份 */
|
||||||
|
/* {yy} 会替换成两位年份 */
|
||||||
|
/* {mm} 会替换成两位月份 */
|
||||||
|
/* {dd} 会替换成两位日期 */
|
||||||
|
/* {hh} 会替换成两位小时 */
|
||||||
|
/* {ii} 会替换成两位分钟 */
|
||||||
|
/* {ss} 会替换成两位秒 */
|
||||||
|
/* 非法字符 \ : * ? " < > | */
|
||||||
|
/* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */
|
||||||
|
private String imagePathFormat = "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}";
|
||||||
|
|
||||||
|
|
||||||
|
/* 涂鸦图片上传配置项 */
|
||||||
|
/* 执行上传涂鸦的action名称 */
|
||||||
|
private String scrawlActionName = "uploadscrawl";
|
||||||
|
/* 提交的图片表单名称 */
|
||||||
|
private String scrawlFieldName = "upfile";
|
||||||
|
/* 上传保存路径;可以自定义保存路径和文件名格式 */
|
||||||
|
private String scrawlPathFormat = "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}";
|
||||||
|
/* 上传大小限制,单位B */
|
||||||
|
private long scrawlMaxSize = 2048000;
|
||||||
|
/* 图片访问路径前缀 */
|
||||||
|
private String scrawlUrlPrefix = "";
|
||||||
|
private String scrawlInsertAlign = "none";
|
||||||
|
|
||||||
|
/* 截图工具上传 */
|
||||||
|
/* 执行上传截图的action名称 */
|
||||||
|
private String snapscreenActionName = "uploadimage";
|
||||||
|
/* 上传保存路径;可以自定义保存路径和文件名格式 */
|
||||||
|
private String snapscreenPathFormat = "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}";
|
||||||
|
/* 图片访问路径前缀 */
|
||||||
|
private String snapscreenUrlPrefix = "";
|
||||||
|
/* 插入的图片浮动方式 */
|
||||||
|
private String snapscreenInsertAlign = "none";
|
||||||
|
|
||||||
|
/* 抓取远程图片配置 */
|
||||||
|
private String[] catcherLocalDomain = new String[]{"127.0.0.1", "localhost", "img.baidu.com"};
|
||||||
|
/* 执行抓取远程图片的action名称 */
|
||||||
|
private String catcherActionName = "catchimage";
|
||||||
|
/* 提交的图片列表表单名称 */
|
||||||
|
private String catcherFieldName = "source";
|
||||||
|
/* 上传保存路径;可以自定义保存路径和文件名格式 */
|
||||||
|
private String catcherPathFormat = "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}";
|
||||||
|
/* 图片访问路径前缀 */
|
||||||
|
private String catcherUrlPrefix = "";
|
||||||
|
/* 上传大小限制,单位B */
|
||||||
|
private long catcherMaxSize = 2048000;
|
||||||
|
/* 抓取图片格式显示 */
|
||||||
|
private String[] catcherAllowFiles = new String[]{".png", ".jpg", ".jpeg", ".gif", ".bmp"};
|
||||||
|
|
||||||
|
/* 上传视频配置 */
|
||||||
|
/* 执行上传视频的action名称 */
|
||||||
|
private String videoActionName = "uploadvideo";
|
||||||
|
/* 提交的视频表单名称 */
|
||||||
|
private String videoFieldName = "upfile";
|
||||||
|
/* 上传保存路径;可以自定义保存路径和文件名格式 */
|
||||||
|
private String videoPathFormat = "/ueditor/jsp/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}";
|
||||||
|
/* 视频访问路径前缀 */
|
||||||
|
private String videoUrlPrefix = "";
|
||||||
|
/* 上传大小限制,单位B,默认100MB */
|
||||||
|
private long videoMaxSize = 102400000;
|
||||||
|
/* 上传视频格式显示 */
|
||||||
|
private String[] videoAllowFiles = new String[]{".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
|
||||||
|
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"};
|
||||||
|
|
||||||
|
/* 上传文件配置 */
|
||||||
|
/* controller里;执行上传视频的action名称 */
|
||||||
|
private String fileActionName = "uploadfile";
|
||||||
|
/* 提交的文件表单名称 */
|
||||||
|
private String fileFieldName = "upfile";
|
||||||
|
/* 上传保存路径;可以自定义保存路径和文件名格式 */
|
||||||
|
private String filePathFormat = "/ueditor/jsp/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}";
|
||||||
|
/* 文件访问路径前缀 */
|
||||||
|
private String fileUrlPrefix = "";
|
||||||
|
/* 上传大小限制,单位B,默认50MB */
|
||||||
|
private long fileMaxSize = 51200000;
|
||||||
|
/* 上传文件格式显示 */
|
||||||
|
private String[] fileAllowFiles = new String[]{ ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".flv", ".swf", ".mkv",
|
||||||
|
".avi", ".rm", ".rmvb", ".mpeg", ".mpg", ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav",
|
||||||
|
".mid", ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso", ".doc", ".docx", ".xls", ".xlsx",
|
||||||
|
".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"};
|
||||||
|
|
||||||
|
/* 列出指定目录下的图片 */
|
||||||
|
/* 执行图片管理的action名称 */
|
||||||
|
private String imageManagerActionName = "listimage";
|
||||||
|
/* 指定要列出图片的目录 */
|
||||||
|
private String imageManagerListPath = "/ueditor/jsp/upload/image/";
|
||||||
|
/* 每次列出文件数量 */
|
||||||
|
private long imageManagerListSize = 20;
|
||||||
|
/* 图片访问路径前缀 */
|
||||||
|
private String imageManagerUrlPrefix = "";
|
||||||
|
/* 插入的图片浮动方式 */
|
||||||
|
private String imageManagerInsertAlign = "none";
|
||||||
|
/* 列出的文件类型 */
|
||||||
|
private String[] imageManagerAllowFiles = new String[]{".png", ".jpg", ".jpeg", ".gif", ".bmp"};
|
||||||
|
|
||||||
|
/* 列出指定目录下的文件 */
|
||||||
|
/* 执行文件管理的action名称 */
|
||||||
|
private String fileManagerActionName = "listfile";
|
||||||
|
/* 指定要列出文件的目录 */
|
||||||
|
private String fileManagerListPath = "/ueditor/jsp/upload/file/";
|
||||||
|
/* 文件访问路径前缀 */
|
||||||
|
private String fileManagerUrlPrefix = "";
|
||||||
|
/* 每次列出文件数量 */
|
||||||
|
private long fileManagerListSize = 20;
|
||||||
|
/* 列出的文件类型 */
|
||||||
|
private String[] fileManagerAllowFiles = new String[]{".png", ".jpg", ".jpeg", ".gif", ".bmp", ".flv", ".swf",
|
||||||
|
".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3",
|
||||||
|
".wav", ".mid", ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso", ".doc", ".docx", ".xls",
|
||||||
|
".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package com.org.utils;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/** 操作消息提醒 **/
|
||||||
|
public class AjaxResult extends HashMap<String, Object> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 状态码 */
|
||||||
|
public static final String CODE_TAG = "code";
|
||||||
|
|
||||||
|
/** 返回内容 */
|
||||||
|
public static final String MSG_TAG = "msg";
|
||||||
|
|
||||||
|
/** 数据对象 */
|
||||||
|
public static final String DATA_TAG = "data";
|
||||||
|
|
||||||
|
/** 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息 **/
|
||||||
|
public AjaxResult() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化一个新创建的 AjaxResult 对象
|
||||||
|
*
|
||||||
|
* @param code 状态码
|
||||||
|
* @param msg 返回内容
|
||||||
|
*/
|
||||||
|
public AjaxResult(int code, String msg){
|
||||||
|
super.put(CODE_TAG, code);
|
||||||
|
super.put(MSG_TAG, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化一个新创建的 AjaxResult 对象
|
||||||
|
*
|
||||||
|
* @param code 状态码
|
||||||
|
* @param msg 返回内容
|
||||||
|
* @param data 数据对象
|
||||||
|
*/
|
||||||
|
public AjaxResult(int code, String msg, Object data){
|
||||||
|
super.put(CODE_TAG, code);
|
||||||
|
super.put(MSG_TAG, msg);
|
||||||
|
if (data != null) super.put(DATA_TAG, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回成功消息
|
||||||
|
*
|
||||||
|
* @return 成功消息
|
||||||
|
*/
|
||||||
|
public static AjaxResult success() { return AjaxResult.success("操作成功"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回成功数据
|
||||||
|
*
|
||||||
|
* @return 成功消息
|
||||||
|
*/
|
||||||
|
public static AjaxResult success(Object data) { return AjaxResult.success("操作成功", data); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回成功消息
|
||||||
|
*
|
||||||
|
* @param msg 返回内容
|
||||||
|
* @return 成功消息
|
||||||
|
*/
|
||||||
|
public static AjaxResult success(String msg) { return AjaxResult.success(msg, null); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回成功消息
|
||||||
|
*
|
||||||
|
* @param msg 返回内容
|
||||||
|
* @param data 数据对象
|
||||||
|
* @return 成功消息
|
||||||
|
*/
|
||||||
|
public static AjaxResult success(String msg, Object data) { return new AjaxResult(HttpStatus.OK.value(), msg, data); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回错误消息
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static AjaxResult error()
|
||||||
|
{
|
||||||
|
return AjaxResult.error("操作失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回错误消息
|
||||||
|
*
|
||||||
|
* @param msg 返回内容
|
||||||
|
* @return 警告消息
|
||||||
|
*/
|
||||||
|
public static AjaxResult error(String msg) { return AjaxResult.error(msg, null); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回错误消息
|
||||||
|
*
|
||||||
|
* @param msg 返回内容
|
||||||
|
* @param data 数据对象
|
||||||
|
* @return 警告消息
|
||||||
|
*/
|
||||||
|
public static AjaxResult error(String msg, Object data) { return new AjaxResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg, data); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回错误消息
|
||||||
|
*
|
||||||
|
* @param code 状态码
|
||||||
|
* @param msg 返回内容
|
||||||
|
* @return 警告消息
|
||||||
|
*/
|
||||||
|
public static AjaxResult error(int code, String msg) { return new AjaxResult(code, msg, null); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AjaxResult put(String key, Object value) {
|
||||||
|
super.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
package com.org.utils;
|
||||||
|
|
||||||
|
/** 通用常量信息 **/
|
||||||
|
public class Constants
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* UTF-8 字符集
|
||||||
|
*/
|
||||||
|
public static final String UTF8 = "UTF-8";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GBK 字符集
|
||||||
|
*/
|
||||||
|
public static final String GBK = "GBK";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http请求
|
||||||
|
*/
|
||||||
|
public static final String HTTP = "http://";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https请求
|
||||||
|
*/
|
||||||
|
public static final String HTTPS = "https://";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用成功标识
|
||||||
|
*/
|
||||||
|
public static final String SUCCESS = "0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用失败标识
|
||||||
|
*/
|
||||||
|
public static final String FAIL = "1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录成功
|
||||||
|
*/
|
||||||
|
public static final String LOGIN_SUCCESS = "Success";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注销
|
||||||
|
*/
|
||||||
|
public static final String LOGOUT = "Logout";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录失败
|
||||||
|
*/
|
||||||
|
public static final String LOGIN_FAIL = "Error";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码 redis key
|
||||||
|
*/
|
||||||
|
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录用户 redis key
|
||||||
|
*/
|
||||||
|
public static final String LOGIN_TOKEN_KEY = "login_tokens:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 防重提交 redis key
|
||||||
|
*/
|
||||||
|
public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码有效期(分钟)
|
||||||
|
*/
|
||||||
|
public static final Integer CAPTCHA_EXPIRATION = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌
|
||||||
|
*/
|
||||||
|
public static final String TOKEN = "token";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌前缀
|
||||||
|
*/
|
||||||
|
public static final String TOKEN_PREFIX = "Bearer ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌前缀
|
||||||
|
*/
|
||||||
|
public static final String LOGIN_USER_KEY = "login_user_key";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID
|
||||||
|
*/
|
||||||
|
public static final String JWT_USERID = "userid";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户名称
|
||||||
|
*/
|
||||||
|
public static final String JWT_USERNAME = "sub";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户头像
|
||||||
|
*/
|
||||||
|
public static final String JWT_AVATAR = "avatar";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
public static final String JWT_CREATED = "created";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户权限
|
||||||
|
*/
|
||||||
|
public static final String JWT_AUTHORITIES = "authorities";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数管理 cache key
|
||||||
|
*/
|
||||||
|
public static final String SYS_CONFIG_KEY = "sys_config:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典管理 cache key
|
||||||
|
*/
|
||||||
|
public static final String SYS_DICT_KEY = "sys_dict:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源映射路径 前缀
|
||||||
|
*/
|
||||||
|
public static final String RESOURCE_PREFIX = "/profile";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* app版本管理 cache key
|
||||||
|
*/
|
||||||
|
public static final String SYS_APP_VERSION_KEY = "sys_app_version:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* app版本强制升级版本号 cache key
|
||||||
|
*/
|
||||||
|
public static final String SYS_APP_VERSION_FORCE_KEY = "sys_app_version_force:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* app版本强制升级版本号 cache key
|
||||||
|
*/
|
||||||
|
public static final String SYS_APP_VERSION_NOTICE_KEY = "sys_app_version_notice:";
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.org.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import org.springframework.web.context.request.RequestAttributes;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
public class HttpServletUtil {
|
||||||
|
|
||||||
|
public static ServletRequestAttributes getServletRequestAttributes(){
|
||||||
|
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||||
|
|
||||||
|
if(requestAttributes == null) throw new CustomException("获取 RequestAttributes 异常");
|
||||||
|
|
||||||
|
return (ServletRequestAttributes) requestAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 HttpServletRequest
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static HttpServletRequest getRequest(){
|
||||||
|
return getServletRequestAttributes().getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 HttpServletResponse
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static HttpServletResponse getResponse(){
|
||||||
|
return getServletRequestAttributes().getResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取String参数
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getParameter(String name) {
|
||||||
|
return getRequest().getParameter(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取String参数
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @param defaultValue
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getParameter(String name, String defaultValue) {
|
||||||
|
return Convert.toStr(getRequest().getParameter(name), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Integer参数
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Integer getParameterToInt(String name) {
|
||||||
|
return Convert.toInt(getRequest().getParameter(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Integer参数
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @param defaultValue
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Integer getParameterToInt(String name, Integer defaultValue) {
|
||||||
|
return Convert.toInt(getRequest().getParameter(name), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
package com.org.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.img.ImgUtil;
|
||||||
|
import cn.hutool.core.lang.Validator;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class ImagePicUtil {
|
||||||
|
// 缩放至的宽度
|
||||||
|
public static int zoomWidth = 1024;
|
||||||
|
// 缩略图的宽度
|
||||||
|
public static int thumbnailWidth = 400;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片缩放
|
||||||
|
* @param filePath
|
||||||
|
* @param width
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static MultipartFile getImagePic(String filePath, int width, String fileName){
|
||||||
|
log.info("ImagePicUtil - getImagePic filePath:{}", filePath);
|
||||||
|
log.info("ImagePicUtil - getImagePic width:{}", width);
|
||||||
|
log.info("ImagePicUtil - getImagePic fileName:{}", fileName);
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
Image image = ImageIO.read(new File(filePath));
|
||||||
|
|
||||||
|
int image_width = image.getWidth(null);
|
||||||
|
log.info("ImagePicUtil - getImagePic image_width:{}", image_width);
|
||||||
|
|
||||||
|
if(image_width <= width){
|
||||||
|
log.info("ImagePicUtil - getImagePic not scale");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
float scale = Float.parseFloat(String.valueOf(width)) / Float.parseFloat(String.valueOf(image_width));
|
||||||
|
log.info("ImagePicUtil - getImagePic scale:{}", scale);
|
||||||
|
|
||||||
|
// 等比缩放图片
|
||||||
|
Image scaleImage = ImgUtil.scale(image, scale);
|
||||||
|
|
||||||
|
// Image 转 BufferedImage
|
||||||
|
BufferedImage bufferedImage = new BufferedImage(scaleImage.getWidth(null), scaleImage.getHeight(null), BufferedImage.TYPE_3BYTE_BGR);
|
||||||
|
Graphics g = bufferedImage.getGraphics();
|
||||||
|
g.drawImage(scaleImage, 0, 0, null);
|
||||||
|
|
||||||
|
// 获取文件后缀
|
||||||
|
String suffix = filePath.substring(filePath.lastIndexOf(".")+1);
|
||||||
|
|
||||||
|
//将newImage写入字节数组输出流
|
||||||
|
ImageIO.write( bufferedImage, suffix, baos );
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("{}", e);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
baos.flush();
|
||||||
|
baos.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("PDFUtil - imgToPdf error {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MockMultipartFile mockMultipartFile = new MockMultipartFile(fileName, fileName, "image/jpeg", baos.toByteArray());
|
||||||
|
log.info("ImagePicUtil - getImagePic ok ...");
|
||||||
|
|
||||||
|
return mockMultipartFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过文件路径
|
||||||
|
* @param path
|
||||||
|
* @return true-支持 false-不支持
|
||||||
|
*/
|
||||||
|
public static boolean checkImageByPath(String path) {
|
||||||
|
log.info("ImagePicUtil - checkImageByPath path:{}", path);
|
||||||
|
// 文本课件没有封面
|
||||||
|
if (Validator.isEmpty(path)) return true;
|
||||||
|
|
||||||
|
// 获取文件后缀,并且转换小写
|
||||||
|
String suffix = path.substring(path.lastIndexOf(".")+1).toLowerCase();
|
||||||
|
log.info("ImagePicUtil - checkImageByPath suffix:{}", suffix);
|
||||||
|
|
||||||
|
String str = constMap1.get(suffix);
|
||||||
|
log.info("ImagePicUtil - checkImageByPath str:{}", str);
|
||||||
|
if (Validator.isNotEmpty(str)) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支持的图片
|
||||||
|
*/
|
||||||
|
private static final Map<String, String> constMap1 = new HashMap<String, String>() {
|
||||||
|
{
|
||||||
|
put("jpg", "jpg");
|
||||||
|
put("jpeg", "jpeg");
|
||||||
|
put("png", "png");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.org.utils;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
|
|
||||||
|
/** 获取i18n资源文件 **/
|
||||||
|
public class MessageUtil {
|
||||||
|
/**
|
||||||
|
* 根据消息键和参数 获取消息 委托给spring messageSource
|
||||||
|
*
|
||||||
|
* @param code 消息键
|
||||||
|
* @param args 参数
|
||||||
|
* @return 获取国际化翻译值
|
||||||
|
*/
|
||||||
|
public static String message(String code, Object... args) {
|
||||||
|
MessageSource messageSource = SpringUtil.getBean(MessageSource.class);
|
||||||
|
return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.org.utils;
|
||||||
|
|
||||||
|
import com.org.system.entity.LoginUser;
|
||||||
|
import com.org.utils.exception.CustomException;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
|
/** 安全服务工具类 **/
|
||||||
|
public class SecurityUtil {
|
||||||
|
|
||||||
|
/** 获取Authentication **/
|
||||||
|
public static Authentication getAuthentication() { return SecurityContextHolder.getContext().getAuthentication(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前是否登录
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isLogin(){
|
||||||
|
String principal = getAuthentication().getPrincipal().toString();
|
||||||
|
if("anonymousUser".equals(principal)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取用户 **/
|
||||||
|
public static LoginUser getLoginUser() {
|
||||||
|
try {
|
||||||
|
return (LoginUser) getAuthentication().getPrincipal();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CustomException("获取用户信息异常", HttpStatus.UNAUTHORIZED.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取用户ID **/
|
||||||
|
public static Long getUserId() {
|
||||||
|
try {
|
||||||
|
return getLoginUser().getUser().getId();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CustomException("获取用户账户异常", HttpStatus.UNAUTHORIZED.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取用户账户 **/
|
||||||
|
public static String getUsername() {
|
||||||
|
try {
|
||||||
|
return getLoginUser().getUsername();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CustomException("获取用户账户异常", HttpStatus.UNAUTHORIZED.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package com.org.utils;
|
||||||
|
|
||||||
|
import org.springframework.aop.framework.AopContext;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/** spring工具类 方便在非spring管理环境中获取bean **/
|
||||||
|
@Component
|
||||||
|
public final class SpringUtil implements BeanFactoryPostProcessor, ApplicationContextAware
|
||||||
|
{
|
||||||
|
/** Spring应用上下文环境 */
|
||||||
|
private static ConfigurableListableBeanFactory beanFactory;
|
||||||
|
|
||||||
|
private static ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { SpringUtil.beanFactory = beanFactory; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringUtil.applicationContext = applicationContext; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取对象
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return Object 一个以所给名字注册的bean的实例
|
||||||
|
* @throws BeansException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T getBean(String name) throws BeansException { return (T) beanFactory.getBean(name); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取类型为requiredType的对象
|
||||||
|
*
|
||||||
|
* @param clz
|
||||||
|
* @return
|
||||||
|
* @throws BeansException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static <T> T getBean(Class<T> clz) throws BeansException { return (T) beanFactory.getBean(clz); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static boolean containsBean(String name) { return beanFactory.containsBean(name); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return boolean
|
||||||
|
* @throws NoSuchBeanDefinitionException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { return beanFactory.isSingleton(name); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
* @return Class 注册对象的类型
|
||||||
|
* @throws NoSuchBeanDefinitionException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException { return beanFactory.getType(name); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
* @throws NoSuchBeanDefinitionException
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { return beanFactory.getAliases(name); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取aop代理对象
|
||||||
|
*
|
||||||
|
* @param invoker
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T getAopProxy(T invoker) { return (T) AopContext.currentProxy(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前的环境配置,无配置返回null
|
||||||
|
*
|
||||||
|
* @return 当前的环境配置
|
||||||
|
*/
|
||||||
|
public static String[] getActiveProfiles() { return applicationContext.getEnvironment().getActiveProfiles(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前的环境配置,当有多个环境配置时,只获取第一个
|
||||||
|
*
|
||||||
|
* @return 当前的环境配置
|
||||||
|
*/
|
||||||
|
public static String getActiveProfile() {
|
||||||
|
final String[] activeProfiles = getActiveProfiles();
|
||||||
|
|
||||||
|
if(activeProfiles == null || activeProfiles.length == 0) return null;
|
||||||
|
return activeProfiles[0];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.org.utils;
|
||||||
|
|
||||||
|
import com.org.utils.exception.BaseException;
|
||||||
|
|
||||||
|
/** sql操作工具类 **/
|
||||||
|
public class SqlUtil {
|
||||||
|
/** 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) **/
|
||||||
|
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查字符,防止注入绕过
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String escapeOrderBySql(String value) {
|
||||||
|
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
|
||||||
|
throw new BaseException("参数不符合规范,不能进行查询");
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证 order by 语法是否符合规范
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isValidOrderBySql(String value) {
|
||||||
|
return value.matches(SQL_PATTERN);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,370 @@
|
||||||
|
package com.org.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.StrFormatter;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/** 字符串工具类 **/
|
||||||
|
public class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||||
|
/** 空字符串 */
|
||||||
|
private static final String NULLSTR = "";
|
||||||
|
|
||||||
|
/** 下划线 */
|
||||||
|
private static final char SEPARATOR = '_';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取参数不为空值
|
||||||
|
*
|
||||||
|
* @param value defaultValue 要判断的value
|
||||||
|
* @return value 返回值
|
||||||
|
*/
|
||||||
|
public static <T> T nvl(T value, T defaultValue) {
|
||||||
|
return value != null ? value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个Collection是否为空, 包含List,Set,Queue
|
||||||
|
*
|
||||||
|
* @param coll 要判断的Collection
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Collection<?> coll) {
|
||||||
|
return isNull(coll) || coll.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个Collection是否非空,包含List,Set,Queue
|
||||||
|
*
|
||||||
|
* @param coll 要判断的Collection
|
||||||
|
* @return true:非空 false:空
|
||||||
|
*/
|
||||||
|
public static boolean isNotEmpty(Collection<?> coll) {
|
||||||
|
return !isEmpty(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象数组是否为空
|
||||||
|
*
|
||||||
|
* @param objects 要判断的对象数组
|
||||||
|
** @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Object[] objects) {
|
||||||
|
return isNull(objects) || (objects.length == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象数组是否非空
|
||||||
|
*
|
||||||
|
* @param objects 要判断的对象数组
|
||||||
|
* @return true:非空 false:空
|
||||||
|
*/
|
||||||
|
public static boolean isNotEmpty(Object[] objects) {
|
||||||
|
return !isEmpty(objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个Map是否为空
|
||||||
|
*
|
||||||
|
* @param map 要判断的Map
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Map<?, ?> map) {
|
||||||
|
return isNull(map) || map.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个Map是否为空
|
||||||
|
*
|
||||||
|
* @param map 要判断的Map
|
||||||
|
* @return true:非空 false:空
|
||||||
|
*/
|
||||||
|
public static boolean isNotEmpty(Map<?, ?> map) {
|
||||||
|
return !isEmpty(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个字符串是否为空串
|
||||||
|
*
|
||||||
|
* @param str String
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(String str) {
|
||||||
|
return isNull(str) || NULLSTR.equals(str.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个字符串是否为非空串
|
||||||
|
*
|
||||||
|
* @param str String
|
||||||
|
* @return true:非空串 false:空串
|
||||||
|
*/
|
||||||
|
public static boolean isNotEmpty(String str) {
|
||||||
|
return !isEmpty(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象是否为空
|
||||||
|
*
|
||||||
|
* @param object Object
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isNull(Object object) {
|
||||||
|
return object == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象是否非空
|
||||||
|
*
|
||||||
|
* @param object Object
|
||||||
|
* @return true:非空 false:空
|
||||||
|
*/
|
||||||
|
public static boolean isNotNull(Object object) {
|
||||||
|
return !isNull(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象是否是数组类型(Java基本型别的数组)
|
||||||
|
*
|
||||||
|
* @param object 对象
|
||||||
|
* @return true:是数组 false:不是数组
|
||||||
|
*/
|
||||||
|
public static boolean isArray(Object object) {
|
||||||
|
return isNotNull(object) && object.getClass().isArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 去空格
|
||||||
|
*/
|
||||||
|
public static String trim(String str) {
|
||||||
|
return (str == null ? "" : str.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 截取字符串
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
* @param start 开始
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String substring(final String str, int start) {
|
||||||
|
if (str == null) return NULLSTR;
|
||||||
|
|
||||||
|
if (start < 0) start = str.length() + start;
|
||||||
|
if (start < 0) start = 0;
|
||||||
|
|
||||||
|
if (start > str.length()) return NULLSTR;
|
||||||
|
|
||||||
|
return str.substring(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 截取字符串
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
* @param start 开始
|
||||||
|
* @param end 结束
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String substring(final String str, int start, int end) {
|
||||||
|
if (str == null) return NULLSTR;
|
||||||
|
|
||||||
|
if (end < 0) end = str.length() + end;
|
||||||
|
if (start < 0) start = str.length() + start;
|
||||||
|
|
||||||
|
if (end > str.length()) end = str.length();
|
||||||
|
if (start > end) return NULLSTR;
|
||||||
|
|
||||||
|
if (start < 0) start = 0;
|
||||||
|
if (end < 0) end = 0;
|
||||||
|
|
||||||
|
return str.substring(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化文本, {} 表示占位符<br>
|
||||||
|
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
|
||||||
|
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
|
||||||
|
* 例:<br>
|
||||||
|
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
|
||||||
|
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
|
||||||
|
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
|
||||||
|
*
|
||||||
|
* @param template 文本模板,被替换的部分用 {} 表示
|
||||||
|
* @param params 参数值
|
||||||
|
* @return 格式化后的文本
|
||||||
|
*/
|
||||||
|
public static String format(String template, Object... params) {
|
||||||
|
if (isEmpty(params) || isEmpty(template)) return template;
|
||||||
|
|
||||||
|
return StrFormatter.format(template, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符串转set
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
* @param sep 分隔符
|
||||||
|
* @return set集合
|
||||||
|
*/
|
||||||
|
public static final Set<String> str2Set(String str, String sep) {
|
||||||
|
return new HashSet<String>(str2List(str, sep, true, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符串转list
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
* @param sep 分隔符
|
||||||
|
* @param filterBlank 过滤纯空白
|
||||||
|
* @param trim 去掉首尾空白
|
||||||
|
* @return list集合
|
||||||
|
*/
|
||||||
|
public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) {
|
||||||
|
List<String> list = new ArrayList<String>();
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(str)) return list;
|
||||||
|
|
||||||
|
// 过滤空白字符串
|
||||||
|
if (filterBlank && StringUtils.isBlank(str)) return list;
|
||||||
|
|
||||||
|
String[] split = str.split(sep);
|
||||||
|
for (String string : split) {
|
||||||
|
if (filterBlank && StringUtils.isBlank(string)) continue;
|
||||||
|
|
||||||
|
if (trim) string = string.trim();
|
||||||
|
|
||||||
|
list.add(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下划线转驼峰命名
|
||||||
|
*/
|
||||||
|
public static String toUnderScoreCase(String str) {
|
||||||
|
if (str == null) return null;
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
// 前置字符是否大写
|
||||||
|
boolean preCharIsUpperCase = true;
|
||||||
|
// 当前字符是否大写
|
||||||
|
boolean curreCharIsUpperCase = true;
|
||||||
|
// 下一字符是否大写
|
||||||
|
boolean nexteCharIsUpperCase = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < str.length(); i++) {
|
||||||
|
char c = str.charAt(i);
|
||||||
|
|
||||||
|
if (i > 0) preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
|
||||||
|
else preCharIsUpperCase = false;
|
||||||
|
|
||||||
|
curreCharIsUpperCase = Character.isUpperCase(c);
|
||||||
|
|
||||||
|
if (i < (str.length() - 1)) nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
|
||||||
|
|
||||||
|
if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) sb.append(SEPARATOR);
|
||||||
|
else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) sb.append(SEPARATOR);
|
||||||
|
|
||||||
|
sb.append(Character.toLowerCase(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否包含字符串
|
||||||
|
*
|
||||||
|
* @param str 验证字符串
|
||||||
|
* @param strs 字符串组
|
||||||
|
* @return 包含返回true
|
||||||
|
*/
|
||||||
|
public static boolean inStringIgnoreCase(String str, String... strs) {
|
||||||
|
if (str != null && strs != null) {
|
||||||
|
for (String s : strs) {
|
||||||
|
if (str.equalsIgnoreCase(trim(s))) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
|
||||||
|
*
|
||||||
|
* @param name 转换前的下划线大写方式命名的字符串
|
||||||
|
* @return 转换后的驼峰式命名的字符串
|
||||||
|
*/
|
||||||
|
public static String convertToCamelCase(String name) {
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
|
if (name == null || name.isEmpty()) return "";
|
||||||
|
else if (!name.contains("_")) return name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||||
|
|
||||||
|
// 用下划线将原始字符串分割
|
||||||
|
String[] camels = name.split("_");
|
||||||
|
for (String camel : camels) {
|
||||||
|
// 跳过原始字符串中开头、结尾的下换线或双重下划线
|
||||||
|
if (camel.isEmpty()) continue;
|
||||||
|
|
||||||
|
// 首字母大写
|
||||||
|
result.append(camel.substring(0, 1).toUpperCase());
|
||||||
|
result.append(camel.substring(1).toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驼峰式命名法 例如:user_name->userName
|
||||||
|
*/
|
||||||
|
public static String toCamelCase(String s) {
|
||||||
|
if (s == null) return null;
|
||||||
|
|
||||||
|
s = s.toLowerCase();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder(s.length());
|
||||||
|
|
||||||
|
boolean upperCase = false;
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
|
||||||
|
if (c == SEPARATOR) {
|
||||||
|
upperCase = true;
|
||||||
|
} else if (upperCase) {
|
||||||
|
sb.append(Character.toUpperCase(c));
|
||||||
|
upperCase = false;
|
||||||
|
} else {
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取固定长度的随机数字字符串
|
||||||
|
*
|
||||||
|
* @param strLength
|
||||||
|
* 长度
|
||||||
|
* @return 指定长度的随机数字字符串
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static String getFixLenNumString(int strLength) {
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
|
Random random = new Random();
|
||||||
|
|
||||||
|
for (int i = 0; i < strLength; i++) {
|
||||||
|
result.append(random.nextInt(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T cast(Object obj) {
|
||||||
|
return (T) obj;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package com.org.utils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
/** 线程相关工具类 **/
|
||||||
|
@Slf4j
|
||||||
|
public class Threads {
|
||||||
|
|
||||||
|
/** sleep等待,单位为毫秒 **/
|
||||||
|
public static void sleep(long milliseconds) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(milliseconds);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error("{}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止线程池
|
||||||
|
* 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
|
||||||
|
* 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
|
||||||
|
* 如果仍人超時,則強制退出.
|
||||||
|
* 另对在shutdown时线程本身被调用中断做了处理.
|
||||||
|
*/
|
||||||
|
public static void shutdownAndAwaitTermination(ExecutorService pool) {
|
||||||
|
if (pool != null && !pool.isShutdown()) {
|
||||||
|
pool.shutdown();
|
||||||
|
try {
|
||||||
|
if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
|
||||||
|
pool.shutdownNow();
|
||||||
|
if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
|
||||||
|
log.info("Pool did not terminate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
log.error("{}", ie);
|
||||||
|
pool.shutdownNow();
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打印线程异常信息
|
||||||
|
*/
|
||||||
|
public static void printException(Runnable r, Throwable t) {
|
||||||
|
if (t == null && r instanceof Future<?>) {
|
||||||
|
try {
|
||||||
|
Future<?> future = (Future<?>) r;
|
||||||
|
if (future.isDone()) {
|
||||||
|
future.get();
|
||||||
|
}
|
||||||
|
} catch (CancellationException ce) {
|
||||||
|
log.error("{}", ce);
|
||||||
|
t = ce;
|
||||||
|
} catch (ExecutionException ee) {
|
||||||
|
log.error("{}", ee);
|
||||||
|
t = ee.getCause();
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
log.error("{}", ie);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t != null) {
|
||||||
|
log.error("{}", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.org.utils.core;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Id请求参数对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class IdParams {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@NotNull(message = "ID不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.org.utils.core;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Max;
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页参数对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PageParams {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页码,默认为1
|
||||||
|
*/
|
||||||
|
@NotNull(message = "页码不能为空")
|
||||||
|
@Min(value = 1, message ="页码不能小于1")
|
||||||
|
private Integer pageNum = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页大小
|
||||||
|
*/
|
||||||
|
@NotNull(message = "分页大小不能为空")
|
||||||
|
@Min(value = 1, message = "分页大小不能小于1")
|
||||||
|
@Max(value = 100, message = "分页大小不能大于100")
|
||||||
|
private Integer pageSize = 10;
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.org.utils.exception;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.org.utils.MessageUtil;
|
||||||
|
|
||||||
|
/** 基础异常 **/
|
||||||
|
public class BaseException extends RuntimeException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 所属模块 **/
|
||||||
|
private String module;
|
||||||
|
|
||||||
|
/** 错误码 **/
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/** 错误码对应的参数 **/
|
||||||
|
private Object[] args;
|
||||||
|
|
||||||
|
/** 错误消息 **/
|
||||||
|
private String defaultMessage;
|
||||||
|
|
||||||
|
public BaseException(String module, String code, Object[] args, String defaultMessage) {
|
||||||
|
this.module = module;
|
||||||
|
this.code = code;
|
||||||
|
this.args = args;
|
||||||
|
this.defaultMessage = defaultMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseException(String module, String code, Object[] args)
|
||||||
|
{
|
||||||
|
this(module, code, args, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseException(String module, String defaultMessage)
|
||||||
|
{
|
||||||
|
this(module, null, null, defaultMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseException(String code, Object[] args)
|
||||||
|
{
|
||||||
|
this(null, code, args, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseException(String defaultMessage)
|
||||||
|
{
|
||||||
|
this(null, null, null, defaultMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
String message = null;
|
||||||
|
if (!StrUtil.isEmpty(code)) {
|
||||||
|
message = MessageUtil.message(code, args);
|
||||||
|
}
|
||||||
|
if (message == null) {
|
||||||
|
message = defaultMessage;
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModule()
|
||||||
|
{
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode()
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] getArgs()
|
||||||
|
{
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultMessage()
|
||||||
|
{
|
||||||
|
return defaultMessage;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.org.utils.exception;
|
||||||
|
|
||||||
|
/** 自定义异常 **/
|
||||||
|
public class CustomException extends RuntimeException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public CustomException(String message)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomException(String message, Integer code)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomException(String message, Throwable e)
|
||||||
|
{
|
||||||
|
super(message, e);
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage()
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCode()
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue