parent
dddb0b322e
commit
29919cadc3
@ -1,29 +1,62 @@
|
|||||||
package org.opsli.api.wrapper.system.dict;
|
package org.opsli.api.wrapper.system.dict;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.opsli.api.base.warpper.ApiWrapper;
|
||||||
|
import org.opsli.common.annotation.validation.ValidationArgs;
|
||||||
|
import org.opsli.common.annotation.validation.ValidationArgsMax;
|
||||||
|
import org.opsli.common.enums.ValiArgsType;
|
||||||
|
import org.opsli.plugins.excel.annotation.ExcelInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @BelongsProject: opsli-boot
|
* @BelongsProject: opsli-boot
|
||||||
* @BelongsPackage: org.opsli.modulars.test.entity
|
* @BelongsPackage: org.opsli.modulars.test.entity
|
||||||
* @Author: Parker
|
* @Author: Parker
|
||||||
* @CreateTime: 2020-09-16 17:33
|
* @CreateTime: 2020-09-16 17:33
|
||||||
* @Description: 数据字典 - 工具类用
|
* @Description: 数据字典
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class DictModel {
|
public class DictModel extends ApiWrapper {
|
||||||
|
|
||||||
/** 类型编号 - 冗余 */
|
|
||||||
|
|
||||||
|
/** 字典类型编号 */
|
||||||
|
@ApiModelProperty(value = "字典类型编号")
|
||||||
|
@ExcelProperty(value = "字典类型编号", order = 1)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL, ValiArgsType.IS_GENERAL})
|
||||||
|
@ValidationArgsMax(120)
|
||||||
private String typeCode;
|
private String typeCode;
|
||||||
|
|
||||||
/** 字典名称 */
|
/** 字典类型名称 */
|
||||||
private String dictName;
|
@ApiModelProperty(value = "字典类型名称")
|
||||||
|
@ExcelProperty(value = "字典类型名称", order = 2)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL, ValiArgsType.IS_GENERAL_WITH_CHINESE})
|
||||||
|
@ValidationArgsMax(120)
|
||||||
|
private String typeName;
|
||||||
|
|
||||||
|
/** 是否内置数据 0是 1否*/
|
||||||
|
@ApiModelProperty(value = "是否内置数据 0是 1否")
|
||||||
|
@ExcelProperty(value = "是否内置数据", order = 3)
|
||||||
|
@ExcelInfo(dictType = "yes_no")
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs(ValiArgsType.IS_NOT_NULL)
|
||||||
|
@ValidationArgsMax(1)
|
||||||
|
private Character izLock;
|
||||||
|
|
||||||
/** 字典值 */
|
/** 备注 */
|
||||||
private String dictValue;
|
@ApiModelProperty(value = "备注")
|
||||||
|
@ExcelProperty(value = "备注", order = 4)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgsMax(255)
|
||||||
|
private String remark;
|
||||||
|
|
||||||
/** 消息 */
|
|
||||||
private SysDictDetailModel model;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
package org.opsli.api.wrapper.system.dict;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.entity
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:33
|
||||||
|
* @Description: 数据字典 - 工具类用
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class DictWrapper {
|
||||||
|
|
||||||
|
/** 类型编号 - 冗余 */
|
||||||
|
private String typeCode;
|
||||||
|
|
||||||
|
/** 字典名称 */
|
||||||
|
private String dictName;
|
||||||
|
|
||||||
|
/** 字典值 */
|
||||||
|
private String dictValue;
|
||||||
|
|
||||||
|
/** 消息 */
|
||||||
|
private DictDetailModel model;
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,61 +0,0 @@
|
|||||||
package org.opsli.api.wrapper.system.dict;
|
|
||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import org.opsli.api.base.warpper.ApiWrapper;
|
|
||||||
import org.opsli.common.annotation.validation.ValidationArgs;
|
|
||||||
import org.opsli.common.annotation.validation.ValidationArgsMax;
|
|
||||||
import org.opsli.common.enums.ValiArgsType;
|
|
||||||
import org.opsli.plugins.excel.annotation.CellStyleFormat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @BelongsProject: opsli-boot
|
|
||||||
* @BelongsPackage: org.opsli.modulars.test.entity
|
|
||||||
* @Author: Parker
|
|
||||||
* @CreateTime: 2020-09-16 17:33
|
|
||||||
* @Description: 数据字典
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = false)
|
|
||||||
public class SysDictModel extends ApiWrapper {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** 字典类型编号 */
|
|
||||||
@ApiModelProperty(value = "字典类型编号")
|
|
||||||
@ExcelProperty(value = "字典类型编号", order = 1)
|
|
||||||
@CellStyleFormat
|
|
||||||
// 验证器
|
|
||||||
@ValidationArgs({ValiArgsType.IS_NOT_NULL, ValiArgsType.IS_GENERAL})
|
|
||||||
@ValidationArgsMax(120)
|
|
||||||
private String typeCode;
|
|
||||||
|
|
||||||
/** 字典类型名称 */
|
|
||||||
@ApiModelProperty(value = "字典类型名称")
|
|
||||||
@ExcelProperty(value = "字典类型名称", order = 2)
|
|
||||||
@CellStyleFormat
|
|
||||||
// 验证器
|
|
||||||
@ValidationArgs({ValiArgsType.IS_NOT_NULL, ValiArgsType.IS_GENERAL_WITH_CHINESE})
|
|
||||||
@ValidationArgsMax(120)
|
|
||||||
private String typeName;
|
|
||||||
|
|
||||||
/** 是否内置数据 */
|
|
||||||
@ApiModelProperty(value = "是否内置数据")
|
|
||||||
@ExcelProperty(value = "是否内置数据", order = 3)
|
|
||||||
@CellStyleFormat
|
|
||||||
// 验证器
|
|
||||||
@ValidationArgs(ValiArgsType.IS_NOT_NULL)
|
|
||||||
private Character izLock;
|
|
||||||
|
|
||||||
/** 备注 */
|
|
||||||
@ApiModelProperty(value = "备注")
|
|
||||||
@ExcelProperty(value = "备注", order = 4)
|
|
||||||
@CellStyleFormat
|
|
||||||
// 验证器
|
|
||||||
@ValidationArgsMax(255)
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
package org.opsli.api.wrapper.system.menu;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.opsli.api.base.warpper.ApiWrapper;
|
||||||
|
import org.opsli.common.annotation.validation.ValidationArgs;
|
||||||
|
import org.opsli.common.annotation.validation.ValidationArgsMax;
|
||||||
|
import org.opsli.common.enums.ValiArgsType;
|
||||||
|
import org.opsli.plugins.excel.annotation.ExcelInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.entity
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:33
|
||||||
|
* @Description: 菜单表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class MenuModel extends ApiWrapper {
|
||||||
|
|
||||||
|
/** 父级主键 */
|
||||||
|
@ApiModelProperty(value = "父级主键")
|
||||||
|
@ExcelProperty(value = "父级主键", order = 1)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs(ValiArgsType.IS_NOT_NULL)
|
||||||
|
@ValidationArgsMax(20)
|
||||||
|
private String parentId;
|
||||||
|
|
||||||
|
/** 菜单编号 */
|
||||||
|
@ApiModelProperty(value = "菜单编号")
|
||||||
|
@ExcelProperty(value = "菜单编号", order = 2)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL,ValiArgsType.IS_GENERAL})
|
||||||
|
@ValidationArgsMax(50)
|
||||||
|
private String menuCode;
|
||||||
|
|
||||||
|
/** 菜单名称 */
|
||||||
|
@ApiModelProperty(value = "菜单名称")
|
||||||
|
@ExcelProperty(value = "菜单名称", order = 3)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL,ValiArgsType.IS_GENERAL_WITH_CHINESE})
|
||||||
|
@ValidationArgsMax(50)
|
||||||
|
private String menuName;
|
||||||
|
|
||||||
|
/** 图标 */
|
||||||
|
@ApiModelProperty(value = "图标")
|
||||||
|
@ExcelProperty(value = "图标", order = 4)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgsMax(50)
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
/** 项目类型:1-菜单2-按钮3-链接4-表单 */
|
||||||
|
@ApiModelProperty(value = "项目类型:1-菜单2-按钮3-链接4-表单")
|
||||||
|
@ExcelProperty(value = "项目类型", order = 5)
|
||||||
|
@ExcelInfo(dictType = "menuType")
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL})
|
||||||
|
@ValidationArgsMax(20)
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/** url地址 */
|
||||||
|
@ApiModelProperty(value = "url地址")
|
||||||
|
@ExcelProperty(value = "url地址", order = 6)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgsMax(200)
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package org.opsli.api.wrapper.system.role;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.opsli.api.base.warpper.ApiWrapper;
|
||||||
|
import org.opsli.common.annotation.validation.ValidationArgs;
|
||||||
|
import org.opsli.common.annotation.validation.ValidationArgsMax;
|
||||||
|
import org.opsli.common.enums.ValiArgsType;
|
||||||
|
import org.opsli.plugins.excel.annotation.ExcelInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.entity
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:33
|
||||||
|
* @Description: 角色表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class RoleModel extends ApiWrapper {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** 角色编码 */
|
||||||
|
@ApiModelProperty(value = "角色编码")
|
||||||
|
@ExcelProperty(value = "角色编码", order = 1)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL,ValiArgsType.IS_GENERAL})
|
||||||
|
@ValidationArgsMax(50)
|
||||||
|
private String roleCode;
|
||||||
|
|
||||||
|
/** 角色名称 */
|
||||||
|
@ApiModelProperty(value = "角色编码")
|
||||||
|
@ExcelProperty(value = "角色编码", order = 2)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL,ValiArgsType.IS_GENERAL})
|
||||||
|
@ValidationArgsMax(50)
|
||||||
|
private String roleName;
|
||||||
|
|
||||||
|
/** 是否内置数据 0是 1否*/
|
||||||
|
@ApiModelProperty(value = "是否内置数据 0是 1否")
|
||||||
|
@ExcelProperty(value = "是否内置数据", order = 3)
|
||||||
|
@ExcelInfo(dictType = "yes_no")
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL,ValiArgsType.IS_GENERAL})
|
||||||
|
@ValidationArgsMax(1)
|
||||||
|
private Character izLock;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
@ApiModelProperty(value = "备注")
|
||||||
|
@ExcelProperty(value = "备注", order = 4)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgsMax(255)
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,121 @@
|
|||||||
|
package org.opsli.api.wrapper.system.user;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelIgnore;
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.opsli.api.base.warpper.ApiWrapper;
|
||||||
|
import org.opsli.common.annotation.validation.ValidationArgs;
|
||||||
|
import org.opsli.common.annotation.validation.ValidationArgsMax;
|
||||||
|
import org.opsli.common.enums.ValiArgsType;
|
||||||
|
import org.opsli.plugins.excel.annotation.ExcelInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.entity
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:33
|
||||||
|
* @Description: 用户信息表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class UserModel extends ApiWrapper {
|
||||||
|
|
||||||
|
|
||||||
|
/** 登录账户 */
|
||||||
|
@ApiModelProperty(value = "登录账户")
|
||||||
|
@ExcelIgnore
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL,ValiArgsType.IS_GENERAL})
|
||||||
|
@ValidationArgsMax(32)
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
/** 登录密码 */
|
||||||
|
@ApiModelProperty(value = "登录密码")
|
||||||
|
@ExcelIgnore
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgsMax(50)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/** 盐值,密码秘钥 */
|
||||||
|
@ApiModelProperty(value = "盐值,密码秘钥")
|
||||||
|
@ExcelIgnore
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgsMax(50)
|
||||||
|
private String secretkey;
|
||||||
|
|
||||||
|
/** 是否锁定 */
|
||||||
|
@ApiModelProperty(value = "是否锁定")
|
||||||
|
@ExcelIgnore
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL})
|
||||||
|
@ValidationArgsMax(1)
|
||||||
|
private Character locked;
|
||||||
|
|
||||||
|
/** 真实姓名 */
|
||||||
|
@ApiModelProperty(value = "真实姓名")
|
||||||
|
@ExcelProperty(value = "真实姓名", order = 1)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_NOT_NULL,ValiArgsType.IS_GENERAL_WITH_CHINESE})
|
||||||
|
@ValidationArgsMax(50)
|
||||||
|
private String realName;
|
||||||
|
|
||||||
|
/** 手机 */
|
||||||
|
@ApiModelProperty(value = "手机")
|
||||||
|
@ExcelProperty(value = "手机", order = 2)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_MOBILE})
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
@ApiModelProperty(value = "邮箱")
|
||||||
|
@ExcelProperty(value = "邮箱", order = 3)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_EMAIL})
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
/** 工号 */
|
||||||
|
@ApiModelProperty(value = "工号")
|
||||||
|
@ExcelProperty(value = "工号", order = 4)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs({ValiArgsType.IS_GENERAL})
|
||||||
|
@ValidationArgsMax(32)
|
||||||
|
private String no;
|
||||||
|
|
||||||
|
/** 头像 */
|
||||||
|
@ApiModelProperty(value = "头像")
|
||||||
|
@ExcelIgnore
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgsMax(255)
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
/** 最后登陆IP */
|
||||||
|
@ApiModelProperty(value = "最后登陆IP")
|
||||||
|
@ExcelIgnore
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgs(ValiArgsType.IS_IPV4)
|
||||||
|
private String loginIp;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
@ApiModelProperty(value = "备注")
|
||||||
|
@ExcelProperty(value = "备注", order = 5)
|
||||||
|
@ExcelInfo
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgsMax(255)
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
|
||||||
|
/** 多租户字段 */
|
||||||
|
@ApiModelProperty(value = "多租户ID")
|
||||||
|
@ExcelIgnore
|
||||||
|
// 验证器
|
||||||
|
@ValidationArgsMax(20)
|
||||||
|
private String tenantId;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,23 +0,0 @@
|
|||||||
package org.opsli.common.annotation;
|
|
||||||
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @BelongsProject: opsli-boot
|
|
||||||
* @BelongsPackage: org.opsli.common.annotation
|
|
||||||
* @Author: Parker
|
|
||||||
* @CreateTime: 2020-09-16 16:36
|
|
||||||
* @Description: 字典标示
|
|
||||||
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
@Documented
|
|
||||||
public @interface DictType {
|
|
||||||
|
|
||||||
/** 字典类型 code */
|
|
||||||
String value();
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.opsli.common.annotation;
|
package org.opsli.common.annotation.hotdata;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.opsli.common.annotation;
|
package org.opsli.common.annotation.hotdata;
|
||||||
|
|
||||||
import org.opsli.common.constants.CacheConstants;
|
import org.opsli.common.constants.CacheConstants;
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.opsli.common.annotation;
|
package org.opsli.common.annotation.hotdata;
|
||||||
|
|
||||||
import org.opsli.common.constants.CacheConstants;
|
import org.opsli.common.constants.CacheConstants;
|
||||||
|
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package org.opsli.common.api;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于存放当前线程下 Token
|
||||||
|
*
|
||||||
|
* @author parker
|
||||||
|
* @date 2020-09-15
|
||||||
|
*/
|
||||||
|
public class TokenThreadLocal {
|
||||||
|
|
||||||
|
/** 临时线程存储 token 容器 */
|
||||||
|
private static final ThreadLocal<String> tokenData = new ThreadLocal<>();
|
||||||
|
|
||||||
|
public static void put(String token) {
|
||||||
|
if (tokenData.get() == null) {
|
||||||
|
tokenData.set(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String get() {
|
||||||
|
return tokenData.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void remove() {
|
||||||
|
try {
|
||||||
|
tokenData.remove();
|
||||||
|
}catch (Exception e){}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package org.opsli.common.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.common.constants
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:42
|
||||||
|
* @Description: 签名
|
||||||
|
*/
|
||||||
|
public interface SignConstants {
|
||||||
|
|
||||||
|
/** username */
|
||||||
|
String ACCOUNT = "account";
|
||||||
|
|
||||||
|
/** user Id */
|
||||||
|
String USER_ID = "userId";
|
||||||
|
|
||||||
|
/** 时间戳 */
|
||||||
|
String TIMESTAMP = "timestamp";
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
package org.opsli.core.aspect;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.opsli.common.api.TokenThreadLocal;
|
||||||
|
import org.opsli.common.exception.ServiceException;
|
||||||
|
import org.opsli.core.utils.UserTokenUtil;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.request.RequestAttributes;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import static org.opsli.common.constants.OrderConstants.TOKEN_AOP_SORT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数校验 拦截处理
|
||||||
|
*
|
||||||
|
* @author parker
|
||||||
|
* @date 2020-09-16
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Order(TOKEN_AOP_SORT)
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class TokenAop {
|
||||||
|
|
||||||
|
|
||||||
|
@Pointcut("execution(public * org.opsli.modulars*..*.*Controller*.*(..))")
|
||||||
|
public void requestMapping() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切如 post 请求
|
||||||
|
* @param point
|
||||||
|
*/
|
||||||
|
@Around("requestMapping()")
|
||||||
|
public Object tokenAop(ProceedingJoinPoint point) throws Throwable {
|
||||||
|
|
||||||
|
// 将 Token放入 线程缓存
|
||||||
|
try {
|
||||||
|
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
|
||||||
|
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
|
||||||
|
HttpServletRequest request = sra.getRequest();
|
||||||
|
String requestToken = UserTokenUtil.getRequestToken(request);
|
||||||
|
if(StringUtils.isNotEmpty(requestToken)){
|
||||||
|
// 放入当前线程缓存中
|
||||||
|
TokenThreadLocal.put(requestToken);
|
||||||
|
}
|
||||||
|
}catch (ServiceException e){
|
||||||
|
throw e;
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error(e.getMessage(),e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防止线程抛异常 线程变量不回收 导致oom
|
||||||
|
Object returnValue = null;
|
||||||
|
try {
|
||||||
|
// 执行正常操作
|
||||||
|
Object[] args= point.getArgs();
|
||||||
|
returnValue = point.proceed(args);
|
||||||
|
} finally {
|
||||||
|
// 线程销毁时 删除 token
|
||||||
|
TokenThreadLocal.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package org.opsli.core.conf;
|
||||||
|
|
||||||
|
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
||||||
|
import com.google.code.kaptcha.util.Config;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成验证码配置
|
||||||
|
*
|
||||||
|
* @author 孙志强
|
||||||
|
|
||||||
|
* @date 2017-04-20 19:22
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class KaptchaConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DefaultKaptcha producer() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.put("kaptcha.border", "no");
|
||||||
|
properties.put("kaptcha.textproducer.font.color", "black");
|
||||||
|
properties.put("kaptcha.textproducer.char.space", "10");
|
||||||
|
properties.put("kaptcha.textproducer.char.string", "1234567890");
|
||||||
|
properties.put("kaptcha.textproducer.char.length", "4");
|
||||||
|
Config config = new Config(properties);
|
||||||
|
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
|
||||||
|
defaultKaptcha.setConfig(config);
|
||||||
|
return defaultKaptcha;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,125 @@
|
|||||||
|
package org.opsli.core.conf;
|
||||||
|
|
||||||
|
import org.apache.shiro.mgt.SecurityManager;
|
||||||
|
import org.apache.shiro.session.mgt.SessionManager;
|
||||||
|
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||||
|
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||||
|
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||||
|
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||||
|
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
||||||
|
import org.opsli.core.security.shiro.filter.OAuth2Filter;
|
||||||
|
import org.opsli.core.security.shiro.realm.OAuth2Realm;
|
||||||
|
import org.opsli.plugins.redis.conf.RedisPluginConfig;
|
||||||
|
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.DependsOn;
|
||||||
|
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||||
|
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shiro配置
|
||||||
|
*
|
||||||
|
* 全程用 token认证 所以也就用不着 什么共享缓存 - 无状态
|
||||||
|
*
|
||||||
|
* @author parker
|
||||||
|
* @date 2017-04-20 18:33
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@AutoConfigureAfter(RedisPluginConfig.class)
|
||||||
|
public class ShiroConfig {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* filer
|
||||||
|
* @param securityManager
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean("shiroFilter")
|
||||||
|
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
|
||||||
|
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
|
||||||
|
shiroFilter.setSecurityManager(securityManager);
|
||||||
|
|
||||||
|
//oauth过滤
|
||||||
|
Map<String, Filter> filters = new HashMap<>();
|
||||||
|
filters.put("oauth2", new OAuth2Filter());
|
||||||
|
shiroFilter.setFilters(filters);
|
||||||
|
|
||||||
|
Map<String, String> filterMap = new LinkedHashMap<>();
|
||||||
|
filterMap.put("/webjars/**", "anon");
|
||||||
|
filterMap.put("/druid/**", "anon");
|
||||||
|
filterMap.put("/app/**", "anon");
|
||||||
|
filterMap.put("/sys/login", "anon");
|
||||||
|
filterMap.put("/swagger/**", "anon");
|
||||||
|
filterMap.put("/v2/api-docs", "anon");
|
||||||
|
filterMap.put("/doc.html", "anon");
|
||||||
|
filterMap.put("/swagger-ui.html", "anon");
|
||||||
|
filterMap.put("/swagger-resources/**", "anon");
|
||||||
|
filterMap.put("/captcha.jpg", "anon");
|
||||||
|
filterMap.put("/ueditor/**", "anon");
|
||||||
|
filterMap.put("/**", "oauth2");
|
||||||
|
shiroFilter.setFilterChainDefinitionMap(filterMap);
|
||||||
|
|
||||||
|
return shiroFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean("sessionManager")
|
||||||
|
public SessionManager sessionManager(){
|
||||||
|
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
|
||||||
|
sessionManager.setSessionValidationSchedulerEnabled(true);
|
||||||
|
sessionManager.setSessionIdCookieEnabled(true);
|
||||||
|
return sessionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean("securityManager")
|
||||||
|
public DefaultWebSecurityManager securityManager(OAuth2Realm oAuth2Realm, SessionManager sessionManager,LettuceConnectionFactory lettuceConnectionFactory) {
|
||||||
|
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
||||||
|
securityManager.setRealm(oAuth2Realm);
|
||||||
|
securityManager.setSessionManager(sessionManager);
|
||||||
|
return securityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public OAuth2Realm oAuth2Realm() {
|
||||||
|
return new OAuth2Realm();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===================== 固定三板斧 =====================
|
||||||
|
// 其实 没有 Spring Security 配置起来简单
|
||||||
|
//
|
||||||
|
|
||||||
|
@Bean("lifecycleBeanPostProcessor")
|
||||||
|
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
|
||||||
|
return new LifecycleBeanPostProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean("defaultAdvisorAutoProxyCreator")
|
||||||
|
@DependsOn("lifecycleBeanPostProcessor")
|
||||||
|
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
|
||||||
|
DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||||
|
proxyCreator.setProxyTargetClass(true);
|
||||||
|
proxyCreator.setUsePrefix(true);
|
||||||
|
proxyCreator.setAdvisorBeanNamePrefix("_no_advisor");
|
||||||
|
return proxyCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启shiro权限注解生效
|
||||||
|
* @param securityManager
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean("authorizationAttributeSourceAdvisor")
|
||||||
|
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
|
||||||
|
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
|
||||||
|
advisor.setSecurityManager(securityManager);
|
||||||
|
return advisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package org.opsli.core.filter;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.opsli.common.api.TokenThreadLocal;
|
||||||
|
import org.opsli.core.utils.UserTokenUtil;
|
||||||
|
|
||||||
|
import javax.servlet.*;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token 拦截器 用于存放 token
|
||||||
|
*/
|
||||||
|
public class TokenFilter implements Filter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||||
|
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||||
|
// 获得请求中 Token
|
||||||
|
String requestToken = UserTokenUtil.getRequestToken(request);
|
||||||
|
if(StringUtils.isNotEmpty(requestToken)){
|
||||||
|
// 放入当前线程缓存中
|
||||||
|
TokenThreadLocal.put(requestToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
filterChain.doFilter(servletRequest,servletResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
// 线程销毁时 删除 token
|
||||||
|
TokenThreadLocal.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package org.opsli.core.listener;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.opsli.core.general.StartPrint;
|
||||||
|
import org.springframework.boot.context.event.ApplicationFailedEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统启动失败
|
||||||
|
*
|
||||||
|
* @author parker
|
||||||
|
* @date 2020-03-31 13:56
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class ApplicationFailedEventListener implements ApplicationListener<ApplicationFailedEvent> {
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationFailedEvent event) {
|
||||||
|
StartPrint.INSTANCE.errorPrint();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package org.opsli.core.listener;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.opsli.core.general.StartPrint;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统启动成功
|
||||||
|
*
|
||||||
|
* @author parker
|
||||||
|
* @date 2020-03-31 13:56
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class ApplicationReadyEventListene implements ApplicationListener<ApplicationReadyEvent> {
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||||
|
ConfigurableApplicationContext applicationContext = event.getApplicationContext();
|
||||||
|
StartPrint.INSTANCE.successPrint(applicationContext.getEnvironment());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,256 @@
|
|||||||
|
package org.opsli.core.security.shiro.cache;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.shiro.cache.Cache;
|
||||||
|
import org.apache.shiro.cache.CacheException;
|
||||||
|
import org.apache.shiro.subject.PrincipalCollection;
|
||||||
|
import org.apache.shiro.util.CollectionUtils;
|
||||||
|
import org.opsli.core.security.shiro.exception.PrincipalIdNullException;
|
||||||
|
import org.opsli.core.security.shiro.exception.PrincipalInstanceException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: sunzhiqiang
|
||||||
|
* @date: 2018/6/22
|
||||||
|
* @description: 参考 shiro-redis 开源项目 Git地址 https://github.com/alexxiyang/shiro-redis
|
||||||
|
*/
|
||||||
|
public class RedisCache<K, V> implements Cache<K, V> {
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(RedisCache.class);
|
||||||
|
|
||||||
|
private RedisManager redisManager;
|
||||||
|
private String keyPrefix = "";
|
||||||
|
private int expire = 0;
|
||||||
|
private String principalIdFieldName = RedisCacheManager.DEFAULT_PRINCIPAL_ID_FIELD_NAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construction
|
||||||
|
* @param redisManager
|
||||||
|
*/
|
||||||
|
public RedisCache(RedisManager redisManager, String prefix, int expire, String principalIdFieldName) {
|
||||||
|
if (redisManager == null) {
|
||||||
|
throw new IllegalArgumentException("redisManager cannot be null.");
|
||||||
|
}
|
||||||
|
this.redisManager = redisManager;
|
||||||
|
if (prefix != null && !"".equals(prefix)) {
|
||||||
|
this.keyPrefix = prefix;
|
||||||
|
}
|
||||||
|
if (expire != -1) {
|
||||||
|
this.expire = expire;
|
||||||
|
}
|
||||||
|
if (principalIdFieldName != null && !"".equals(principalIdFieldName)) {
|
||||||
|
this.principalIdFieldName = principalIdFieldName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V get(K key) throws CacheException {
|
||||||
|
logger.debug("get key [{}]",key);
|
||||||
|
|
||||||
|
if (key == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String redisCacheKey = getRedisCacheKey(key);
|
||||||
|
Object rawValue = redisManager.get(redisCacheKey);
|
||||||
|
if (rawValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
V value = (V) rawValue;
|
||||||
|
return value;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CacheException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V put(K key, V value) throws CacheException {
|
||||||
|
logger.debug("put key [{}]",key);
|
||||||
|
if (key == null) {
|
||||||
|
logger.warn("Saving a null key is meaningless, return value directly without call Redis.");
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String redisCacheKey = getRedisCacheKey(key);
|
||||||
|
redisManager.set(redisCacheKey, value != null ? value : null, expire);
|
||||||
|
return value;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CacheException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V remove(K key) throws CacheException {
|
||||||
|
logger.debug("remove key [{}]",key);
|
||||||
|
if (key == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String redisCacheKey = getRedisCacheKey(key);
|
||||||
|
Object rawValue = redisManager.get(redisCacheKey);
|
||||||
|
V previous = (V) rawValue;
|
||||||
|
redisManager.del(redisCacheKey);
|
||||||
|
return previous;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CacheException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRedisCacheKey(K key) {
|
||||||
|
if (key == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.keyPrefix + getStringRedisKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStringRedisKey(K key) {
|
||||||
|
String redisKey;
|
||||||
|
if (key instanceof PrincipalCollection) {
|
||||||
|
redisKey = getRedisKeyFromPrincipalIdField((PrincipalCollection) key);
|
||||||
|
} else {
|
||||||
|
redisKey = key.toString();
|
||||||
|
}
|
||||||
|
return redisKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRedisKeyFromPrincipalIdField(PrincipalCollection key) {
|
||||||
|
String redisKey;
|
||||||
|
Object principalObject = key.getPrimaryPrincipal();
|
||||||
|
Method pincipalIdGetter = null;
|
||||||
|
Method[] methods = principalObject.getClass().getDeclaredMethods();
|
||||||
|
for (Method m:methods) {
|
||||||
|
if (RedisCacheManager.DEFAULT_PRINCIPAL_ID_FIELD_NAME.equals(this.principalIdFieldName)
|
||||||
|
&& ("getAuthCacheKey".equals(m.getName()) || "getId".equals(m.getName()))) {
|
||||||
|
pincipalIdGetter = m;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (m.getName().equals("get" + this.principalIdFieldName.substring(0, 1).toUpperCase() + this.principalIdFieldName.substring(1))) {
|
||||||
|
pincipalIdGetter = m;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pincipalIdGetter == null) {
|
||||||
|
throw new PrincipalInstanceException(principalObject.getClass(), this.principalIdFieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Object idObj = pincipalIdGetter.invoke(principalObject);
|
||||||
|
if (idObj == null) {
|
||||||
|
throw new PrincipalIdNullException(principalObject.getClass(), this.principalIdFieldName);
|
||||||
|
}
|
||||||
|
redisKey = idObj.toString();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new PrincipalInstanceException(principalObject.getClass(), this.principalIdFieldName, e);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
throw new PrincipalInstanceException(principalObject.getClass(), this.principalIdFieldName, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return redisKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() throws CacheException {
|
||||||
|
logger.debug("clear cache");
|
||||||
|
Set<String> keys = null;
|
||||||
|
try {
|
||||||
|
keys = redisManager.scan(this.keyPrefix + "*");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("get keys error", e);
|
||||||
|
}
|
||||||
|
if (keys == null || keys.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String key: keys) {
|
||||||
|
redisManager.del(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
Long longSize = 0L;
|
||||||
|
try {
|
||||||
|
longSize = new Long(redisManager.scanSize(this.keyPrefix + "*"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("get keys error", e);
|
||||||
|
}
|
||||||
|
return longSize.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public Set<K> keys() {
|
||||||
|
Set<String> keys = null;
|
||||||
|
try {
|
||||||
|
keys = redisManager.scan(this.keyPrefix + "*");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("get keys error", e);
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(keys)) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<K> convertedKeys = new HashSet<K>();
|
||||||
|
for (String key:keys) {
|
||||||
|
try {
|
||||||
|
convertedKeys.add((K) key);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("deserialize keys error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return convertedKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<V> values() {
|
||||||
|
Set<String> keys = null;
|
||||||
|
try {
|
||||||
|
keys = redisManager.scan(this.keyPrefix + "*");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("get values error", e);
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(keys)) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<V> values = new ArrayList<V>(keys.size());
|
||||||
|
for (String key : keys) {
|
||||||
|
V value = null;
|
||||||
|
try {
|
||||||
|
value = (V) redisManager.get(key);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("deserialize values= error", e);
|
||||||
|
}
|
||||||
|
if (value != null) {
|
||||||
|
values.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableList(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKeyPrefix() {
|
||||||
|
return keyPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyPrefix(String keyPrefix) {
|
||||||
|
this.keyPrefix = keyPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrincipalIdFieldName() {
|
||||||
|
return principalIdFieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrincipalIdFieldName(String principalIdFieldName) {
|
||||||
|
this.principalIdFieldName = principalIdFieldName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
package org.opsli.core.security.shiro.cache;
|
||||||
|
|
||||||
|
import org.apache.shiro.cache.Cache;
|
||||||
|
import org.apache.shiro.cache.CacheException;
|
||||||
|
import org.apache.shiro.cache.CacheManager;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 参考 shiro-redis 开源项目 Git地址 https://github.com/alexxiyang/shiro-redis
|
||||||
|
*/
|
||||||
|
public class RedisCacheManager implements CacheManager {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(RedisCacheManager.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fast lookup by name map
|
||||||
|
*/
|
||||||
|
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
|
||||||
|
|
||||||
|
private RedisManager redisManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* expire time in seconds
|
||||||
|
*/
|
||||||
|
private static final int DEFAULT_EXPIRE = 1800;
|
||||||
|
private int expire = DEFAULT_EXPIRE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Redis key prefix for caches
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_CACHE_KEY_PREFIX = "shiro:cache:";
|
||||||
|
private String keyPrefix = DEFAULT_CACHE_KEY_PREFIX;
|
||||||
|
|
||||||
|
public static final String DEFAULT_PRINCIPAL_ID_FIELD_NAME = "authCacheKey or id";
|
||||||
|
private String principalIdFieldName = DEFAULT_PRINCIPAL_ID_FIELD_NAME;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <K, V> Cache<K, V> getCache(String name) throws CacheException {
|
||||||
|
logger.debug("get cache, name={}",name);
|
||||||
|
|
||||||
|
Cache cache = caches.get(name);
|
||||||
|
|
||||||
|
if (cache == null) {
|
||||||
|
cache = new RedisCache<K, V>(redisManager,keyPrefix + name + ":", expire, principalIdFieldName);
|
||||||
|
caches.put(name, cache);
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RedisManager getRedisManager() {
|
||||||
|
return redisManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRedisManager(RedisManager redisManager) {
|
||||||
|
this.redisManager = redisManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKeyPrefix() {
|
||||||
|
return keyPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyPrefix(String keyPrefix) {
|
||||||
|
this.keyPrefix = keyPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExpire() {
|
||||||
|
return expire;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpire(int expire) {
|
||||||
|
this.expire = expire;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrincipalIdFieldName() {
|
||||||
|
return principalIdFieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrincipalIdFieldName(String principalIdFieldName) {
|
||||||
|
this.principalIdFieldName = principalIdFieldName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,147 @@
|
|||||||
|
package org.opsli.core.security.shiro.cache;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnection;
|
||||||
|
import org.springframework.data.redis.core.Cursor;
|
||||||
|
import org.springframework.data.redis.core.RedisCallback;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.ScanOptions;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author sunzhiqiang
|
||||||
|
* 基于spring和redis的redisTemplate工具类
|
||||||
|
*/
|
||||||
|
public class RedisManager {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
//=============================common============================
|
||||||
|
/**
|
||||||
|
* 指定缓存失效时间
|
||||||
|
* @param key 键
|
||||||
|
* @param time 时间(秒)
|
||||||
|
*/
|
||||||
|
public void expire(String key,long time){
|
||||||
|
redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断key是否存在
|
||||||
|
* @param key 键
|
||||||
|
* @return true 存在 false不存在
|
||||||
|
*/
|
||||||
|
public Boolean hasKey(String key){
|
||||||
|
return redisTemplate.hasKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除缓存
|
||||||
|
* @param key 可以传一个值 或多个
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void del(String ... key){
|
||||||
|
if(key!=null&&key.length>0){
|
||||||
|
if(key.length==1){
|
||||||
|
redisTemplate.delete(key[0]);
|
||||||
|
}else{
|
||||||
|
redisTemplate.delete(CollectionUtils.arrayToList(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除key
|
||||||
|
* @param keys
|
||||||
|
*/
|
||||||
|
public void del(Collection keys){
|
||||||
|
redisTemplate.delete(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================String=============================
|
||||||
|
/**
|
||||||
|
* 普通缓存获取
|
||||||
|
* @param key 键
|
||||||
|
* @return 值
|
||||||
|
*/
|
||||||
|
public Object get(String key){
|
||||||
|
return redisTemplate.opsForValue().get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 普通缓存放入
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
*/
|
||||||
|
public void set(String key,Object value) {
|
||||||
|
redisTemplate.opsForValue().set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 普通缓存放入并设置时间
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
|
||||||
|
*/
|
||||||
|
public void set(String key,Object value,long time){
|
||||||
|
if(time>0){
|
||||||
|
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||||
|
}else{
|
||||||
|
set(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用scan命令 查询某些前缀的key
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Set<String> scan(String key){
|
||||||
|
Set<String> execute = this.redisTemplate.execute(new RedisCallback<Set<String>>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> doInRedis(RedisConnection connection) throws DataAccessException {
|
||||||
|
|
||||||
|
Set<String> binaryKeys = new HashSet<>();
|
||||||
|
|
||||||
|
Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(key).count(1000).build());
|
||||||
|
while (cursor.hasNext()) {
|
||||||
|
binaryKeys.add(new String(cursor.next()));
|
||||||
|
}
|
||||||
|
return binaryKeys;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return execute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用scan命令 查询某些前缀的key 有多少个
|
||||||
|
* 用来获取当前session数量,也就是在线用户
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Long scanSize(String key){
|
||||||
|
long dbSize = this.redisTemplate.execute(new RedisCallback<Long>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long doInRedis(RedisConnection connection) throws DataAccessException {
|
||||||
|
long count = 0L;
|
||||||
|
Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match(key).count(1000).build());
|
||||||
|
while (cursor.hasNext()) {
|
||||||
|
cursor.next();
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return dbSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
package org.opsli.core.security.shiro.cache.serializer;
|
||||||
|
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||||
|
import org.springframework.data.redis.serializer.SerializationException;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>序列化工具类</p>
|
||||||
|
*
|
||||||
|
* @author sunzhiqiang23
|
||||||
|
* @date 2020-04-27 19:48
|
||||||
|
*/
|
||||||
|
public class SerializeUtils implements RedisSerializer {
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(SerializeUtils.class);
|
||||||
|
|
||||||
|
public static boolean isEmpty(byte[] data) {
|
||||||
|
return (data == null || data.length == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 序列化
|
||||||
|
* @param object
|
||||||
|
* @return
|
||||||
|
* @throws SerializationException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public byte[] serialize(Object object) throws SerializationException {
|
||||||
|
byte[] result = null;
|
||||||
|
|
||||||
|
if (object == null) {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
try (
|
||||||
|
ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128);
|
||||||
|
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream)
|
||||||
|
){
|
||||||
|
|
||||||
|
if (!(object instanceof Serializable)) {
|
||||||
|
throw new IllegalArgumentException(SerializeUtils.class.getSimpleName() + " requires a Serializable payload " +
|
||||||
|
"but received an object of type [" + object.getClass().getName() + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
objectOutputStream.writeObject(object);
|
||||||
|
objectOutputStream.flush();
|
||||||
|
result = byteStream.toByteArray();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Failed to serialize",ex);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 反序列化
|
||||||
|
* @param bytes
|
||||||
|
* @return
|
||||||
|
* @throws SerializationException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object deserialize(byte[] bytes) throws SerializationException {
|
||||||
|
|
||||||
|
Object result = null;
|
||||||
|
|
||||||
|
if (isEmpty(bytes)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (
|
||||||
|
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
|
||||||
|
ObjectInputStream objectInputStream = new ObjectInputStream(byteStream)
|
||||||
|
){
|
||||||
|
result = objectInputStream.readObject();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to deserialize",e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package org.opsli.core.security.shiro.exception;
|
||||||
|
|
||||||
|
public class PrincipalIdNullException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final String MESSAGE = "Principal Id shouldn't be null!";
|
||||||
|
|
||||||
|
public PrincipalIdNullException(Class clazz, String idMethodName) {
|
||||||
|
super(clazz + " id field: " + idMethodName + ", value is null\n" + MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package org.opsli.core.security.shiro.exception;
|
||||||
|
|
||||||
|
public class PrincipalInstanceException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final String MESSAGE = "We need a field to identify this Cache Object in Redis. "
|
||||||
|
+ "So you need to defined an id field which you can get unique id to identify this principal. "
|
||||||
|
+ "For example, if you use UserInfo as Principal class, the id field maybe userId, userName, email, etc. "
|
||||||
|
+ "For example, getUserId(), getUserName(), getEmail(), etc.\n"
|
||||||
|
+ "Default value is \"id\", that means your principal object has a method called \"getId()\"";
|
||||||
|
|
||||||
|
public PrincipalInstanceException(Class clazz, String idMethodName) {
|
||||||
|
super(clazz + " must has getter for field: " + idMethodName + "\n" + MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrincipalInstanceException(Class clazz, String idMethodName, Exception e) {
|
||||||
|
super(clazz + " must has getter for field: " + idMethodName + "\n" + MESSAGE, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package org.opsli.core.security.shiro.session;
|
||||||
|
|
||||||
|
import org.apache.shiro.session.Session;
|
||||||
|
import org.apache.shiro.session.SessionListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p></p>
|
||||||
|
*
|
||||||
|
* @author sunzhiqiang23
|
||||||
|
* @date 2020-04-25 17:29
|
||||||
|
*/
|
||||||
|
public class MySessionListener implements SessionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart(Session session) {
|
||||||
|
System.out.println("会话创建:" + session.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop(Session session) {
|
||||||
|
System.out.println("会话退出:" + session.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExpiration(Session session) {
|
||||||
|
System.out.println("会话过期:" + session.getId());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package org.opsli.core.security.shiro.session;
|
||||||
|
|
||||||
|
import org.apache.shiro.session.Session;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p></p>
|
||||||
|
*
|
||||||
|
* @author sunzhiqiang23
|
||||||
|
* @date 2020-04-27 20:52
|
||||||
|
*/
|
||||||
|
public class SessionInMemory {
|
||||||
|
private Session session;
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
public Session getSession() {
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSession(Session session) {
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(Date createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
package org.opsli.core.security.shiro.session;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.shiro.session.Session;
|
||||||
|
import org.apache.shiro.session.UnknownSessionException;
|
||||||
|
import org.apache.shiro.session.mgt.SessionKey;
|
||||||
|
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
||||||
|
import org.apache.shiro.web.session.mgt.WebSessionKey;
|
||||||
|
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>解决单次请求需要多次访问redis</p>
|
||||||
|
*
|
||||||
|
* @author sunzhiqiang23
|
||||||
|
* @date 2020-04-27 20:58
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class ShiroSessionManager extends DefaultWebSessionManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取session
|
||||||
|
* 优化单次请求需要多次访问redis的问题
|
||||||
|
* @param sessionKey
|
||||||
|
* @return
|
||||||
|
* @throws UnknownSessionException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
|
||||||
|
Serializable sessionId = getSessionId(sessionKey);
|
||||||
|
|
||||||
|
ServletRequest request = null;
|
||||||
|
if (sessionKey instanceof WebSessionKey) {
|
||||||
|
request = ((WebSessionKey) sessionKey).getServletRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request != null && null != sessionId) {
|
||||||
|
Object sessionObj = request.getAttribute(sessionId.toString());
|
||||||
|
if (sessionObj != null) {
|
||||||
|
log.debug("read session from request");
|
||||||
|
return (Session) sessionObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Session session = super.retrieveSession(sessionKey);
|
||||||
|
if (request != null && null != sessionId) {
|
||||||
|
request.setAttribute(sessionId.toString(), session);
|
||||||
|
}
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package org.opsli.core.security.shiro.token;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.shiro.authc.AuthenticationToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jwt token
|
||||||
|
*
|
||||||
|
* @author parker
|
||||||
|
|
||||||
|
* @date 2017-05-20 13:22
|
||||||
|
*/
|
||||||
|
public class JwtToken implements AuthenticationToken {
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
public JwtToken(String token){
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPrincipal() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getCredentials() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package org.opsli.core.security.shiro.token;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.shiro.authc.AuthenticationToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth2 token
|
||||||
|
*
|
||||||
|
* @author 孙志强
|
||||||
|
|
||||||
|
* @date 2017-05-20 13:22
|
||||||
|
*/
|
||||||
|
public class OAuth2Token implements AuthenticationToken {
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
public OAuth2Token(String token){
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPrincipal() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getCredentials() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018 人人开源 http://www.renren.io
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.opsli.core.security.shiro.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis所有Keys
|
||||||
|
*
|
||||||
|
* @author Mark sunlightcs@gmail.com
|
||||||
|
* @since 3.0.0 2017-07-18
|
||||||
|
*/
|
||||||
|
public class RedisKeys {
|
||||||
|
|
||||||
|
public static String getSysConfigKey(String key){
|
||||||
|
return "system:config:" + key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getShiroSessionKey(String key){
|
||||||
|
return "sessionid:" + key;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018 人人开源 http://www.renren.io
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.opsli.core.security.shiro.utils;
|
||||||
|
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.apache.shiro.crypto.hash.SimpleHash;
|
||||||
|
import org.apache.shiro.session.Session;
|
||||||
|
import org.apache.shiro.subject.Subject;
|
||||||
|
import org.opsli.api.wrapper.system.user.UserModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shiro工具类
|
||||||
|
*
|
||||||
|
* @author 孙志强
|
||||||
|
|
||||||
|
* @date 2016年11月12日 上午9:49:19
|
||||||
|
*/
|
||||||
|
public class ShiroUtils {
|
||||||
|
|
||||||
|
/** 加密算法 */
|
||||||
|
public final static String hashAlgorithmName = "MD5";
|
||||||
|
/** 循环次数 */
|
||||||
|
public final static int hashIterations = 1;
|
||||||
|
|
||||||
|
public static String sha256(String password, String salt) {
|
||||||
|
return new SimpleHash(hashAlgorithmName, password, salt, hashIterations).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Session getSession() {
|
||||||
|
return SecurityUtils.getSubject().getSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Subject getSubject() {
|
||||||
|
return SecurityUtils.getSubject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UserModel getUser() {
|
||||||
|
return (UserModel) SecurityUtils.getSubject().getPrincipal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getUserId() {
|
||||||
|
return getUser().getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setSessionAttribute(Object key, Object value) {
|
||||||
|
getSession().setAttribute(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object getSessionAttribute(Object key) {
|
||||||
|
return getSession().getAttribute(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isLogin() {
|
||||||
|
return SecurityUtils.getSubject().getPrincipal() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void logout() {
|
||||||
|
SecurityUtils.getSubject().logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getKaptcha(String key) throws RuntimeException {
|
||||||
|
Object kaptcha = getSessionAttribute(key);
|
||||||
|
if(kaptcha == null){
|
||||||
|
throw new RuntimeException("验证码已失效");
|
||||||
|
}
|
||||||
|
getSession().removeAttribute(key);
|
||||||
|
return kaptcha.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package org.opsli.core.utils;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64工具
|
||||||
|
* @author 孙志强
|
||||||
|
* @date 2018/11/05 23:10
|
||||||
|
*/
|
||||||
|
public final class Base64ConvertUtil {
|
||||||
|
/**
|
||||||
|
* 加密
|
||||||
|
* @param str
|
||||||
|
* @return java.lang.String
|
||||||
|
*/
|
||||||
|
public static String encode(String str) throws UnsupportedEncodingException {
|
||||||
|
byte[] encodeBytes = Base64.getEncoder().encode(str.getBytes("utf-8"));
|
||||||
|
return new String(encodeBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解密
|
||||||
|
* @param str
|
||||||
|
* @return java.lang.String
|
||||||
|
*/
|
||||||
|
public static String decode(String str) throws UnsupportedEncodingException {
|
||||||
|
byte[] decodeBytes = Base64.getDecoder().decode(str.getBytes("utf-8"));
|
||||||
|
return new String(decodeBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==============
|
||||||
|
private Base64ConvertUtil(){}
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
package org.opsli.core.utils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.google.code.kaptcha.Producer;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.opsli.plugins.redis.RedisPlugin;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码
|
||||||
|
*
|
||||||
|
* @author parker
|
||||||
|
* @since 2.0.0 2018-02-10
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class CaptchaUtil{
|
||||||
|
|
||||||
|
/** 缓存前缀 */
|
||||||
|
private static final String PREFIX = "opsli:temp:captcha:";
|
||||||
|
/** 默认验证码保存 5 分钟 */
|
||||||
|
private static final int TIME_OUT = 300;
|
||||||
|
/** Redis插件 */
|
||||||
|
private static RedisPlugin redisPlugin;
|
||||||
|
/** 谷歌验证码 */
|
||||||
|
private static Producer producer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得验证码
|
||||||
|
* @param uuid
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static BufferedImage getCaptcha(String uuid) {
|
||||||
|
if(StringUtils.isBlank(uuid)){
|
||||||
|
throw new RuntimeException("uuid不能为空");
|
||||||
|
}
|
||||||
|
//生成文字验证码
|
||||||
|
String code = producer.createText();
|
||||||
|
|
||||||
|
boolean ret = redisPlugin.put(PREFIX + uuid, code, TIME_OUT);
|
||||||
|
|
||||||
|
if(ret){
|
||||||
|
return producer.createImage(code);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验验证码
|
||||||
|
* @param uuid
|
||||||
|
* @param code
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean validate(String uuid, String code) {
|
||||||
|
if(StringUtils.isEmpty(uuid)) return false;
|
||||||
|
|
||||||
|
// 验证码
|
||||||
|
String codeTemp = (String) redisPlugin.get(PREFIX + uuid);
|
||||||
|
|
||||||
|
if(StringUtils.isEmpty(codeTemp)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除验证码
|
||||||
|
redisPlugin.del(PREFIX + uuid);
|
||||||
|
|
||||||
|
return codeTemp.equalsIgnoreCase(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==========================
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setRedisPlugin(RedisPlugin redisPlugin) {
|
||||||
|
CaptchaUtil.redisPlugin = redisPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setProducer(Producer producer) {
|
||||||
|
CaptchaUtil.producer = producer;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package org.opsli.core.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成token
|
||||||
|
*
|
||||||
|
* @author Parker
|
||||||
|
|
||||||
|
* @date 2017-05-20 14:41
|
||||||
|
*/
|
||||||
|
public final class TokenGenerator {
|
||||||
|
|
||||||
|
public static String generateValue() {
|
||||||
|
return generateValue(UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final char[] hexCode = "0123456789abcdef".toCharArray();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成Token
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String generateValue(String param) {
|
||||||
|
try {
|
||||||
|
MessageDigest algorithm = MessageDigest.getInstance("MD5");
|
||||||
|
algorithm.reset();
|
||||||
|
algorithm.update(param.getBytes());
|
||||||
|
byte[] messageDigest = algorithm.digest();
|
||||||
|
return toHexString(messageDigest);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("生成Token失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static String toHexString(byte[] data) {
|
||||||
|
if(data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StringBuilder r = new StringBuilder(data.length*2);
|
||||||
|
for ( byte b : data) {
|
||||||
|
r.append(hexCode[(b >> 4) & 0xF]);
|
||||||
|
r.append(hexCode[(b & 0xF)]);
|
||||||
|
}
|
||||||
|
return r.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =========================
|
||||||
|
private TokenGenerator(){}
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
123123
|
||||||
@ -0,0 +1 @@
|
|||||||
|
## 改造微服务时 将Feign 接口写在这里
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.opsli.modulars.system.login.entity;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录表单
|
||||||
|
*
|
||||||
|
* @author liuzp
|
||||||
|
* @since 2.0.0 2018-01-25
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class LoginForm {
|
||||||
|
|
||||||
|
/** 用户名 */
|
||||||
|
@ApiModelProperty(value = "用户名")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
/** 密码 */
|
||||||
|
@ApiModelProperty(value = "密码")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/** 验证码 */
|
||||||
|
@ApiModelProperty(value = "验证码")
|
||||||
|
private String captcha;
|
||||||
|
|
||||||
|
/** UUID */
|
||||||
|
@ApiModelProperty(value = "UUID")
|
||||||
|
private String uuid;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
## 改造微服务时 将Feign 接口写在这里
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package org.opsli.modulars.system.menu.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.opsli.core.base.entity.BaseEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.entity
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:33
|
||||||
|
* @Description: 菜单表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class SysMenu extends BaseEntity {
|
||||||
|
|
||||||
|
|
||||||
|
/** 父级主键 */
|
||||||
|
private String parentId;
|
||||||
|
|
||||||
|
/** 菜单编号 */
|
||||||
|
private String menuCode;
|
||||||
|
|
||||||
|
/** 菜单名称 */
|
||||||
|
private String menuName;
|
||||||
|
|
||||||
|
/** 图标 */
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
/** 项目类型:1-菜单2-按钮3-链接4-表单 */
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/** url地址 */
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
/** 逻辑删除字段 */
|
||||||
|
@TableLogic
|
||||||
|
private Integer deleted;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package org.opsli.modulars.system.menu.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.opsli.modulars.system.menu.entity.SysMenu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.mapper
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-17 13:01
|
||||||
|
* @Description: 角色 Mapper
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface MenuMapper extends BaseMapper<SysMenu> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 唯一验证
|
||||||
|
* @param entity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer uniqueVerificationByCode(SysMenu entity);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.opsli.modulars.system.menu.mapper.MenuMapper">
|
||||||
|
|
||||||
|
<!-- 数据库字段 -->
|
||||||
|
<sql id="SysRoleColumns">
|
||||||
|
a.id as id,
|
||||||
|
|
||||||
|
a.parent_id as parentId,
|
||||||
|
a.menu_code as menuCode,
|
||||||
|
a.menu_name as menuName,
|
||||||
|
a.icon as icon,
|
||||||
|
a.type as type,
|
||||||
|
a.url as url,
|
||||||
|
a.iz_lock as izLock,
|
||||||
|
|
||||||
|
a.create_by as createBy,
|
||||||
|
a.create_time as createTime,
|
||||||
|
a.update_by as updateBy,
|
||||||
|
a.update_time as updateTime,
|
||||||
|
a.version as version,
|
||||||
|
a.deleted as deleted
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<sql id="SysRoleJoins">
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="uniqueVerificationByCode" parameterType="SysMenu" resultType="Integer">
|
||||||
|
select
|
||||||
|
count(0)
|
||||||
|
from
|
||||||
|
sys_menu a
|
||||||
|
where
|
||||||
|
a.menu_code = #{menuCode}
|
||||||
|
and a.deleted = 0
|
||||||
|
<if test="id != null and id != ''">
|
||||||
|
AND a.id != #{id}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package org.opsli.modulars.system.menu.service;
|
||||||
|
|
||||||
|
import org.opsli.api.wrapper.system.menu.MenuModel;
|
||||||
|
import org.opsli.core.base.service.interfaces.CrudServiceInterface;
|
||||||
|
import org.opsli.modulars.system.menu.entity.SysMenu;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.service
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-17 13:07
|
||||||
|
* @Description: 角色 接口
|
||||||
|
*/
|
||||||
|
public interface IMenuService extends CrudServiceInterface<SysMenu, MenuModel> {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
package org.opsli.modulars.system.menu.service.impl;
|
||||||
|
|
||||||
|
import org.opsli.api.wrapper.system.menu.MenuModel;
|
||||||
|
import org.opsli.common.exception.ServiceException;
|
||||||
|
import org.opsli.common.utils.WrapperUtil;
|
||||||
|
import org.opsli.core.base.service.impl.CrudServiceImpl;
|
||||||
|
import org.opsli.modulars.system.SystemMsg;
|
||||||
|
import org.opsli.modulars.system.menu.entity.SysMenu;
|
||||||
|
import org.opsli.modulars.system.menu.mapper.MenuMapper;
|
||||||
|
import org.opsli.modulars.system.menu.service.IMenuService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.service
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:34
|
||||||
|
* @Description: 角色 接口实现类
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class MenuServiceImpl extends CrudServiceImpl<MenuMapper, SysMenu, MenuModel> implements IMenuService {
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private MenuMapper mapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuModel insert(MenuModel model) {
|
||||||
|
if(model == null) return null;
|
||||||
|
|
||||||
|
SysMenu entity = super.transformM2T(model);
|
||||||
|
// 唯一验证
|
||||||
|
Integer count = mapper.uniqueVerificationByCode(entity);
|
||||||
|
if(count != null && count > 0){
|
||||||
|
// 重复
|
||||||
|
throw new ServiceException(SystemMsg.EXCEPTION_ROLE_UNIQUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.insert(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public MenuModel update(MenuModel model) {
|
||||||
|
if(model == null) return null;
|
||||||
|
|
||||||
|
SysMenu entity = super.transformM2T(model);
|
||||||
|
// 唯一验证
|
||||||
|
Integer count = mapper.uniqueVerificationByCode(entity);
|
||||||
|
if(count != null && count > 0){
|
||||||
|
// 重复
|
||||||
|
throw new ServiceException(SystemMsg.EXCEPTION_ROLE_UNIQUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.update(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,156 @@
|
|||||||
|
package org.opsli.modulars.system.menu.web;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.opsli.api.base.result.ResultVo;
|
||||||
|
import org.opsli.api.web.system.menu.MenuApi;
|
||||||
|
import org.opsli.api.wrapper.system.menu.MenuModel;
|
||||||
|
import org.opsli.common.annotation.ApiRestController;
|
||||||
|
import org.opsli.core.base.concroller.BaseRestController;
|
||||||
|
import org.opsli.core.persistence.Page;
|
||||||
|
import org.opsli.core.persistence.querybuilder.QueryBuilder;
|
||||||
|
import org.opsli.core.persistence.querybuilder.WebQueryBuilder;
|
||||||
|
import org.opsli.modulars.system.menu.entity.SysMenu;
|
||||||
|
import org.opsli.modulars.system.menu.service.IMenuService;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.web
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-13 17:40
|
||||||
|
* @Description: 菜单
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@ApiRestController("/sys/menu")
|
||||||
|
public class MenuRestController extends BaseRestController<SysMenu, MenuModel, IMenuService>
|
||||||
|
implements MenuApi {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单 查一条
|
||||||
|
* @param model 模型
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "获得单条字典明细数据", notes = "获得单条字典明细数据 - ID")
|
||||||
|
@Override
|
||||||
|
public ResultVo<MenuModel> get(MenuModel model) {
|
||||||
|
// 如果系统内部调用 则直接查数据库
|
||||||
|
if(model != null && model.getIzApi() != null && model.getIzApi()){
|
||||||
|
model = IService.get(model);
|
||||||
|
}
|
||||||
|
return ResultVo.success(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单 查询分页
|
||||||
|
* @param pageNo 当前页
|
||||||
|
* @param pageSize 每页条数
|
||||||
|
* @param request request
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||||
|
|
||||||
|
QueryBuilder<SysMenu> queryBuilder = new WebQueryBuilder<>(SysMenu.class, request.getParameterMap());
|
||||||
|
Page<SysMenu, MenuModel> page = new Page<>(pageNo, pageSize);
|
||||||
|
page.setQueryWrapper(queryBuilder.build());
|
||||||
|
page = IService.findPage(page);
|
||||||
|
|
||||||
|
return ResultVo.success(page.getBootstrapData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单 新增
|
||||||
|
* @param model 模型
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "新增字典明细数据", notes = "新增字典明细数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> insert(MenuModel model) {
|
||||||
|
// 调用新增方法
|
||||||
|
IService.insert(model);
|
||||||
|
return ResultVo.success("新增字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单 修改
|
||||||
|
* @param model 模型
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "修改字典明细数据", notes = "修改字典明细数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> update(MenuModel model) {
|
||||||
|
// 调用修改方法
|
||||||
|
IService.update(model);
|
||||||
|
return ResultVo.success("修改字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单 删除
|
||||||
|
* @param id ID
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "删除字典明细数据数据", notes = "删除字典明细数据数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> del(String id){
|
||||||
|
IService.delete(id);
|
||||||
|
return ResultVo.success("删除字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单 批量删除
|
||||||
|
* @param ids ID 数组
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "批量删除字典明细数据数据", notes = "批量删除字典明细数据数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> delAll(String[] ids){
|
||||||
|
IService.deleteAll(ids);
|
||||||
|
return ResultVo.success("批量删除字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单 Excel 导出
|
||||||
|
* @param request request
|
||||||
|
* @param response response
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "导出Excel", notes = "导出Excel")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> exportExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
QueryBuilder<SysMenu> queryBuilder = new WebQueryBuilder<>(SysMenu.class, request.getParameterMap());
|
||||||
|
return super.excelExport(MenuApi.TITLE, queryBuilder.build(), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单 Excel 导入
|
||||||
|
* @param request 文件流 request
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "导入Excel", notes = "导入Excel")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> excelImport(MultipartHttpServletRequest request) {
|
||||||
|
return super.excelImport(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单 Excel 下载导入模版
|
||||||
|
* @param response response
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "导出Excel模版", notes = "导出Excel模版")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> importTemplate(HttpServletResponse response) {
|
||||||
|
return super.importTemplate(MenuApi.TITLE, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
## 改造微服务时 将Feign 接口写在这里
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
package org.opsli.modulars.system.role.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.opsli.core.base.entity.BaseEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.entity
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:33
|
||||||
|
* @Description: 角色表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class SysRole extends BaseEntity {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** 角色编码 */
|
||||||
|
private String roleCode;
|
||||||
|
|
||||||
|
/** 角色名称 */
|
||||||
|
private String roleName;
|
||||||
|
|
||||||
|
/** 是否内置数据 0是 1否*/
|
||||||
|
private Character izLock;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
/** 逻辑删除字段 */
|
||||||
|
@TableLogic
|
||||||
|
private Integer deleted;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package org.opsli.modulars.system.role.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.opsli.modulars.system.role.entity.SysRole;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.mapper
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-17 13:01
|
||||||
|
* @Description: 角色 Mapper
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface RoleMapper extends BaseMapper<SysRole> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 唯一验证
|
||||||
|
* @param entity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer uniqueVerificationByCode(SysRole entity);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.opsli.modulars.system.role.mapper.RoleMapper">
|
||||||
|
|
||||||
|
<!-- 数据库字段 -->
|
||||||
|
<sql id="SysRoleColumns">
|
||||||
|
a.id as id,
|
||||||
|
|
||||||
|
a.role_code as roleCode,
|
||||||
|
a.role_name as roleName,
|
||||||
|
a.iz_lock as izLock,
|
||||||
|
a.remark as remark,
|
||||||
|
|
||||||
|
a.create_by as createBy,
|
||||||
|
a.create_time as createTime,
|
||||||
|
a.update_by as updateBy,
|
||||||
|
a.update_time as updateTime,
|
||||||
|
a.version as version,
|
||||||
|
a.deleted as deleted
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<sql id="SysRoleJoins">
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="uniqueVerificationByCode" parameterType="SysRole" resultType="Integer">
|
||||||
|
select
|
||||||
|
count(0)
|
||||||
|
from
|
||||||
|
sys_role a
|
||||||
|
where
|
||||||
|
a.role_code = #{roleCode}
|
||||||
|
and a.deleted = 0
|
||||||
|
<if test="id != null and id != ''">
|
||||||
|
AND a.id != #{id}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package org.opsli.modulars.system.role.service;
|
||||||
|
|
||||||
|
import org.opsli.api.wrapper.system.role.RoleModel;
|
||||||
|
import org.opsli.core.base.service.interfaces.CrudServiceInterface;
|
||||||
|
import org.opsli.modulars.system.role.entity.SysRole;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.service
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-17 13:07
|
||||||
|
* @Description: 角色 接口
|
||||||
|
*/
|
||||||
|
public interface IRoleService extends CrudServiceInterface<SysRole, RoleModel> {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package org.opsli.modulars.system.role.service.impl;
|
||||||
|
|
||||||
|
import org.opsli.api.wrapper.system.role.RoleModel;
|
||||||
|
import org.opsli.common.exception.ServiceException;
|
||||||
|
import org.opsli.core.base.service.impl.CrudServiceImpl;
|
||||||
|
import org.opsli.modulars.system.SystemMsg;
|
||||||
|
import org.opsli.modulars.system.role.entity.SysRole;
|
||||||
|
import org.opsli.modulars.system.role.mapper.RoleMapper;
|
||||||
|
import org.opsli.modulars.system.role.service.IRoleService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.service
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:34
|
||||||
|
* @Description: 角色 接口实现类
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class RoleServiceImpl extends CrudServiceImpl<RoleMapper, SysRole, RoleModel> implements IRoleService {
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private RoleMapper mapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RoleModel insert(RoleModel model) {
|
||||||
|
if(model == null) return null;
|
||||||
|
|
||||||
|
SysRole entity = super.transformM2T(model);
|
||||||
|
// 唯一验证
|
||||||
|
Integer count = mapper.uniqueVerificationByCode(entity);
|
||||||
|
if(count != null && count > 0){
|
||||||
|
// 重复
|
||||||
|
throw new ServiceException(SystemMsg.EXCEPTION_ROLE_UNIQUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.insert(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public RoleModel update(RoleModel model) {
|
||||||
|
if(model == null) return null;
|
||||||
|
|
||||||
|
SysRole entity = super.transformM2T(model);
|
||||||
|
// 唯一验证
|
||||||
|
Integer count = mapper.uniqueVerificationByCode(entity);
|
||||||
|
if(count != null && count > 0){
|
||||||
|
// 重复
|
||||||
|
throw new ServiceException(SystemMsg.EXCEPTION_ROLE_UNIQUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.update(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,156 @@
|
|||||||
|
package org.opsli.modulars.system.role.web;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.opsli.api.base.result.ResultVo;
|
||||||
|
import org.opsli.api.web.system.role.RoleApi;
|
||||||
|
import org.opsli.api.wrapper.system.role.RoleModel;
|
||||||
|
import org.opsli.common.annotation.ApiRestController;
|
||||||
|
import org.opsli.core.base.concroller.BaseRestController;
|
||||||
|
import org.opsli.core.persistence.Page;
|
||||||
|
import org.opsli.core.persistence.querybuilder.QueryBuilder;
|
||||||
|
import org.opsli.core.persistence.querybuilder.WebQueryBuilder;
|
||||||
|
import org.opsli.modulars.system.role.entity.SysRole;
|
||||||
|
import org.opsli.modulars.system.role.service.IRoleService;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.web
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-13 17:40
|
||||||
|
* @Description: 角色
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@ApiRestController("/sys/role")
|
||||||
|
public class RoleRestController extends BaseRestController<SysRole, RoleModel, IRoleService>
|
||||||
|
implements RoleApi {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色 查一条
|
||||||
|
* @param model 模型
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "获得单条字典明细数据", notes = "获得单条字典明细数据 - ID")
|
||||||
|
@Override
|
||||||
|
public ResultVo<RoleModel> get(RoleModel model) {
|
||||||
|
// 如果系统内部调用 则直接查数据库
|
||||||
|
if(model != null && model.getIzApi() != null && model.getIzApi()){
|
||||||
|
model = IService.get(model);
|
||||||
|
}
|
||||||
|
return ResultVo.success(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色 查询分页
|
||||||
|
* @param pageNo 当前页
|
||||||
|
* @param pageSize 每页条数
|
||||||
|
* @param request request
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||||
|
|
||||||
|
QueryBuilder<SysRole> queryBuilder = new WebQueryBuilder<>(SysRole.class, request.getParameterMap());
|
||||||
|
Page<SysRole, RoleModel> page = new Page<>(pageNo, pageSize);
|
||||||
|
page.setQueryWrapper(queryBuilder.build());
|
||||||
|
page = IService.findPage(page);
|
||||||
|
|
||||||
|
return ResultVo.success(page.getBootstrapData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色 新增
|
||||||
|
* @param model 模型
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "新增字典明细数据", notes = "新增字典明细数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> insert(RoleModel model) {
|
||||||
|
// 调用新增方法
|
||||||
|
IService.insert(model);
|
||||||
|
return ResultVo.success("新增字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色 修改
|
||||||
|
* @param model 模型
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "修改字典明细数据", notes = "修改字典明细数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> update(RoleModel model) {
|
||||||
|
// 调用修改方法
|
||||||
|
IService.update(model);
|
||||||
|
return ResultVo.success("修改字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色 删除
|
||||||
|
* @param id ID
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "删除字典明细数据数据", notes = "删除字典明细数据数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> del(String id){
|
||||||
|
IService.delete(id);
|
||||||
|
return ResultVo.success("删除字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色 批量删除
|
||||||
|
* @param ids ID 数组
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "批量删除字典明细数据数据", notes = "批量删除字典明细数据数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> delAll(String[] ids){
|
||||||
|
IService.deleteAll(ids);
|
||||||
|
return ResultVo.success("批量删除字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色 Excel 导出
|
||||||
|
* @param request request
|
||||||
|
* @param response response
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "导出Excel", notes = "导出Excel")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> exportExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
QueryBuilder<SysRole> queryBuilder = new WebQueryBuilder<>(SysRole.class, request.getParameterMap());
|
||||||
|
return super.excelExport(RoleApi.TITLE, queryBuilder.build(), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色 Excel 导入
|
||||||
|
* @param request 文件流 request
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "导入Excel", notes = "导入Excel")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> excelImport(MultipartHttpServletRequest request) {
|
||||||
|
return super.excelImport(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色 Excel 下载导入模版
|
||||||
|
* @param response response
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "导出Excel模版", notes = "导出Excel模版")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> importTemplate(HttpServletResponse response) {
|
||||||
|
return super.importTemplate(RoleApi.TITLE, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
## 改造微服务时 将Feign 接口写在这里
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
package org.opsli.modulars.system.user.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.opsli.core.base.entity.BaseEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.entity
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:33
|
||||||
|
* @Description: 用户信息表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class SysUser extends BaseEntity {
|
||||||
|
|
||||||
|
|
||||||
|
/** 登录账户 */
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
/** 登录密码 */
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/** 盐值,密码秘钥 */
|
||||||
|
private String secretKey;
|
||||||
|
|
||||||
|
/** 是否锁定 */
|
||||||
|
private String locked;
|
||||||
|
|
||||||
|
/** 真实姓名 */
|
||||||
|
private String realName;
|
||||||
|
|
||||||
|
/** 手机 */
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
/** 邮箱 */
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
/** 工号 */
|
||||||
|
private String no;
|
||||||
|
|
||||||
|
/** 头像 */
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
/** 最后登陆IP */
|
||||||
|
private String loginIp;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
/** 逻辑删除字段 */
|
||||||
|
@TableLogic
|
||||||
|
private Integer deleted;
|
||||||
|
|
||||||
|
/** 多租户字段 */
|
||||||
|
private String tenantId;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package org.opsli.modulars.system.user.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.opsli.modulars.system.menu.entity.SysMenu;
|
||||||
|
import org.opsli.modulars.system.user.entity.SysUser;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.mapper
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-17 13:01
|
||||||
|
* @Description: 用户 Mapper
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface UserMapper extends BaseMapper<SysUser> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 唯一验证
|
||||||
|
* @param entity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer uniqueVerificationByUsername(SysUser entity);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID 获得当前角色编码集合
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<String> getRoleCodeList(String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID 获得权限
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<String> queryAllPerms(String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID 获得菜单集合
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<SysMenu> findMenuListByUserId(String userId);
|
||||||
|
}
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="org.opsli.modulars.system.user.mapper.UserMapper">
|
||||||
|
|
||||||
|
<!-- 数据库字段 -->
|
||||||
|
<sql id="SysDictColumns">
|
||||||
|
a.id as id,
|
||||||
|
|
||||||
|
a.username as username,
|
||||||
|
a.password as password,
|
||||||
|
a.secret_key as secretKey,
|
||||||
|
a.no as no,
|
||||||
|
a.real_name as realName,
|
||||||
|
a.locked as locked,
|
||||||
|
a.mobile as mobile,
|
||||||
|
a.email as email,
|
||||||
|
a.avatar as avatar,
|
||||||
|
a.login_ip as loginIp,
|
||||||
|
a.remark as remark,
|
||||||
|
a.tenant_id as tenantId,
|
||||||
|
|
||||||
|
a.create_by as createBy,
|
||||||
|
a.create_time as createTime,
|
||||||
|
a.update_by as updateBy,
|
||||||
|
a.update_time as updateTime,
|
||||||
|
a.version as version,
|
||||||
|
a.deleted as deleted
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<sql id="SysDictJoins">
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="uniqueVerificationByUsername" parameterType="SysUser" resultType="Integer">
|
||||||
|
select
|
||||||
|
count(0)
|
||||||
|
from
|
||||||
|
sys_user a
|
||||||
|
where
|
||||||
|
a.username = #{username}
|
||||||
|
and a.deleted = 0
|
||||||
|
<if test="id != null and id != ''">
|
||||||
|
AND a.id != #{id}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
<select id="queryAllPerms" resultType="String">
|
||||||
|
select
|
||||||
|
a.menu_code
|
||||||
|
from
|
||||||
|
sys_menu a,
|
||||||
|
sys_role_menu_ref b,
|
||||||
|
sys_user_role_ref c
|
||||||
|
where
|
||||||
|
a.id = b.module_id
|
||||||
|
and b.role_id = c.role_id
|
||||||
|
and a.type in ( '2', '3', '4' )
|
||||||
|
and c.user_id = #{userId}
|
||||||
|
where
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="getRoleCodeList" resultType="String">
|
||||||
|
select
|
||||||
|
b.role_code
|
||||||
|
from
|
||||||
|
sys_user_role_ref a,
|
||||||
|
sys_role b
|
||||||
|
where
|
||||||
|
a.role_id = b.id
|
||||||
|
and a.user_id = #{userId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 根据用户id查询菜单列表-->
|
||||||
|
<select id="findMenuListByUserId" resultType="SysMenu">
|
||||||
|
select
|
||||||
|
c.id,
|
||||||
|
c.icon,
|
||||||
|
c.menu_name,
|
||||||
|
c.url,
|
||||||
|
c.parent_Id
|
||||||
|
from
|
||||||
|
sys_user_role_ref a,
|
||||||
|
sys_role_menu_ref b,
|
||||||
|
sys_menu c
|
||||||
|
where
|
||||||
|
a.role_Id = b.role_Id
|
||||||
|
and b.menu_id = c.id
|
||||||
|
and c.parent_id != -1
|
||||||
|
and a.user_id = #{userId}
|
||||||
|
and c.type = '1'
|
||||||
|
order by c.id
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package org.opsli.modulars.system.user.service;
|
||||||
|
|
||||||
|
import org.opsli.api.wrapper.system.menu.MenuModel;
|
||||||
|
import org.opsli.api.wrapper.system.user.UserModel;
|
||||||
|
import org.opsli.core.base.service.interfaces.CrudServiceInterface;
|
||||||
|
import org.opsli.modulars.system.user.entity.SysUser;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.service
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-17 13:07
|
||||||
|
* @Description: 用户 接口
|
||||||
|
*/
|
||||||
|
public interface IUserService extends CrudServiceInterface<SysUser, UserModel> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 用户名 获得当前用户
|
||||||
|
* @param username
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
UserModel queryByUserName(String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID 获得当前角色编码集合
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<String> getRoleCodeList(String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID 获得权限
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<String> getAllPerms(String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID 获得菜单集合
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<MenuModel> getMenuListByUserId(String userId);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,102 @@
|
|||||||
|
package org.opsli.modulars.system.user.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import org.opsli.api.wrapper.system.menu.MenuModel;
|
||||||
|
import org.opsli.api.wrapper.system.user.UserModel;
|
||||||
|
import org.opsli.common.exception.ServiceException;
|
||||||
|
import org.opsli.common.utils.HumpUtil;
|
||||||
|
import org.opsli.common.utils.WrapperUtil;
|
||||||
|
import org.opsli.core.base.service.impl.CrudServiceImpl;
|
||||||
|
import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
|
||||||
|
import org.opsli.core.persistence.querybuilder.QueryBuilder;
|
||||||
|
import org.opsli.core.utils.UserUtil;
|
||||||
|
import org.opsli.modulars.system.SystemMsg;
|
||||||
|
import org.opsli.modulars.system.menu.entity.SysMenu;
|
||||||
|
import org.opsli.modulars.system.user.entity.SysUser;
|
||||||
|
import org.opsli.modulars.system.user.mapper.UserMapper;
|
||||||
|
import org.opsli.modulars.system.user.service.IUserService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.service
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-16 17:34
|
||||||
|
* @Description: 角色 接口实现类
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserModel> implements IUserService {
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private UserMapper mapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel insert(UserModel model) {
|
||||||
|
if(model == null) return null;
|
||||||
|
|
||||||
|
SysUser entity = super.transformM2T(model);
|
||||||
|
// 唯一验证
|
||||||
|
Integer count = mapper.uniqueVerificationByUsername(entity);
|
||||||
|
if(count != null && count > 0){
|
||||||
|
// 重复
|
||||||
|
throw new ServiceException(SystemMsg.EXCEPTION_USER_UNIQUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.insert(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@Override
|
||||||
|
public UserModel update(UserModel model) {
|
||||||
|
if(model == null) return null;
|
||||||
|
|
||||||
|
SysUser entity = super.transformM2T(model);
|
||||||
|
// 唯一验证
|
||||||
|
Integer count = mapper.uniqueVerificationByUsername(entity);
|
||||||
|
if(count != null && count > 0){
|
||||||
|
// 重复
|
||||||
|
throw new ServiceException(SystemMsg.EXCEPTION_USER_UNIQUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
UserModel update = super.update(model);
|
||||||
|
if(update != null){
|
||||||
|
// 刷新用户缓存
|
||||||
|
UserUtil.refreshUser(update);
|
||||||
|
}
|
||||||
|
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel queryByUserName(String username) {
|
||||||
|
String key = HumpUtil.humpToUnderline("username");
|
||||||
|
QueryBuilder<SysUser> queryBuilder = new GenQueryBuilder<>();
|
||||||
|
QueryWrapper<SysUser> queryWrapper = queryBuilder.build();
|
||||||
|
queryWrapper.eq(key, username);
|
||||||
|
SysUser user = this.getOne(queryWrapper);
|
||||||
|
return super.transformT2M(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getRoleCodeList(String userId) {
|
||||||
|
return mapper.getRoleCodeList(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getAllPerms(String userId) {
|
||||||
|
return mapper.queryAllPerms(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MenuModel> getMenuListByUserId(String userId) {
|
||||||
|
List<SysMenu> menuList = mapper.findMenuListByUserId(userId);
|
||||||
|
return WrapperUtil.transformInstance(menuList, MenuModel.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,206 @@
|
|||||||
|
package org.opsli.modulars.system.user.web;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.opsli.api.base.result.ResultVo;
|
||||||
|
import org.opsli.api.web.system.user.UserApi;
|
||||||
|
import org.opsli.api.wrapper.system.menu.MenuModel;
|
||||||
|
import org.opsli.api.wrapper.system.user.UserModel;
|
||||||
|
import org.opsli.common.annotation.ApiRestController;
|
||||||
|
import org.opsli.core.base.concroller.BaseRestController;
|
||||||
|
import org.opsli.core.persistence.Page;
|
||||||
|
import org.opsli.core.persistence.querybuilder.QueryBuilder;
|
||||||
|
import org.opsli.core.persistence.querybuilder.WebQueryBuilder;
|
||||||
|
import org.opsli.modulars.system.user.entity.SysUser;
|
||||||
|
import org.opsli.modulars.system.user.service.IUserService;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: opsli-boot
|
||||||
|
* @BelongsPackage: org.opsli.modulars.test.web
|
||||||
|
* @Author: Parker
|
||||||
|
* @CreateTime: 2020-09-13 17:40
|
||||||
|
* @Description: 用户信息
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@ApiRestController("/sys/user")
|
||||||
|
public class UserRestController extends BaseRestController<SysUser, UserModel, IUserService>
|
||||||
|
implements UserApi {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息 查一条
|
||||||
|
* @param model 模型
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "获得单条字典明细数据", notes = "获得单条字典明细数据 - ID")
|
||||||
|
@Override
|
||||||
|
public ResultVo<UserModel> get(UserModel model) {
|
||||||
|
// 如果系统内部调用 则直接查数据库
|
||||||
|
if(model != null && model.getIzApi() != null && model.getIzApi()){
|
||||||
|
model = IService.get(model);
|
||||||
|
}
|
||||||
|
return ResultVo.success(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息 查询分页
|
||||||
|
* @param pageNo 当前页
|
||||||
|
* @param pageSize 每页条数
|
||||||
|
* @param request request
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||||
|
|
||||||
|
QueryBuilder<SysUser> queryBuilder = new WebQueryBuilder<>(SysUser.class, request.getParameterMap());
|
||||||
|
Page<SysUser, UserModel> page = new Page<>(pageNo, pageSize);
|
||||||
|
page.setQueryWrapper(queryBuilder.build());
|
||||||
|
page = IService.findPage(page);
|
||||||
|
|
||||||
|
return ResultVo.success(page.getBootstrapData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息 新增
|
||||||
|
* @param model 模型
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "新增字典明细数据", notes = "新增字典明细数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> insert(UserModel model) {
|
||||||
|
// 调用新增方法
|
||||||
|
IService.insert(model);
|
||||||
|
return ResultVo.success("新增字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息 修改
|
||||||
|
* @param model 模型
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "修改字典明细数据", notes = "修改字典明细数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> update(UserModel model) {
|
||||||
|
// 调用修改方法
|
||||||
|
IService.update(model);
|
||||||
|
return ResultVo.success("修改字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息 删除
|
||||||
|
* @param id ID
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "删除字典明细数据数据", notes = "删除字典明细数据数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> del(String id){
|
||||||
|
IService.delete(id);
|
||||||
|
return ResultVo.success("删除字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息 批量删除
|
||||||
|
* @param ids ID 数组
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "批量删除字典明细数据数据", notes = "批量删除字典明细数据数据")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> delAll(String[] ids){
|
||||||
|
IService.deleteAll(ids);
|
||||||
|
return ResultVo.success("批量删除字典明细数据成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息 Excel 导出
|
||||||
|
* @param request request
|
||||||
|
* @param response response
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "导出Excel", notes = "导出Excel")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> exportExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
QueryBuilder<SysUser> queryBuilder = new WebQueryBuilder<>(SysUser.class, request.getParameterMap());
|
||||||
|
return super.excelExport(UserApi.TITLE, queryBuilder.build(), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息 Excel 导入
|
||||||
|
* @param request 文件流 request
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "导入Excel", notes = "导入Excel")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> excelImport(MultipartHttpServletRequest request) {
|
||||||
|
return super.excelImport(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息 Excel 下载导入模版
|
||||||
|
* @param response response
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "导出Excel模版", notes = "导出Excel模版")
|
||||||
|
@Override
|
||||||
|
public ResultVo<?> importTemplate(HttpServletResponse response) {
|
||||||
|
return super.importTemplate(UserApi.TITLE, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 username 获得用户
|
||||||
|
* @param username 用户名
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "根据 username 获得用户", notes = "根据 username 获得用户")
|
||||||
|
@Override
|
||||||
|
public ResultVo<UserModel> getUserByUsername(String username) {
|
||||||
|
UserModel userModel = IService.queryByUserName(username);
|
||||||
|
if(userModel != null){
|
||||||
|
return ResultVo.success(userModel);
|
||||||
|
}
|
||||||
|
return ResultVo.error("没有该用户");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 userId 获得用户角色
|
||||||
|
* @param userId 用户Id
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ResultVo<List<String>> getRolesByUserId(String userId) {
|
||||||
|
List<String> roleCodeList = IService.getRoleCodeList(userId);
|
||||||
|
return ResultVo.success(roleCodeList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 userId 获得用户权限
|
||||||
|
* @param userId 用户Id
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ResultVo<List<String>> getAllPerms(String userId) {
|
||||||
|
List<String> allPerms = IService.getAllPerms(userId);
|
||||||
|
return ResultVo.success(allPerms);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 userId 获得用户菜单
|
||||||
|
* @param userId 用户Id
|
||||||
|
* @return ResultVo
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ResultVo<List<MenuModel>> getMenuListByUserId(String userId) {
|
||||||
|
List<MenuModel> menuModelList = IService.getMenuListByUserId(userId);
|
||||||
|
return ResultVo.success(menuModelList);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,19 +1,14 @@
|
|||||||
package org.opsli;
|
package org.opsli;
|
||||||
|
|
||||||
import org.opsli.general.StartPrint;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
|
||||||
|
|
||||||
|
|
||||||
@SpringBootApplication()
|
@SpringBootApplication()
|
||||||
public class OpsliApplication {
|
public class OpsliApplication {
|
||||||
|
|
||||||
public static void main(String[] args){
|
public static void main(String[] args){
|
||||||
ConfigurableApplicationContext application = SpringApplication.run(OpsliApplication.class, args);
|
SpringApplication.run(OpsliApplication.class, args);
|
||||||
// 打印启动日志
|
|
||||||
StartPrint.INSTANCE.print(application.getEnvironment());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue