完善:完善用户登录 API,优化部分包结构(引入 MyBatis Plus、多数据源、P6Spy、Liquibase 等依赖,详情可见 README 介绍)
This commit is contained in:
parent
00e2b44d0e
commit
78e84e8941
112
README.md
112
README.md
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
### 简介
|
### 简介
|
||||||
|
|
||||||
ContiNew-Admin (incubating) 中后台管理框架,Continue New Admin,持续以最新流行技术栈构建。当前阶段采用的技术栈:Spring Boot、Undertow、Sa-Token、JWT、Redis、Redisson、Hutool 等。
|
ContiNew-Admin (incubating) 中后台管理框架,Continue New Admin,持续以最新流行技术栈构建。当前阶段采用的技术栈:Spring Boot、Undertow、Sa-Token、JWT、MariaDB、MyBatis Plus、Redis、Redisson、Hutool 等。
|
||||||
|
|
||||||
### 开始
|
### 开始
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ git clone https://github.com/Charles7c/continew-admin.git
|
|||||||
# 2.在 IDE(IntelliJ IDEA/Eclipse)中打开本项目
|
# 2.在 IDE(IntelliJ IDEA/Eclipse)中打开本项目
|
||||||
|
|
||||||
# 3.修改配置文件中的 Redis 配置信息
|
# 3.修改配置文件中的 Redis 配置信息
|
||||||
# [3.也可以在 IntelliJ IDEA 中直接配置程序启动环境变量(REDIS_HOST、REDIS_PORT、REDIS_PWD、REDIS_DB)]
|
# [3.也可以在 IntelliJ IDEA 中直接配置程序启动环境变量(DB_HOST、DB_PORT、DB_USER、DB_PWD、DB_NAME;REDIS_HOST、REDIS_PORT、REDIS_PWD、REDIS_DB)]
|
||||||
|
|
||||||
# 4.启动程序
|
# 4.启动程序
|
||||||
# 4.1 启动成功:访问 http://localhost:8000/,页面输出:ContiNew-Admin backend service started successfully.
|
# 4.1 启动成功:访问 http://localhost:8000/,页面输出:ContiNew-Admin backend service started successfully.
|
||||||
@ -29,7 +29,7 @@ git clone https://github.com/Charles7c/continew-admin.git
|
|||||||
# 5.1.1 服务器安装好 docker 及 docker-compose(参考:https://blog.charles7c.top/categories/fragments/2022/10/31/CentOS%E5%AE%89%E8%A3%85Docker)
|
# 5.1.1 服务器安装好 docker 及 docker-compose(参考:https://blog.charles7c.top/categories/fragments/2022/10/31/CentOS%E5%AE%89%E8%A3%85Docker)
|
||||||
# 5.1.2 执行 mvn package -P prod 进行项目打包,将 target 目录下的 continew-admin.jar 放到 /docker/continew-admin/server 目录下
|
# 5.1.2 执行 mvn package -P prod 进行项目打包,将 target 目录下的 continew-admin.jar 放到 /docker/continew-admin/server 目录下
|
||||||
# 5.1.3 将 docker 目录上传到服务器 / 目录下,并授权(chmod -R 777 /docker)
|
# 5.1.3 将 docker 目录上传到服务器 / 目录下,并授权(chmod -R 777 /docker)
|
||||||
# 5.1.4 修改 docker-compose.yml 中的 Redis 配置、continew-admin-server 配置、Nginx 配置
|
# 5.1.4 修改 docker-compose.yml 中的 MariaDB 配置、Redis 配置、continew-admin-server 配置、Nginx 配置
|
||||||
# 5.1.5 执行 docker-compose up -d 创建并后台运行所有容器
|
# 5.1.5 执行 docker-compose up -d 创建并后台运行所有容器
|
||||||
# 5.2 其他方式部署
|
# 5.2 其他方式部署
|
||||||
```
|
```
|
||||||
@ -41,6 +41,13 @@ git clone https://github.com/Charles7c/continew-admin.git
|
|||||||
| [Spring Boot](https://spring.io/projects/spring-boot) | 2.7.6 | 简化新 Spring 应用的初始搭建以及开发过程。 |
|
| [Spring Boot](https://spring.io/projects/spring-boot) | 2.7.6 | 简化新 Spring 应用的初始搭建以及开发过程。 |
|
||||||
| [Undertow](https://undertow.io/) | 2.2.20.Final | 采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。 |
|
| [Undertow](https://undertow.io/) | 2.2.20.Final | 采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。 |
|
||||||
| [Sa-Token + JWT](https://sa-token.dev33.cn/) | 1.33.0 | 轻量级 Java 权限认证框架,让鉴权变得简单、优雅。 |
|
| [Sa-Token + JWT](https://sa-token.dev33.cn/) | 1.33.0 | 轻量级 Java 权限认证框架,让鉴权变得简单、优雅。 |
|
||||||
|
| [MariaDB](https://mariadb.org/) | 10.10.2 | MySQL 的一个分支,主要由开源社区在维护,完全兼容 MySQL,包括 API 和命令行,能轻松成为 MySQL 的代替品。 |
|
||||||
|
| [MyBatis Plus](https://baomidou.com/) | 3.5.2 | MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,简化开发、提高效率。 |
|
||||||
|
| [dynamic-datasource-spring-boot-starter](https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611) | 3.6.1 | 基于 Spring Boot 的快速集成多数据源的启动器。 |
|
||||||
|
| Hikari | 4.0.3 | JDBC 连接池,号称 “史上最快连接池”,SpringBoot 在 2.0 之后,采用的默认数据库连接池就是 Hikari。 |
|
||||||
|
| [mysql-connector-j](https://dev.mysql.com/doc/connector-j/8.0/en/) | 8.0.31 | MySQL Java 驱动。 |
|
||||||
|
| [P6Spy](https://github.com/p6spy/p6spy) | 3.9.1 | SQL 性能分析组件。 |
|
||||||
|
| [Liquibase](https://github.com/liquibase/liquibase) | 4.9.1 | 用于管理数据库版本,跟踪、管理和应用数据库变化。 |
|
||||||
| [Redis](https://redis.io/) | 6.2.7 | 高性能的 key-value 数据库。 |
|
| [Redis](https://redis.io/) | 6.2.7 | 高性能的 key-value 数据库。 |
|
||||||
| [Redisson](https://github.com/redisson/redisson/wiki/Redisson%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D) | 3.19.0 | 不仅仅是一个 Redis Java 客户端,同其他 Redis Java 客户端有着很大的区别,相比之下其他客户端提供的功能还仅仅停留在作为数据库驱动层面上,比如仅针对 Redis 提供连接方式,发送命令和处理返回结果等。而 Redisson 充分的利用了 Redis 键值数据库提供的一系列优势,基于 Java 实用工具包中常用接口,为使用者提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间的协作。 |
|
| [Redisson](https://github.com/redisson/redisson/wiki/Redisson%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D) | 3.19.0 | 不仅仅是一个 Redis Java 客户端,同其他 Redis Java 客户端有着很大的区别,相比之下其他客户端提供的功能还仅仅停留在作为数据库驱动层面上,比如仅针对 Redis 提供连接方式,发送命令和处理返回结果等。而 Redisson 充分的利用了 Redis 键值数据库提供的一系列优势,基于 Java 实用工具包中常用接口,为使用者提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间的协作。 |
|
||||||
| Easy Captcha | 1.6.2 | Java 图形验证码,支持 gif、中文、算术等类型,可用于 Java Web、JavaSE 等项目。 |
|
| Easy Captcha | 1.6.2 | Java 图形验证码,支持 gif、中文、算术等类型,可用于 Java Web、JavaSE 等项目。 |
|
||||||
@ -58,52 +65,63 @@ git clone https://github.com/Charles7c/continew-admin.git
|
|||||||
```bash
|
```bash
|
||||||
continew-admin # 全局通用项目配置及依赖版本管理
|
continew-admin # 全局通用项目配置及依赖版本管理
|
||||||
├─ continew-admin-webapi # API 模块(存放 Controller 层代码,打包部署的模块)
|
├─ continew-admin-webapi # API 模块(存放 Controller 层代码,打包部署的模块)
|
||||||
│ ├─ src
|
│ └─ src
|
||||||
│ │ ├─ main
|
│ └─ main
|
||||||
│ │ │ ├─ java # 工程源文件代码目录
|
│ ├─ java # 工程源文件代码目录
|
||||||
│ │ │ │ └─ top
|
│ │ └─ top
|
||||||
│ │ │ │ └─ charles7c
|
│ │ └─ charles7c
|
||||||
│ │ │ │ ├─ cnadmin
|
│ │ └─ cnadmin
|
||||||
│ │ │ │ │ └─ webapi
|
│ │ ├─ webapi
|
||||||
│ │ │ │ │ └─ controller
|
│ │ │ └─ controller
|
||||||
│ │ │ │ │ └─ auth # 认证相关 API
|
│ │ │ └─ auth # 认证相关 API
|
||||||
│ │ │ │ └─ ContinewAdminApplication.java # 启动入口
|
│ │ └─ ContinewAdminApplication.java # 启动入口
|
||||||
│ │ │ ├─ resources # 工程配置目录
|
│ └─ resources # 工程配置目录
|
||||||
|
│ └─ db.changelog.v0.0.1 # 数据库脚本文件
|
||||||
├─ continew-admin-system # 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等)
|
├─ continew-admin-system # 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等)
|
||||||
│ ├─ src
|
│ └─ src
|
||||||
│ │ ├─ main
|
│ └─ main
|
||||||
│ │ │ ├─ java # 工程源文件代码目录
|
│ ├─ java # 工程源文件代码目录
|
||||||
│ │ │ │ └─ top
|
│ │ └─ top
|
||||||
│ │ │ │ └─ charles7c
|
│ │ └─ charles7c
|
||||||
│ │ │ │ └─ cnadmin
|
│ │ └─ cnadmin
|
||||||
│ │ │ │ └─ auth # 认证相关业务及配置
|
│ │ ├─ auth # 认证相关业务及配置
|
||||||
│ │ │ │ ├─ config # 认证相关配置
|
│ │ │ ├─ config # 认证相关配置
|
||||||
│ │ │ │ │ ├─ satoken # Sa-Token 配置
|
│ │ │ │ ├─ satoken # Sa-Token 配置
|
||||||
│ │ │ │ │ └─ properties # 认证相关配置属性
|
│ │ │ │ └─ properties # 认证相关配置属性
|
||||||
│ │ │ │ ├─ model # 认证相关模型
|
│ │ │ ├─ model # 认证相关模型
|
||||||
│ │ │ │ │ ├─ entity # 认证相关实体对象
|
│ │ │ │ ├─ request # 认证相关请求对象
|
||||||
│ │ │ │ │ ├─ request # 认证相关请求对象
|
│ │ │ │ └─ vo # 认证相关 VO(View Object)
|
||||||
│ │ │ │ │ └─ vo # 认证相关 VO(View Object)
|
│ │ │ └─ service # 认证相关业务接口及实现类
|
||||||
│ │ │ │ └─ service # 认证相关业务
|
│ │ │ └─ impl # 认证相关业务实现类
|
||||||
│ │ │ │ └─ impl # 认证相关业务实现
|
│ │ └─ system # 系统管理相关业务及配置
|
||||||
|
│ │ ├─ mapper # 系统管理相关 Mapper
|
||||||
|
│ │ ├─ model # 系统管理相关模型
|
||||||
|
│ │ │ └─ entity # 系统管理相关实体对象
|
||||||
|
│ │ └─ service # 系统管理相关业务接口及实现类
|
||||||
|
│ │ └─ impl # 系统管理相关业务实现类
|
||||||
|
│ └─ resources # 工程配置目录
|
||||||
|
│ └─ mapper # MyBatis Mapper XML 文件目录
|
||||||
├─ continew-admin-common # 公共模块(存放公共工具类,公共配置等)
|
├─ continew-admin-common # 公共模块(存放公共工具类,公共配置等)
|
||||||
│ ├─ src
|
│ └─ src
|
||||||
│ │ ├─ main
|
│ └─ main
|
||||||
│ │ │ ├─ java # 工程源文件代码目录
|
│ └─ java # 工程源文件代码目录
|
||||||
│ │ │ │ └─ top
|
│ └─ top
|
||||||
│ │ │ │ └─ charles7c
|
│ └─ charles7c
|
||||||
│ │ │ │ └─ cnadmin
|
│ └─ cnadmin
|
||||||
│ │ │ │ └─ common
|
│ └─ common
|
||||||
│ │ │ │ ├─ config # 公共配置
|
│ ├─ config # 公共配置
|
||||||
│ │ │ │ │ ├─ jackson # Jackson 配置
|
│ │ ├─ jackson # Jackson 配置
|
||||||
│ │ │ │ │ └─ properties # 公共配置属性
|
│ │ ├─ mybatis # MyBatis Plus 配置
|
||||||
│ │ │ │ ├─ consts # 公共常量
|
│ │ └─ properties # 公共配置属性
|
||||||
│ │ │ │ ├─ exception # 公共异常
|
│ ├─ consts # 公共常量
|
||||||
│ │ │ │ ├─ handler # 公共处理器
|
│ ├─ exception # 公共异常
|
||||||
│ │ │ │ ├─ model # 公共模型
|
│ ├─ handler # 公共处理器
|
||||||
│ │ │ │ │ ├─ entity # 公共实体对象
|
│ ├─ model # 公共模型
|
||||||
│ │ │ │ │ └─ vo # 公共 VO(View Object)
|
│ │ ├─ dto # 公共 DTO(Data Transfer Object)
|
||||||
│ │ │ │ └─ util # 公共工具类
|
│ │ ├─ entity # 公共实体对象
|
||||||
|
│ │ └─ vo # 公共 VO(View Object)
|
||||||
|
│ └─ util # 公共工具类
|
||||||
|
│ └─ helper # 公共 Helper(助手)
|
||||||
```
|
```
|
||||||
|
|
||||||
### License
|
### License
|
||||||
|
@ -84,6 +84,31 @@ limitations under the License.
|
|||||||
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- ################ 持久层相关 ################ -->
|
||||||
|
<!-- MyBatis Plus(MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,简化开发、提高效率) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Dynamic Datasource(基于 Spring Boot 的快速集成多数据源的启动器) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- MySQL Java 驱动 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- P6Spy(SQL 性能分析组件) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>p6spy</groupId>
|
||||||
|
<artifactId>p6spy</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- ################ 工具库相关 ################ -->
|
<!-- ################ 工具库相关 ################ -->
|
||||||
<!-- Knife4j(前身是 swagger-bootstrap-ui,集 Swagger2 和 OpenAPI3 为一体的增强解决方案) -->
|
<!-- Knife4j(前身是 swagger-bootstrap-ui,集 Swagger2 和 OpenAPI3 为一体的增强解决方案) -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.charles7c.cnadmin.common.config.mybatis;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.apache.ibatis.reflection.MetaObject;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
|
||||||
|
import top.charles7c.cnadmin.common.exception.ServiceException;
|
||||||
|
import top.charles7c.cnadmin.common.model.entity.BaseEntity;
|
||||||
|
import top.charles7c.cnadmin.common.util.helper.LoginHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MyBatis Plus 元对象处理器配置(插入或修改时自动填充)
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2022/12/22 19:52
|
||||||
|
*/
|
||||||
|
public class MyBatisPlusMetaObjectHandler implements MetaObjectHandler {
|
||||||
|
|
||||||
|
/** 创建人 */
|
||||||
|
private static final String CREATE_USER = "createUser";
|
||||||
|
/** 创建时间 */
|
||||||
|
private static final String CREATE_TIME = "createTime";
|
||||||
|
/** 修改人 */
|
||||||
|
private static final String UPDATE_USER = "updateUser";
|
||||||
|
/** 修改时间 */
|
||||||
|
private static final String UPDATE_TIME = "updateTime";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插入数据时填充
|
||||||
|
*
|
||||||
|
* @param metaObject
|
||||||
|
* 元对象
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertFill(MetaObject metaObject) {
|
||||||
|
try {
|
||||||
|
if (ObjectUtil.isNull(metaObject)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long createUser = LoginHelper.getUserId();
|
||||||
|
Date createTime = new Date();
|
||||||
|
if (metaObject.getOriginalObject() instanceof BaseEntity) {
|
||||||
|
// 继承了 BaseEntity 的类,填充创建信息
|
||||||
|
BaseEntity baseEntity = (BaseEntity)metaObject.getOriginalObject();
|
||||||
|
baseEntity.setCreateUser(baseEntity.getCreateUser() != null ? baseEntity.getCreateUser() : createUser);
|
||||||
|
baseEntity.setCreateTime(baseEntity.getCreateTime() != null ? baseEntity.getCreateTime() : createTime);
|
||||||
|
baseEntity.setUpdateUser(baseEntity.getUpdateUser() != null ? baseEntity.getUpdateUser() : createUser);
|
||||||
|
baseEntity.setUpdateTime(baseEntity.getUpdateTime() != null ? baseEntity.getUpdateTime() : createTime);
|
||||||
|
} else {
|
||||||
|
// 未继承 BaseEntity 的类,根据类中拥有的创建信息进行填充,不存在创建信息不进行填充
|
||||||
|
this.fillFieldValue(metaObject, CREATE_USER, createUser, false);
|
||||||
|
this.fillFieldValue(metaObject, CREATE_TIME, createTime, false);
|
||||||
|
this.fillFieldValue(metaObject, UPDATE_USER, createUser, false);
|
||||||
|
this.fillFieldValue(metaObject, UPDATE_TIME, createTime, false);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ServiceException("插入数据时自动填充异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改数据时填充
|
||||||
|
*
|
||||||
|
* @param metaObject
|
||||||
|
* 元对象
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void updateFill(MetaObject metaObject) {
|
||||||
|
try {
|
||||||
|
if (ObjectUtil.isNull(metaObject)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long updateUser = LoginHelper.getUserId();
|
||||||
|
Date updateTime = new Date();
|
||||||
|
if (metaObject.getOriginalObject() instanceof BaseEntity) {
|
||||||
|
// 继承了 BaseEntity 的类,填充修改信息
|
||||||
|
BaseEntity baseEntity = (BaseEntity)metaObject.getOriginalObject();
|
||||||
|
baseEntity.setUpdateUser(updateUser);
|
||||||
|
baseEntity.setUpdateTime(updateTime);
|
||||||
|
} else {
|
||||||
|
// 未继承 BaseEntity 的类,根据类中拥有的修改信息进行填充,不存在修改信息不进行填充
|
||||||
|
this.fillFieldValue(metaObject, UPDATE_USER, updateUser, true);
|
||||||
|
this.fillFieldValue(metaObject, UPDATE_TIME, updateTime, true);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ServiceException("修改数据时自动填充异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充属性值
|
||||||
|
*
|
||||||
|
* @param metaObject
|
||||||
|
* 元数据对象
|
||||||
|
* @param fieldName
|
||||||
|
* 要填充的属性名
|
||||||
|
* @param fillFieldValue
|
||||||
|
* 要填充的属性值
|
||||||
|
* @param isOverride
|
||||||
|
* 如果属性值不为空,是否覆盖(true 覆盖、false 不覆盖)
|
||||||
|
*/
|
||||||
|
private void fillFieldValue(MetaObject metaObject, String fieldName, Object fillFieldValue, boolean isOverride) {
|
||||||
|
if (metaObject.hasSetter(fieldName)) {
|
||||||
|
Object fieldValue = metaObject.getValue(fieldName);
|
||||||
|
setFieldValByName(fieldName, fieldValue != null && !isOverride ? fieldValue : fillFieldValue, metaObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.charles7c.cnadmin.common.config.mybatis;
|
||||||
|
|
||||||
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
|
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||||
|
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
|
||||||
|
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||||
|
|
||||||
|
import cn.hutool.core.net.NetUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MyBatis Plus 配置
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2022/12/22 19:51
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@MapperScan("${mybatis-plus.mapper-package}")
|
||||||
|
public class MybatisPlusConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插件配置
|
||||||
|
*
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||||
|
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||||
|
// 分页插件
|
||||||
|
interceptor.addInnerInterceptor(paginationInnerInterceptor());
|
||||||
|
return interceptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页插件配置(<a href="https://baomidou.com/pages/97710a/#paginationinnerinterceptor">...</a>)
|
||||||
|
*/
|
||||||
|
private PaginationInnerInterceptor paginationInnerInterceptor() {
|
||||||
|
// 对于单一数据库类型来说,都建议配置该值,避免每次分页都去抓取数据库类型
|
||||||
|
// PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
|
||||||
|
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
|
||||||
|
// 溢出总页数后是否进行处理
|
||||||
|
paginationInnerInterceptor.setOverflow(false);
|
||||||
|
// 单页分页条数限制
|
||||||
|
paginationInnerInterceptor.setMaxLimit(-1L);
|
||||||
|
return paginationInnerInterceptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 元对象处理器配置(插入或修改时自动填充)
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
MetaObjectHandler metaObjectHandler() {
|
||||||
|
return new MyBatisPlusMetaObjectHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID 生成器配置,仅在主键类型(idType)配置为 ASSIGN_ID 或 ASSIGN_UUID 时有效(使用网卡信息绑定雪花生成器,防止集群雪花 ID 重复)
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
IdentifierGenerator idGenerator() {
|
||||||
|
return new DefaultIdentifierGenerator(NetUtil.getLocalhost());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.charles7c.cnadmin.common.exception;
|
||||||
|
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务异常
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2022/12/23 22:55
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class ServiceException extends RuntimeException {
|
||||||
|
|
||||||
|
public ServiceException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,10 +19,12 @@ package top.charles7c.cnadmin.common.handler;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
import javax.validation.ConstraintViolationException;
|
import javax.validation.ConstraintViolationException;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.validation.BindException;
|
import org.springframework.validation.BindException;
|
||||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||||
@ -37,6 +39,8 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
|
|
||||||
import top.charles7c.cnadmin.common.exception.BadRequestException;
|
import top.charles7c.cnadmin.common.exception.BadRequestException;
|
||||||
import top.charles7c.cnadmin.common.model.vo.R;
|
import top.charles7c.cnadmin.common.model.vo.R;
|
||||||
|
import top.charles7c.cnadmin.common.util.ExceptionUtils;
|
||||||
|
import top.charles7c.cnadmin.common.util.StreamUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局异常处理器
|
* 全局异常处理器
|
||||||
@ -85,7 +89,8 @@ public class GlobalExceptionHandler {
|
|||||||
@ExceptionHandler(BindException.class)
|
@ExceptionHandler(BindException.class)
|
||||||
public R handleBindException(BindException e, HttpServletRequest request) {
|
public R handleBindException(BindException e, HttpServletRequest request) {
|
||||||
log.error("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
log.error("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
||||||
return R.fail(HttpStatus.BAD_REQUEST.value(), e.getMessage());
|
String message = StreamUtils.join(e.getAllErrors(), DefaultMessageSourceResolvable::getDefaultMessage, ",");
|
||||||
|
return R.fail(HttpStatus.BAD_REQUEST.value(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,7 +100,8 @@ public class GlobalExceptionHandler {
|
|||||||
@ExceptionHandler(ConstraintViolationException.class)
|
@ExceptionHandler(ConstraintViolationException.class)
|
||||||
public R constraintViolationException(ConstraintViolationException e, HttpServletRequest request) {
|
public R constraintViolationException(ConstraintViolationException e, HttpServletRequest request) {
|
||||||
log.error("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
log.error("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
||||||
return R.fail(HttpStatus.BAD_REQUEST.value(), e.getMessage());
|
String message = StreamUtils.join(e.getConstraintViolations(), ConstraintViolation::getMessage, ",");
|
||||||
|
return R.fail(HttpStatus.BAD_REQUEST.value(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,7 +111,8 @@ public class GlobalExceptionHandler {
|
|||||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
|
public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
|
||||||
log.error("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
log.error("请求地址'{}',参数验证失败", request.getRequestURI(), e);
|
||||||
return R.fail(HttpStatus.BAD_REQUEST.value(), e.getMessage());
|
return R.fail(HttpStatus.BAD_REQUEST.value(), ExceptionUtils
|
||||||
|
.exToNull(() -> Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,20 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package top.charles7c.cnadmin.auth.model.entity;
|
package top.charles7c.cnadmin.common.model.dto;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import top.charles7c.cnadmin.common.model.entity.BaseEntity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户实体
|
* 登录用户信息
|
||||||
*
|
*
|
||||||
* @author Charles7c
|
* @author Charles7c
|
||||||
* @since 2022/12/21 20:42
|
* @since 2022/12/24 13:01
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class SysUser extends BaseEntity {
|
public class LoginUser implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@ -41,11 +41,6 @@ public class SysUser extends BaseEntity {
|
|||||||
*/
|
*/
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
/**
|
|
||||||
* 密码
|
|
||||||
*/
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 昵称
|
* 昵称
|
||||||
*/
|
*/
|
||||||
@ -57,10 +52,25 @@ public class SysUser extends BaseEntity {
|
|||||||
private Integer gender;
|
private Integer gender;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 头像
|
* 手机号码
|
||||||
|
*/
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邮箱
|
||||||
|
*/
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 头像地址
|
||||||
*/
|
*/
|
||||||
private String avatar;
|
private String avatar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String notes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态(1启用 2禁用)
|
* 状态(1启用 2禁用)
|
||||||
*/
|
*/
|
@ -21,6 +21,9 @@ import java.util.Date;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实体类基类
|
* 实体类基类
|
||||||
*
|
*
|
||||||
@ -35,20 +38,24 @@ public class BaseEntity implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 创建人
|
* 创建人
|
||||||
*/
|
*/
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private Long createUser;
|
private Long createUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建时间
|
* 创建时间
|
||||||
*/
|
*/
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改人
|
* 修改人
|
||||||
*/
|
*/
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
private Long updateUser;
|
private Long updateUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改时间
|
* 修改时间
|
||||||
*/
|
*/
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
private Date updateTime;
|
private Date updateTime;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.charles7c.cnadmin.common.util;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stream 工具类
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2022/12/22 19:51
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class StreamUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将集合中的指定字段使用分隔符拼接成字符串
|
||||||
|
*
|
||||||
|
* @param collection
|
||||||
|
* 集合
|
||||||
|
* @param function
|
||||||
|
* 字段方法
|
||||||
|
* @param delimiter
|
||||||
|
* 分隔符
|
||||||
|
* @param <E>
|
||||||
|
* /
|
||||||
|
* @return 拼接结果
|
||||||
|
*/
|
||||||
|
public static <E> String join(Collection<E> collection, Function<E, String> function, CharSequence delimiter) {
|
||||||
|
if (CollUtil.isEmpty(collection)) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.charles7c.cnadmin.common.util.helper;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.context.SaHolder;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
|
||||||
|
import top.charles7c.cnadmin.common.model.dto.LoginUser;
|
||||||
|
import top.charles7c.cnadmin.common.util.ExceptionUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录助手
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2022/12/24 12:58
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class LoginHelper {
|
||||||
|
|
||||||
|
private static final String LOGIN_USER_KEY = "LOGIN_USER";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户登录并缓存用户信息
|
||||||
|
*
|
||||||
|
* @param loginUser
|
||||||
|
* 登录用户信息
|
||||||
|
*/
|
||||||
|
public static void login(LoginUser loginUser) {
|
||||||
|
SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
|
||||||
|
StpUtil.login(loginUser.getUserId());
|
||||||
|
StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取登录用户信息
|
||||||
|
*
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static LoginUser getLoginUser() {
|
||||||
|
LoginUser loginUser = (LoginUser)SaHolder.getStorage().get(LOGIN_USER_KEY);
|
||||||
|
if (loginUser != null) {
|
||||||
|
return loginUser;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
loginUser = (LoginUser)StpUtil.getTokenSession().get(LOGIN_USER_KEY);
|
||||||
|
SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
return loginUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取登录用户 ID
|
||||||
|
*
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static Long getUserId() {
|
||||||
|
return ExceptionUtils.exToNull(() -> getLoginUser().getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取登录用户名
|
||||||
|
*
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static String getUsername() {
|
||||||
|
return ExceptionUtils.exToNull(() -> getLoginUser().getUsername());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取登录用户昵称
|
||||||
|
*
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static String getNickname() {
|
||||||
|
return ExceptionUtils.exToNull(() -> getLoginUser().getNickname());
|
||||||
|
}
|
||||||
|
}
|
@ -21,13 +21,16 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
|
||||||
import top.charles7c.cnadmin.auth.model.entity.SysUser;
|
|
||||||
import top.charles7c.cnadmin.auth.service.LoginService;
|
import top.charles7c.cnadmin.auth.service.LoginService;
|
||||||
import top.charles7c.cnadmin.auth.service.UserService;
|
|
||||||
import top.charles7c.cnadmin.common.consts.CommonConstants;
|
import top.charles7c.cnadmin.common.consts.CommonConstants;
|
||||||
|
import top.charles7c.cnadmin.common.model.dto.LoginUser;
|
||||||
import top.charles7c.cnadmin.common.util.CheckUtils;
|
import top.charles7c.cnadmin.common.util.CheckUtils;
|
||||||
import top.charles7c.cnadmin.common.util.SecureUtils;
|
import top.charles7c.cnadmin.common.util.SecureUtils;
|
||||||
|
import top.charles7c.cnadmin.common.util.helper.LoginHelper;
|
||||||
|
import top.charles7c.cnadmin.system.model.entity.SysUser;
|
||||||
|
import top.charles7c.cnadmin.system.service.UserService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录业务实现类
|
* 登录业务实现类
|
||||||
@ -53,7 +56,8 @@ public class LoginServiceImpl implements LoginService {
|
|||||||
CheckUtils.exIfEqual(CommonConstants.STATUS_DISABLE, sysUser.getStatus(), "此账号已被禁用,如有疑问,请联系管理员");
|
CheckUtils.exIfEqual(CommonConstants.STATUS_DISABLE, sysUser.getStatus(), "此账号已被禁用,如有疑问,请联系管理员");
|
||||||
|
|
||||||
// 登录
|
// 登录
|
||||||
StpUtil.login(userId);
|
LoginUser loginUser = BeanUtil.copyProperties(sysUser, LoginUser.class);
|
||||||
|
LoginHelper.login(loginUser);
|
||||||
|
|
||||||
// 返回令牌
|
// 返回令牌
|
||||||
return StpUtil.getTokenValue();
|
return StpUtil.getTokenValue();
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.charles7c.cnadmin.system.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import top.charles7c.cnadmin.system.model.entity.SysUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户 Mapper
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2022/12/22 21:47
|
||||||
|
*/
|
||||||
|
public interface UserMapper extends BaseMapper<SysUser> {}
|
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.charles7c.cnadmin.system.model.entity;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import top.charles7c.cnadmin.common.model.entity.BaseEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户实体
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2022/12/21 20:42
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("sys_user")
|
||||||
|
public class SysUser extends BaseEntity {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户 ID
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户名
|
||||||
|
*/
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 昵称
|
||||||
|
*/
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性别(0未知 1男 2女)
|
||||||
|
*/
|
||||||
|
private Integer gender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号码
|
||||||
|
*/
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邮箱
|
||||||
|
*/
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 头像地址
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String notes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态(1启用 2禁用)
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最后一次修改密码的时间
|
||||||
|
*/
|
||||||
|
private Date pwdResetTime;
|
||||||
|
}
|
@ -14,9 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package top.charles7c.cnadmin.auth.service;
|
package top.charles7c.cnadmin.system.service;
|
||||||
|
|
||||||
import top.charles7c.cnadmin.auth.model.entity.SysUser;
|
import top.charles7c.cnadmin.system.model.entity.SysUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户业务接口
|
* 用户业务接口
|
@ -14,15 +14,17 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package top.charles7c.cnadmin.auth.service.impl;
|
package top.charles7c.cnadmin.system.service.impl;
|
||||||
|
|
||||||
import java.util.Date;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import top.charles7c.cnadmin.auth.model.entity.SysUser;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import top.charles7c.cnadmin.auth.service.UserService;
|
|
||||||
import top.charles7c.cnadmin.common.util.SecureUtils;
|
import top.charles7c.cnadmin.system.mapper.UserMapper;
|
||||||
|
import top.charles7c.cnadmin.system.model.entity.SysUser;
|
||||||
|
import top.charles7c.cnadmin.system.service.UserService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户业务实现类
|
* 用户业务实现类
|
||||||
@ -31,24 +33,13 @@ import top.charles7c.cnadmin.common.util.SecureUtils;
|
|||||||
* @since 2022/12/21 21:49
|
* @since 2022/12/21 21:49
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class UserServiceImpl implements UserService {
|
public class UserServiceImpl implements UserService {
|
||||||
|
|
||||||
|
private final UserMapper userMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SysUser getByUsername(String username) {
|
public SysUser getByUsername(String username) {
|
||||||
if (!"admin".equals(username)) {
|
return userMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
|
||||||
return null;
|
|
||||||
}
|
|
||||||
SysUser sysUser = new SysUser();
|
|
||||||
sysUser.setUserId(1L);
|
|
||||||
sysUser.setUsername("admin");
|
|
||||||
sysUser.setPassword(SecureUtils.md5Salt("123456", sysUser.getUserId().toString()));
|
|
||||||
sysUser.setNickname("超级管理员");
|
|
||||||
sysUser.setGender(1);
|
|
||||||
sysUser.setStatus(1);
|
|
||||||
sysUser.setCreateUser(1L);
|
|
||||||
sysUser.setCreateTime(new Date());
|
|
||||||
sysUser.setUpdateUser(1L);
|
|
||||||
sysUser.setUpdateTime(new Date());
|
|
||||||
return sysUser;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
|
<mapper namespace="top.charles7c.cnadmin.system.mapper.UserMapper">
|
||||||
|
</mapper>
|
@ -32,6 +32,12 @@ limitations under the License.
|
|||||||
<description>API 模块(存放 Controller 层代码,打包部署的模块)</description>
|
<description>API 模块(存放 Controller 层代码,打包部署的模块)</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- Liquibase(用于管理数据库版本,跟踪、管理和应用数据库变化) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.liquibase</groupId>
|
||||||
|
<artifactId>liquibase-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
@ -77,7 +77,7 @@ public class LoginController {
|
|||||||
|
|
||||||
@SaIgnore
|
@SaIgnore
|
||||||
@Operation(summary = "用户退出", description = "注销用户的当前登录")
|
@Operation(summary = "用户退出", description = "注销用户的当前登录")
|
||||||
@Parameter(name = "Authorization", description = "令牌", required = true, example = "Bearer xxxxxxxxx",
|
@Parameter(name = "Authorization", description = "令牌", required = true, example = "Bearer xxxx-xxxx-xxxx-xxxx",
|
||||||
in = ParameterIn.HEADER)
|
in = ParameterIn.HEADER)
|
||||||
@PostMapping("/logout")
|
@PostMapping("/logout")
|
||||||
public R logout() {
|
public R logout() {
|
||||||
|
@ -3,6 +3,56 @@ server:
|
|||||||
# HTTP 端口(默认 8080)
|
# HTTP 端口(默认 8080)
|
||||||
port: 8000
|
port: 8000
|
||||||
|
|
||||||
|
--- ### 数据源配置
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
|
## 动态数据源配置(可配多主多从:m1、s1...、纯粹多库:mysql、oracle...、混合配置:m1、s1、oracle...)
|
||||||
|
dynamic:
|
||||||
|
# 是否启用 P6Spy(SQL 性能分析组件,默认 false,该插件有性能损耗,不建议生产环境使用)
|
||||||
|
p6spy: true
|
||||||
|
# 设置默认的数据源或者数据源组(默认 master)
|
||||||
|
primary: master
|
||||||
|
# 严格匹配数据源(true 未匹配到指定数据源时抛异常;false 使用默认数据源;默认 false)
|
||||||
|
strict: false
|
||||||
|
datasource:
|
||||||
|
# 主库配置(可配多个,构成多主)
|
||||||
|
master:
|
||||||
|
url: jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:continew_admin}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=10&failOverReadOnly=false
|
||||||
|
username: ${DB_USER:root}
|
||||||
|
password: ${DB_PWD:123456}
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
# 从库配置(可配多个,构成多从)
|
||||||
|
slave_1:
|
||||||
|
url: jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:continew_admin}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=10&failOverReadOnly=false
|
||||||
|
username:
|
||||||
|
password:
|
||||||
|
lazy: true
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
type: ${spring.datasource.type}
|
||||||
|
hikari:
|
||||||
|
# 最大连接池数量
|
||||||
|
max-pool-size: 20
|
||||||
|
# 最小空闲线程数量
|
||||||
|
min-idle: 10
|
||||||
|
# 获取连接超时时间
|
||||||
|
connection-timeout: 10000
|
||||||
|
# 校验超时时间
|
||||||
|
validation-timeout: 5000
|
||||||
|
# 空闲连接最大存活时间(默认 10 分钟)
|
||||||
|
idle-timeout: 60000
|
||||||
|
# 此属性控制池中连接的最长生命周期,0 表示无限生命周期(默认 30 分钟)
|
||||||
|
max-lifetime: 900000
|
||||||
|
# 连接测试 query(配置检测连接是否有效)
|
||||||
|
connection-test-query: SELECT 1
|
||||||
|
|
||||||
|
--- ### Liquibase 配置
|
||||||
|
spring.liquibase:
|
||||||
|
# 是否启用
|
||||||
|
enabled: true
|
||||||
|
# 配置文件路径
|
||||||
|
change-log: classpath:/db/changelog/db.changelog-master.yaml
|
||||||
|
|
||||||
--- ### Redis 单机配置
|
--- ### Redis 单机配置
|
||||||
spring:
|
spring:
|
||||||
redis:
|
redis:
|
||||||
@ -23,12 +73,6 @@ spring:
|
|||||||
security:
|
security:
|
||||||
# 排除路径配置
|
# 排除路径配置
|
||||||
excludes:
|
excludes:
|
||||||
# 静态资源
|
|
||||||
- /*.html
|
|
||||||
- /**/*.html
|
|
||||||
- /**/*.css
|
|
||||||
- /**/*.js
|
|
||||||
- /webSocket/**
|
|
||||||
# 接口文档相关资源
|
# 接口文档相关资源
|
||||||
- /favicon.ico
|
- /favicon.ico
|
||||||
- /doc.html
|
- /doc.html
|
||||||
|
@ -3,6 +3,56 @@ server:
|
|||||||
# HTTP 端口(默认 8080)
|
# HTTP 端口(默认 8080)
|
||||||
port: 18000
|
port: 18000
|
||||||
|
|
||||||
|
--- ### 数据源配置
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
|
## 动态数据源配置(可配多主多从:m1、s1...、纯粹多库:mysql、oracle...、混合配置:m1、s1、oracle...)
|
||||||
|
dynamic:
|
||||||
|
# 是否启用 P6Spy(SQL 性能分析组件,默认 false,该插件有性能损耗,不建议生产环境使用)
|
||||||
|
p6spy: false
|
||||||
|
# 设置默认的数据源或者数据源组(默认 master)
|
||||||
|
primary: master
|
||||||
|
# 严格匹配数据源(true 未匹配到指定数据源时抛异常;false 使用默认数据源;默认 false)
|
||||||
|
strict: false
|
||||||
|
datasource:
|
||||||
|
# 主库配置(可配多个,构成多主)
|
||||||
|
master:
|
||||||
|
url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:continew_admin}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=10&failOverReadOnly=false
|
||||||
|
username: ${DB_USER:root}
|
||||||
|
password: ${DB_PWD:123456}
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
# 从库配置(可配多个,构成多从)
|
||||||
|
slave_1:
|
||||||
|
url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:continew_admin}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true&autoReconnect=true&maxReconnects=10&failOverReadOnly=false
|
||||||
|
username:
|
||||||
|
password:
|
||||||
|
lazy: true
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
type: ${spring.datasource.type}
|
||||||
|
hikari:
|
||||||
|
# 最大连接池数量
|
||||||
|
max-pool-size: 20
|
||||||
|
# 最小空闲线程数量
|
||||||
|
min-idle: 10
|
||||||
|
# 获取连接超时时间
|
||||||
|
connection-timeout: 10000
|
||||||
|
# 校验超时时间
|
||||||
|
validation-timeout: 5000
|
||||||
|
# 空闲连接最大存活时间(默认 10 分钟)
|
||||||
|
idle-timeout: 60000
|
||||||
|
# 此属性控制池中连接的最长生命周期,0 表示无限生命周期(默认 30 分钟)
|
||||||
|
max-lifetime: 900000
|
||||||
|
# 连接测试 query(配置检测连接是否有效)
|
||||||
|
connection-test-query: SELECT 1
|
||||||
|
|
||||||
|
--- ### Liquibase 配置
|
||||||
|
spring.liquibase:
|
||||||
|
# 是否启用
|
||||||
|
enabled: true
|
||||||
|
# 配置文件路径
|
||||||
|
change-log: classpath:/db/changelog/db.changelog-master.yaml
|
||||||
|
|
||||||
--- ### Redis 单机配置
|
--- ### Redis 单机配置
|
||||||
spring:
|
spring:
|
||||||
redis:
|
redis:
|
||||||
@ -19,17 +69,6 @@ spring:
|
|||||||
# 是否开启 SSL
|
# 是否开启 SSL
|
||||||
ssl: false
|
ssl: false
|
||||||
|
|
||||||
--- ### 安全配置
|
|
||||||
security:
|
|
||||||
# 排除路径配置
|
|
||||||
excludes:
|
|
||||||
# 静态资源
|
|
||||||
- /*.html
|
|
||||||
- /**/*.html
|
|
||||||
- /**/*.css
|
|
||||||
- /**/*.js
|
|
||||||
- /webSocket/**
|
|
||||||
|
|
||||||
--- ### 非对称加密配置(例如:密码加密传输,前端公钥加密,后端私钥解密;在线生成 RSA 密钥对:http://web.chacuo.net/netrsakeypair)
|
--- ### 非对称加密配置(例如:密码加密传输,前端公钥加密,后端私钥解密;在线生成 RSA 密钥对:http://web.chacuo.net/netrsakeypair)
|
||||||
rsa:
|
rsa:
|
||||||
# 私钥
|
# 私钥
|
||||||
|
@ -79,6 +79,54 @@ sa-token:
|
|||||||
# JWT秘钥
|
# JWT秘钥
|
||||||
jwt-secret-key: asdasdasifhueuiwyurfewbfjsdafjk
|
jwt-secret-key: asdasdasifhueuiwyurfewbfjsdafjk
|
||||||
|
|
||||||
|
--- ### 安全配置
|
||||||
|
security:
|
||||||
|
# 排除路径配置
|
||||||
|
excludes:
|
||||||
|
# 静态资源
|
||||||
|
- /*.html
|
||||||
|
- /**/*.html
|
||||||
|
- /**/*.css
|
||||||
|
- /**/*.js
|
||||||
|
- /webSocket/**
|
||||||
|
|
||||||
|
--- ### MyBatis Plus 配置
|
||||||
|
mybatis-plus:
|
||||||
|
# Mapper 接口扫描包配置(该配置为自定义配置,非 MP 配置,不支持多包,如有需要可通过注解配置或提升扫描包层级)
|
||||||
|
# 该配置目前的唯一使用场景为:@MapperScan("${mybatis-plus.mapper-package}")
|
||||||
|
mapper-package: top.charles7c.**.mapper
|
||||||
|
# Mapper XML 文件目录配置
|
||||||
|
mapper-locations: classpath*:/mapper/**/*Mapper.xml
|
||||||
|
# 类型别名扫描包配置
|
||||||
|
type-aliases-package: top.charles7c.**.model
|
||||||
|
check-config-location: true
|
||||||
|
configuration:
|
||||||
|
# 自动驼峰命名规则(camel case)映射
|
||||||
|
map-underscore-to-camel-case: true
|
||||||
|
# MyBatis 自动映射策略
|
||||||
|
# NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射
|
||||||
|
auto-mapping-behavior: PARTIAL
|
||||||
|
# MyBatis 自动映射时未知列或未知属性处理策
|
||||||
|
# NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息
|
||||||
|
auto-mapping-unknown-column-behavior: NONE
|
||||||
|
# 日志配置
|
||||||
|
# 默认:org.apache.ibatis.logging.slf4j.Slf4jImpl
|
||||||
|
# 更详细(会有性能损耗):org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
# 关闭(可单纯使用 p6spy 分析):org.apache.ibatis.logging.nologging.NoLoggingImpl
|
||||||
|
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
|
||||||
|
global-config:
|
||||||
|
banner: true
|
||||||
|
db-config:
|
||||||
|
# 主键类型(默认 assign_id 表示自行赋值)
|
||||||
|
# auto 代表使用数据库自增策略(需要在表中设置好自增约束)
|
||||||
|
id-type: AUTO
|
||||||
|
# 逻辑删除字段
|
||||||
|
logic-delete-field: isDeleted
|
||||||
|
# 逻辑删除全局值(默认 1,表示已删除)
|
||||||
|
logic-delete-value: 1
|
||||||
|
# 逻辑未删除全局值(默认 0,表示未删除)
|
||||||
|
logic-not-delete-value: 0
|
||||||
|
|
||||||
--- ### 服务器配置
|
--- ### 服务器配置
|
||||||
server:
|
server:
|
||||||
servlet:
|
servlet:
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
databaseChangeLog:
|
||||||
|
- include:
|
||||||
|
file: db/changelog/v0.0.1/continew-admin_table.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/v0.0.1/continew-admin_column.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/v0.0.1/continew-admin_data.sql
|
@ -0,0 +1,2 @@
|
|||||||
|
-- liquibase formatted sql
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
-- liquibase formatted sql
|
||||||
|
|
||||||
|
-- changeset Charles7c:1
|
||||||
|
-- 初始化默认用户:admin/123456;test/123456
|
||||||
|
INSERT IGNORE INTO `sys_user` VALUES (1, 'admin', '超级管理员', 'f0df7414507bcb57e07e18555821228a', 1, NULL, 'charles7c@126.com', NULL, NULL, 1, NULL, 1, NOW(), 1, NOW());
|
||||||
|
INSERT IGNORE INTO `sys_user` VALUES (2, 'test', '测试员', '8e114197e1b33783a00542ad67e80516', 0, NULL, NULL, NULL, NULL, 2, NULL, 1, NOW(), 1, NOW());
|
@ -0,0 +1,25 @@
|
|||||||
|
-- liquibase formatted sql
|
||||||
|
|
||||||
|
-- changeset Charles7c:1
|
||||||
|
CREATE TABLE IF NOT EXISTS `sys_user` (
|
||||||
|
`user_id` bigint(20) unsigned AUTO_INCREMENT COMMENT '用户ID',
|
||||||
|
`username` varchar(255) NOT NULL COMMENT '用户名',
|
||||||
|
`nickname` varchar(255) DEFAULT NULL COMMENT '昵称',
|
||||||
|
`password` varchar(255) DEFAULT NULL COMMENT '密码',
|
||||||
|
`gender` tinyint(1) unsigned DEFAULT 0 COMMENT '性别(0未知 1男 2女)',
|
||||||
|
`phone` varchar(255) DEFAULT NULL COMMENT '手机号码',
|
||||||
|
`email` varchar(255) DEFAULT NULL COMMENT '邮箱',
|
||||||
|
`avatar` varchar(255) DEFAULT NULL COMMENT '头像地址',
|
||||||
|
`notes` varchar(512) DEFAULT NULL COMMENT '备注',
|
||||||
|
`status` tinyint(1) unsigned DEFAULT 1 COMMENT '状态(1启用 2禁用)',
|
||||||
|
`pwd_reset_time` datetime DEFAULT NULL COMMENT '最后一次修改密码的时间',
|
||||||
|
`create_user` bigint(20) unsigned NOT NULL COMMENT '创建人',
|
||||||
|
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||||
|
`update_user` bigint(20) unsigned NOT NULL COMMENT '修改人',
|
||||||
|
`update_time` datetime NOT NULL COMMENT '修改时间',
|
||||||
|
PRIMARY KEY (`user_id`) USING BTREE,
|
||||||
|
UNIQUE INDEX `uk_username`(`username`) USING BTREE,
|
||||||
|
UNIQUE INDEX `uk_email`(`email`) USING BTREE,
|
||||||
|
INDEX `idx_createUser`(`create_user`) USING BTREE,
|
||||||
|
INDEX `idx_updateUser`(`update_user`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
|
30
continew-admin-webapi/src/main/resources/spy.properties
Normal file
30
continew-admin-webapi/src/main/resources/spy.properties
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
############################################################################
|
||||||
|
# P6Spy 配置(SQL 性能分析组件) #
|
||||||
|
############################################################################
|
||||||
|
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
|
||||||
|
# 自定义日志打印
|
||||||
|
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
|
||||||
|
#日志输出到控制台
|
||||||
|
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
|
||||||
|
# 使用日志系统记录 SQL
|
||||||
|
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
|
||||||
|
# 设置 P6Spy Driver 代理
|
||||||
|
deregisterdrivers=true
|
||||||
|
# 取消 JDBC URL 前缀
|
||||||
|
useprefix=true
|
||||||
|
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
|
||||||
|
excludecategories=info,debug,result,commit,resultset
|
||||||
|
# 日期格式
|
||||||
|
dateformat=yyyy-MM-dd HH:mm:ss
|
||||||
|
# SQL语句打印时间格式
|
||||||
|
databaseDialectTimestampFormat=yyyy-MM-dd HH:mm:ss
|
||||||
|
# 实际驱动可多个
|
||||||
|
#driverlist=org.h2.Driver
|
||||||
|
# 是否启用慢 SQL 记录
|
||||||
|
outagedetection=true
|
||||||
|
# 慢 SQL 记录标准 2 秒
|
||||||
|
outagedetectioninterval=2
|
||||||
|
# 是否过滤 Log
|
||||||
|
filter=true
|
||||||
|
# 过滤 Log 时所排除的 SQL 关键字,以逗号分隔
|
||||||
|
exclude=SELECT 1
|
@ -1,5 +1,21 @@
|
|||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
|
mariadb:
|
||||||
|
container_name: mariadb
|
||||||
|
image: mariadb
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
MYSQL_ROOT_PASSWORD: 你的root用户密码
|
||||||
|
# 初始化数据库(后续的初始化 SQL 会在这个库执行)
|
||||||
|
MYSQL_DATABASE: continew_admin
|
||||||
|
#MYSQL_USER: 你的数据库用户名
|
||||||
|
#MYSQL_PASSWORD: 你的数据库密码
|
||||||
|
ports:
|
||||||
|
- '3306:3306'
|
||||||
|
volumes:
|
||||||
|
- /docker/mysql/:/var/lib/mysql
|
||||||
|
privileged: true
|
||||||
redis:
|
redis:
|
||||||
container_name: redis
|
container_name: redis
|
||||||
image: redis:6.2.7
|
image: redis:6.2.7
|
||||||
@ -20,6 +36,11 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
|
DB_HOST: 172.17.0.1
|
||||||
|
DB_PORT: 3306
|
||||||
|
DB_USER: 你的数据库用户名
|
||||||
|
DB_PWD: 你的数据库密码
|
||||||
|
DB_NAME: continew_admin
|
||||||
REDIS_HOST: 172.17.0.1
|
REDIS_HOST: 172.17.0.1
|
||||||
REDIS_PORT: 6379
|
REDIS_PORT: 6379
|
||||||
REDIS_PWD: 你的 Redis 密码
|
REDIS_PWD: 你的 Redis 密码
|
||||||
@ -30,6 +51,7 @@ services:
|
|||||||
- /docker/continew-admin/server/logs:/logs
|
- /docker/continew-admin/server/logs:/logs
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
- redis
|
||||||
|
- mariadb
|
||||||
privileged: true
|
privileged: true
|
||||||
nginx:
|
nginx:
|
||||||
container_name: nginx
|
container_name: nginx
|
||||||
|
29
pom.xml
29
pom.xml
@ -44,6 +44,11 @@ limitations under the License.
|
|||||||
<properties>
|
<properties>
|
||||||
<sa-token.version>1.33.0</sa-token.version>
|
<sa-token.version>1.33.0</sa-token.version>
|
||||||
|
|
||||||
|
<!-- ### 持久层相关 ### -->
|
||||||
|
<mybatis-plus.version>3.5.2</mybatis-plus.version>
|
||||||
|
<dynamic-ds.version>3.6.1</dynamic-ds.version>
|
||||||
|
<p6spy.version>3.9.1</p6spy.version>
|
||||||
|
|
||||||
<!-- ### 工具库相关 ### -->
|
<!-- ### 工具库相关 ### -->
|
||||||
<knife4j.version>4.0.0</knife4j.version>
|
<knife4j.version>4.0.0</knife4j.version>
|
||||||
<redisson.version>3.19.0</redisson.version>
|
<redisson.version>3.19.0</redisson.version>
|
||||||
@ -78,7 +83,7 @@ limitations under the License.
|
|||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-all</artifactId>
|
<artifactId>hutool-jwt</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
@ -90,6 +95,28 @@ limitations under the License.
|
|||||||
<version>${sa-token.version}</version>
|
<version>${sa-token.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- ################ 持久层相关 ################ -->
|
||||||
|
<!-- MyBatis Plus(MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,简化开发、提高效率) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
<version>${mybatis-plus.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Dynamic Datasource(基于 Spring Boot 的快速集成多数据源的启动器) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||||
|
<version>${dynamic-ds.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- P6Spy(SQL 性能分析组件) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>p6spy</groupId>
|
||||||
|
<artifactId>p6spy</artifactId>
|
||||||
|
<version>${p6spy.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- ################ 工具库相关 ################ -->
|
<!-- ################ 工具库相关 ################ -->
|
||||||
<!-- Knife4j(前身是 swagger-bootstrap-ui,集 Swagger2 和 OpenAPI3 为一体的增强解决方案) -->
|
<!-- Knife4j(前身是 swagger-bootstrap-ui,集 Swagger2 和 OpenAPI3 为一体的增强解决方案) -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
Loading…
Reference in New Issue
Block a user