Commit b7fc803a authored by 凌鑫's avatar 凌鑫

1.0

parents
Pipeline #556 failed with stages
# Created by .ignore support plugin (hsz.mobi)
### Java template
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
output/
logs/
*.iml
.idea/
logging.path_IS_UNDEFINED
Deploy
target/
\ No newline at end of file
#Thu Feb 16 16:03:17 CST 2023
gradle.version=7.6
# Read Me First
The following was discovered as part of building this project:
* The JVM level was changed from '1.8' to '17', review
the [JDK Version Range](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions#jdk-version-range)
on the wiki for more details.
# Getting Started
### Reference Documentation
For further reference, please consider the following sections:
* [Official Gradle documentation](https://docs.gradle.org)
* [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.0.2/gradle-plugin/reference/html/)
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.0.2/gradle-plugin/reference/html/#build-image)
### Additional Links
These additional references should also help you:
* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle)
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>chfa-platform-api</artifactId>
<groupId>com.changfa</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>chfa-platform-system</artifactId>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>chfa-platform-api</artifactId>
<groupId>com.changfa</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>chfa-platform-tdengine</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.changfa.domain;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @ClassDescription: tdEngine的基础实体类
* @ClassName: BaseEntity
* @Author: thinglinks
* @Date: 2021-12-30 14:39:25
* @Version 1.0
*/
@Data
public class BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 数据库名称
*/
@NotBlank(message = "invalid operation: databaseName can not be empty")
private String dataBaseName;
/**
* 超级表名称
*/
@NotBlank(message = "invalid operation: superTableName can not be empty")
private String superTableName;
}
package com.changfa.domain;
import com.changfa.enums.DataTypeEnum;
import lombok.Data;
/**
* @ClassDescription: 建表的字段实体类
* @ClassName: Fields
* @Author: thinglinks
* @Date: 2021-12-28 09:09:04
* @Version 1.0
*/
@Data
public class Fields {
private static final long serialVersionUID = 1L;
/**
* 字段名称
*/
private String fieldName;
/**
* 字段值
*/
private Object fieldValue;
/**
* 字段数据类型
*/
private DataTypeEnum dataType;
/**
* 字段字节大小
*/
private Integer size;
public Fields() {
}
public Fields(String fieldName, String dataType, Integer size) {
this.fieldName = fieldName;
//根据规则匹配字段数据类型
switch (dataType.toLowerCase()) {
case ("json"):
this.dataType = DataTypeEnum.JSON;
this.size = size;
break;
case ("string"):
this.dataType = DataTypeEnum.NCHAR;
this.size = size;
break;
case ("binary"):
this.dataType = DataTypeEnum.BINARY;
this.size = size;
break;
case ("int"):
this.dataType = DataTypeEnum.INT;
break;
case ("bool"):
this.dataType = DataTypeEnum.BOOL;
break;
case ("decimal"):
this.dataType = DataTypeEnum.DOUBLE;
break;
case ("timestamp"):
if ("eventTime".equals(fieldName)) {
this.fieldName = "eventTime";
}
this.dataType = DataTypeEnum.TIMESTAMP;
break;
}
}
}
package com.changfa.domain;
import lombok.Data;
import org.springframework.util.StringUtils;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassDescription: 建表的字段实体类的vo类
* @ClassName: FieldsVo
* @Author: thinglinks
* @Date: 2021-12-28 11:30:06
* @Version 1.0
*/
@Data
public class FieldsVo {
private static final long serialVersionUID = 1L;
/**
* 字段名称
*/
private String fieldName;
/**
* 字段数据类型
*/
private String dataType;
/**
* 字段字节大小
*/
private Integer size;
/**
*@MethodDescription 字段实体类转为vo类
*@param fields 字段实体类
*@return FieldsVo 字段实体vo类
*@author thinglinks
*@Date 2021/12/28 13:48
*/
public static FieldsVo fieldsTranscoding(Fields fields) throws SQLException {
if (!StringUtils.hasLength(fields.getFieldName()) || fields.getDataType() == null) {
//TODO 修改抛出的异常类,改为自定义异常类
throw new SQLException("invalid operation: fieldName or dataType can not be null");
}
FieldsVo fieldsVo = new FieldsVo();
fieldsVo.setFieldName(fields.getFieldName());
fieldsVo.setDataType(fields.getDataType().getDataType());
fieldsVo.setSize(fields.getSize());
return fieldsVo;
}
/**
*@MethodDescription 字段实体类集合转为vo类集合
*@param fieldsList 字段实体类集合
*@return List<FieldsVo> 字段实体vo类集合
*@author thinglinks
*@Date 2021/12/28 14:00
*/
public static List<FieldsVo> fieldsTranscoding(List<Fields> fieldsList) throws SQLException{
List<FieldsVo> fieldsVoList = new ArrayList<>();
for (Fields fields : fieldsList) {
fieldsVoList.add(fieldsTranscoding(fields));
}
return fieldsVoList;
}
}
package com.changfa.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Optional;
/**
*产品超级表模型
*@author wwz
*@date 2023/2/2 18:02
*/
@Data
public class ProductSuperTableModel {
private static final long serialVersionUID = 1L;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+8")
private Timestamp ts;
private String superTableName;
/**
* columnsName,columnsProperty
*/
private HashMap<Optional,Optional> columns;
/**
* tagsName,tagsProperty
*/
private HashMap<Optional,Optional> tags;
}
package com.changfa.domain;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @ClassDescription: 查询所需入参对象
* @ClassName: SelectDto
* @Author: thinglinks
* @Date: 2022-01-07 14:12:26
* @Version 1.0
*/
@Data
public class SelectDto {
@NotBlank(message = "invalid operation: dataBaseName can not be empty")
private String dataBaseName;
@NotBlank(message = "invalid operation: tableName can not be empty")
private String tableName;
// @NotBlank(message = "invalid operation: fieldName can not be empty")
private String fieldName;
// @NotNull(message = "invalid operation: startTime can not be null")
private Long startTime;
// @NotNull(message = "invalid operation: endTime can not be null")
private Long endTime;
}
package com.changfa.domain;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
* @ClassDescription: 创建超级表需要的入参的实体类
* @ClassName: SuperTableDto
* @Author: thinglinks
* @Date: 2021-12-28 15:03:45
* @Version 1.0
*/
@Data
public class SuperTableDto extends BaseEntity {
/**
* 超级表的表结构(业务相关)
* 第一个字段的数据类型必须为timestamp
* 字符相关数据类型必须指定大小
* 字段名称和字段数据类型不能为空
*/
@NotEmpty(message = "invalid operation: schemaFields can not be empty")
private List<Fields> schemaFields;
/**
* 超级表的标签字段,可以作为子表在超级表里的标识
* 字符相关数据类型必须指定大小
* 字段名称和字段数据类型不能为空
*/
@NotEmpty(message = "invalid operation: tagsFields can not be empty")
private List<Fields> tagsFields;
/**
* 字段信息对象,超级表添加列时使用该属性
*/
private Fields fields;
}
package com.changfa.domain;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.List;
/**
* @ClassDescription: 创建超级表的子表需要的入参的实体类
* @ClassName: TableDto
* @Author: thinglinks
* @Date: 2021-12-30 14:42:47
* @Version 1.0
*/
@Data
public class TableDto extends BaseEntity{
/**
* 超级表普通列字段的值
* 值需要与创建超级表时普通列字段的数据类型对应上
*/
private List<Fields> schemaFieldValues;
/**
* 超级表标签字段的值
* 值需要与创建超级表时标签字段的数据类型对应上
*/
private List<Fields> tagsFieldValues;
/**
* 表名称
*/
@NotBlank(message = "invalid operation: tableName can not be empty")
private String tableName;
}
package com.changfa.domain;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @program: thinglinks
* @description: 标签查询模型
* @packagename: com.mqttsnet.thinglinks.tdengine.api.domain.rule
* @author: ShiHuan Sun
* @e-mainl: 13733918655@163.com
* @date: 2022-07-27 18:40
**/
@Data
public class TagsSelectDao {
@NotBlank(message = "invalid operation: dataBaseName can not be empty")
private String dataBaseName;
@NotBlank(message = "invalid operation: stableName can not be empty")
private String stableName;
@NotBlank(message = "invalid operation: tagsName can not be empty")
private String tagsName;
// @NotNull(message = "invalid operation: startTime can not be null")
private Long startTime;
// @NotNull(message = "invalid operation: endTime can not be null")
private Long endTime;
}
package com.changfa.enums;
/**
* @EnumDescription: tdEngine支持的数据类型的枚举类
* @EnumName: DataTypeEnum
* @Author: thinglinks
* @Date: 2021-12-27 16:32:53
*/
public enum DataTypeEnum {
/**
* 时间戳 缺省精度毫秒(格林威治时间开始)
*/
TIMESTAMP("timestamp"),
/**
* 单字节整形 范围[-127, 127] -128用作于NULL
*/
TINYINT("tinyint"),
/**
* 短整型 范围[-32767, 32767] -32768用作于NULL
*/
SMALLINT("smallint"),
/**
* 整形 范围[-2^31+1, 2^31-1] -2^31用作于NULL
*/
INT("int"),
/**
* 长整型 范围[-2^63+1, 2^63-1] -2^63用作于NULL
*/
BIGINT("bigint"),
/**
* 浮点型 有效位数6-7 范围[-3.4E38, 3.4E38]
*/
FLOAT("float"),
/**
* 双精度浮点型 有效位数15-16 范围[-1.7E308, 1.7E308]
*/
DOUBLE("double"),
/**
* 单字节字符串(建议只用于处理ASCII可见字符)最大长度16000
*/
BINARY("binary"),
/**
* 记录包含多字节字符在内的字符串(如中文字符)最大长度4093
*/
NCHAR("nchar"),
/**
* 布尔型 {true, false}
*/
BOOL("bool"),
/**
* json数据类型 只有tag类型可以是json格式
*/
JSON("json");
private final String dataType;
DataTypeEnum(String dataType) {
this.dataType = dataType;
}
public String getDataType() {
return dataType;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>chfa-platform</artifactId>
<groupId>com.changfa</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>chfa-platform-api</artifactId>
<packaging>pom</packaging>
<modules>
<module>chfa-platform-system</module>
<module>chfa-platform-tdengine</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>chfa-platform</artifactId>
<groupId>com.changfa</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>chfa-platform-auth</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.changfa</groupId>
<artifactId>chfa-platform-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.changfa.annotations;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface GuestAccess {
}
package com.changfa.config.constants;
/**
* @author wwz
*/
public class UserConstants {
public static final String USER_KEY = "user";
public static final String USER_ID = "userId";
}
package com.changfa.config.shiro;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.changfa.constants.*;
import com.changfa.dto.MenuDto;
import com.changfa.dto.UserBaseDto;
import com.changfa.entity.TRole;
import com.changfa.entity.TUser;
import com.changfa.enums.LoginStatus;
import com.changfa.enums.StatusEnum;
import com.changfa.exception.BuzEx;
import com.changfa.service.ITRoleService;
import com.changfa.service.ITUserService;
import com.changfa.utils.BCrypt;
import com.changfa.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
/**
* @author wwz
*/
@Slf4j
public class CustomRealm extends AuthorizingRealm {
@Autowired
private ITUserService userService;
@Autowired
private ITRoleService roleService;
@Autowired
private RedisTemplate redisTemplate;
/**
* @MethodName doGetAuthorizationInfo
* @Description 权限配置类
* @Param [principalCollection]
* @Return AuthorizationInfo
* @Author WangShiLin
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
log.info("=======================权限配置=========================");
//获取登录用户名
String name = (String) principalCollection.getPrimaryPrincipal();
//查询用户名称
UserBaseDto userBaseDto = LoginConstant.userBaseInfo();
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
TRole role = userBaseDto.getRole();
if(role != null){
simpleAuthorizationInfo.addRole(role.getRoleCode());
}
//添加角色和权限
return simpleAuthorizationInfo;
}
/**
* @MethodName doGetAuthenticationInfo
* @Description 认证配置类
* @Param [authenticationToken]
* @Return AuthenticationInfo
* @Author wwz
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
if (StringUtils.isEmpty(authenticationToken.getPrincipal())) {
return null;
}
SimpleAuthenticationInfo simpleAuthenticationInfo = null;
//获取用户信息
String name = authenticationToken.getPrincipal().toString();
char[] passwords = (char[]) authenticationToken.getCredentials();
String password = String.valueOf(passwords);
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("account",name);
TUser tSysUser = userService.getOne(wrapper);
if (tSysUser == null) {
//这里返回后会报出对应异常
return null;
} else {
if (LoginStatus.DISABLE.getCode().equals(tSysUser.getStatus())) {
throw new BuzEx(StatusEnum.LOGIN_LOCK);
}
String pwd = new String(Base64Utils.decode(password.getBytes()));
if (!BCrypt.checkpw(pwd, tSysUser.getPassword())) {
throw new AuthenticationException();
}
tSysUser.setPassword(null);
tSysUser.setSalt(null);
//这里验证authenticationToken和simpleAuthenticationInfo的信息
String token = JwtUtil.genToken(refreshUser(tSysUser), 60);
String key = RedisConstants.UserCacheKey.USER_KEY.concat(tSysUser.getAccount());
Object tokenValue = redisTemplate.opsForValue().get(key);
if(tokenValue != null && !"".equals(tokenValue)){
redisTemplate.delete(CommomConstants.keyPrefix.concat(tokenValue.toString()));
}
ThreadContext threadContext = ThreadContext.getInstance();
threadContext.set(token);
redisTemplate.opsForValue().set(key,token,2, TimeUnit.HOURS);
simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, password, getName());
return simpleAuthenticationInfo;
}
}
public UserBaseDto refreshUser(TUser tSysUser){
UserBaseDto userBaseDto = new UserBaseDto();
userBaseDto.setUser(tSysUser);
TRole tRole = roleService.selectRoleByUserId(tSysUser.getId());
if(tRole != null){
userBaseDto.setRole(tRole);
}
return userBaseDto;
}
/**
* 左侧菜单通过递归算法实现树
* @param parentId 父Id
* @param menuList 当前所有菜单
* @return
*/
public List<MenuDto> recursionForMenu(int parentId,List<MenuDto> menuList){
List<MenuDto> list = new ArrayList<>();
/**
* Optional.ofNullable(menuList).orElse(new ArrayList<>()) 如果menuList是空的则返回一个new ArrayList<>()
* .stream() 返回List中的流
* .filter(menu -> menu.getParentId().equals(parentId)) 筛选List,返回只有条件成立的元素(当前元素的parentId必须等于父id)
* .forEach 遍历这个list
*/
Optional.ofNullable(menuList).orElse(new ArrayList<>())
.stream()
.filter(menu -> menu.getParentKey().equals(parentId))
.forEach(menu -> {
MenuDto MenuDto = new MenuDto();
MenuDto.setName(menu.getName());
//是否是目录
// MenuDto.setAlwaysShow(menu.getLevel().equals(1)?true:false);
MenuDto.setPath(menu.getPath());
MenuDto.setId(menu.getId());
MenuDto.setComponent(StringUtils.hasLength(menu.getComponent())?menu.getComponent():"Layout");
// MenuDto.setMeta(new MetaVO(menu.getName(),menu.getIcon(),new ArrayList<>(Arrays.asList(1))));
List<MenuDto> children=recursionForMenu(menu.getId(),menuList);
MenuDto.setChildren(children);
list.add(MenuDto);
});
return list;
}
}
package com.changfa.config.shiro;
import com.alibaba.fastjson.JSON;
import com.changfa.config.RedisConfig;
import com.changfa.config.constants.UserConstants;
import com.changfa.constants.CommomConstants;
import com.changfa.constants.RedisConstants;
import com.changfa.constants.ThreadContext;
import com.changfa.dto.UserBaseDto;
import com.changfa.utils.JwtUtil;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.crazycake.shiro.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @author wwz
*/
public class CustomRedisSessionDAO extends RedisSessionDAO {
private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class);
private static final String DEFAULT_SESSION_KEY_PREFIX = "shiro:session:";
private long sessionInMemoryTimeout = 1000L;
private int expire = 7200;
private RedisSerializer keySerializer = new StringSerializer();
private RedisSerializer valueSerializer = new ObjectSerializer();
private static ThreadLocal sessionsInThread = new ThreadLocal();
private RedisConfig.ByteRedisTemplate<String, Byte[]> redisTemplate;
private RedisTemplate stringRedisTemplate;
public CustomRedisSessionDAO() {
}
@Override
public int getExpire() {
return expire;
}
@Override
public void setExpire(int expire) {
this.expire = expire;
}
@Override
public void update(Session session) throws UnknownSessionException {
this.saveSession(session);
}
public static UserBaseDto userBaseInfo(String sessionId) {
return JSON.parseObject(JwtUtil.getTokenData(sessionId).toString(), UserBaseDto.class);
}
private void saveSession(Session session) throws UnknownSessionException {
if (session != null && session.getId() != null) {
if ((long) (this.expire * 1000) < session.getTimeout()) {
logger.warn("Redis session expire time: " + this.expire * 1000 + " is less than Session timeout: " + session.getTimeout() + " . It may cause some problems.");
}
byte[] value = new byte[0];
try {
value = valueSerializer.serialize(session);
Object tokenValue = session.getAttribute("account");
UserBaseDto userBaseDto = null;
try {
if (tokenValue == null || "".equals(tokenValue)) {
userBaseDto = userBaseInfo(session.getId().toString());
if (userBaseDto != null) {
tokenValue = userBaseDto.getUser().getAccount();
}
}
} catch (Exception e) {
logger.error(e.getMessage());
}
if (tokenValue != null && !"".equals(tokenValue)) {
redisTemplate.opsForValue().set(this.getRedisSessionKey(session.getId()), value, this.expire, TimeUnit.SECONDS);
session.setTimeout(this.expire * 1000);
stringRedisTemplate.opsForValue().set(RedisConstants.UserCacheKey.USER_KEY.concat(tokenValue.toString()), session.getId().toString(), this.expire, TimeUnit.SECONDS);
}else{
redisTemplate.opsForValue().set(this.getRedisSessionKey(session.getId()), value, this.expire, TimeUnit.SECONDS);
}
logger.info("===============>session time is {}", session.getTimeout());
} catch (SerializationException e) {
e.printStackTrace();
}
} else {
logger.error("session or session id is null");
throw new UnknownSessionException("session or session id is null");
}
}
@Override
public void delete(Session session) {
if (session != null && session.getId() != null) {
try {
redisTemplate.delete(this.getRedisSessionKey(session.getId()));
Object tokenValue = session.getAttribute("account");
if (tokenValue != null && !"".equals(tokenValue)) {
stringRedisTemplate.delete(RedisConstants.UserCacheKey.USER_KEY.concat(tokenValue.toString()));
}
} catch (Exception var3) {
logger.error("delete session error. session id=" + session.getId());
}
} else {
logger.error("session or session id is null");
}
}
@Override
public Collection<Session> getActiveSessions() {
HashSet sessions = new HashSet();
try {
Set<String> keys = redisTemplate.keys(CommomConstants.keyPrefix + "*");
if (keys != null && keys.size() > 0) {
Iterator i$ = keys.iterator();
while (i$.hasNext()) {
String key = (String) i$.next();
Session s = (Session) valueSerializer.deserialize((byte[]) this.redisTemplate.opsForValue().get(key));
Object o = s.getAttribute(UserConstants.USER_KEY);
if (o != null) {
sessions.add(s);
}
}
}
} catch (Exception var6) {
logger.error("get active sessions error.");
}
return sessions;
}
@Override
protected Serializable doCreate(Session session) {
if (session == null) {
logger.error("session is null");
throw new UnknownSessionException("session is null");
} else {
ThreadContext threadContext = ThreadContext.getInstance();
Object token = threadContext.get();
Serializable sessionId = null;
if (ObjectUtils.isEmpty(token)) {
sessionId = this.generateSessionId(session);
} else {
sessionId = token.toString();
}
this.assignSessionId(session, sessionId);
this.saveSession(session);
return sessionId;
}
}
@Override
protected Session doReadSession(Serializable sessionId) {
if (sessionId == null) {
logger.warn("session id is null");
return null;
} else {
Session s = this.getSessionFromThreadLocal(sessionId);
if (s != null) {
return s;
} else {
logger.debug("read session from redis");
try {
s = (Session) this.valueSerializer.deserialize((byte[]) this.redisTemplate.opsForValue().get(this.getRedisSessionKey(sessionId)));
this.setSessionToThreadLocal(sessionId, s);
} catch (Exception var4) {
logger.error("read session error. settionId=" + sessionId);
}
return s;
}
}
}
private void setSessionToThreadLocal(Serializable sessionId, Session s) {
Map<Serializable, SessionInMemory> sessionMap = (Map) sessionsInThread.get();
if (sessionMap == null) {
sessionMap = new HashMap();
sessionsInThread.set(sessionMap);
}
SessionInMemory sessionInMemory = new SessionInMemory();
sessionInMemory.setCreateTime(new Date());
sessionInMemory.setSession(s);
((Map) sessionMap).put(sessionId, sessionInMemory);
}
private Session getSessionFromThreadLocal(Serializable sessionId) {
Session s = null;
if (sessionsInThread.get() == null) {
return null;
} else {
Map<Serializable, SessionInMemory> sessionMap = (Map) sessionsInThread.get();
SessionInMemory sessionInMemory = (SessionInMemory) sessionMap.get(sessionId);
if (sessionInMemory == null) {
return null;
} else {
Date now = new Date();
long duration = now.getTime() - sessionInMemory.getCreateTime().getTime();
if (duration < this.sessionInMemoryTimeout) {
s = sessionInMemory.getSession();
logger.debug("read session from memory");
} else {
sessionMap.remove(sessionId);
}
return s;
}
}
}
private String getRedisSessionKey(Serializable sessionId) {
return CommomConstants.keyPrefix + sessionId;
}
public RedisConfig.ByteRedisTemplate getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisConfig.ByteRedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void setStringRedisTemplate(RedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
}
package com.changfa.config.shiro;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* @author wwz
*/
public class CustomRolesAuthorizationFilter extends AuthorizationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest req,ServletResponse resp, Object mappedValue) throws Exception {
Subject subject = getSubject(req, resp);
String[] rolesArray = (String[]) mappedValue;
//没有角色限制,有权限访问
if (rolesArray == null || rolesArray.length == 0) {
return true;
}
for (int i = 0; i < rolesArray.length; i++) {
//若当前用户是rolesArray中的任何一个,则有权限访问
if (subject.hasRole(rolesArray[i])) {
return true;
}
}
return false;
}
}
\ No newline at end of file
package com.changfa.config.shiro;
import com.changfa.constants.CommomConstants;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;
/**
* Created by Administrator on 2017/12/11.
* 自定义sessionId获取
*/
public class MySessionManager extends DefaultWebSessionManager {
private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
public MySessionManager() {
super();
}
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
String id = WebUtils.toHttp(request).getHeader(CommomConstants.AUTHORIZATION);
//如果请求头中有 Authorization 则其值为sessionId
if (StringUtils.hasLength(id) ) {
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
return id;
} else {
//否则按默认规则从cookie取sessionId
return super.getSessionId(request, response);
}
}
/**
* Stores the Session's ID, usually as a Cookie, to associate with future requests.
*
* @param session the session that was just {@link #createSession created}.
*/
/* @Override
protected void onStart(Session session, SessionContext context) {
super.onStart(session, context);
if (!WebUtils.isHttp(context)) {
log.debug("SessionContext argument is not HTTP compatible or does not have an HTTP request/response " +
"pair. No session ID cookie will be set.");
return;
}
HttpServletRequest request = WebUtils.getHttpRequest(context);
HttpServletResponse response = WebUtils.getHttpResponse(context);
String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
if (isSessionIdCookieEnabled()) {
Serializable sessionId = session.getId();
storeSessionId(sessionId, request, response);
} else {
log.debug("Session ID cookie is disabled. No cookie has been set for new session with id {}", session.getId());
}
request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
}*/
}
\ No newline at end of file
package com.changfa.config.shiro;
import com.changfa.config.RedisConfig;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration;
import org.springframework.util.Base64Utils;
import org.springframework.util.ObjectUtils;
import javax.servlet.Filter;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* @author wwz
* shiro配置
*/
public class ShiroConfig {
@Value("${shiro.ignoreAll}")
private boolean ignoreAll;
@Autowired
private ShiroProperties shiroProperties;
@Autowired
private RedisConfig.ByteRedisTemplate redisTemplate;
@Autowired
@Qualifier(value = "redisTemplate")
private RedisTemplate stringRedisTemplate;
private static final Logger logger = LoggerFactory.getLogger(ShiroConfig.class);
/**
* 设置session会话过期时间为两小时
*/
private static final Integer expireTime = 3600 * 2;
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}
//将自己的验证方式加入容器
@Bean
public CustomRealm myShiroRealm() {
CustomRealm customRealm = new CustomRealm();
return customRealm;
}
/**
* RedisSessionDAO shiro sessionDao层的实现 通过redis
* SessionDAO的作用是为Session提供CRUD并进行持久化的一个shiro组件
* MemorySessionDAO 直接在内存中进行会话维护
* EnterpriseCacheSessionDAO 提供了缓存功能的会话维护,默认情况下使用MapCache实现,内部使用ConcurrentHashMap保存缓存的会话。
*/
@Bean
public CustomRedisSessionDAO redisSessionDAO() {
CustomRedisSessionDAO redisSessionDAO = new CustomRedisSessionDAO();
redisSessionDAO.setRedisTemplate(redisTemplate);
redisSessionDAO.setStringRedisTemplate(stringRedisTemplate);
redisSessionDAO.setRedisManager(redisManager);
redisSessionDAO.setExpire(expireTime);
redisSessionDAO.setSessionIdGenerator(new CustomSessionIdGenerator());
return redisSessionDAO;
}
class CustomSessionIdGenerator implements SessionIdGenerator {
public CustomSessionIdGenerator(){
}
@Override
public Serializable generateId(Session session) {
return Base64Utils.encodeToString(UUID.randomUUID().toString().toUpperCase().replaceAll("-","").getBytes()).toUpperCase();
}
}
/**
* sessionManager = session管理
* @return
*/
@Bean
public SessionManager sessionManager() {
MySessionManager mySessionManager = new MySessionManager();
mySessionManager.setSessionDAO(redisSessionDAO());
mySessionManager.setSessionIdCookieEnabled(false);
mySessionManager.setSessionIdUrlRewritingEnabled(false);
//mySessionManager.setGlobalSessionTimeout(-1000);
return mySessionManager;
}
/**
* 配置shiro redisManager
* <p>
* 使用的是shiro-redis开源插件
*
* @return
*/
@Bean
@ConfigurationProperties(prefix = "spring.redis")
public RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
return redisManager;
}
@Autowired
RedisManager redisManager;
/**
* cacheManager 缓存 redis实现
* <p>
* 使用的是shiro-redis开源插件
*
* @return
*/
@Bean
public RedisCacheManager redisCacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager();
redisCacheManager.setRedisManager(redisManager);
redisCacheManager.setExpire(expireTime);
return redisCacheManager;
}
@Autowired
RedisCacheManager redisCacheManager;
//权限管理,配置主要是Realm的管理认证
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
securityManager.setSessionManager(sessionManager());
securityManager.setCacheManager(redisCacheManager);
securityManager.setRememberMeManager(null);
return securityManager;
}
@Autowired
private SecurityManager securityManager;
//Filter工厂,设置对应的过滤条件和跳转条件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
logger.info("==============初始化shiro================");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String,Filter> filterMap = shiroFilterFactoryBean.getFilters();
filterMap.put("authc",new ShiroLoginFilter());
shiroFilterFactoryBean.setFilters(filterMap);
Map<String, String> map = new LinkedHashMap<>();
//登录
//shiroFilterFactoryBean.setLoginUrl("/loginPage");
//首页
//错误页面,认证不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
//登出
//对所有用户认证
if(!ignoreAll){
List<String> ignoreAuthc = shiroProperties.getIgnoreAuthc();
if(!ObjectUtils.isEmpty(ignoreAuthc)){
ignoreAuthc.stream().forEach(item->{
map.put(item,"anon");
});
}
map.put("/**", "authc");
}else{
map.put("/**", "anon");
}
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public ProxyTransactionManagementConfiguration proxyTransactionManagementConfiguration(){
return new ProxyTransactionManagementConfiguration();
}
public boolean getIgnoreAll() {
return ignoreAll;
}
public void setIgnoreAll(boolean ignoreAll) {
this.ignoreAll = ignoreAll;
}
}
package com.changfa.config.shiro;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* @author wwz
*/
@Component
@Data
@ConfigurationProperties(prefix = "shiro")
public class ShiroConstants {
private Map<String,List<String>> roleAuthcMaps;
}
package com.changfa.config.shiro;
import com.alibaba.fastjson.JSON;
import com.changfa.annotations.GuestAccess;
import com.changfa.constants.ApiResult;
import com.changfa.enums.StatusEnum;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.UserFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.support.RequestContextUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.annotation.Annotation;
/**
* @author:wwz
**/
@Component
public class ShiroLoginFilter extends UserFilter {
@Override
protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
response.setContentType("application/json; charset=utf-8");
response.getWriter().print(JSON.toJSON(ApiResult.error(StatusEnum.NOT_AUTH)));
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
if (isLoginRequest(request, response)) {
return true;
} else {
HttpServletRequest servletRequest = WebUtils.toHttp(request);
if(isAllowed(servletRequest)){
return true;
}
Subject subject = getSubject(request, response);
// If principal is not null, then the user is known and should be allowed access.
return subject.getPrincipal() != null;
}
}
private boolean isAllowed(HttpServletRequest request) {
WebApplicationContext ctx = RequestContextUtils.findWebApplicationContext(request);
RequestMappingHandlerMapping mapping = ctx.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
HandlerExecutionChain handler = null;
try {
handler = mapping.getHandler(request);
if(handler == null){
return false;
}
Annotation[] declaredAnnotations = ((HandlerMethod) handler.getHandler()).
getMethod().getDeclaredAnnotations();
for (Annotation annotation : declaredAnnotations) {
/**
*如果含有@GuestAccess注解,则认为是不需要验证是否登录,
*直接放行即可
**/
if (GuestAccess.class.equals(annotation.annotationType())) {
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public void saveRequestAndRedirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
// saveRequest(request);
redirectToLogin(request, response);
}
}
package com.changfa.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class PageDto {
@ApiModelProperty(value = "当前页")
private long pageNum= 0;
@ApiModelProperty(value = "每页显示的条数")
private long pageSize = 10;
}
package com.changfa.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class QueryUserDto extends PageDto{
@ApiModelProperty(value = "系统账号")
private String account;
@ApiModelProperty(value = "所属角色")
private Integer roleId;
@ApiModelProperty(value = "用户姓名")
private String userName;
}
package com.changfa.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class RoleDto extends PageDto {
@ApiModelProperty(value = "角色名称")
private String roleName;
}
package com.changfa.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
@ApiModel(value = "User对象", description = "")
public class SaveUserDto {
@ApiModelProperty(value = "用户id")
private Integer userId;
@ApiModelProperty(value = "用户姓名")
@NotEmpty(message = "用户姓名不能为空")
private String userName;
@ApiModelProperty(value = "登录账号")
@NotEmpty(message = "账号不能为空")
private String account;
@ApiModelProperty(value = "密码",hidden = true)
// @NotEmpty(message = "密码不能为空")
private String password;
@ApiModelProperty(value = "联系电话")
private String mobilePhone;
@ApiModelProperty(value = "【1:启动,2:禁用】")
private Integer status;
@ApiModelProperty(value = "所属角色")
@NotNull(message = "所属角色不能为空")
private Integer roleId;
}
package com.changfa.dto;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
@Data
public class UserDto {
@NotEmpty(message = "账号不能为空")
private String account;
@NotEmpty(message = "密码不能为空")
private String password;
}
package com.changfa.entity;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.changfa.constants.LoginConstant;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class BaseEntity implements Serializable {
@TableField("create_by")
@ExcelIgnore
private String createBy;
@ExcelIgnore
@TableField("modify_by")
private String modifyBy;
@TableField("create_time")
@ExcelIgnore
@JSONField(format="yyyy-MM-dd")//数据库导出页面时json格式化
@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+08")
private Date createTime;
@ExcelIgnore
@JSONField(format="yyyy-MM-dd")//数据库导出页面时json格式化
@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+08")
@TableField("modify_time")
private Date modifyTime;
public <T extends BaseEntity>T fillCreated(String userName){
//JwtUtil.getTokenData()
this.createBy = userName;
Date current = new Date();
this.createTime = current;
return (T)this;
}
public <T extends BaseEntity>T fillUpdate(String userName){
//JwtUtil.getTokenData()
this.modifyBy = userName;
Date current = new Date();
this.modifyTime = current;
return (T)this;
}
/**
* 信息填充
*/
public <T extends BaseEntity>T fillCreated(){
//JwtUtil.getTokenData()
TUser sysUser = LoginConstant.currentUser();
String userName = sysUser.getUserName();
this.createBy = userName;
Date current = new Date();
this.createTime = current;
return (T)this;
}
/**
* 信息填充
*/
public <T extends BaseEntity>T fillUpdate(){
TUser sysUser = LoginConstant.currentUser();
String userName = sysUser.getUserName();
this.modifyBy = userName;
Date current = new Date();
this.modifyTime = current;
return (T)this;
}
public Integer currentUserId(){
TUser sysUser = LoginConstant.currentUser();
return sysUser.getId();
}
}
package com.changfa.entity;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 菜单表
* </p>
*
* @author wwz
* @since 2022-06-24
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("t_menu")
@ApiModel(value="TMenu对象", description="菜单表")
public class TMenu extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "菜单名称")
@TableField("menu_name")
private String menuName;
@ApiModelProperty(value = "菜单编码")
@TableField("menu_code")
private String menuCode;
@ApiModelProperty(value = "菜单权限(后端)")
@TableField("menu_auth")
private String menuAuth;
@ApiModelProperty(value = "所属上级")
@TableField("parent_key")
private Integer parentKey;
@ApiModelProperty(value = "组件")
@TableField("component")
private String component;
@TableLogic(delval = "1",value = "0")
// @ExcelProperty(value = "删除状态",converter = LogicDelConvert.class)
private Integer logicDel;
}
package com.changfa.entity;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 角色菜单表
* </p>
*
* @author wwz
* @since 2022-06-24
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("t_role_menu")
@ApiModel(value="TRoleMenu对象", description="角色菜单表")
public class TRoleMenu extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "角色主键")
@TableField("role_id")
private Integer roleId;
@ApiModelProperty(value = "菜单主键")
@TableField("menu_id")
private Integer menuId;
@TableLogic(delval = "1",value = "0")
// @ExcelProperty(value = "删除状态",converter = LogicDelConvert.class)
private Integer logicDel;
}
package com.changfa.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 用户角色表
* </p>
*
* @author wwz
* @since 2022-06-24
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("t_user_role")
@ApiModel(value="TUserRole对象", description="用户角色表")
public class TUserRole extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "角色主键")
@TableField("role_id")
private Integer roleId;
@ApiModelProperty(value = "用户主键")
@TableField("user_id")
private Integer userId;
@TableField("logic_del")
private Integer logicDel;
}
package com.changfa.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.changfa.dto.MenuDto;
import com.changfa.entity.TMenu;
import java.util.List;
/**
* <p>
* 菜单表 Mapper 接口
* </p>
*
* @author wwz
* @since 2022-06-24
*/
public interface TMenuMapper extends BaseMapper<TMenu> {
List<MenuDto> selectMenuListByRoleId(Integer roleId);
}
package com.changfa.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.changfa.entity.TRole;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* <p>
* Mapper 接口
* </p>
*
* @author wwz
* @since 2022-06-24
*/
public interface TRoleMapper extends BaseMapper<TRole> {
TRole selectRoleByUserId(Integer userId);
List<Map<String,Object>> selectRoleList(@Param("ew") Wrapper wrapper, Page page);
}
package com.changfa.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.changfa.entity.TRoleMenu;
/**
* <p>
* 角色菜单表 Mapper 接口
* </p>
*
* @author wwz
* @since 2022-06-24
*/
public interface TRoleMenuMapper extends BaseMapper<TRoleMenu> {
}
package com.changfa.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.changfa.entity.TUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author wwz
* @since 2022-06-24
*/
public interface TUserMapper extends BaseMapper<TUser> {
List<TUser> selectUserPage(Page page, @Param("ew") Wrapper wrapper);
}
package com.changfa.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.changfa.entity.TUserRole;
/**
* <p>
* 用户角色表 Mapper 接口
* </p>
*
* @author wwz
* @since 2022-06-24
*/
public interface TUserRoleMapper extends BaseMapper<TUserRole> {
}
package com.changfa.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.changfa.dto.MenuDto;
import com.changfa.entity.TMenu;
import java.util.List;
/**
* <p>
* 菜单表 服务类
* </p>
*
* @author wwz
* @since 2022-06-24
*/
public interface ITMenuService extends IService<TMenu> {
List<MenuDto> selectMenuListByRoleId(Integer roleId);
}
package com.changfa.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.changfa.entity.TRoleMenu;
import java.util.List;
/**
* <p>
* 角色菜单表 服务类
* </p>
*
* @author wwz
* @since 2022-06-24
*/
public interface ITRoleMenuService extends IService<TRoleMenu> {
boolean assignPermissions(Integer roleId, List<Integer> menuIds);
}
package com.changfa.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.changfa.entity.TRole;
import java.util.Map;
/**
* <p>
* 服务类
* </p>
*
* @author wwz
* @since 2022-06-24
*/
public interface ITRoleService extends IService<TRole> {
TRole selectRoleByUserId(Integer userId);
boolean deleteRoleById(Integer roleId);
Page<Map<String,Object>> listPage(Wrapper wrapper, Page page);
}
package com.changfa.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.changfa.entity.TUserRole;
/**
* <p>
* 用户角色表 服务类
* </p>
*
* @author wwz
* @since 2022-06-24
*/
public interface ITUserRoleService extends IService<TUserRole> {
}
package com.changfa.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.changfa.dto.SaveUserDto;
import com.changfa.entity.TUser;
/**
* <p>
* 服务类
* </p>
*
* @author wwz
* @since 2022-06-24
*/
public interface ITUserService extends IService<TUser> {
boolean deleteUser(Integer userId);
boolean saveUser(SaveUserDto saveUserDto);
Page selectUserPage(Page page, Wrapper wrapper);
}
package com.changfa.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.changfa.dto.MenuDto;
import com.changfa.entity.TMenu;
import com.changfa.mapper.TMenuMapper;
import com.changfa.service.ITMenuService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 菜单表 服务实现类
* </p>
*
* @author wwz
* @since 2022-06-24
*/
@Service
public class TMenuServiceImpl extends ServiceImpl<TMenuMapper, TMenu> implements ITMenuService {
@Override
public List<MenuDto> selectMenuListByRoleId(Integer roleId) {
return this.baseMapper.selectMenuListByRoleId(roleId);
}
}
package com.changfa.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.changfa.entity.TRoleMenu;
import com.changfa.mapper.TRoleMenuMapper;
import com.changfa.service.ITRoleMenuService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 角色菜单表 服务实现类
* </p>
*
* @author wwz
* @since 2022-06-24
*/
@Service
public class TRoleMenuServiceImpl extends ServiceImpl<TRoleMenuMapper, TRoleMenu> implements ITRoleMenuService {
@Override
@Transactional(
rollbackFor = {Exception.class}
)
public boolean assignPermissions(Integer roleId, List<Integer> menuIds) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("role_id",roleId);
if(this.baseMapper.selectCount(queryWrapper)>0){
this.baseMapper.delete(queryWrapper);
}
List<TRoleMenu> list = new ArrayList<>();
menuIds.stream().forEach(item->{
TRoleMenu roleMenu = new TRoleMenu();
roleMenu.setMenuId(item);
roleMenu.setRoleId(roleId);
roleMenu.fillCreated();
list.add(roleMenu);
});
return this.saveBatch(list);
}
}
package com.changfa.service.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.changfa.enums.StatusEnum;
import com.changfa.entity.TRole;
import com.changfa.exception.BuzEx;
import com.changfa.mapper.TRoleMapper;
import com.changfa.mapper.TRoleMenuMapper;
import com.changfa.mapper.TUserRoleMapper;
import com.changfa.service.ITRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
/**
* <p>
* 服务实现类
* </p>
*
* @author wwz
* @since 2022-06-24
*/
@Service
public class TRoleServiceImpl extends ServiceImpl<TRoleMapper, TRole> implements ITRoleService {
@Autowired
private TRoleMenuMapper roleMenuMapper;
@Autowired
private TUserRoleMapper userRoleMapper;
@Override
public TRole selectRoleByUserId(Integer userId) {
return this.baseMapper.selectRoleByUserId(userId);
}
@Override
@Transactional
public boolean deleteRoleById(Integer roleId) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("role_id",roleId);
// 查询如果角色被分配。抛出提示
if(userRoleMapper.selectCount(queryWrapper) > 0){
throw new BuzEx(StatusEnum.ROLE_NOT_FREE);
}
// 删除角色
if(this.baseMapper.deleteById(roleId) > 0){
queryWrapper = new QueryWrapper();
queryWrapper.eq("role_id",roleId);
// 删除角色菜单信息
roleMenuMapper.delete(queryWrapper);
return true;
};
return false;
}
@Override
public Page<Map<String,Object>> listPage(Wrapper wrapper, Page page) {
page.setRecords(this.baseMapper.selectRoleList(wrapper,page));
return page;
}
}
package com.changfa.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.changfa.entity.TUserRole;
import com.changfa.mapper.TUserRoleMapper;
import com.changfa.service.ITUserRoleService;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户角色表 服务实现类
* </p>
*
* @author wwz
* @since 2022-06-24
*/
@Service
public class TUserRoleServiceImpl extends ServiceImpl<TUserRoleMapper, TUserRole> implements ITUserRoleService {
}
package com.changfa.service.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.changfa.enums.StatusEnum;
import com.changfa.dto.SaveUserDto;
import com.changfa.entity.TUser;
import com.changfa.entity.TUserRole;
import com.changfa.exception.BuzEx;
import com.changfa.mapper.TUserMapper;
import com.changfa.mapper.TUserRoleMapper;
import com.changfa.service.ITUserService;
import com.changfa.utils.BCrypt;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author wwz
* @since 2022-06-24
*/
@Service
public class TUserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements ITUserService {
@Autowired
private TUserRoleMapper userRoleMapper;
/**
* 删除对应的用户以及角色
* @param userId
* @return
*/
@Override
@Transactional
public boolean deleteUser(Integer userId) {
if(this.baseMapper.deleteById(userId) > 0){
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("user_id",userId);
userRoleMapper.delete(wrapper);
return true;
}
return false;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveUser(SaveUserDto saveUserDto) {
TUser tUser = new TUser();
String salt = BCrypt.gensalt();
BeanUtils.copyProperties(saveUserDto,tUser);
tUser.setSalt(salt);
tUser.setPassword(BCrypt.hashpw( saveUserDto.getPassword(),salt));
tUser.fillCreated();
tUser.setId(saveUserDto.getUserId());
if(saveOrUpdate(tUser)){
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("user_id",tUser.getId());
int result = userRoleMapper.selectCount(wrapper);
if(result != 0){
userRoleMapper.delete(wrapper);
}
TUserRole userRole = new TUserRole();
userRole.fillCreated();
userRole.setUserId(tUser.getId());
userRole.setRoleId(saveUserDto.getRoleId());
if(retBool(userRoleMapper.insert(userRole))){
return true;
}
throw new BuzEx(StatusEnum.FAIL);
}
return false;
}
@Override
public Page selectUserPage(Page page, Wrapper wrapper) {
page.setRecords(this.baseMapper.selectUserPage(page,wrapper));
return page;
}
@Override
@Transactional
public void saveBatchByImport(List<?> list,boolean isBackMap){
/* String defaultPwd = "123456";
if(!ObjectUtils.isEmpty(list)){
List<Map<String,Object>> dictList = dictService.listByCache(DictConstants.DEFAULT_PASSWORD);
if (!ObjectUtils.isEmpty(dictList)) {
defaultPwd = dictList.get(0).getOrDefault("value",defaultPwd).toString();
}
for(Object userVo:list){
LinkedHashMap<String,Object> linkedHashMap = (LinkedHashMap<String,Object>) userVo;
TUser user = new TUser();
List<String> collection = new ArrayList(linkedHashMap.values());
user.setAccount(collection.get(1));
user.setUserName(collection.get(0));
String salt = BCrypt.gensalt();
user.setSalt(salt);
user.setPassword(BCrypt.hashpw(defaultPwd,salt));
user.setStatus(1);
user.fillCreated();
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("account",user.getAccount());
if(this.baseMapper.selectCount(wrapper)>0){
logger.debug("存在相同用户,暂不处理");
continue;
}
if(this.baseMapper.insert(user) > 0){
wrapper = new QueryWrapper();
wrapper.eq("role_name",collection.get(2));
List<TRole> roles = this.roleMapper.selectList(wrapper);
if(!ObjectUtils.isEmpty(roles)){
TUserRole userRole = new TUserRole();
userRole.fillCreated();
userRole.setUserId(user.getId());
userRole.setRoleId(roles.get(0).getId());
userRoleMapper.insert(userRole);
}
}
}
}*/
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>chfa-platform</artifactId>
<groupId>com.changfa</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>chfa-platform-common</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.5</version>
</dependency>
<!-- easyexcel 依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<artifactId>lettuce-core</artifactId>
<groupId>io.lettuce</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>2.8.24</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.12</version>
</dependency>
<!--feign客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j</artifactId>
<version>2.8.3</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.20</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.baomidou.mybatisplus.extension.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import com.changfa.constants.ApiResult;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
public interface IService<T> {
int DEFAULT_BATCH_SIZE = 1000;
default boolean save(T entity) {
return SqlHelper.retBool(this.getBaseMapper().insert(entity));
}
@Transactional(
rollbackFor = {Exception.class}
)
default boolean saveBatch(Collection<T> entityList) {
return this.saveBatch(entityList, 1000);
}
boolean saveBatch(Collection<T> var1, int var2);
@Transactional(
rollbackFor = {Exception.class}
)
default boolean saveOrUpdateBatch(Collection<T> entityList) {
return this.saveOrUpdateBatch(entityList, 1000);
}
boolean saveOrUpdateBatch(Collection<T> var1, int var2);
default boolean removeById(Serializable id) {
return SqlHelper.retBool(this.getBaseMapper().deleteById(id));
}
default boolean removeByMap(Map<String, Object> columnMap) {
Assert.notEmpty(columnMap, "error: columnMap must not be empty", new Object[0]);
return SqlHelper.retBool(this.getBaseMapper().deleteByMap(columnMap));
}
default boolean remove(Wrapper<T> queryWrapper) {
return SqlHelper.retBool(this.getBaseMapper().delete(queryWrapper));
}
default boolean removeByIds(Collection<? extends Serializable> idList) {
return CollectionUtils.isEmpty(idList) ? false : SqlHelper.retBool(this.getBaseMapper().deleteBatchIds(idList));
}
default boolean updateById(T entity) {
return SqlHelper.retBool(this.getBaseMapper().updateById(entity));
}
default boolean update(Wrapper<T> updateWrapper) {
return this.update(null, updateWrapper);
}
default boolean update(T entity, Wrapper<T> updateWrapper) {
return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));
}
@Transactional(
rollbackFor = {Exception.class}
)
default boolean updateBatchById(Collection<T> entityList) {
return this.updateBatchById(entityList, 1000);
}
boolean updateBatchById(Collection<T> var1, int var2);
boolean saveOrUpdate(T var1);
default T getById(Serializable id) {
return this.getBaseMapper().selectById(id);
}
default List<T> listByIds(Collection<? extends Serializable> idList) {
return this.getBaseMapper().selectBatchIds(idList);
}
default List<T> listByMap(Map<String, Object> columnMap) {
return this.getBaseMapper().selectByMap(columnMap);
}
default T getOne(Wrapper<T> queryWrapper) {
return this.getOne(queryWrapper, true);
}
T getOne(Wrapper<T> var1, boolean var2);
Map<String, Object> getMap(Wrapper<T> var1);
<V> V getObj(Wrapper<T> var1, Function<? super Object, V> var2);
default int count() {
return this.count(Wrappers.emptyWrapper());
}
default int count(Wrapper<T> queryWrapper) {
return SqlHelper.retCount(this.getBaseMapper().selectCount(queryWrapper));
}
default List<T> list(Wrapper<T> queryWrapper) {
return this.getBaseMapper().selectList(queryWrapper);
}
default List<T> list() {
return this.list(Wrappers.emptyWrapper());
}
default <E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper) {
return this.getBaseMapper().selectPage(page, queryWrapper);
}
default <E extends IPage<T>> E page(E page) {
return this.page(page, Wrappers.emptyWrapper());
}
default List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper) {
return this.getBaseMapper().selectMaps(queryWrapper);
}
default List<Map<String, Object>> listMaps() {
return this.listMaps(Wrappers.emptyWrapper());
}
default List<Object> listObjs() {
return this.listObjs(Function.identity());
}
default <V> List<V> listObjs(Function<? super Object, V> mapper) {
return this.listObjs(Wrappers.emptyWrapper(), mapper);
}
default List<Object> listObjs(Wrapper<T> queryWrapper) {
return this.listObjs(queryWrapper, Function.identity());
}
default <V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
return (List)this.getBaseMapper().selectObjs(queryWrapper).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList());
}
default <E extends IPage<Map<String, Object>>> E pageMaps(E page, Wrapper<T> queryWrapper) {
return this.getBaseMapper().selectMapsPage(page, queryWrapper);
}
default <E extends IPage<Map<String, Object>>> E pageMaps(E page) {
return this.pageMaps(page, Wrappers.emptyWrapper());
}
BaseMapper<T> getBaseMapper();
default QueryChainWrapper<T> query() {
return ChainWrappers.queryChain(this.getBaseMapper());
}
default LambdaQueryChainWrapper<T> lambdaQuery() {
return ChainWrappers.lambdaQueryChain(this.getBaseMapper());
}
default UpdateChainWrapper<T> update() {
return ChainWrappers.updateChain(this.getBaseMapper());
}
default LambdaUpdateChainWrapper<T> lambdaUpdate() {
return ChainWrappers.lambdaUpdateChain(this.getBaseMapper());
}
default boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper) {
return this.update(entity, updateWrapper) || this.saveOrUpdate(entity);
}
ApiResult downloadExcel(Wrapper wrapper, HttpServletResponse response, String fileName)throws Exception;
ApiResult downloadExcel(List<?> list,HttpServletResponse response,String fileName)throws Exception;
ApiResult importExcel(MultipartFile multipartFile,boolean isBackMap)throws Exception;
}
package com.changfa.annotation;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ModelName {
String value();
}
package com.changfa.annotation;
import java.lang.annotation.*;
/**
* 系统日志注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
String value();
String type();
}
package com.changfa.aop;
import com.alibaba.fastjson.JSON;
import com.changfa.constants.LoginConstant;
import com.changfa.entity.TUser;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.SneakyThrows;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;
/**
* @author wwz
*/
@Aspect
public class AopLogConfig {
/**
* 进入方法时间戳
*/
private Long startTime;
/**
* 方法结束时间戳(计时)
*/
private Long endTime;
@Pointcut("execution(* com.changfa.controller..*(..))")
public void pointcut() {
}
/**
* 前置通知:
* 1. 在执行目标方法之前执行,比如请求接口之前的登录验证;
* 2. 在前置通知中设置请求日志信息,如开始时间,请求参数,注解内容等
*
* @param joinPoint
* @throws Throwable
*/
@Before("pointcut()")
@SneakyThrows
public void doBefore(JoinPoint joinPoint) {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) {
return;
}
HttpServletRequest request = attributes.getRequest();
Logger log = LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringType());
//获取请求头中的User-Agent
UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
//打印请求的内容
startTime = System.currentTimeMillis();
log.info("请求开始时间:{}", LocalDateTime.now());
log.info("调用方法:{}", ((MethodSignature) joinPoint.getSignature()).getMethod().getName());
log.info("请求Url : {}", request.getRequestURL().toString());
log.info("请求方式 : {}", request.getMethod());
log.info("请求ip : {}", request.getRemoteAddr());
log.info("请求参数 : {}", Arrays.toString(joinPoint.getArgs()));
// 系统信息
log.info("浏览器:{}", userAgent.getBrowser().toString());
log.info("浏览器版本:{}", userAgent.getBrowserVersion());
log.info("操作系统: {}", userAgent.getOperatingSystem().toString());
try {
if (!request.getRequestURI().contains("user/login")) {
TUser user = LoginConstant.currentUser();
if (user != null) {
log.info("当前用户: {}", user.getAccount());
}
}
} catch (Exception e) {
}
}
/**
* 返回通知:
* 1. 在目标方法正常结束之后执行
* 1. 在返回通知中补充请求日志信息,如返回时间,方法耗时,返回值,并且保存日志信息
*
* @param ret
* @throws Throwable
*/
@AfterReturning(returning = "ret", pointcut = "pointcut()")
@SneakyThrows
public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {
endTime = System.currentTimeMillis();
Logger log = LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringType());
log.info("请求结束时间:{}", LocalDateTime.now());
log.info("请求耗时:{}ms", (endTime - startTime));
// 处理完请求,返回内容
log.info("请求返回 : {}", JSON.toJSONString(ret));
}
/**
* 异常通知:
* 1. 在目标方法非正常结束,发生异常或者抛出异常时执行
* 1. 在异常通知中设置异常信息,并将其保存
*
* @param throwable
*/
@AfterThrowing(value = "pointcut()", throwing = "throwable")
public void doAfterThrowing(JoinPoint joinPoint, Throwable throwable) {
// 保存异常日志记录
Logger log = LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringType());
log.error("发生异常时间:{}", LocalDateTime.now());
log.error("抛出异常:{}", throwable.getMessage());
}
}
package com.changfa.base;
import com.alibaba.fastjson.JSON;
import com.changfa.dto.UserBaseDto;
import com.changfa.entity.TUser;
import com.changfa.utils.JwtUtil;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class BaseController {
protected final Logger log = LoggerFactory.getLogger(this.getClass());
public static UserBaseDto userBaseInfo(){
return JSON.parseObject(JwtUtil.getTokenData(SecurityUtils.getSubject().getSession().getId().toString()).toString(), UserBaseDto.class);
}
public static TUser currentUser(){
return JSON.parseObject(JwtUtil.getTokenData(SecurityUtils.getSubject().getSession().getId().toString()).toString(), UserBaseDto.class).getUser();
}
}
package com.changfa.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* Created with IntelliJ IDEA.
*
* @author wwz
* * @Description:
*/
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
/*
corsConfiguration.addAllowedOrigin("*");
*/
corsConfiguration.addAllowedOriginPattern("*");
// 预检请求的有效期,单位为秒。
corsConfiguration.setMaxAge(3600L);
// 是否支持安全证书(必需参数)
corsConfiguration.setAllowCredentials(true);
return corsConfiguration;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
/*
package com.changfa.config;
import com.changfa.enums.StatusEnum;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod;
import springfox.documentation.builders.*;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Configuration
@EnableSwagger2WebMvc
@EnableKnife4j
public class Knife4jConfiguration {
*/
/**
* 通过 createRestApi函数来构建一个DocketBean
* 函数名,可以随意命名,喜欢什么命名就什么命名
*//*
private List<Parameter> globalOperationParameters(){
List<Parameter> operationParameters = new ArrayList<>();
ParameterBuilder tokenPar = new ParameterBuilder();
tokenPar.name("Authorizations").description("Authorizations")
.modelRef(new ModelRef("string")).parameterType("header").required(false);
operationParameters.add(tokenPar.build());
return operationParameters;
}
private List<ResponseMessage> responseMessage(){
//添加全局响应状态码
List<ResponseMessage> responseMessageList = new ArrayList<>();
Arrays.stream(StatusEnum.values()).forEach(statusEnum -> {
responseMessageList.add(
new ResponseMessageBuilder().code(statusEnum.getCode()).message(statusEnum.getMessage()).responseModel(
new ModelRef(statusEnum.getMessage())).build()
);
});
return responseMessageList;
}
@Bean(value = "defaultApi2")
public Docket defaultApi2() {
Docket docket=new Docket(DocumentationType.SWAGGER_2).globalOperationParameters(globalOperationParameters())
.globalResponseMessage(RequestMethod.POST,responseMessage())
.globalResponseMessage(RequestMethod.GET,responseMessage())
.globalResponseMessage(RequestMethod.DELETE,responseMessage())
.globalResponseMessage(RequestMethod.PUT,responseMessage())
.apiInfo(apiInfo())
//分组名称
.groupName("2.X版本")
.select()
//这里指定Controller扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.changfa.controller"))
.paths(PathSelectors.any())
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
return docket;
}
//构建 api文档的详细信息函数
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//页面标题
.title("北京畅发平台服务端接口文档")
//条款地址
.version("1.0")
//描述
.description("API 描述")
.build();
}
private List<ApiKey> securitySchemes() {
List<ApiKey> apiKeys = new ArrayList<>();
apiKeys.add(new ApiKey("Authorizations", "Authorizations", "header"));
return apiKeys;
}
private List<SecurityContext> securityContexts() {
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$")).build());
return securityContexts;
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorizations", authorizationScopes));
return securityReferences;
}
}*/
package com.changfa.config;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.extension.MybatisMapWrapperFactory;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setObjectWrapperFactory(new MybatisMapWrapperFactory());
}
@Bean
public PaginationInterceptor mybatisPlusInterceptor() {
PaginationInterceptor interceptor = new PaginationInterceptor();
return interceptor;
}
}
package com.changfa.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
public class TaskConfig {
private static int corePoolSize = Runtime.getRuntime().availableProcessors();
@Bean("syncExecutorPool")
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 核心池大小
taskExecutor.setCorePoolSize(corePoolSize);
// 最大线程数
taskExecutor.setMaxPoolSize(corePoolSize+1);
// 队列程度
taskExecutor.setQueueCapacity(100);
// 线程空闲时间
taskExecutor.setKeepAliveSeconds(60);
// 线程前缀名称
taskExecutor.setThreadNamePrefix("syncExecutor--");
// 该方法用来设置 线程池关闭 的时候 等待 所有任务都完成后,再继续 销毁 其他的 Bean,
// 这样这些 异步任务 的 销毁 就会先于 数据库连接池对象 的销毁。
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
// 任务的等待时间 如果超过这个时间还没有销毁就 强制销毁,以确保应用最后能够被关闭,而不是阻塞住。
taskExecutor.setAwaitTerminationSeconds(60);
// 线程不够用时由调用的线程处理该任务
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return taskExecutor;
}
}
package com.changfa.config;
import com.changfa.config.interceptor.RefererInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 防盗链
* @return
*/
@Bean
public RefererInterceptor refererInterceptor(){
return new RefererInterceptor();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("doc.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
package com.changfa.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.websocket.*;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
@Component
@ClientEndpoint
public class WebSocketClient {
@Value("${websocket.server.url:127.0.0.1:8692/ws}")
private String serverUrl;
@Value("${websocket.server.user:system@1}")
private String user;
@Value("${websocket.server.isOpen:false}")
private boolean isOpen;
private Session session;
@PostConstruct
void init() {
try {
if(!isOpen){
return;
}
// 本机地址
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
String wsUrl = "ws://" + serverUrl + "/" + user;
URI uri = URI.create(wsUrl);
session = container.connectToServer(WebSocketClient.class, uri);
} catch (DeploymentException | IOException e) {
e.printStackTrace();
}
}
/**
* 打开连接
* @param session
*/
@OnOpen
public void onOpen(Session session) {
System.out.println("打开");
this.session = session;
}
/**
* 接收消息
* @param text
*/
@OnMessage
public void onMessage(String text) {
System.out.println(text);
}
/**
* 异常处理
* @param throwable
*/
@OnError
public void onError(Throwable throwable) {
throwable.printStackTrace();
}
/**
* 关闭连接
*/
@OnClose
public void onClosing() throws IOException {
System.out.println("关闭");
session.close();
}
/**
* 主动发送消息
*/
public void send(String message) {
try{
this.session.getAsyncRemote().sendText(message);
}catch (Exception e){
}
}
public void close() throws IOException{
if(this.session.isOpen()){
this.session.close();
}
}
}
package com.changfa.config.interceptor;
import com.changfa.config.interceptor.properties.RefererProperties;
import com.changfa.config.shiro.ShiroProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public class RefererInterceptor implements HandlerInterceptor {
@Autowired
private RefererProperties refererProperties;
@Autowired
private ShiroProperties shiroProperties;
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) {
String method = req.getMethod();
String referer = req.getHeader("referer");
if("POST".equals(method) || "GET".equals(method)){
if(!StringUtils.hasLength(referer)){
// 状态置为404
List<String> ignoreList = shiroProperties.getIgnoreAuthc();
if(!ObjectUtils.isEmpty(ignoreList)){
if(ignoreList.contains(req.getRequestURI().replace(req.getContextPath(),""))){
return true;
}
}
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
return false;
}
List<String> list = refererProperties.getRefererDomain();
if(!ObjectUtils.isEmpty(list)){
try{
referer = referer.split(":")[1].replace("//","");
if(!list.contains(referer)){
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
return false;
}
}catch (Exception e){
}
}
}
return true;
}
}
package com.changfa.config.interceptor.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@ConfigurationProperties(prefix = "referer")
@Data
@Component
public class RefererProperties {
private List<String> refererDomain = new ArrayList<>();
}
package com.changfa.config.shiro;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@ConfigurationProperties(prefix = "shiro")
@Data
@Component
public class ShiroProperties {
private List<String> ignoreAuthc;
}
package com.changfa.config.swagger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
@Configuration
@EnableSwagger2
@EnableAutoConfiguration
@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
public class SwaggerAutoConfiguration
{
/**
* 默认的排除路径,排除Spring Boot默认的错误处理路径和端点
*/
private static final List<String> DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**");
private static final String BASE_PATH = "/**";
@Bean
@ConditionalOnMissingBean
public SwaggerProperties swaggerProperties()
{
return new SwaggerProperties();
}
@Bean
public Docket api(SwaggerProperties swaggerProperties)
{
// base-path处理
if (swaggerProperties.getBasePath().isEmpty())
{
swaggerProperties.getBasePath().add(BASE_PATH);
}
// noinspection unchecked
List<Predicate<String>> basePath = new ArrayList<Predicate<String>>();
swaggerProperties.getBasePath().forEach(path -> basePath.add(PathSelectors.ant(path)));
// exclude-path处理
if (swaggerProperties.getExcludePath().isEmpty())
{
swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH);
}
List<Predicate<String>> excludePath = new ArrayList<>();
swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path)));
ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2).host(swaggerProperties.getHost())
.apiInfo(apiInfo(swaggerProperties)).select()
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()));
swaggerProperties.getBasePath().forEach(p -> builder.paths(PathSelectors.ant(p)));
swaggerProperties.getExcludePath().forEach(p -> builder.paths(PathSelectors.ant(p).negate()));
return builder.build().securitySchemes(securitySchemes()).securityContexts(securityContexts()).pathMapping("/");
}
/**
* 安全模式,这里指定token通过Authorization头请求头传递
*/
private List<SecurityScheme> securitySchemes()
{
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
return apiKeyList;
}
/**
* 安全上下文
*/
private List<SecurityContext> securityContexts()
{
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
.build());
return securityContexts;
}
/**
* 默认的全局鉴权策略
*
* @return
*/
private List<SecurityReference> defaultAuth()
{
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
private ApiInfo apiInfo(SwaggerProperties swaggerProperties)
{
return new ApiInfoBuilder()
.title(swaggerProperties.getTitle())
.description(swaggerProperties.getDescription())
.license(swaggerProperties.getLicense())
.licenseUrl(swaggerProperties.getLicenseUrl())
.termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
.contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail()))
.version(swaggerProperties.getVersion())
.build();
}
@Bean
public BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
@SuppressWarnings({"NullableProblems", "unchecked"})
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
if (null != field) {
field.setAccessible(true);
List<RequestMappingInfoHandlerMapping> mappings = (List<RequestMappingInfoHandlerMapping>) field.get(bean);
mappings.removeIf(e -> null != e.getPatternParser());
}
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
return bean;
}
};
}
}
package com.changfa.config.swagger;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
@ConfigurationProperties("swagger")
public class SwaggerProperties
{
/**
* 是否开启swagger
*/
private Boolean enabled;
/**
* swagger会解析的包路径
**/
private String basePackage = "";
/**
* swagger会解析的url规则
**/
private List<String> basePath = new ArrayList<>();
/**
* 在basePath基础上需要排除的url规则
**/
private List<String> excludePath = new ArrayList<>();
/**
* 标题
**/
private String title = "";
/**
* 描述
**/
private String description = "";
/**
* 版本
**/
private String version = "";
/**
* 许可证
**/
private String license = "";
/**
* 许可证URL
**/
private String licenseUrl = "";
/**
* 服务条款URL
**/
private String termsOfServiceUrl = "";
/**
* host信息
**/
private String host = "";
/**
* 联系人信息
*/
private Contact contact = new Contact();
/**
* 全局统一鉴权配置
**/
private Authorization authorization = new Authorization();
public Boolean getEnabled()
{
return enabled;
}
public void setEnabled(Boolean enabled)
{
this.enabled = enabled;
}
public String getBasePackage()
{
return basePackage;
}
public void setBasePackage(String basePackage)
{
this.basePackage = basePackage;
}
public List<String> getBasePath()
{
return basePath;
}
public void setBasePath(List<String> basePath)
{
this.basePath = basePath;
}
public List<String> getExcludePath()
{
return excludePath;
}
public void setExcludePath(List<String> excludePath)
{
this.excludePath = excludePath;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public String getVersion()
{
return version;
}
public void setVersion(String version)
{
this.version = version;
}
public String getLicense()
{
return license;
}
public void setLicense(String license)
{
this.license = license;
}
public String getLicenseUrl()
{
return licenseUrl;
}
public void setLicenseUrl(String licenseUrl)
{
this.licenseUrl = licenseUrl;
}
public String getTermsOfServiceUrl()
{
return termsOfServiceUrl;
}
public void setTermsOfServiceUrl(String termsOfServiceUrl)
{
this.termsOfServiceUrl = termsOfServiceUrl;
}
public String getHost()
{
return host;
}
public void setHost(String host)
{
this.host = host;
}
public Contact getContact()
{
return contact;
}
public void setContact(Contact contact)
{
this.contact = contact;
}
public Authorization getAuthorization()
{
return authorization;
}
public void setAuthorization(Authorization authorization)
{
this.authorization = authorization;
}
public static class Contact
{
/**
* 联系人
**/
private String name = "";
/**
* 联系人url
**/
private String url = "";
/**
* 联系人email
**/
private String email = "";
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
}
public static class Authorization
{
/**
* 鉴权策略ID,需要和SecurityReferences ID保持一致
*/
private String name = "";
/**
* 需要开启鉴权URL的正则
*/
private String authRegex = "^.*$";
/**
* 鉴权作用域列表
*/
private List<AuthorizationScope> authorizationScopeList = new ArrayList<>();
private List<String> tokenUrlList = new ArrayList<>();
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getAuthRegex()
{
return authRegex;
}
public void setAuthRegex(String authRegex)
{
this.authRegex = authRegex;
}
public List<AuthorizationScope> getAuthorizationScopeList()
{
return authorizationScopeList;
}
public void setAuthorizationScopeList(List<AuthorizationScope> authorizationScopeList)
{
this.authorizationScopeList = authorizationScopeList;
}
public List<String> getTokenUrlList()
{
return tokenUrlList;
}
public void setTokenUrlList(List<String> tokenUrlList)
{
this.tokenUrlList = tokenUrlList;
}
}
public static class AuthorizationScope
{
/**
* 作用域名称
*/
private String scope = "";
/**
* 作用域描述
*/
private String description = "";
public String getScope()
{
return scope;
}
public void setScope(String scope)
{
this.scope = scope;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
}
}
\ No newline at end of file
package com.changfa.constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.changfa.enums.StatusEnum;
import com.changfa.utils.PageBuilder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* API 返回结果封装
*
* @author Bamboo
* @since 2020-03-18
*/
@Data
@NoArgsConstructor
public class ApiResult implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 是否成功
*/
private Boolean success;
/**
* 状态码
*/
private Integer code;
/**
* 提示信息
*/
private String message;
/**
* 返回数据
*/
private Object data;
private ApiResult(Boolean success, Integer code, String message, Object data) {
this.success = success;
this.code = code;
this.message = message;
this.data = data;
}
/**
* 成功
*
* @return {ApiResult}
*/
public static ApiResult success() {
return new ApiResult(true, StatusEnum.OK.getCode(), StatusEnum.OK.getMessage(), "");
}
/**
* 成功
*
* @return {ApiResult}
*/
public static ApiResult success(String msg) {
return new ApiResult(true, StatusEnum.OK.getCode(), msg, "");
}
/**
* 成功
*
* @return {ApiResult}
*/
public static ApiResult success(Object data) {
return new ApiResult(true, StatusEnum.OK.getCode(), StatusEnum.OK.getMessage(), data);
}
/**
*
* @param page
* @return
*/
public static ApiResult success(Page page) {
PageBuilder pageBuilder = new PageBuilder();
return new ApiResult(true, StatusEnum.OK.getCode(), StatusEnum.OK.getMessage(), pageBuilder.builder(page));
}
/**
* 成功
*
* @return {ApiResult}
*/
public static ApiResult success(String msg, Object data) {
return new ApiResult(true, StatusEnum.OK.getCode(), msg, data);
}
/**
* 错误
*
* @return {ApiResult}
*/
public static ApiResult error(String msg) {
return new ApiResult(false, StatusEnum.INTERNAL_SERVER_ERROR.getCode(), msg, "");
}
public static ApiResult error(StatusEnum statusEnum) {
return new ApiResult(false, statusEnum.getCode(), statusEnum.getMessage(), "");
}
/**
* 错误
*
* @return {ApiResult}
*/
public static ApiResult error(Integer code, String msg) {
return new ApiResult(false, code, msg, "");
}
/**
* 错误
*
* @return {ApiResult}
*/
public static ApiResult error(Integer code, String msg, Object data) {
return new ApiResult(false, code, msg, data);
}
/**
* 自定义提示
*
* @return {ApiResult}
*/
public static ApiResult msg(Boolean success, Integer code, String msg, Object data) {
return new ApiResult(success, code, msg, data);
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
package com.changfa.constants;
public class CommomConstants {
public static final String AUTHORIZATION = "Authorizations";
public static final String keyPrefix = "shiro:session:";
public interface LEVEL{
//提示
Integer PROMPT = 1;
//一般
Integer NORMAL = 2;
//紧急
Integer EMERGENCY = 3;
}
public interface DEVICE_TYPE{
//可视对讲
Integer d10 = 10;
//交换机
Integer d1 = 1;
//路由器
Integer d2 = 2;
}
public interface WORK_RESULT{
//
Integer pending = 1;
Integer processed = 2;
Integer ignored = 3;
}
public interface DEVICE_OFF{
int STATUS_ONLINE = 1;
//2-离线
int STATUS_OFFLINE = 2;
}
public interface EXECUTE_PLAN{
String API = "接口";
String SDK = "SDK";
String PING = "ping";
String PROTOCOL = "协议";
//String SEND = "推送";
String HEART = "心跳";
}
}
package com.changfa.constants;
public interface DictConstants {
public final static String DEFAULT_PASSWORD = "DEFAULT_PASSWORD";
public final static String WB_TIME = "WB_TIME";
public final static String ALARM_TYPE = "ALARM_TYPE";
public final static String DEVICE_TYPE = "DEVICE_TYPE";
public final static String OFF_RATIO_COLOR = "OFF_RATIO_COLOR";
// 告警级别
public final static String ALARM_LEVEL = "ALARM_LEVEL";
public enum DictEnum{
;
DictEnum(String name,String subCode){
this.name = name;
this.subCode = subCode;
}
DictEnum(String name,String subCode,Integer code){
this.name = name;
this.subCode = subCode;
this.code = code;
}
//public static String get
private String name;
private String subCode;
private Integer code;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubCode() {
return subCode;
}
public void setSubCode(String subCode) {
this.subCode = subCode;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
}
package com.changfa.constants;
import com.alibaba.fastjson.JSON;
import com.changfa.dto.UserBaseDto;
import com.changfa.entity.TUser;
import com.changfa.utils.JwtUtil;
import org.apache.shiro.SecurityUtils;
public class LoginConstant {
public static TUser currentUser(){
return JSON.parseObject(JwtUtil.getTokenData(SecurityUtils.getSubject().getSession().getId().toString()).toString(), UserBaseDto.class).getUser();
}
public static UserBaseDto userBaseInfo(){
return JSON.parseObject(JwtUtil.getTokenData(SecurityUtils.getSubject().getSession().getId().toString()).toString(), UserBaseDto.class);
}
}
package com.changfa.constants;
/**
* @Description 方法类型枚举
* @Author lm
* @Date 2021/11/09 19:16
* @Version 1.0
**/
public class MethodTypeConstants {
/**
* 添加
*/
public static final String ADD="ADD";
/**
* 更新
*/
public static final String UPDATE="UPDATE";
/**
* 删除
*/
public static final String DEL="DEL";
/**
* 登录
*/
public static final String LOGIN="LOGIN";
/**
* 导入
*/
public static final String IMP="IMP";
/**
* 导出
*/
public static final String EXP="EXP";
}
/**
* Date: 2019/11/13
* Author: Zhengja
*/
package com.changfa.constants;
public final class RedisConstants {
public static final String _PREFIX = "sys:";
public static final String LOG_PREFIX = "log:";
//缓存组
public static final class EntityCacheKey {
public static final String DICT = _PREFIX + "dict:";
public static final String TIME = _PREFIX + "time:";
public static final String DICT_NO = _PREFIX + "dict";
public static final String MANAGE = _PREFIX + "manage";
public static final String OPINION = _PREFIX + "opinion";
public static final String POINT = _PREFIX + "point";
public static final String REPORTBIZ = _PREFIX + "reportbiz";
public static final String REPORTDATA = _PREFIX + "reportdata";
public static final String RESOURCE = _PREFIX + "resource";
public static final String TASK = _PREFIX + "task";
public final static String ZBB_LIST = "zbb_list";
public final static String MESSAGE = _PREFIX+"message";
public final static String TOP_LEVEL = MESSAGE+":isopen";
public final static String UNIQUE_KEY = "UNIQUE_KEY:INCR";
}
//缓存组
public static final class UserCacheKey {
public final static String USER_KEY = "user:";
}
//临时缓存 key
public static final String TEMP_REGION_IMPORT_KEY = LOG_PREFIX+"temp:import";
}
package com.changfa.constants;
public class ThreadContext {
private Object object;
private static ThreadLocal<Object> t = new ThreadLocal<>();
private static ThreadContext threadContext;
public static ThreadContext getInstance(){
if(threadContext == null){
threadContext = new ThreadContext();
}
return threadContext;
}
public ThreadContext(){
}
public void set(Object o){
t.set(o);
}
public Object get(){
return t.get();
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
package com.changfa.custom;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ExCondition<T> extends QueryWrapper<T>{
private static Pattern humpPattern = Pattern.compile("[A-Z]");
public static ExCondition create(){
return new ExCondition();
}
public QueryWrapper<T> eq(String column, Object params) {
if(ObjectUtils.isEmpty(params)){
return this;
}
return super.eq(true, humpToLine(column), params);
}
public QueryWrapper<T> ne(String column, Object params) {
if(ObjectUtils.isEmpty(params)){
return this;
}
return super.ne(true, humpToLine(column), params);
}
public QueryWrapper<T> in(String column, Collection<?> params) {
if(ObjectUtils.isEmpty(params)){
return this;
}
return super.in(true, humpToLine(column), params);
}
public QueryWrapper<T> likeRight(String column, Object params) {
if(ObjectUtils.isEmpty(params)){
return this;
}
return super.likeRight(true, humpToLine(column), params);
}
public QueryWrapper<T> like(String column, Object params) {
if(ObjectUtils.isEmpty(params)){
return this;
}
return super.like(true, humpToLine(column), params);
}
public QueryWrapper<T> between(String column, Object params, Object params1) {
if(ObjectUtils.isEmpty(params) || ObjectUtils.isEmpty(params1)){
return this;
}
return super.between(true, humpToLine(column), params,params1);
}
/**
* 驼峰转下划线,最后转为大写
* @param str
* @return
*/
public static String humpToLine(String str) {
Matcher matcher = humpPattern.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, "_" + matcher.group(0).toUpperCase());
}
matcher.appendTail(sb);
return sb.toString();
}
public static void main(String[] args){
System.out.println(humpToLine("user_name"));
}
}
package com.changfa.dto;
import java.io.Serializable;
import java.util.List;
public class MenuDto implements Serializable{
private String path;
private String name;
private String component;
private Integer id;
private Integer parentKey;
private List<MenuDto> children;
private String meta;
private String hidden;
private String redirect;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComponent() {
return component;
}
public void setComponent(String component) {
this.component = component;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getParentKey() {
return parentKey;
}
public void setParentKey(Integer parentKey) {
this.parentKey = parentKey;
}
public List<MenuDto> getChildren() {
return children;
}
public void setChildren(List<MenuDto> children) {
this.children = children;
}
public String getMeta() {
return meta;
}
public void setMeta(String meta) {
this.meta = meta;
}
public String getHidden() {
return hidden;
}
public void setHidden(String hidden) {
this.hidden = hidden;
}
public String getRedirect() {
return redirect;
}
public void setRedirect(String redirect) {
this.redirect = redirect;
}
}
package com.changfa.dto;
import com.changfa.entity.TRole;
import com.changfa.entity.TUser;
import lombok.Data;
import java.util.List;
@Data
public class UserBaseDto {
private List<MenuDto> menuList;
private TRole role;
private TUser user;
}
package com.changfa.entity;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
/**
* <p>
*
* </p>
*
* @author wwz
* @since 2022-06-24
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("t_role")
@ApiModel(value="TRole对象", description="")
public class TRole extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键id",hidden = true)
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "角色名称")
@TableField("role_name")
@NotEmpty(message = "角色名称不能为空")
private String roleName;
@ApiModelProperty(value = "角色编号")
@TableField("role_code")
@NotEmpty(message = "角色编码不能为空")
private String roleCode;
@ApiModelProperty(value = "顺序")
@TableField("order_no")
private Integer orderNo;
@ApiModelProperty(value = "描述")
@TableField("describe_info")
private String describeInfo;
@TableLogic(delval = "1",value = "0")
@ApiModelProperty(value = "删除状态",hidden = true)
// @ExcelProperty(value = "删除状态",converter = LogicDelConvert.class)
private Integer logicDel;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment