commit
This commit is contained in:
commit
98e9f73313
|
|
@ -0,0 +1,27 @@
|
|||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
logs/
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
.idea
|
||||
*.iml
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
target/
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 MAKU
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
## 简介
|
||||
**FastBoot**是采用SpringBoot、SpringSecurity、Mybatis-Plus等框架,开发的一套企业级脚手架系统,使用门槛极低,且采用MIT开源协议,完全免费开源,可免费用于**商业项目**等场景。
|
||||
|
||||
## 使命
|
||||
致力于打造成一套高质量、低BUG、易于上手、可维护性强的低代码开发脚手架系统。
|
||||
|
||||
## 软件需求
|
||||
- JDK1.8
|
||||
- MySQL8.0
|
||||
- Maven3.0+
|
||||
- Redis3.0+
|
||||
|
||||
## 环境搭建
|
||||
- 下载项目源码,一般通过git clone命令
|
||||
- idea、eclipse需安装lombok插件,不然会提示找不到get set方法
|
||||
- 创建数据库fast_boot,数据库编码为utf8mb4
|
||||
- 执行db/mysql.sql文件,初始化数据库脚本
|
||||
- 修改application-dev.yml文件,配置MySQL、Redis账号信息
|
||||
- 在fast-boot目录下,执行mvn clean install
|
||||
|
||||
## 本地启动
|
||||
- 在fast-server工程里面,运行ServerApplication.java,则可启动项目
|
||||
- 接口文档路径:http://localhost:8080/doc.html
|
||||
- 账号密码:admin/admin
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
CREATE TABLE sys_user
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
username varchar(50) NOT NULL COMMENT '用户名',
|
||||
password varchar(100) COMMENT '密码',
|
||||
real_name varchar(50) COMMENT '姓名',
|
||||
avatar varchar(200) COMMENT '头像',
|
||||
gender tinyint COMMENT '性别 0:男 1:女',
|
||||
email varchar(100) COMMENT '邮箱',
|
||||
mobile varchar(20) COMMENT '手机号',
|
||||
org_id bigint COMMENT '机构ID',
|
||||
super_admin tinyint COMMENT '超级管理员 0:否 1:是',
|
||||
status tinyint COMMENT '状态 0:停用 1:正常',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARSET = utf8mb4 COMMENT ='用户管理';
|
||||
|
||||
CREATE TABLE sys_org
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
pid bigint COMMENT '上级ID',
|
||||
name varchar(50) COMMENT '机构名称',
|
||||
sort int COMMENT '排序',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id),
|
||||
key idx_pid (pid)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARSET = utf8mb4 COMMENT ='机构管理';
|
||||
|
||||
create table sys_role
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
name varchar(50) COMMENT '角色名称',
|
||||
remark varchar(100) COMMENT '备注',
|
||||
data_scope tinyint COMMENT '数据范围 0:全部数据 1:本部门及子部门数据 2:本部门数据 3:本人数据 4:自定义数据',
|
||||
org_id bigint COMMENT '机构ID',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id),
|
||||
key idx_org_id (org_id)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARACTER SET utf8mb4 COMMENT ='角色管理';
|
||||
|
||||
create table sys_user_role
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
role_id bigint COMMENT '角色ID',
|
||||
user_id bigint COMMENT '用户ID',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id),
|
||||
key idx_role_id (role_id),
|
||||
key idx_user_id (user_id)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARACTER SET utf8mb4 COMMENT ='用户角色关系';
|
||||
|
||||
CREATE TABLE sys_post
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
post_code varchar(100) COMMENT '岗位编码',
|
||||
post_name varchar(100) COMMENT '岗位名称',
|
||||
sort int COMMENT '排序',
|
||||
status tinyint COMMENT '状态 0:停用 1:正常',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARACTER SET utf8mb4 COMMENT ='岗位管理';
|
||||
|
||||
CREATE TABLE sys_user_post
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
user_id bigint COMMENT '用户ID',
|
||||
post_id bigint COMMENT '岗位ID',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id),
|
||||
key idx_user_id (user_id),
|
||||
key idx_post_id (post_id)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARACTER SET utf8mb4 COMMENT ='用户岗位关系';
|
||||
|
||||
create table sys_menu
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
pid bigint COMMENT '上级ID,一级菜单为0',
|
||||
name varchar(200) COMMENT '菜单名称',
|
||||
url varchar(200) COMMENT '菜单URL',
|
||||
authority varchar(500) COMMENT '授权标识(多个用逗号分隔,如:sys:menu:list,sys:menu:save)',
|
||||
type tinyint COMMENT '类型 0:菜单 1:按钮 2:接口',
|
||||
open_style tinyint COMMENT '打开方式 0:内部 1:外部',
|
||||
icon varchar(50) COMMENT '菜单图标',
|
||||
sort int COMMENT '排序',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id),
|
||||
key idx_pid (pid)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARACTER SET utf8mb4 COMMENT ='菜单管理';
|
||||
|
||||
create table sys_role_menu
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
role_id bigint COMMENT '角色ID',
|
||||
menu_id bigint COMMENT '菜单ID',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id),
|
||||
key idx_role_id (role_id),
|
||||
key idx_menu_id (menu_id)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARACTER SET utf8mb4 COMMENT ='角色菜单关系';
|
||||
|
||||
create table sys_role_data_scope
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
role_id bigint COMMENT '角色ID',
|
||||
org_id bigint COMMENT '机构ID',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id),
|
||||
key idx_role_id (role_id)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARACTER SET utf8mb4 COMMENT ='角色数据权限';
|
||||
|
||||
CREATE TABLE sys_oauth_client (
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
client_id varchar(256) NOT NULL COMMENT '客户端id',
|
||||
client_secret varchar(256) COMMENT '客户端密钥',
|
||||
resource_ids varchar(256) COMMENT '资源ids',
|
||||
scope varchar(256) COMMENT '授权范围',
|
||||
authorized_grant_types varchar(256) COMMENT '授权类型',
|
||||
web_server_redirect_uri varchar(256) COMMENT '回调地址',
|
||||
authorities varchar(256) COMMENT '权限标识',
|
||||
access_token_validity int COMMENT '访问令牌有效期',
|
||||
refresh_token_validity int COMMENT '刷新令牌有效期',
|
||||
additional_information varchar(4096) COMMENT '附加信息',
|
||||
autoapprove varchar(128) COMMENT '自动授权',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='客户端管理';
|
||||
|
||||
create table sys_dict_type
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
dict_type varchar(100) NOT NULL COMMENT '字典类型',
|
||||
dict_name varchar(255) NOT NULL COMMENT '字典名称',
|
||||
remark varchar(255) COMMENT '备注',
|
||||
sort int COMMENT '排序',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARACTER SET utf8mb4 COMMENT ='字典类型';
|
||||
|
||||
create table sys_dict_data
|
||||
(
|
||||
id bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
dict_type_id bigint NOT NULL COMMENT '字典类型ID',
|
||||
dict_label varchar(255) NOT NULL COMMENT '字典标签',
|
||||
dict_value varchar(255) COMMENT '字典值',
|
||||
remark varchar(255) COMMENT '备注',
|
||||
sort int COMMENT '排序',
|
||||
version int COMMENT '版本号',
|
||||
deleted tinyint COMMENT '删除标识 0:正常 1:已删除',
|
||||
creator bigint COMMENT '创建者',
|
||||
create_time datetime COMMENT '创建时间',
|
||||
updater bigint COMMENT '更新者',
|
||||
update_time datetime COMMENT '更新时间',
|
||||
primary key (id)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 10000 DEFAULT CHARACTER SET utf8mb4 COMMENT ='字典数据';
|
||||
|
||||
|
||||
INSERT INTO sys_user (id, username, password, real_name, gender, email, mobile, status, org_id, super_admin, version, deleted, creator, create_time, updater, update_time) VALUES (10000, 'admin', '$2a$10$XCoT1x7oMt97bBVpz5fCz.AtsDm3WUliBO//FA61CHQM7wnicC6GK', 'admin', 0, 'babamu@126.com', '13612345678', 1, null, 1, 0, 0, 10000, now(), 10000, now());
|
||||
INSERT INTO sys_oauth_client (id, client_id, client_secret, resource_ids, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove, version, deleted, creator, create_time, updater, update_time) VALUES (10000, 'web', '123456', '', 'all', '["authorization_code","password","implicit","client_credentials","refresh_token"]', 'https://gitee.com/makunet', NULL, 43200, 604800, NULL, 'true', 0, 0, 10000, now(), 10000, now());
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>net.maku</groupId>
|
||||
<artifactId>fast-boot</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>fast-boot-framework</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.maku.framework.common.constant;
|
||||
|
||||
/**
|
||||
* 常量
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface Constant {
|
||||
/**
|
||||
* 根节点标识
|
||||
*/
|
||||
Long ROOT = 0L;
|
||||
/**
|
||||
* 当前页码
|
||||
*/
|
||||
String PAGE = "page";
|
||||
/**
|
||||
* 数据权限
|
||||
*/
|
||||
String DATA_SCOPE = "dataScope";
|
||||
/**
|
||||
* 超级管理员
|
||||
*/
|
||||
Integer SUPER_ADMIN = 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package net.maku.framework.common.dao;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* 基础Dao
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface BaseDao<T> extends BaseMapper<T> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package net.maku.framework.common.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Entity基类
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
public abstract class BaseEntity {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Long creator;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Long updater;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
@Version
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Integer version;
|
||||
|
||||
/**
|
||||
* 删除标记
|
||||
*/
|
||||
@TableLogic
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Integer deleted;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package net.maku.framework.common.exception;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 错误编码
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ErrorCode {
|
||||
UNAUTHORIZED(401, "未授权,不能访问"),
|
||||
FORBIDDEN(403, "没权限,禁止访问"),
|
||||
INTERNAL_SERVER_ERROR(500, "服务器异常,请稍后再试"),
|
||||
ACCOUNT_PASSWORD_ERROR(1001, "账号或密码错误");
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package net.maku.framework.common.exception;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 自定义异常
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class FastException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int code;
|
||||
private String msg;
|
||||
|
||||
public FastException(String msg) {
|
||||
super(msg);
|
||||
this.code = ErrorCode.INTERNAL_SERVER_ERROR.getCode();
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public FastException(ErrorCode errorCode) {
|
||||
super(errorCode.getMsg());
|
||||
this.code = errorCode.getCode();
|
||||
this.msg = errorCode.getMsg();
|
||||
}
|
||||
|
||||
public FastException(String msg, Throwable e) {
|
||||
super(msg, e);
|
||||
this.code = ErrorCode.INTERNAL_SERVER_ERROR.getCode();
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package net.maku.framework.common.exception;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
|
||||
/**
|
||||
* 异常处理器
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class FastExceptionHandler {
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(FastException.class)
|
||||
public Result<String> handleRenException(FastException ex){
|
||||
|
||||
return Result.error(ex.getCode(), ex.getMsg());
|
||||
}
|
||||
|
||||
/**
|
||||
* SpringMVC参数绑定,Validator校验不正确
|
||||
*/
|
||||
@ExceptionHandler(BindException.class)
|
||||
public Result<String> bindException(BindException ex) {
|
||||
FieldError fieldError = ex.getFieldError();
|
||||
assert fieldError != null;
|
||||
return Result.error(fieldError.getDefaultMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(AccessDeniedException.class)
|
||||
public Result<String> handleAccessDeniedException(Exception ex){
|
||||
|
||||
return Result.error(ErrorCode.FORBIDDEN);
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public Result<String> handleException(Exception ex){
|
||||
|
||||
return Result.error(ex.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package net.maku.framework.common.handler;
|
||||
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import net.maku.framework.security.user.SecurityUser;
|
||||
import net.maku.framework.security.user.UserDetail;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* mybatis-plus 自动填充字段
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class FieldMetaObjectHandler implements MetaObjectHandler {
|
||||
private final static String CREATE_TIME = "createTime";
|
||||
private final static String CREATOR = "creator";
|
||||
private final static String UPDATE_TIME = "updateTime";
|
||||
private final static String UPDATER = "updater";
|
||||
private final static String ORG_ID = "orgId";
|
||||
private final static String VERSION = "version";
|
||||
private final static String DELETED = "deleted";
|
||||
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
Date date = new Date();
|
||||
|
||||
// 创建者
|
||||
strictInsertFill(metaObject, CREATOR, Long.class, user.getId());
|
||||
// 创建时间
|
||||
strictInsertFill(metaObject, CREATE_TIME, Date.class, date);
|
||||
// 更新者
|
||||
strictInsertFill(metaObject, UPDATER, Long.class, user.getId());
|
||||
// 更新时间
|
||||
strictInsertFill(metaObject, UPDATE_TIME, Date.class, date);
|
||||
// 创建者所属机构
|
||||
strictInsertFill(metaObject, ORG_ID, Long.class, user.getOrgId());
|
||||
// 版本号
|
||||
strictInsertFill(metaObject, VERSION, Integer.class, 0);
|
||||
// 删除标识
|
||||
strictInsertFill(metaObject, DELETED, Integer.class, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
// 更新者
|
||||
strictUpdateFill(metaObject, UPDATER, Long.class, SecurityUser.getUserId());
|
||||
// 更新时间
|
||||
strictUpdateFill(metaObject, UPDATE_TIME, Date.class, new Date());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package net.maku.framework.common.interceptor;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 数据范围
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class DataScope {
|
||||
private String sqlFilter;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
package net.maku.framework.common.interceptor;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.StringValue;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.Select;
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 数据权限
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class DataScopeInnerInterceptor implements InnerInterceptor {
|
||||
|
||||
@Override
|
||||
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
|
||||
DataScope scope = getDataScope(parameter);
|
||||
// 不进行数据过滤
|
||||
if(scope == null || StrUtil.isBlank(scope.getSqlFilter())){
|
||||
return;
|
||||
}
|
||||
|
||||
// 拼接新SQL
|
||||
String buildSql = getSelect(boundSql.getSql(), scope);
|
||||
|
||||
// 重写SQL
|
||||
PluginUtils.mpBoundSql(boundSql).sql(buildSql);
|
||||
}
|
||||
|
||||
private DataScope getDataScope(Object parameter){
|
||||
if (parameter == null){
|
||||
return null;
|
||||
}
|
||||
|
||||
// 判断参数里是否有DataScope对象
|
||||
if (parameter instanceof Map) {
|
||||
Map<?, ?> parameterMap = (Map<?, ?>) parameter;
|
||||
for (Map.Entry entry : parameterMap.entrySet()) {
|
||||
if (entry.getValue() != null && entry.getValue() instanceof DataScope) {
|
||||
return (DataScope) entry.getValue();
|
||||
}
|
||||
}
|
||||
} else if (parameter instanceof DataScope) {
|
||||
return (DataScope) parameter;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getSelect(String buildSql, DataScope scope){
|
||||
try {
|
||||
Select select = (Select) CCJSqlParserUtil.parse(buildSql);
|
||||
PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
|
||||
|
||||
Expression expression = plainSelect.getWhere();
|
||||
if(expression == null){
|
||||
plainSelect.setWhere(new StringValue(scope.getSqlFilter()));
|
||||
}else{
|
||||
AndExpression andExpression = new AndExpression(expression, new StringValue(scope.getSqlFilter()));
|
||||
plainSelect.setWhere(andExpression);
|
||||
}
|
||||
|
||||
return select.toString().replaceAll("'", "");
|
||||
}catch (JSQLParserException e){
|
||||
return buildSql;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package net.maku.framework.common.page;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分页工具类
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "分页数据")
|
||||
public class PageResult<T> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(name = "总记录数")
|
||||
private int total;
|
||||
|
||||
@Schema(name = "列表数据")
|
||||
private List<T> list;
|
||||
|
||||
/**
|
||||
* 分页
|
||||
* @param list 列表数据
|
||||
* @param total 总记录数
|
||||
*/
|
||||
public PageResult(List<T> list, long total) {
|
||||
this.list = list;
|
||||
this.total = (int)total;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package net.maku.framework.common.query;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Range;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 查询公共参数
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
public class Query {
|
||||
@NotNull(message = "页码不能为空")
|
||||
@Min(value = 1, message = "页码最小值为 1")
|
||||
@Schema(name = "当前页码", required = true)
|
||||
Integer page;
|
||||
|
||||
@NotNull(message = "每页条数不能为空")
|
||||
@Range(min = 1, max = 1000, message = "每页条数,取值范围 1-1000")
|
||||
@Schema(name = "每页条数", required = true)
|
||||
Integer limit;
|
||||
|
||||
@Schema(name = "排序字段")
|
||||
String order;
|
||||
|
||||
@Schema(name = "是否升序")
|
||||
boolean asc;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package net.maku.framework.common.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* 基础服务接口,所有Service接口都要继承
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface BaseService<T> extends IService<T> {
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
package net.maku.framework.common.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.maku.framework.common.constant.Constant;
|
||||
import net.maku.framework.common.interceptor.DataScope;
|
||||
import net.maku.framework.common.query.Query;
|
||||
import net.maku.framework.common.service.BaseService;
|
||||
import net.maku.framework.security.user.SecurityUser;
|
||||
import net.maku.framework.security.user.UserDetail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 基础服务类,所有Service都要继承
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements BaseService<T> {
|
||||
|
||||
/**
|
||||
* 获取分页对象
|
||||
* @param query 分页参数
|
||||
*/
|
||||
protected IPage<T> getPage(Query query) {
|
||||
Page<T> page = new Page<>(query.getPage(), query.getLimit());
|
||||
|
||||
// 排序
|
||||
if(StringUtils.isNotBlank(query.getOrder())){
|
||||
if(query.isAsc()) {
|
||||
return page.addOrder(OrderItem.asc(query.getOrder()));
|
||||
}else {
|
||||
return page.addOrder(OrderItem.desc(query.getOrder()));
|
||||
}
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 原生SQL 数据权限
|
||||
* @param tableAlias 表别名,多表关联时,需要填写表别名
|
||||
* @return 返回数据权限
|
||||
*/
|
||||
protected DataScope getDataScope(String tableAlias) {
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
// 如果是超级管理员,则不进行数据过滤
|
||||
if(user.getSuperAdmin().equals(Constant.SUPER_ADMIN)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取表的别名
|
||||
if(StringUtils.isNotBlank(tableAlias)){
|
||||
tableAlias += ".";
|
||||
}
|
||||
|
||||
StringBuilder sqlFilter = new StringBuilder();
|
||||
sqlFilter.append(" (");
|
||||
|
||||
// 数据权限范围
|
||||
List<Long> dataScopeList = user.getDataScopeList();
|
||||
// 全部数据权限
|
||||
if (dataScopeList == null){
|
||||
return null;
|
||||
}
|
||||
// 数据过滤
|
||||
if(dataScopeList.size() > 0){
|
||||
sqlFilter.append(tableAlias).append("org_id");
|
||||
|
||||
sqlFilter.append(" in(").append(StrUtil.join(",", dataScopeList)).append(")");
|
||||
|
||||
sqlFilter.append(" or ");
|
||||
}
|
||||
|
||||
// 查询本人数据
|
||||
sqlFilter.append(tableAlias).append("creator").append("=").append(user.getId());
|
||||
|
||||
sqlFilter.append(")");
|
||||
|
||||
return new DataScope(sqlFilter.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* MyBatis-Plus 数据权限
|
||||
*/
|
||||
protected void dataScopeWrapper(QueryWrapper<T> queryWrapper) {
|
||||
DataScope dataScope = getDataScope(null);
|
||||
if (dataScope != null){
|
||||
queryWrapper.apply(dataScope.getSqlFilter());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package net.maku.framework.common.utils;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import net.maku.framework.common.exception.FastException;
|
||||
|
||||
/**
|
||||
* 校验工具类
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class AssertUtils {
|
||||
|
||||
public static void isBlank(String str, String variable) {
|
||||
if (StrUtil.isBlank(str)) {
|
||||
throw new FastException(variable + "不能为空");
|
||||
}
|
||||
}
|
||||
|
||||
public static void isNull(Object object, String variable) {
|
||||
if (object == null) {
|
||||
throw new FastException(variable + "不能为空");
|
||||
}
|
||||
}
|
||||
|
||||
public static void isArrayEmpty(Object[] array, String variable) {
|
||||
if(ArrayUtil.isEmpty(array)){
|
||||
throw new FastException(variable + "不能为空");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package net.maku.framework.common.utils;
|
||||
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 日期处理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class DateUtils {
|
||||
/** 时间格式(yyyy-MM-dd) */
|
||||
public final static String DATE_PATTERN = "yyyy-MM-dd";
|
||||
/** 时间格式(yyyy-MM-dd HH:mm:ss) */
|
||||
public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 日期格式化 日期格式为:yyyy-MM-dd
|
||||
* @param date 日期
|
||||
* @return 返回yyyy-MM-dd格式日期
|
||||
*/
|
||||
public static String format(Date date) {
|
||||
return format(date, DATE_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期格式化 日期格式为:yyyy-MM-dd
|
||||
* @param date 日期
|
||||
* @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN
|
||||
* @return 返回yyyy-MM-dd格式日期
|
||||
*/
|
||||
public static String format(Date date, String pattern) {
|
||||
if(date != null){
|
||||
SimpleDateFormat df = new SimpleDateFormat(pattern);
|
||||
return df.format(date);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期解析
|
||||
* @param date 日期
|
||||
* @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN
|
||||
* @return 返回Date
|
||||
*/
|
||||
public static Date parse(String date, String pattern) {
|
||||
try {
|
||||
return new SimpleDateFormat(pattern).parse(date);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package net.maku.framework.common.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
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 java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Http
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class HttpContextUtils {
|
||||
|
||||
public static HttpServletRequest getHttpServletRequest() {
|
||||
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||
if(requestAttributes == null){
|
||||
return null;
|
||||
}
|
||||
|
||||
return ((ServletRequestAttributes) requestAttributes).getRequest();
|
||||
}
|
||||
|
||||
public static Map<String, String> getParameterMap(HttpServletRequest request) {
|
||||
Enumeration<String> parameters = request.getParameterNames();
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
while (parameters.hasMoreElements()) {
|
||||
String parameter = parameters.nextElement();
|
||||
String value = request.getParameter(parameter);
|
||||
if (StrUtil.isNotBlank(value)) {
|
||||
params.put(parameter, value);
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
public static String getDomain(){
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
StringBuffer url = request.getRequestURL();
|
||||
return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
|
||||
}
|
||||
|
||||
public static String getOrigin(){
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
return request.getHeader(HttpHeaders.ORIGIN);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package net.maku.framework.common.utils;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* JSON 工具类
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class JsonUtils {
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public static String toJsonString(Object object) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(object);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T parseObject(String text, Class<T> clazz) {
|
||||
if (StrUtil.isEmpty(text)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return objectMapper.readValue(text, clazz);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T parseObject(byte[] bytes, Class<T> clazz) {
|
||||
if (ArrayUtil.isEmpty(bytes)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return objectMapper.readValue(bytes, clazz);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T parseObject(String text, TypeReference<T> typeReference) {
|
||||
try {
|
||||
return objectMapper.readValue(text, typeReference);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> List<T> parseArray(String text, Class<T> clazz) {
|
||||
if (StrUtil.isEmpty(text)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
try {
|
||||
return objectMapper.readValue(text, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package net.maku.framework.common.utils;
|
||||
|
||||
/**
|
||||
* Redis Key管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class RedisKeys {
|
||||
|
||||
/**
|
||||
* 验证码Key
|
||||
*/
|
||||
public static String getCaptchaKey(String key) {
|
||||
return "sys:captcha:" + key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权码Key
|
||||
*/
|
||||
public static String getOauthCode(String code) {
|
||||
return "oauth:code:" + code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信小程序授权key
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getWxMpAuthKey(String key) {
|
||||
return "wx:mp:auth:" + key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信小程序授权类型key
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getWxMpAuthTypeKey(String key) {
|
||||
return "wx:mp:auth:type:" + key;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
package net.maku.framework.common.utils;
|
||||
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Redis工具类
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Component
|
||||
public class RedisUtils {
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
/** 默认过期时长为24小时,单位:秒 */
|
||||
public final static long DEFAULT_EXPIRE = 60 * 60 * 24L;
|
||||
/** 过期时长为1小时,单位:秒 */
|
||||
public final static long HOUR_ONE_EXPIRE = 60 * 60 * 1L;
|
||||
/** 过期时长为6小时,单位:秒 */
|
||||
public final static long HOUR_SIX_EXPIRE = 60 * 60 * 6L;
|
||||
/** 不设置过期时长 */
|
||||
public final static long NOT_EXPIRE = -1L;
|
||||
|
||||
public void set(String key, Object value, long expire){
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
if(expire != NOT_EXPIRE){
|
||||
expire(key, expire);
|
||||
}
|
||||
}
|
||||
|
||||
public void set(String key, Object value){
|
||||
set(key, value, DEFAULT_EXPIRE);
|
||||
}
|
||||
|
||||
public Object get(String key, long expire) {
|
||||
Object value = redisTemplate.opsForValue().get(key);
|
||||
if(expire != NOT_EXPIRE){
|
||||
expire(key, expire);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object get(String key) {
|
||||
return get(key, NOT_EXPIRE);
|
||||
}
|
||||
|
||||
public void delete(String key) {
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
public void delete(Collection<String> keys) {
|
||||
redisTemplate.delete(keys);
|
||||
}
|
||||
|
||||
public Object hGet(String key, String field) {
|
||||
return redisTemplate.opsForHash().get(key, field);
|
||||
}
|
||||
|
||||
public Map<String, Object> hGetAll(String key){
|
||||
HashOperations<String, String, Object> hashOperations = redisTemplate.opsForHash();
|
||||
return hashOperations.entries(key);
|
||||
}
|
||||
|
||||
public void hMSet(String key, Map<String, Object> map){
|
||||
hMSet(key, map, DEFAULT_EXPIRE);
|
||||
}
|
||||
|
||||
public void hMSet(String key, Map<String, Object> map, long expire){
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
|
||||
if(expire != NOT_EXPIRE){
|
||||
expire(key, expire);
|
||||
}
|
||||
}
|
||||
|
||||
public void hSet(String key, String field, Object value) {
|
||||
hSet(key, field, value, DEFAULT_EXPIRE);
|
||||
}
|
||||
|
||||
public void hSet(String key, String field, Object value, long expire) {
|
||||
redisTemplate.opsForHash().put(key, field, value);
|
||||
|
||||
if(expire != NOT_EXPIRE){
|
||||
expire(key, expire);
|
||||
}
|
||||
}
|
||||
|
||||
public void expire(String key, long expire){
|
||||
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public void hDel(String key, Object... fields){
|
||||
redisTemplate.opsForHash().delete(key, fields);
|
||||
}
|
||||
|
||||
public void leftPush(String key, Object value){
|
||||
leftPush(key, value, DEFAULT_EXPIRE);
|
||||
}
|
||||
|
||||
public void leftPush(String key, Object value, long expire){
|
||||
redisTemplate.opsForList().leftPush(key, value);
|
||||
|
||||
if(expire != NOT_EXPIRE){
|
||||
expire(key, expire);
|
||||
}
|
||||
}
|
||||
|
||||
public Object rightPop(String key){
|
||||
return redisTemplate.opsForList().rightPop(key);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package net.maku.framework.common.utils;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import net.maku.framework.common.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* 响应数据
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "响应")
|
||||
public class Result<T> {
|
||||
@Schema(name = "编码", description = "0表示成功,其他值表示失败")
|
||||
private int code = 0;
|
||||
|
||||
@Schema(name = "消息内容")
|
||||
private String msg = "success";
|
||||
|
||||
@Schema(name = "响应数据")
|
||||
private T data;
|
||||
|
||||
public static <T> Result<T> ok() {
|
||||
return ok(null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> ok(T data) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setData(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T> Result<T> error() {
|
||||
return error(ErrorCode.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(String msg) {
|
||||
return error(ErrorCode.INTERNAL_SERVER_ERROR.getCode(), msg);
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(ErrorCode errorCode) {
|
||||
return error(errorCode.getCode(), errorCode.getMsg());
|
||||
}
|
||||
|
||||
public static <T> Result<T> error(int code, String msg) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(code);
|
||||
result.setMsg(msg);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package net.maku.framework.common.utils;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 树节点,所有需要实现树节点的,都需要继承该类
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
public class TreeNode<T> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 上级ID
|
||||
*/
|
||||
private Long pid;
|
||||
/**
|
||||
* 子节点列表
|
||||
*/
|
||||
private List<T> children = new ArrayList<>();
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package net.maku.framework.common.utils;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 树形结构工具类,如:菜单、机构等
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class TreeUtils {
|
||||
|
||||
/**
|
||||
* 根据pid,构建树节点
|
||||
*/
|
||||
public static <T extends TreeNode> List<T> build(List<T> treeNodes, Long pid) {
|
||||
// pid不能为空
|
||||
AssertUtils.isNull(pid, "pid");
|
||||
|
||||
List<T> treeList = new ArrayList<>();
|
||||
for(T treeNode : treeNodes) {
|
||||
if (pid.equals(treeNode.getPid())) {
|
||||
treeList.add(findChildren(treeNodes, treeNode));
|
||||
}
|
||||
}
|
||||
|
||||
return treeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找子节点
|
||||
*/
|
||||
private static <T extends TreeNode> T findChildren(List<T> treeNodes, T rootNode) {
|
||||
for(T treeNode : treeNodes) {
|
||||
if(rootNode.getId().equals(treeNode.getPid())) {
|
||||
rootNode.getChildren().add(findChildren(treeNodes, treeNode));
|
||||
}
|
||||
}
|
||||
return rootNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建树节点
|
||||
*/
|
||||
public static <T extends TreeNode> List<T> build(List<T> treeNodes) {
|
||||
List<T> result = new ArrayList<>();
|
||||
|
||||
// list转map
|
||||
Map<Long, T> nodeMap = new LinkedHashMap<>(treeNodes.size());
|
||||
for(T treeNode : treeNodes){
|
||||
nodeMap.put(treeNode.getId(), treeNode);
|
||||
}
|
||||
|
||||
for(T node : nodeMap.values()) {
|
||||
T parent = nodeMap.get(node.getPid());
|
||||
if(parent != null && !(node.getId().equals(parent.getId()))){
|
||||
parent.getChildren().add(node);
|
||||
continue;
|
||||
}
|
||||
|
||||
result.add(node);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package net.maku.framework.config;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import net.maku.framework.common.handler.FieldMetaObjectHandler;
|
||||
import net.maku.framework.common.interceptor.DataScopeInnerInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* mybatis-plus 配置
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Configuration
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
|
||||
// 数据权限
|
||||
mybatisPlusInterceptor.addInnerInterceptor(new DataScopeInnerInterceptor());
|
||||
// 分页插件
|
||||
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
|
||||
// 乐观锁
|
||||
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
|
||||
// 防止全表更新与删除
|
||||
mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
|
||||
|
||||
return mybatisPlusInterceptor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FieldMetaObjectHandler fieldMetaObjectHandler(){
|
||||
return new FieldMetaObjectHandler();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package net.maku.framework.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
|
||||
/**
|
||||
* Redis配置
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
|
||||
@Bean
|
||||
public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer(){
|
||||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
|
||||
|
||||
return jackson2JsonRedisSerializer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
|
||||
RedisTemplate<String, Object> template = new RedisTemplate<>();
|
||||
// Key HashKey使用String序列化
|
||||
template.setKeySerializer(RedisSerializer.string());
|
||||
template.setHashKeySerializer(RedisSerializer.string());
|
||||
|
||||
// Value HashValue使用Jackson2JsonRedisSerializer序列化
|
||||
template.setValueSerializer(jackson2JsonRedisSerializer());
|
||||
template.setHashValueSerializer(jackson2JsonRedisSerializer());
|
||||
|
||||
template.setConnectionFactory(factory);
|
||||
return template;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package net.maku.framework.config;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Contact;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.info.License;
|
||||
import org.springdoc.core.GroupedOpenApi;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Swagger配置
|
||||
*
|
||||
* @author 阿沐 dolinked@qq.com
|
||||
*/
|
||||
@Configuration
|
||||
public class SwaggerConfig{
|
||||
|
||||
@Bean
|
||||
public GroupedOpenApi userApi(){
|
||||
String[] paths = { "/**" };
|
||||
String[] packagedToMatch = { "net.maku" };
|
||||
return GroupedOpenApi.builder().group("FastBoot")
|
||||
.pathsToMatch(paths)
|
||||
.packagesToScan(packagedToMatch).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAPI customOpenAPI() {
|
||||
Contact contact= new Contact();
|
||||
contact.setName("阿沐 babamu@126.com");
|
||||
|
||||
return new OpenAPI().info(new Info()
|
||||
.title("FastBoot")
|
||||
.description( "FastBoot")
|
||||
.contact(contact)
|
||||
.version("1.0")
|
||||
.termsOfService("https://gitee.com/makunet")
|
||||
.license(new License().name("MIT")
|
||||
.url("https://gitee.com/makunet")));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package net.maku.framework.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Web MVC配置
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedOriginPatterns("*")
|
||||
.allowCredentials(true)
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
|
||||
.maxAge(3600);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
converters.add(new ByteArrayHttpMessageConverter());
|
||||
converters.add(new StringHttpMessageConverter());
|
||||
converters.add(new ResourceHttpMessageConverter());
|
||||
converters.add(new AllEncompassingFormHttpMessageConverter());
|
||||
converters.add(new StringHttpMessageConverter());
|
||||
converters.add(jackson2HttpMessageConverter());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
|
||||
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
// 忽略未知属性
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
// 统一日期格式转换,不建议开启
|
||||
//mapper.setDateFormat(new SimpleDateFormat(DateUtils.DATE_TIME_PATTERN));
|
||||
mapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
|
||||
|
||||
converter.setObjectMapper(mapper);
|
||||
return converter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package net.maku.framework.security.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.security.exception.FastWebResponseExceptionTranslator;
|
||||
import net.maku.framework.security.token.FastTokenEnhancer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
|
||||
import org.springframework.security.oauth2.provider.ClientDetailsService;
|
||||
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
|
||||
/**
|
||||
* 认证服务器配置
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@EnableAuthorizationServer
|
||||
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final ClientDetailsService fastClientDetailsService;
|
||||
private final UserDetailsService userDetailsService;
|
||||
private final AuthorizationCodeServices redisAuthorizationCodeServices;
|
||||
private final TokenStore tokenStore;
|
||||
|
||||
/**
|
||||
* 配置客户端信息
|
||||
*/
|
||||
@Override
|
||||
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
|
||||
clients.withClientDetails(fastClientDetailsService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
|
||||
endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST, HttpMethod.DELETE);
|
||||
// 密码模式
|
||||
endpoints.authenticationManager(authenticationManager);
|
||||
// 支持刷新令牌
|
||||
endpoints.userDetailsService(userDetailsService);
|
||||
// 令牌管理
|
||||
endpoints.tokenStore(tokenStore);
|
||||
// 令牌增强
|
||||
endpoints.tokenEnhancer(tokenEnhancer());
|
||||
// 登录或者鉴权失败时的返回信息
|
||||
endpoints.exceptionTranslator(new FastWebResponseExceptionTranslator());
|
||||
// 配置授权码模式,存放在Redis中
|
||||
endpoints.authorizationCodeServices(redisAuthorizationCodeServices);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TokenEnhancer tokenEnhancer() {
|
||||
return new FastTokenEnhancer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(AuthorizationServerSecurityConfigurer security) {
|
||||
security
|
||||
.allowFormAuthenticationForClients()
|
||||
.tokenKeyAccess("permitAll()") // 匿名可访问/oauth/token_key
|
||||
.checkTokenAccess("isAuthenticated()") // 认证后可访问/oauth/check_token
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package net.maku.framework.security.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
/**
|
||||
* 加密配置
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Configuration
|
||||
public class PasswordConfig {
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder(){
|
||||
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package net.maku.framework.security.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.security.exception.SecurityAuthenticationEntryPoint;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
|
||||
/**
|
||||
* 资源服务器配置
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@EnableResourceServer
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
|
||||
private final TokenStore tokenStore;
|
||||
|
||||
@Override
|
||||
public void configure(ResourceServerSecurityConfigurer resources) {
|
||||
resources.tokenStore(tokenStore);
|
||||
|
||||
resources.authenticationEntryPoint(new SecurityAuthenticationEntryPoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
.and()
|
||||
.requestMatchers()
|
||||
// 被保护的资源
|
||||
.antMatchers("/sys/**", "/wx/mp/**")
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
.anyRequest().authenticated()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.maku.framework.security.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
|
||||
|
||||
/**
|
||||
* TokenStore
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
public class TokenStoreConfig {
|
||||
private final RedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
@Bean
|
||||
public TokenStore tokenStore() {
|
||||
// 使用redis存储token
|
||||
return new RedisTokenStore(redisConnectionFactory);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package net.maku.framework.security.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
/**
|
||||
* Spring Security配置
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@EnableWebSecurity
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
private final UserDetailsService userDetailsService;
|
||||
private final OncePerRequestFilter validateCodeFilter;
|
||||
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.userDetailsService(userDetailsService);
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码模式需要
|
||||
*/
|
||||
@Bean
|
||||
@Override
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception{
|
||||
return super.authenticationManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
|
||||
.formLogin()
|
||||
.loginPage("/login")
|
||||
.loginProcessingUrl("/login")
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/oauth/authorize").authenticated()
|
||||
.anyRequest().permitAll()
|
||||
.and().headers().frameOptions().disable()
|
||||
.and().csrf().disable()
|
||||
;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(WebSecurity web) {
|
||||
web.ignoring().antMatchers(HttpMethod.OPTIONS);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package net.maku.framework.security.exception;
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
|
||||
/**
|
||||
* 认证异常类
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class FastAuthenticationException extends AuthenticationException {
|
||||
public FastAuthenticationException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
|
||||
public FastAuthenticationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package net.maku.framework.security.exception;
|
||||
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
|
||||
/**
|
||||
* 自定义异常
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class FastOAuth2Exception extends OAuth2Exception {
|
||||
private String msg;
|
||||
|
||||
public FastOAuth2Exception(String msg) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public FastOAuth2Exception(String msg, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package net.maku.framework.security.exception;
|
||||
|
||||
import net.maku.framework.common.exception.ErrorCode;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.oauth2.common.DefaultThrowableAnalyzer;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.exceptions.ClientAuthenticationException;
|
||||
import org.springframework.security.oauth2.common.exceptions.InsufficientScopeException;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.security.web.util.ThrowableAnalyzer;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
|
||||
/**
|
||||
* 登录或者鉴权失败时的返回信息
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Component
|
||||
public class FastWebResponseExceptionTranslator implements WebResponseExceptionTranslator<OAuth2Exception> {
|
||||
private final ThrowableAnalyzer throwableAnalyzer = new DefaultThrowableAnalyzer();
|
||||
|
||||
@Override
|
||||
public ResponseEntity<OAuth2Exception> translate(Exception e) {
|
||||
Throwable[] causeChain = throwableAnalyzer.determineCauseChain(e);
|
||||
|
||||
Exception exception = (AuthenticationException) throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class, causeChain);
|
||||
if (exception != null) {
|
||||
return handleOAuth2Exception(new FastOAuth2Exception(e.getMessage(), e));
|
||||
}
|
||||
|
||||
exception = (AccessDeniedException) throwableAnalyzer.getFirstThrowableOfType(AccessDeniedException.class, causeChain);
|
||||
if (exception != null) {
|
||||
return handleOAuth2Exception(new FastOAuth2Exception(exception.getMessage(), exception));
|
||||
}
|
||||
|
||||
exception = (InvalidGrantException) throwableAnalyzer.getFirstThrowableOfType(InvalidGrantException.class, causeChain);
|
||||
if (exception != null) {
|
||||
return handleOAuth2Exception(new FastOAuth2Exception(exception.getMessage(), exception));
|
||||
}
|
||||
|
||||
exception = (HttpRequestMethodNotSupportedException) throwableAnalyzer.getFirstThrowableOfType(HttpRequestMethodNotSupportedException.class, causeChain);
|
||||
if (exception != null) {
|
||||
return handleOAuth2Exception(new FastOAuth2Exception(exception.getMessage(), exception));
|
||||
}
|
||||
|
||||
exception = (OAuth2Exception) throwableAnalyzer.getFirstThrowableOfType(OAuth2Exception.class, causeChain);
|
||||
if (exception != null) {
|
||||
return handleOAuth2Exception((OAuth2Exception) exception);
|
||||
}
|
||||
|
||||
return handleOAuth2Exception(new FastOAuth2Exception(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), e));
|
||||
}
|
||||
|
||||
private ResponseEntity<OAuth2Exception> handleOAuth2Exception(OAuth2Exception e) {
|
||||
int status = e.getHttpErrorCode();
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set(HttpHeaders.CACHE_CONTROL, "no-store");
|
||||
headers.set(HttpHeaders.PRAGMA, "no-cache");
|
||||
if (status == HttpStatus.UNAUTHORIZED.value() || (e instanceof InsufficientScopeException)) {
|
||||
headers.set(HttpHeaders.WWW_AUTHENTICATE, String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, e.getSummary()));
|
||||
}
|
||||
|
||||
if (e instanceof ClientAuthenticationException) {
|
||||
return new ResponseEntity<>(e, headers, HttpStatus.valueOf(status));
|
||||
}
|
||||
Result<String> result = Result.error(ErrorCode.ACCOUNT_PASSWORD_ERROR);
|
||||
|
||||
return new ResponseEntity(result, headers, HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package net.maku.framework.security.exception;
|
||||
|
||||
import net.maku.framework.common.exception.ErrorCode;
|
||||
import net.maku.framework.common.utils.HttpContextUtils;
|
||||
import net.maku.framework.common.utils.JsonUtils;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 匿名用户(token不存在、错误),异常处理器
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class SecurityAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
|
||||
response.setContentType("application/json; charset=utf-8");
|
||||
response.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
response.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
|
||||
|
||||
response.getWriter().print(JsonUtils.toJsonString(Result.error(ErrorCode.UNAUTHORIZED)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package net.maku.framework.security.handler;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import net.maku.framework.common.utils.HttpContextUtils;
|
||||
import net.maku.framework.common.utils.JsonUtils;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 认证失败处理器
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Component
|
||||
public class UserAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) {
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
response.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
|
||||
|
||||
response.getWriter().write(JsonUtils.toJsonString(Result.error(e.getMessage())));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package net.maku.framework.security.token;
|
||||
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 令牌
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class FastTokenEnhancer implements TokenEnhancer {
|
||||
|
||||
@Override
|
||||
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
|
||||
if(accessToken instanceof DefaultOAuth2AccessToken){
|
||||
DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) accessToken;
|
||||
|
||||
// 增加额外信息
|
||||
Map<String, Object> info = new HashMap<>();
|
||||
info.put("code", new Result<>().getCode());
|
||||
token.setAdditionalInformation(info);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
return accessToken;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package net.maku.framework.security.user;
|
||||
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class SecurityUser {
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*/
|
||||
public static UserDetail getUser() {
|
||||
UserDetail user;
|
||||
try {
|
||||
user = (UserDetail)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
}catch (Exception e){
|
||||
return new UserDetail();
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户ID
|
||||
*/
|
||||
public static Long getUserId() {
|
||||
return getUser().getId();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package net.maku.framework.security.user;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 登录用户信息
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
public class UserDetail implements UserDetails {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
private String username;
|
||||
private String password;
|
||||
private String realName;
|
||||
private String avatar;
|
||||
private Integer gender;
|
||||
private String email;
|
||||
private String mobile;
|
||||
private Long orgId;
|
||||
private Integer status;
|
||||
private Integer superAdmin;
|
||||
private Date createTime;
|
||||
/**
|
||||
* 数据权限范围
|
||||
*
|
||||
* null:表示全部数据权限
|
||||
*/
|
||||
private List<Long> dataScopeList;
|
||||
/**
|
||||
* 帐户是否过期
|
||||
*/
|
||||
private boolean isAccountNonExpired = true;
|
||||
/**
|
||||
* 帐户是否被锁定
|
||||
*/
|
||||
private boolean isAccountNonLocked = true;
|
||||
/**
|
||||
* 密码是否过期
|
||||
*/
|
||||
private boolean isCredentialsNonExpired = true;
|
||||
/**
|
||||
* 帐户是否可用
|
||||
*/
|
||||
private boolean isEnabled = true;
|
||||
/**
|
||||
* 拥有权限集合
|
||||
*/
|
||||
private Set<GrantedAuthority> authorities;
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return this.authorities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return this.isAccountNonExpired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return this.isAccountNonLocked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return this.isCredentialsNonExpired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return this.isEnabled;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>net.maku</groupId>
|
||||
<artifactId>fast-boot</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>fast-boot-system</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.maku</groupId>
|
||||
<artifactId>fast-boot-framework</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package net.maku.security.filter;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.security.handler.UserAuthenticationFailureHandler;
|
||||
import net.maku.security.service.CaptchaService;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 验证码过滤器
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class ValidateCodeFilter extends OncePerRequestFilter {
|
||||
private final static String OAUTH_TOKEN_URL = "/oauth/token";
|
||||
private final CaptchaService captchaService;
|
||||
private final UserAuthenticationFailureHandler authenticationFailureHandler;
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
if(request.getServletPath().equals(OAUTH_TOKEN_URL)
|
||||
&& request.getMethod().equalsIgnoreCase("POST")
|
||||
&& "password".equalsIgnoreCase(request.getParameter("grant_type"))) {
|
||||
try {
|
||||
// 校验验证码
|
||||
validate(request);
|
||||
}catch (AuthenticationException e) {
|
||||
// 失败处理器
|
||||
authenticationFailureHandler.onAuthenticationFailure(request, response, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private void validate(HttpServletRequest request) {
|
||||
String key = request.getParameter("key");
|
||||
String captcha = request.getParameter("captcha");
|
||||
|
||||
boolean flag = captchaService.validate(key, captcha);
|
||||
|
||||
// if(!flag) {
|
||||
// throw new FastAuthenticationException("验证码错误");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package net.maku.security.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.wf.captcha.SpecCaptcha;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.utils.RedisKeys;
|
||||
import net.maku.framework.common.utils.RedisUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class CaptchaService {
|
||||
private final RedisUtils redisUtils;
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
* @param key key
|
||||
* @return 返回base64图片验证码
|
||||
*/
|
||||
public String generate(String key) {
|
||||
// 生成验证码
|
||||
SpecCaptcha captcha = new SpecCaptcha(150, 40);
|
||||
captcha.setLen(5);
|
||||
captcha.setCharType(Captcha.TYPE_DEFAULT);
|
||||
|
||||
// 保存到缓存
|
||||
key = RedisKeys.getCaptchaKey(key);
|
||||
redisUtils.set(key, captcha.text(), 300);
|
||||
|
||||
return captcha.toBase64();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证码效验
|
||||
* @param key key
|
||||
* @param code 验证码
|
||||
* @return true:成功 false:失败
|
||||
*/
|
||||
public boolean validate(String key, String code) {
|
||||
if(StrUtil.isBlank(key) || StrUtil.isBlank(code)){
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取验证码
|
||||
String captcha = getCache(key);
|
||||
|
||||
// 效验成功
|
||||
if(code.equalsIgnoreCase(captcha)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private String getCache(String key){
|
||||
key = RedisKeys.getCaptchaKey(key);
|
||||
String captcha = (String)redisUtils.get(key);
|
||||
// 删除验证码
|
||||
if(captcha != null){
|
||||
redisUtils.delete(key);
|
||||
}
|
||||
|
||||
return captcha;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package net.maku.security.service;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.utils.JsonUtils;
|
||||
import net.maku.system.dao.SysOauthClientDao;
|
||||
import net.maku.system.entity.SysOauthClientEntity;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.security.oauth2.provider.ClientDetailsService;
|
||||
import org.springframework.security.oauth2.provider.ClientRegistrationException;
|
||||
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* ClientDetailsService
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class FastClientDetailsService implements ClientDetailsService {
|
||||
private final SysOauthClientDao sysOauthClientDao;
|
||||
|
||||
@Override
|
||||
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
|
||||
SysOauthClientEntity oauthClient = sysOauthClientDao.getByClientId(clientId);
|
||||
|
||||
return clientDetailsMapper(oauthClient);
|
||||
}
|
||||
|
||||
private ClientDetails clientDetailsMapper(SysOauthClientEntity entity) {
|
||||
BaseClientDetails client = new BaseClientDetails();
|
||||
client.setClientId(entity.getClientId());
|
||||
// 密码前追加 {noop} 前缀,表示密码是明文
|
||||
client.setClientSecret(String.format("{noop}%s", entity.getClientSecret()));
|
||||
|
||||
if (ArrayUtil.isNotEmpty(entity.getAuthorizedGrantTypes())) {
|
||||
client.setAuthorizedGrantTypes(CollUtil.newArrayList(entity.getAuthorizedGrantTypes()));
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(entity.getAuthorities())) {
|
||||
client.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(entity.getAuthorities()));
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(entity.getResourceIds())) {
|
||||
client.setResourceIds(StringUtils.commaDelimitedListToSet(entity.getResourceIds()));
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(entity.getWebServerRedirectUri())) {
|
||||
client.setRegisteredRedirectUri(StringUtils.commaDelimitedListToSet(entity.getWebServerRedirectUri()));
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(entity.getScope())) {
|
||||
client.setScope(StringUtils.commaDelimitedListToSet(entity.getScope()));
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(entity.getAutoapprove())) {
|
||||
client.setAutoApproveScopes(StringUtils.commaDelimitedListToSet(entity.getAutoapprove()));
|
||||
}
|
||||
|
||||
if (entity.getAccessTokenValidity() != null) {
|
||||
client.setAccessTokenValiditySeconds(entity.getAccessTokenValidity());
|
||||
}
|
||||
|
||||
if (entity.getRefreshTokenValidity() != null) {
|
||||
client.setRefreshTokenValiditySeconds(entity.getRefreshTokenValidity());
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(entity.getAdditionalInformation())) {
|
||||
Map<String, Object> map = JsonUtils.parseObject(entity.getAdditionalInformation(), Map.class);
|
||||
client.setAdditionalInformation(map);
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
package net.maku.security.service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.exception.ErrorCode;
|
||||
import net.maku.framework.common.exception.FastException;
|
||||
import net.maku.framework.security.user.UserDetail;
|
||||
import net.maku.system.convert.SysUserConvert;
|
||||
import net.maku.system.dao.SysRoleDao;
|
||||
import net.maku.system.dao.SysRoleDataScopeDao;
|
||||
import net.maku.system.dao.SysUserDao;
|
||||
import net.maku.system.entity.SysUserEntity;
|
||||
import net.maku.system.enums.DataScopeEnum;
|
||||
import net.maku.system.enums.UserStatusEnum;
|
||||
import net.maku.system.service.SysMenuService;
|
||||
import net.maku.system.service.SysOrgService;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* UserDetailsService
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class FastUserDetailsService implements UserDetailsService {
|
||||
private final SysMenuService sysMenuService;
|
||||
private final SysOrgService sysOrgService;
|
||||
private final SysUserDao sysUserDao;
|
||||
private final SysRoleDao sysRoleDao;
|
||||
private final SysRoleDataScopeDao sysRoleDataScopeDao;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
SysUserEntity userEntity = sysUserDao.getByUsername(username);
|
||||
if(userEntity == null) {
|
||||
throw new FastException(ErrorCode.ACCOUNT_PASSWORD_ERROR);
|
||||
}
|
||||
|
||||
// 转换成UserDetail对象
|
||||
UserDetail userDetail = SysUserConvert.INSTANCE.convertDetail(userEntity);
|
||||
|
||||
// 告诉spring-security,密码使用的bcrypt加密
|
||||
userDetail.setPassword(String.format("{bcrypt}%s", userDetail.getPassword()));
|
||||
|
||||
// 账号不可用
|
||||
if(userEntity.getStatus() == UserStatusEnum.DISABLE.getValue()){
|
||||
userDetail.setEnabled(false);
|
||||
}
|
||||
|
||||
// 数据权限范围
|
||||
List<Long> dataScopeList = getDataScope(userDetail);
|
||||
userDetail.setDataScopeList(dataScopeList);
|
||||
|
||||
// 用户权限列表
|
||||
Set<GrantedAuthority> authorities = getUserAuthority(userDetail);
|
||||
userDetail.setAuthorities(authorities);
|
||||
|
||||
return userDetail;
|
||||
}
|
||||
|
||||
private List<Long> getDataScope(UserDetail userDetail){
|
||||
Integer dataScope = sysRoleDao.getDataScopeByUserId(userDetail.getId());
|
||||
if (dataScope == null){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
if (dataScope.equals(DataScopeEnum.ALL.getValue())) {
|
||||
// 全部数据权限,则返回null
|
||||
return null;
|
||||
} else if (dataScope.equals(DataScopeEnum.DEPT_AND_CHILD.getValue())) {
|
||||
// 本部门及子部门数据
|
||||
List<Long> dataScopeList = sysOrgService.getSubOrgIdList(userDetail.getOrgId());
|
||||
// 自定义数据权限范围
|
||||
dataScopeList.addAll(sysRoleDataScopeDao.getDataScopeList(userDetail.getId()));
|
||||
|
||||
return dataScopeList;
|
||||
} else if (dataScope.equals(DataScopeEnum.DEPT_ONLY.getValue())) {
|
||||
// 本部门数据
|
||||
List<Long> dataScopeList = new ArrayList<>();
|
||||
dataScopeList.add(userDetail.getOrgId());
|
||||
// 自定义数据权限范围
|
||||
dataScopeList.addAll(sysRoleDataScopeDao.getDataScopeList(userDetail.getId()));
|
||||
|
||||
return dataScopeList;
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private Set<GrantedAuthority> getUserAuthority(UserDetail user) {
|
||||
// 获取用户权限标识
|
||||
Set<String> permsSet = sysMenuService.getUserAuthority(user);
|
||||
|
||||
// 封装权限标识
|
||||
Set<GrantedAuthority> authorities = new HashSet<>();
|
||||
authorities.addAll(permsSet.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet()));
|
||||
|
||||
return authorities;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package net.maku.security.service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.utils.RedisKeys;
|
||||
import net.maku.framework.common.utils.RedisUtils;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.code.RandomValueAuthorizationCodeServices;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 基于Redis的授权码模式
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class RedisAuthorizationCodeServices extends RandomValueAuthorizationCodeServices {
|
||||
private final RedisUtils redisUtils;
|
||||
|
||||
@Override
|
||||
protected void store(String code, OAuth2Authentication authentication) {
|
||||
String key = RedisKeys.getOauthCode(code);
|
||||
redisUtils.set(key, authentication);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2Authentication remove(String code) {
|
||||
String key = RedisKeys.getOauthCode(code);
|
||||
return (OAuth2Authentication)redisUtils.get(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package net.maku.system.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.system.convert.SysDictDataConvert;
|
||||
import net.maku.system.entity.SysDictDataEntity;
|
||||
import net.maku.system.service.SysDictDataService;
|
||||
import net.maku.system.vo.dict.data.SysDictDataPostVO;
|
||||
import net.maku.system.vo.dict.data.SysDictDataPutVO;
|
||||
import net.maku.system.vo.dict.data.SysDictDataQuery;
|
||||
import net.maku.system.vo.dict.data.SysDictDataVO;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典数据
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/dict/data")
|
||||
@Tag(name="字典数据")
|
||||
@AllArgsConstructor
|
||||
public class SysDictDataController {
|
||||
private final SysDictDataService sysDictDataService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
//@PreAuthorize("hasAuthority('sys:dict:page')")
|
||||
public Result<PageResult<SysDictDataVO>> page(@Valid SysDictDataQuery query){
|
||||
PageResult<SysDictDataVO> page = sysDictDataService.page(query);
|
||||
|
||||
return Result.ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
//@PreAuthorize("hasAuthority('sys:dict:info')")
|
||||
public Result<SysDictDataVO> get(@PathVariable("id") Long id){
|
||||
SysDictDataEntity entity = sysDictDataService.getById(id);
|
||||
|
||||
return Result.ok(SysDictDataConvert.INSTANCE.convert(entity));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
//@PreAuthorize("hasAuthority('sys:dict:save')")
|
||||
public Result<String> save(@RequestBody @Valid SysDictDataPostVO vo){
|
||||
sysDictDataService.save(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
//@PreAuthorize("hasAuthority('sys:dict:update')")
|
||||
public Result<String> update(@RequestBody @Valid SysDictDataPutVO vo){
|
||||
sysDictDataService.update(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
//@PreAuthorize("hasAuthority('sys:dict:delete')")
|
||||
public Result<String> delete(@RequestBody List<Long> idList){
|
||||
sysDictDataService.delete(idList);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package net.maku.system.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.system.convert.SysDictTypeConvert;
|
||||
import net.maku.system.entity.SysDictTypeEntity;
|
||||
import net.maku.system.service.SysDictTypeService;
|
||||
import net.maku.system.vo.dict.SysDictVO;
|
||||
import net.maku.system.vo.dict.type.SysDictTypePostVO;
|
||||
import net.maku.system.vo.dict.type.SysDictTypePutVO;
|
||||
import net.maku.system.vo.dict.type.SysDictTypeQuery;
|
||||
import net.maku.system.vo.dict.type.SysDictTypeVO;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/dict/type")
|
||||
@Tag(name="字典类型")
|
||||
@AllArgsConstructor
|
||||
public class SysDictTypeController {
|
||||
private final SysDictTypeService sysDictTypeService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
//@PreAuthorize("hasAuthority('sys:dict:page')")
|
||||
public Result<PageResult<SysDictTypeVO>> page(@Valid SysDictTypeQuery query){
|
||||
PageResult<SysDictTypeVO> page = sysDictTypeService.page(query);
|
||||
|
||||
return Result.ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
//@PreAuthorize("hasAuthority('sys:dict:info')")
|
||||
public Result<SysDictTypeVO> get(@PathVariable("id") Long id){
|
||||
SysDictTypeEntity entity = sysDictTypeService.getById(id);
|
||||
|
||||
return Result.ok(SysDictTypeConvert.INSTANCE.convert(entity));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
//@PreAuthorize("hasAuthority('sys:dict:save')")
|
||||
public Result<String> save(@RequestBody @Valid SysDictTypePostVO vo){
|
||||
sysDictTypeService.save(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
//@PreAuthorize("hasAuthority('sys:dict:update')")
|
||||
public Result<String> update(@RequestBody @Valid SysDictTypePutVO vo){
|
||||
sysDictTypeService.update(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
//@PreAuthorize("hasAuthority('sys:dict:delete')")
|
||||
public Result<String> delete(@RequestBody List<Long> idList){
|
||||
sysDictTypeService.delete(idList);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@GetMapping("all")
|
||||
@Operation(summary = "全部字典数据")
|
||||
public Result<List<SysDictVO>> all(){
|
||||
List<SysDictVO> dictList = sysDictTypeService.getDictList();
|
||||
|
||||
return Result.ok(dictList);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package net.maku.system.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.framework.security.user.SecurityUser;
|
||||
import net.maku.framework.security.user.UserDetail;
|
||||
import net.maku.system.convert.SysMenuConvert;
|
||||
import net.maku.system.entity.SysMenuEntity;
|
||||
import net.maku.system.enums.MenuTypeEnum;
|
||||
import net.maku.system.service.SysMenuService;
|
||||
import net.maku.system.vo.menu.SysMenuPostVO;
|
||||
import net.maku.system.vo.menu.SysMenuPutVO;
|
||||
import net.maku.system.vo.menu.SysMenuVO;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 菜单管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/menu")
|
||||
@Tag(name="菜单管理")
|
||||
@AllArgsConstructor
|
||||
public class SysMenuController {
|
||||
private final SysMenuService sysMenuService;
|
||||
|
||||
@GetMapping("nav")
|
||||
@Operation(summary = "导航列表")
|
||||
public Result<List<SysMenuVO>> nav(){
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
List<SysMenuVO> list = sysMenuService.getUserMenuList(user, MenuTypeEnum.MENU.getValue());
|
||||
|
||||
return Result.ok(list);
|
||||
}
|
||||
|
||||
@GetMapping("authority")
|
||||
@Operation(summary = "用户权限标识")
|
||||
public Result<Set<String>> authority(){
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
Set<String> set = sysMenuService.getUserAuthority(user);
|
||||
|
||||
return Result.ok(set);
|
||||
}
|
||||
|
||||
@GetMapping("list")
|
||||
@Operation(summary = "菜单列表")
|
||||
@Parameter(name = "type", description = "菜单类型 0:菜单 1:按钮 2:接口 null:全部")
|
||||
public Result<List<SysMenuVO>> list(Integer type){
|
||||
List<SysMenuVO> list = sysMenuService.getMenuList(type);
|
||||
|
||||
return Result.ok(list);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
//@PreAuthorize("hasAuthority('sys:menu:info')")
|
||||
public Result<SysMenuVO> get(@PathVariable("id") Long id){
|
||||
SysMenuEntity entity = sysMenuService.getById(id);
|
||||
|
||||
return Result.ok(SysMenuConvert.INSTANCE.convert(entity));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
//@PreAuthorize("hasAuthority('sys:menu:save')")
|
||||
public Result<String> save(@RequestBody @Valid SysMenuPostVO vo){
|
||||
sysMenuService.save(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
//@PreAuthorize("hasAuthority('sys:menu:update')")
|
||||
public Result<String> update(@RequestBody @Valid SysMenuPutVO vo){
|
||||
sysMenuService.update(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@Operation(summary = "删除")
|
||||
//@PreAuthorize("hasAuthority('sys:menu:delete')")
|
||||
public Result<String> delete(@PathVariable("id") Long id){
|
||||
// 判断是否有子菜单或按钮
|
||||
Long count = sysMenuService.getSubMenuCount(id);
|
||||
if(count > 0){
|
||||
return Result.error("存在子菜单");
|
||||
}
|
||||
|
||||
sysMenuService.delete(id);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package net.maku.system.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.query.Query;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.system.convert.SysOauthClientConvert;
|
||||
import net.maku.system.entity.SysOauthClientEntity;
|
||||
import net.maku.system.service.SysOauthClientService;
|
||||
import net.maku.system.vo.oauth.SysOauthClientPostVO;
|
||||
import net.maku.system.vo.oauth.SysOauthClientPutVO;
|
||||
import net.maku.system.vo.oauth.SysOauthClientVO;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 客户端管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/client")
|
||||
@Tag(name="客户端管理")
|
||||
@AllArgsConstructor
|
||||
public class SysOauthClientController {
|
||||
private final SysOauthClientService sysOauthClientService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
//@PreAuthorize("hasAuthority('sys:client:page')")
|
||||
public Result<PageResult<SysOauthClientVO>> page(@Valid Query query){
|
||||
PageResult<SysOauthClientVO> page = sysOauthClientService.page(query);
|
||||
|
||||
return Result.ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
//@PreAuthorize("hasAuthority('sys:client:info')")
|
||||
public Result<SysOauthClientVO> get(@PathVariable("id") Long id){
|
||||
SysOauthClientEntity entity = sysOauthClientService.getById(id);
|
||||
|
||||
return Result.ok(SysOauthClientConvert.INSTANCE.convert(entity));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
//@PreAuthorize("hasAuthority('sys:client:save')")
|
||||
public Result<String> save(@RequestBody SysOauthClientPostVO vo){
|
||||
sysOauthClientService.save(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
//@PreAuthorize("hasAuthority('sys:client:update')")
|
||||
public Result<String> update(@RequestBody @Valid SysOauthClientPutVO vo){
|
||||
sysOauthClientService.update(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
//@PreAuthorize("hasAuthority('sys:client:delete')")
|
||||
public Result<String> delete(@RequestBody List<Long> idList){
|
||||
sysOauthClientService.delete(idList);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package net.maku.system.controller;
|
||||
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.security.service.CaptchaService;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 认证管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("oauth")
|
||||
@Tag(name="认证管理")
|
||||
@AllArgsConstructor
|
||||
public class SysOauthController {
|
||||
private final CaptchaService captchaService;
|
||||
private final TokenStore tokenStore;
|
||||
|
||||
@GetMapping("captcha")
|
||||
@Operation(summary = "验证码")
|
||||
public Result<Map<String, Object>> captcha() {
|
||||
// 生成key
|
||||
String key = UUID.randomUUID().toString();
|
||||
// 生成base64验证码
|
||||
String image = captchaService.generate(key);
|
||||
|
||||
// 封装返回数据
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("key", key);
|
||||
data.put("image", image);
|
||||
|
||||
return Result.ok(data);
|
||||
}
|
||||
|
||||
@PostMapping("logout")
|
||||
@Operation(summary = "退出")
|
||||
public Result<String> logout(HttpServletRequest request) {
|
||||
String access_token = request.getHeader(HttpHeaders.AUTHORIZATION).replace("Bearer ", "");
|
||||
OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(access_token);
|
||||
if (oAuth2AccessToken != null) {
|
||||
tokenStore.removeAccessToken(oAuth2AccessToken);
|
||||
OAuth2RefreshToken oAuth2RefreshToken = oAuth2AccessToken.getRefreshToken();
|
||||
tokenStore.removeRefreshToken(oAuth2RefreshToken);
|
||||
tokenStore.removeAccessTokenUsingRefreshToken(oAuth2RefreshToken);
|
||||
}
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package net.maku.system.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.system.convert.SysOrgConvert;
|
||||
import net.maku.system.entity.SysOrgEntity;
|
||||
import net.maku.system.service.SysOrgService;
|
||||
import net.maku.system.vo.org.SysOrgPostVO;
|
||||
import net.maku.system.vo.org.SysOrgPutVO;
|
||||
import net.maku.system.vo.org.SysOrgVO;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 机构管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/org")
|
||||
@Tag(name="机构管理")
|
||||
@AllArgsConstructor
|
||||
public class SysOrgController {
|
||||
private final SysOrgService sysOrgService;
|
||||
|
||||
@GetMapping("list")
|
||||
@Operation(summary = "列表")
|
||||
//@PreAuthorize("hasAuthority('sys:org:list')")
|
||||
public Result<List<SysOrgVO>> list(){
|
||||
List<SysOrgVO> list = sysOrgService.getList();
|
||||
|
||||
return Result.ok(list);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
//@PreAuthorize("hasAuthority('sys:org:info')")
|
||||
public Result<SysOrgVO> get(@PathVariable("id") Long id){
|
||||
SysOrgEntity entity = sysOrgService.getById(id);
|
||||
|
||||
return Result.ok(SysOrgConvert.INSTANCE.convert(entity));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
//@PreAuthorize("hasAuthority('sys:org:save')")
|
||||
public Result<String> save(@RequestBody @Valid SysOrgPostVO vo){
|
||||
sysOrgService.save(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
//@PreAuthorize("hasAuthority('sys:org:update')")
|
||||
public Result<String> update(@RequestBody @Valid SysOrgPutVO vo){
|
||||
sysOrgService.update(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@Operation(summary = "删除")
|
||||
//@PreAuthorize("hasAuthority('sys:org:delete')")
|
||||
public Result<String> delete(@PathVariable("id") Long id){
|
||||
sysOrgService.delete(id);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package net.maku.system.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.system.convert.SysPostConvert;
|
||||
import net.maku.system.entity.SysPostEntity;
|
||||
import net.maku.system.service.SysPostService;
|
||||
import net.maku.system.vo.post.SysPostPostVO;
|
||||
import net.maku.system.vo.post.SysPostPutVO;
|
||||
import net.maku.system.vo.post.SysPostQuery;
|
||||
import net.maku.system.vo.post.SysPostVO;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 岗位管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/post")
|
||||
@Tag(name="岗位管理")
|
||||
@AllArgsConstructor
|
||||
public class SysPostController {
|
||||
private final SysPostService sysPostService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
//@PreAuthorize("hasAuthority('sys:post:page')")
|
||||
public Result<PageResult<SysPostVO>> page(@Valid SysPostQuery query){
|
||||
PageResult<SysPostVO> page = sysPostService.page(query);
|
||||
|
||||
return Result.ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("list")
|
||||
@Operation(summary = "列表")
|
||||
public Result<List<SysPostVO>> list(){
|
||||
List<SysPostVO> list = sysPostService.getList();
|
||||
|
||||
return Result.ok(list);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
//@PreAuthorize("hasAuthority('sys:post:info')")
|
||||
public Result<SysPostVO> get(@PathVariable("id") Long id){
|
||||
SysPostEntity entity = sysPostService.getById(id);
|
||||
|
||||
return Result.ok(SysPostConvert.INSTANCE.convert(entity));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
//@PreAuthorize("hasAuthority('sys:post:save')")
|
||||
public Result<String> save(@RequestBody SysPostPostVO vo){
|
||||
sysPostService.save(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
//@PreAuthorize("hasAuthority('sys:post:update')")
|
||||
public Result<String> update(@RequestBody @Valid SysPostPutVO vo){
|
||||
sysPostService.update(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
//@PreAuthorize("hasAuthority('sys:post:delete')")
|
||||
public Result<String> delete(@RequestBody List<Long> idList){
|
||||
sysPostService.delete(idList);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
package net.maku.system.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.framework.security.user.SecurityUser;
|
||||
import net.maku.framework.security.user.UserDetail;
|
||||
import net.maku.system.convert.SysRoleConvert;
|
||||
import net.maku.system.entity.SysRoleEntity;
|
||||
import net.maku.system.service.SysMenuService;
|
||||
import net.maku.system.service.SysRoleDataScopeService;
|
||||
import net.maku.system.service.SysRoleMenuService;
|
||||
import net.maku.system.service.SysRoleService;
|
||||
import net.maku.system.vo.menu.SysMenuVO;
|
||||
import net.maku.system.vo.role.SysRolePostVO;
|
||||
import net.maku.system.vo.role.SysRolePutVO;
|
||||
import net.maku.system.vo.role.SysRoleQuery;
|
||||
import net.maku.system.vo.role.SysRoleVO;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/role")
|
||||
@Tag(name="角色管理")
|
||||
@AllArgsConstructor
|
||||
public class SysRoleController {
|
||||
private final SysRoleService sysRoleService;
|
||||
private final SysRoleMenuService sysRoleMenuService;
|
||||
private final SysRoleDataScopeService sysRoleDataScopeService;
|
||||
private final SysMenuService sysMenuService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
//@PreAuthorize("hasAuthority('sys:role:page')")
|
||||
public Result<PageResult<SysRoleVO>> page(@Valid SysRoleQuery query){
|
||||
PageResult<SysRoleVO> page = sysRoleService.page(query);
|
||||
|
||||
return Result.ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("list")
|
||||
@Operation(summary = "列表")
|
||||
//@PreAuthorize("hasAuthority('sys:role:list')")
|
||||
public Result<List<SysRoleVO>> list(){
|
||||
List<SysRoleVO> list = sysRoleService.getList(new SysRoleQuery());
|
||||
|
||||
return Result.ok(list);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
//@PreAuthorize("hasAuthority('sys:role:info')")
|
||||
public Result<SysRolePostVO> get(@PathVariable("id") Long id){
|
||||
SysRoleEntity entity = sysRoleService.getById(id);
|
||||
|
||||
// 转换对象
|
||||
SysRolePostVO role = SysRoleConvert.INSTANCE.convert(entity);
|
||||
|
||||
// 查询角色对应的菜单
|
||||
List<Long> menuIdList = sysRoleMenuService.getMenuIdList(id);
|
||||
role.setMenuIdList(menuIdList);
|
||||
|
||||
// 查询角色对应的数据权限
|
||||
List<Long> orgIdList = sysRoleDataScopeService.getOrgIdList(id);
|
||||
role.setOrgIdList(orgIdList);
|
||||
|
||||
return Result.ok(role);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
//@PreAuthorize("hasAuthority('sys:role:save')")
|
||||
public Result<String> save(@RequestBody @Valid SysRolePostVO vo){
|
||||
|
||||
sysRoleService.save(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
//@PreAuthorize("hasAuthority('sys:role:update')")
|
||||
public Result<String> update(@RequestBody @Valid SysRolePutVO vo){
|
||||
sysRoleService.update(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
//@PreAuthorize("hasAuthority('sys:role:delete')")
|
||||
public Result<String> delete(@RequestBody List<Long> idList){
|
||||
sysRoleService.delete(idList);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@GetMapping("menu")
|
||||
@Operation(summary = "角色菜单")
|
||||
//@PreAuthorize("hasAuthority('sys:role:menu')")
|
||||
public Result<List<SysMenuVO>> menu(){
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
List<SysMenuVO> list = sysMenuService.getUserMenuList(user, null);
|
||||
|
||||
return Result.ok(list);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
package net.maku.system.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.framework.security.user.SecurityUser;
|
||||
import net.maku.framework.security.user.UserDetail;
|
||||
import net.maku.system.convert.SysUserConvert;
|
||||
import net.maku.system.entity.SysUserEntity;
|
||||
import net.maku.system.service.SysUserPostService;
|
||||
import net.maku.system.service.SysUserRoleService;
|
||||
import net.maku.system.service.SysUserService;
|
||||
import net.maku.system.vo.user.*;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 用户管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/user")
|
||||
@AllArgsConstructor
|
||||
@Tag(name="用户管理")
|
||||
public class SysUserController {
|
||||
private final SysUserService sysUserService;
|
||||
private final SysUserRoleService sysUserRoleService;
|
||||
private final SysUserPostService sysUserPostService;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
public Result<PageResult<SysUserVO>> page(@Valid SysUserQuery query){
|
||||
PageResult<SysUserVO> page = sysUserService.page(query);
|
||||
|
||||
return Result.ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
//@PreAuthorize("hasAuthority('sys:user:info')")
|
||||
public Result<SysUserVO> get(@PathVariable("id") Long id){
|
||||
SysUserEntity entity = sysUserService.getById(id);
|
||||
|
||||
SysUserVO vo = SysUserConvert.INSTANCE.convert(entity);
|
||||
|
||||
// 用户角色列表
|
||||
List<Long> roleIdList = sysUserRoleService.getRoleIdList(id);
|
||||
vo.setRoleIdList(roleIdList);
|
||||
|
||||
// 用户岗位列表
|
||||
List<Long> postIdList = sysUserPostService.getPostIdList(id);
|
||||
vo.setPostIdList(postIdList);
|
||||
|
||||
return Result.ok(vo);
|
||||
}
|
||||
|
||||
@GetMapping("info")
|
||||
@Operation(summary = "登录用户")
|
||||
public Result<SysUserVO> info(){
|
||||
SysUserVO user = SysUserConvert.INSTANCE.convert(SecurityUser.getUser());
|
||||
|
||||
return Result.ok(user);
|
||||
}
|
||||
|
||||
@PutMapping("password")
|
||||
@Operation(summary = "修改密码")
|
||||
public Result<String> password(@RequestBody @Valid SysUserPasswordVO vo){
|
||||
// 原密码不正确
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
if(!passwordEncoder.matches(vo.getPassword(), user.getPassword())){
|
||||
return Result.error("原密码不正确");
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
sysUserService.updatePassword(user.getId(), passwordEncoder.encode(vo.getNewPassword()));
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
//@PreAuthorize("hasAuthority('sys:user:save')")
|
||||
public Result<String> save(@RequestBody @Valid SysUserPostVO vo){
|
||||
// 新增密码不能为空
|
||||
if (StrUtil.isBlank(vo.getPassword())){
|
||||
Result.error("密码不能为空");
|
||||
}
|
||||
|
||||
// 密码加密
|
||||
vo.setPassword(passwordEncoder.encode(vo.getPassword()));
|
||||
|
||||
// 保存
|
||||
sysUserService.save(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
//@PreAuthorize("hasAuthority('sys:user:update')")
|
||||
public Result<String> update(@RequestBody @Valid SysUserPutVO vo){
|
||||
// 如果密码不为空,则进行加密处理
|
||||
if(StrUtil.isBlank(vo.getPassword())){
|
||||
vo.setPassword(null);
|
||||
}else{
|
||||
vo.setPassword(passwordEncoder.encode(vo.getPassword()));
|
||||
}
|
||||
|
||||
sysUserService.update(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
//@PreAuthorize("hasAuthority('sys:user:delete')")
|
||||
public Result<String> delete(@RequestBody List<Long> idList){
|
||||
sysUserService.delete(idList);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package net.maku.system.convert;
|
||||
|
||||
import net.maku.system.entity.SysDictDataEntity;
|
||||
import net.maku.system.vo.dict.data.SysDictDataPostVO;
|
||||
import net.maku.system.vo.dict.data.SysDictDataPutVO;
|
||||
import net.maku.system.vo.dict.data.SysDictDataVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface SysDictDataConvert {
|
||||
SysDictDataConvert INSTANCE = Mappers.getMapper(SysDictDataConvert.class);
|
||||
|
||||
SysDictDataEntity convert(SysDictDataPostVO vo);
|
||||
|
||||
SysDictDataEntity convert(SysDictDataPutVO vo);
|
||||
|
||||
SysDictDataVO convert(SysDictDataEntity entity);
|
||||
|
||||
List<SysDictDataVO> convertList(List<SysDictDataEntity> list);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package net.maku.system.convert;
|
||||
|
||||
import net.maku.system.entity.SysDictTypeEntity;
|
||||
import net.maku.system.vo.dict.type.SysDictTypePostVO;
|
||||
import net.maku.system.vo.dict.type.SysDictTypePutVO;
|
||||
import net.maku.system.vo.dict.type.SysDictTypeVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface SysDictTypeConvert {
|
||||
SysDictTypeConvert INSTANCE = Mappers.getMapper(SysDictTypeConvert.class);
|
||||
|
||||
SysDictTypeEntity convert(SysDictTypePostVO vo);
|
||||
|
||||
SysDictTypeEntity convert(SysDictTypePutVO vo);
|
||||
|
||||
SysDictTypeVO convert(SysDictTypeEntity entity);
|
||||
|
||||
List<SysDictTypeVO> convertList(List<SysDictTypeEntity> list);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.maku.system.convert;
|
||||
|
||||
import net.maku.system.entity.SysMenuEntity;
|
||||
import net.maku.system.vo.menu.SysMenuPostVO;
|
||||
import net.maku.system.vo.menu.SysMenuPutVO;
|
||||
import net.maku.system.vo.menu.SysMenuVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface SysMenuConvert {
|
||||
SysMenuConvert INSTANCE = Mappers.getMapper(SysMenuConvert.class);
|
||||
|
||||
SysMenuEntity convert(SysMenuPostVO vo);
|
||||
|
||||
SysMenuEntity convert(SysMenuPutVO vo);
|
||||
|
||||
SysMenuVO convert(SysMenuEntity entity);
|
||||
|
||||
List<SysMenuVO> convertList(List<SysMenuEntity> list);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.maku.system.convert;
|
||||
|
||||
import net.maku.system.entity.SysOauthClientEntity;
|
||||
import net.maku.system.vo.oauth.SysOauthClientPostVO;
|
||||
import net.maku.system.vo.oauth.SysOauthClientPutVO;
|
||||
import net.maku.system.vo.oauth.SysOauthClientVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface SysOauthClientConvert {
|
||||
SysOauthClientConvert INSTANCE = Mappers.getMapper(SysOauthClientConvert.class);
|
||||
|
||||
SysOauthClientEntity convert(SysOauthClientPostVO vo);
|
||||
|
||||
SysOauthClientEntity convert(SysOauthClientPutVO vo);
|
||||
|
||||
SysOauthClientVO convert(SysOauthClientEntity entity);
|
||||
|
||||
List<SysOauthClientVO> convertList(List<SysOauthClientEntity> list);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.maku.system.convert;
|
||||
|
||||
import net.maku.system.entity.SysOrgEntity;
|
||||
import net.maku.system.vo.org.SysOrgPostVO;
|
||||
import net.maku.system.vo.org.SysOrgPutVO;
|
||||
import net.maku.system.vo.org.SysOrgVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface SysOrgConvert {
|
||||
SysOrgConvert INSTANCE = Mappers.getMapper(SysOrgConvert.class);
|
||||
|
||||
SysOrgEntity convert(SysOrgPostVO vo);
|
||||
|
||||
SysOrgEntity convert(SysOrgPutVO vo);
|
||||
|
||||
SysOrgVO convert(SysOrgEntity entity);
|
||||
|
||||
List<SysOrgVO> convertList(List<SysOrgEntity> list);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.maku.system.convert;
|
||||
|
||||
import net.maku.system.entity.SysPostEntity;
|
||||
import net.maku.system.vo.post.SysPostPostVO;
|
||||
import net.maku.system.vo.post.SysPostPutVO;
|
||||
import net.maku.system.vo.post.SysPostVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface SysPostConvert {
|
||||
SysPostConvert INSTANCE = Mappers.getMapper(SysPostConvert.class);
|
||||
|
||||
SysPostEntity convert(SysPostPostVO vo);
|
||||
|
||||
SysPostEntity convert(SysPostPutVO vo);
|
||||
|
||||
SysPostVO convert(SysPostEntity entity);
|
||||
|
||||
List<SysPostVO> convertList(List<SysPostEntity> list);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package net.maku.system.convert;
|
||||
|
||||
import net.maku.system.entity.SysRoleEntity;
|
||||
import net.maku.system.vo.role.SysRolePostVO;
|
||||
import net.maku.system.vo.role.SysRolePutVO;
|
||||
import net.maku.system.vo.role.SysRoleVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface SysRoleConvert {
|
||||
SysRoleConvert INSTANCE = Mappers.getMapper(SysRoleConvert.class);
|
||||
|
||||
SysRoleEntity convert(SysRolePostVO vo);
|
||||
|
||||
SysRoleEntity convert(SysRolePutVO vo);
|
||||
|
||||
SysRoleVO convert(SysRoleEntity entity);
|
||||
|
||||
List<SysRoleVO> convertList(List<SysRoleEntity> list);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package net.maku.system.convert;
|
||||
|
||||
import net.maku.framework.security.user.UserDetail;
|
||||
import net.maku.system.entity.SysUserEntity;
|
||||
import net.maku.system.vo.user.SysUserPostVO;
|
||||
import net.maku.system.vo.user.SysUserPutVO;
|
||||
import net.maku.system.vo.user.SysUserVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface SysUserConvert {
|
||||
SysUserConvert INSTANCE = Mappers.getMapper(SysUserConvert.class);
|
||||
|
||||
SysUserEntity convert(SysUserPostVO vo);
|
||||
|
||||
SysUserEntity convert(SysUserPutVO vo);
|
||||
|
||||
SysUserVO convert(SysUserEntity entity);
|
||||
|
||||
SysUserVO convert(UserDetail userDetail);
|
||||
|
||||
UserDetail convertDetail(SysUserEntity entity);
|
||||
|
||||
List<SysUserVO> convertList(List<SysUserEntity> list);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysDictDataEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 字典数据
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysDictDataDao extends BaseDao<SysDictDataEntity> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysDictTypeEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysDictTypeDao extends BaseDao<SysDictTypeEntity> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysMenuEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysMenuDao extends BaseDao<SysMenuEntity> {
|
||||
|
||||
/**
|
||||
* 查询所有菜单列表
|
||||
*
|
||||
* @param type 菜单类型
|
||||
*/
|
||||
List<SysMenuEntity> getMenuList(@Param("type") Integer type);
|
||||
|
||||
/**
|
||||
* 查询用户菜单列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param type 菜单类型
|
||||
*/
|
||||
List<SysMenuEntity> getUserMenuList(@Param("userId") Long userId, @Param("type") Integer type);
|
||||
|
||||
/**
|
||||
* 查询用户权限列表
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
List<String> getUserAuthorityList(@Param("userId") Long userId);
|
||||
|
||||
/**
|
||||
* 查询所有权限列表
|
||||
*/
|
||||
List<String> getAuthorityList();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysOauthClientEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 客户端管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysOauthClientDao extends BaseDao<SysOauthClientEntity> {
|
||||
|
||||
default SysOauthClientEntity getByClientId(String clientId){
|
||||
return this.selectOne(new QueryWrapper<SysOauthClientEntity>().eq("client_id", clientId));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysOrgEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 机构管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysOrgDao extends BaseDao<SysOrgEntity> {
|
||||
|
||||
List<SysOrgEntity> getList(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 获取所有机构的id、pid列表
|
||||
*/
|
||||
List<SysOrgEntity> getIdAndPidList();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysPostEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 岗位管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysPostDao extends BaseDao<SysPostEntity> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysRoleEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 角色管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysRoleDao extends BaseDao<SysRoleEntity> {
|
||||
|
||||
/**
|
||||
* 根据用户ID,获取用户最大的数据范围
|
||||
*/
|
||||
Integer getDataScopeByUserId(@Param("userId") Long userId);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysRoleDataScopeEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色数据权限
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysRoleDataScopeDao extends BaseDao<SysRoleDataScopeEntity> {
|
||||
|
||||
/**
|
||||
* 根据角色ID,获取机构ID列表
|
||||
*/
|
||||
List<Long> getOrgIdList(@Param("roleId") Long roleId);
|
||||
|
||||
/**
|
||||
* 获取用户的数据权限列表
|
||||
*/
|
||||
List<Long> getDataScopeList(@Param("userId") Long userId);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysRoleMenuEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色与菜单对应关系
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysRoleMenuDao extends BaseDao<SysRoleMenuEntity> {
|
||||
|
||||
/**
|
||||
* 根据角色ID,获取菜单ID列表
|
||||
*/
|
||||
List<Long> getMenuIdList(@Param("roleId") Long roleId);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysUserEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 系统用户
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysUserDao extends BaseDao<SysUserEntity> {
|
||||
|
||||
List<SysUserEntity> getList(Map<String, Object> params);
|
||||
|
||||
SysUserEntity getById(@Param("id") Long id);
|
||||
|
||||
default SysUserEntity getByUsername(String username){
|
||||
return this.selectOne(new QueryWrapper<SysUserEntity>().eq("username", username));
|
||||
}
|
||||
|
||||
default SysUserEntity getByMobile(String mobile){
|
||||
return this.selectOne(new QueryWrapper<SysUserEntity>().eq("mobile", mobile));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysUserPostEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户岗位关系
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysUserPostDao extends BaseDao<SysUserPostEntity> {
|
||||
|
||||
/**
|
||||
* 岗位ID列表
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
List<Long> getPostIdList(@Param("userId") Long userId);
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.maku.system.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.system.entity.SysUserRoleEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户角色关系
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysUserRoleDao extends BaseDao<SysUserRoleEntity> {
|
||||
|
||||
/**
|
||||
* 角色ID列表
|
||||
* @param userId 用户ID
|
||||
*
|
||||
* @return 返回角色ID列表
|
||||
*/
|
||||
List<Long> getRoleIdList(@Param("userId") Long userId);
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 数据字典
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableName("sys_dict_data")
|
||||
public class SysDictDataEntity extends BaseEntity {
|
||||
/**
|
||||
* 字典类型ID
|
||||
*/
|
||||
private Long dictTypeId;
|
||||
/**
|
||||
* 字典标签
|
||||
*/
|
||||
private String dictLabel;
|
||||
/**
|
||||
* 字典值
|
||||
*/
|
||||
private String dictValue;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableName("sys_dict_type")
|
||||
public class SysDictTypeEntity extends BaseEntity {
|
||||
/**
|
||||
* 字典类型
|
||||
*/
|
||||
private String dictType;
|
||||
/**
|
||||
* 字典名称
|
||||
*/
|
||||
private String dictName;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 菜单管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_menu")
|
||||
public class SysMenuEntity extends BaseEntity {
|
||||
/**
|
||||
* 上级ID,一级菜单为0
|
||||
*/
|
||||
private Long pid;
|
||||
/**
|
||||
* 菜单名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 菜单URL
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 授权标识(多个用逗号分隔,如:sys:menu:list,sys:menu:save)
|
||||
*/
|
||||
private String authority;
|
||||
/**
|
||||
* 类型 0:菜单 1:按钮 2:接口
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* 打开方式 0:内部 1:外部
|
||||
*/
|
||||
private Integer openStyle;
|
||||
/**
|
||||
* 菜单图标
|
||||
*/
|
||||
private String icon;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 客户端管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName(value = "sys_oauth_client", autoResultMap = true)
|
||||
public class SysOauthClientEntity extends BaseEntity {
|
||||
/**
|
||||
* 客户端ID
|
||||
*/
|
||||
private String clientId;
|
||||
/**
|
||||
* 客户端密钥
|
||||
*/
|
||||
private String clientSecret;
|
||||
/**
|
||||
* 资源ids
|
||||
*/
|
||||
private String resourceIds;
|
||||
/**
|
||||
* 授权范围
|
||||
*/
|
||||
private String scope;
|
||||
/**
|
||||
* 授权类型
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private String[] authorizedGrantTypes;
|
||||
/**
|
||||
* 回调地址
|
||||
*/
|
||||
private String webServerRedirectUri;
|
||||
/**
|
||||
* 权限标识
|
||||
*/
|
||||
private String authorities;
|
||||
/**
|
||||
* 访问令牌有效期
|
||||
*/
|
||||
private Integer accessTokenValidity;
|
||||
/**
|
||||
* 刷新令牌有效期
|
||||
*/
|
||||
private Integer refreshTokenValidity;
|
||||
/**
|
||||
* 附加信息
|
||||
*/
|
||||
private String additionalInformation;
|
||||
/**
|
||||
* 自动授权
|
||||
*/
|
||||
private String autoapprove;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 机构管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_org")
|
||||
public class SysOrgEntity extends BaseEntity {
|
||||
/**
|
||||
* 上级ID
|
||||
*/
|
||||
private Long pid;
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 上级名称
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String parentName;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 岗位管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_post")
|
||||
public class SysPostEntity extends BaseEntity {
|
||||
/**
|
||||
* 岗位编码
|
||||
*/
|
||||
private String postCode;
|
||||
/**
|
||||
* 岗位名称
|
||||
*/
|
||||
private String postName;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 状态 0:停用 1:正常
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 角色数据权限
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_role_data_scope")
|
||||
public class SysRoleDataScopeEntity extends BaseEntity {
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long roleId;
|
||||
/**
|
||||
* 机构ID
|
||||
*/
|
||||
private Long orgId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
import net.maku.system.enums.DataScopeEnum;
|
||||
|
||||
/**
|
||||
* 角色
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_role")
|
||||
public class SysRoleEntity extends BaseEntity {
|
||||
/**
|
||||
* 角色名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 数据范围 {@link DataScopeEnum}
|
||||
*/
|
||||
private Integer dataScope;
|
||||
/**
|
||||
* 机构ID
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Long orgId;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 角色菜单关系
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_role_menu")
|
||||
public class SysRoleMenuEntity extends BaseEntity {
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long roleId;
|
||||
/**
|
||||
* 菜单ID
|
||||
*/
|
||||
private Long menuId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
import net.maku.system.enums.UserStatusEnum;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableName("sys_user")
|
||||
public class SysUserEntity extends BaseEntity {
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* 姓名
|
||||
*/
|
||||
private String realName;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 性别 0:男 1:女
|
||||
*/
|
||||
private Integer gender;
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 机构ID
|
||||
*/
|
||||
private Long orgId;
|
||||
/**
|
||||
* 超级管理员 0:否 1:是
|
||||
*/
|
||||
private Integer superAdmin;
|
||||
/**
|
||||
* 状态 {@link UserStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 机构名称
|
||||
*/
|
||||
@TableField(exist=false)
|
||||
private String orgName;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 用户岗位关系
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_user_post")
|
||||
public class SysUserPostEntity extends BaseEntity {
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 岗位ID
|
||||
*/
|
||||
private Long postId;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package net.maku.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 用户角色关系
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_user_role")
|
||||
public class SysUserRoleEntity extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long roleId;
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package net.maku.system.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 数据范围枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DataScopeEnum {
|
||||
/**
|
||||
* 全部数据
|
||||
*/
|
||||
ALL(0),
|
||||
/**
|
||||
* 本部门及子部门数据
|
||||
*/
|
||||
DEPT_AND_CHILD(1),
|
||||
/**
|
||||
* 本部门数据
|
||||
*/
|
||||
DEPT_ONLY(2),
|
||||
/**
|
||||
* 本人数据
|
||||
*/
|
||||
SELF(3),
|
||||
/**
|
||||
* 自定义数据
|
||||
*/
|
||||
CUSTOM(4);
|
||||
|
||||
private final Integer value;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package net.maku.system.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 菜单类型枚举
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MenuTypeEnum {
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
MENU(0),
|
||||
/**
|
||||
* 按钮
|
||||
*/
|
||||
BUTTON(1),
|
||||
/**
|
||||
* 接口
|
||||
*/
|
||||
INTERFACE(2);
|
||||
|
||||
private final int value;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package net.maku.system.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 超级管理员枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SuperAdminEnum {
|
||||
YES(1),
|
||||
NO(0);
|
||||
|
||||
private final Integer value;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package net.maku.system.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 用户状态
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum UserStatusEnum {
|
||||
/**
|
||||
* 停用
|
||||
*/
|
||||
DISABLE(0),
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
ENABLED(1);
|
||||
|
||||
private final int value;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package net.maku.system.service;
|
||||
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.service.BaseService;
|
||||
import net.maku.system.entity.SysDictDataEntity;
|
||||
import net.maku.system.vo.dict.data.SysDictDataPostVO;
|
||||
import net.maku.system.vo.dict.data.SysDictDataPutVO;
|
||||
import net.maku.system.vo.dict.data.SysDictDataQuery;
|
||||
import net.maku.system.vo.dict.data.SysDictDataVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据字典
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface SysDictDataService extends BaseService<SysDictDataEntity> {
|
||||
|
||||
PageResult<SysDictDataVO> page(SysDictDataQuery query);
|
||||
|
||||
void save(SysDictDataPostVO vo);
|
||||
|
||||
void update(SysDictDataPutVO vo);
|
||||
|
||||
void delete(List<Long> idList);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package net.maku.system.service;
|
||||
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.service.BaseService;
|
||||
import net.maku.system.entity.SysDictTypeEntity;
|
||||
import net.maku.system.vo.dict.SysDictVO;
|
||||
import net.maku.system.vo.dict.type.SysDictTypePostVO;
|
||||
import net.maku.system.vo.dict.type.SysDictTypePutVO;
|
||||
import net.maku.system.vo.dict.type.SysDictTypeQuery;
|
||||
import net.maku.system.vo.dict.type.SysDictTypeVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据字典
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface SysDictTypeService extends BaseService<SysDictTypeEntity> {
|
||||
|
||||
PageResult<SysDictTypeVO> page(SysDictTypeQuery query);
|
||||
|
||||
void save(SysDictTypePostVO vo);
|
||||
|
||||
void update(SysDictTypePutVO vo);
|
||||
|
||||
void delete(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 获取全部字典列表
|
||||
*/
|
||||
List<SysDictVO> getDictList();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package net.maku.system.service;
|
||||
|
||||
import net.maku.framework.common.service.BaseService;
|
||||
import net.maku.framework.security.user.UserDetail;
|
||||
import net.maku.system.entity.SysMenuEntity;
|
||||
import net.maku.system.vo.menu.SysMenuPostVO;
|
||||
import net.maku.system.vo.menu.SysMenuPutVO;
|
||||
import net.maku.system.vo.menu.SysMenuVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* 菜单管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface SysMenuService extends BaseService<SysMenuEntity> {
|
||||
|
||||
void save(SysMenuPostVO vo);
|
||||
|
||||
void update(SysMenuPutVO vo);
|
||||
|
||||
void delete(Long id);
|
||||
|
||||
/**
|
||||
* 菜单列表
|
||||
*
|
||||
* @param type 菜单类型
|
||||
*/
|
||||
List<SysMenuVO> getMenuList(Integer type);
|
||||
|
||||
/**
|
||||
* 用户菜单列表
|
||||
*
|
||||
* @param user 用户
|
||||
* @param type 菜单类型
|
||||
*/
|
||||
List<SysMenuVO> getUserMenuList(UserDetail user, Integer type);
|
||||
|
||||
/**
|
||||
* 获取子菜单的数量
|
||||
* @param pid 父菜单ID
|
||||
*/
|
||||
Long getSubMenuCount(Long pid);
|
||||
|
||||
/**
|
||||
* 获取用户权限列表
|
||||
*/
|
||||
Set<String> getUserAuthority(UserDetail user);
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package net.maku.system.service;
|
||||
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.query.Query;
|
||||
import net.maku.framework.common.service.BaseService;
|
||||
import net.maku.system.entity.SysOauthClientEntity;
|
||||
import net.maku.system.vo.oauth.SysOauthClientPostVO;
|
||||
import net.maku.system.vo.oauth.SysOauthClientPutVO;
|
||||
import net.maku.system.vo.oauth.SysOauthClientVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 客户端管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface SysOauthClientService extends BaseService<SysOauthClientEntity> {
|
||||
|
||||
PageResult<SysOauthClientVO> page(Query query);
|
||||
|
||||
void save(SysOauthClientPostVO vo);
|
||||
|
||||
void update(SysOauthClientPutVO vo);
|
||||
|
||||
void delete(List<Long> idList);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package net.maku.system.service;
|
||||
|
||||
import net.maku.framework.common.service.BaseService;
|
||||
import net.maku.system.entity.SysOrgEntity;
|
||||
import net.maku.system.vo.org.SysOrgPostVO;
|
||||
import net.maku.system.vo.org.SysOrgPutVO;
|
||||
import net.maku.system.vo.org.SysOrgVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 机构管理
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface SysOrgService extends BaseService<SysOrgEntity> {
|
||||
|
||||
List<SysOrgVO> getList();
|
||||
|
||||
void save(SysOrgPostVO vo);
|
||||
|
||||
void update(SysOrgPutVO vo);
|
||||
|
||||
void delete(Long id);
|
||||
|
||||
/**
|
||||
* 根据机构ID,获取子机构ID列表(包含本机构ID)
|
||||
* @param id 机构ID
|
||||
*/
|
||||
List<Long> getSubOrgIdList(Long id);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user