diff --git a/README.md b/README.md
index bc384c71..5993ea01 100644
--- a/README.md
+++ b/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)中打开本项目
# 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.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.2 执行 mvn package -P prod 进行项目打包,将 target 目录下的 continew-admin.jar 放到 /docker/continew-admin/server 目录下
# 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.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 应用的初始搭建以及开发过程。 |
| [Undertow](https://undertow.io/) | 2.2.20.Final | 采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。 |
| [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 数据库。 |
| [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 等项目。 |
@@ -58,52 +65,63 @@ git clone https://github.com/Charles7c/continew-admin.git
```bash
continew-admin # 全局通用项目配置及依赖版本管理
├─ continew-admin-webapi # API 模块(存放 Controller 层代码,打包部署的模块)
- │ ├─ src
- │ │ ├─ main
- │ │ │ ├─ java # 工程源文件代码目录
- │ │ │ │ └─ top
- │ │ │ │ └─ charles7c
- │ │ │ │ ├─ cnadmin
- │ │ │ │ │ └─ webapi
- │ │ │ │ │ └─ controller
- │ │ │ │ │ └─ auth # 认证相关 API
- │ │ │ │ └─ ContinewAdminApplication.java # 启动入口
- │ │ │ ├─ resources # 工程配置目录
+ │ └─ src
+ │ └─ main
+ │ ├─ java # 工程源文件代码目录
+ │ │ └─ top
+ │ │ └─ charles7c
+ │ │ └─ cnadmin
+ │ │ ├─ webapi
+ │ │ │ └─ controller
+ │ │ │ └─ auth # 认证相关 API
+ │ │ └─ ContinewAdminApplication.java # 启动入口
+ │ └─ resources # 工程配置目录
+ │ └─ db.changelog.v0.0.1 # 数据库脚本文件
├─ continew-admin-system # 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等)
- │ ├─ src
- │ │ ├─ main
- │ │ │ ├─ java # 工程源文件代码目录
- │ │ │ │ └─ top
- │ │ │ │ └─ charles7c
- │ │ │ │ └─ cnadmin
- │ │ │ │ └─ auth # 认证相关业务及配置
- │ │ │ │ ├─ config # 认证相关配置
- │ │ │ │ │ ├─ satoken # Sa-Token 配置
- │ │ │ │ │ └─ properties # 认证相关配置属性
- │ │ │ │ ├─ model # 认证相关模型
- │ │ │ │ │ ├─ entity # 认证相关实体对象
- │ │ │ │ │ ├─ request # 认证相关请求对象
- │ │ │ │ │ └─ vo # 认证相关 VO(View Object)
- │ │ │ │ └─ service # 认证相关业务
- │ │ │ │ └─ impl # 认证相关业务实现
+ │ └─ src
+ │ └─ main
+ │ ├─ java # 工程源文件代码目录
+ │ │ └─ top
+ │ │ └─ charles7c
+ │ │ └─ cnadmin
+ │ │ ├─ auth # 认证相关业务及配置
+ │ │ │ ├─ config # 认证相关配置
+ │ │ │ │ ├─ satoken # Sa-Token 配置
+ │ │ │ │ └─ properties # 认证相关配置属性
+ │ │ │ ├─ model # 认证相关模型
+ │ │ │ │ ├─ request # 认证相关请求对象
+ │ │ │ │ └─ vo # 认证相关 VO(View Object)
+ │ │ │ └─ service # 认证相关业务接口及实现类
+ │ │ │ └─ impl # 认证相关业务实现类
+ │ │ └─ system # 系统管理相关业务及配置
+ │ │ ├─ mapper # 系统管理相关 Mapper
+ │ │ ├─ model # 系统管理相关模型
+ │ │ │ └─ entity # 系统管理相关实体对象
+ │ │ └─ service # 系统管理相关业务接口及实现类
+ │ │ └─ impl # 系统管理相关业务实现类
+ │ └─ resources # 工程配置目录
+ │ └─ mapper # MyBatis Mapper XML 文件目录
├─ continew-admin-common # 公共模块(存放公共工具类,公共配置等)
- │ ├─ src
- │ │ ├─ main
- │ │ │ ├─ java # 工程源文件代码目录
- │ │ │ │ └─ top
- │ │ │ │ └─ charles7c
- │ │ │ │ └─ cnadmin
- │ │ │ │ └─ common
- │ │ │ │ ├─ config # 公共配置
- │ │ │ │ │ ├─ jackson # Jackson 配置
- │ │ │ │ │ └─ properties # 公共配置属性
- │ │ │ │ ├─ consts # 公共常量
- │ │ │ │ ├─ exception # 公共异常
- │ │ │ │ ├─ handler # 公共处理器
- │ │ │ │ ├─ model # 公共模型
- │ │ │ │ │ ├─ entity # 公共实体对象
- │ │ │ │ │ └─ vo # 公共 VO(View Object)
- │ │ │ │ └─ util # 公共工具类
+ │ └─ src
+ │ └─ main
+ │ └─ java # 工程源文件代码目录
+ │ └─ top
+ │ └─ charles7c
+ │ └─ cnadmin
+ │ └─ common
+ │ ├─ config # 公共配置
+ │ │ ├─ jackson # Jackson 配置
+ │ │ ├─ mybatis # MyBatis Plus 配置
+ │ │ └─ properties # 公共配置属性
+ │ ├─ consts # 公共常量
+ │ ├─ exception # 公共异常
+ │ ├─ handler # 公共处理器
+ │ ├─ model # 公共模型
+ │ │ ├─ dto # 公共 DTO(Data Transfer Object)
+ │ │ ├─ entity # 公共实体对象
+ │ │ └─ vo # 公共 VO(View Object)
+ │ └─ util # 公共工具类
+ │ └─ helper # 公共 Helper(助手)
```
### License
diff --git a/continew-admin-common/pom.xml b/continew-admin-common/pom.xml
index 4725f56d..483a0c17 100644
--- a/continew-admin-common/pom.xml
+++ b/continew-admin-common/pom.xml
@@ -84,6 +84,31 @@ limitations under the License.
sa-token-dao-redis-jackson
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+
+
+
+
+ com.baomidou
+ dynamic-datasource-spring-boot-starter
+
+
+
+
+ com.mysql
+ mysql-connector-j
+
+
+
+
+ p6spy
+ p6spy
+
+
diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/config/mybatis/MyBatisPlusMetaObjectHandler.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/config/mybatis/MyBatisPlusMetaObjectHandler.java
new file mode 100644
index 00000000..7c7cd6bf
--- /dev/null
+++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/config/mybatis/MyBatisPlusMetaObjectHandler.java
@@ -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);
+ }
+ }
+}
diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/config/mybatis/MybatisPlusConfiguration.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/config/mybatis/MybatisPlusConfiguration.java
new file mode 100644
index 00000000..c0b55dd7
--- /dev/null
+++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/config/mybatis/MybatisPlusConfiguration.java
@@ -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;
+ }
+
+ /**
+ * 分页插件配置(...)
+ */
+ 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());
+ }
+}
diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/exception/ServiceException.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/exception/ServiceException.java
new file mode 100644
index 00000000..3f360404
--- /dev/null
+++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/exception/ServiceException.java
@@ -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);
+ }
+
+}
diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/handler/GlobalExceptionHandler.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/handler/GlobalExceptionHandler.java
index 2b8666ea..2cc96dd4 100644
--- a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/handler/GlobalExceptionHandler.java
+++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/handler/GlobalExceptionHandler.java
@@ -19,10 +19,12 @@ package top.charles7c.cnadmin.common.handler;
import java.util.Objects;
import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
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.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)
public R handleBindException(BindException e, HttpServletRequest request) {
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)
public R constraintViolationException(ConstraintViolationException e, HttpServletRequest request) {
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)
public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
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()));
}
/**
diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/entity/SysUser.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/dto/LoginUser.java
similarity index 76%
rename from continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/entity/SysUser.java
rename to continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/dto/LoginUser.java
index 9980ad52..15e76fe0 100644
--- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/entity/SysUser.java
+++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/dto/LoginUser.java
@@ -14,20 +14,20 @@
* 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 top.charles7c.cnadmin.common.model.entity.BaseEntity;
-
/**
- * 用户实体
+ * 登录用户信息
*
* @author Charles7c
- * @since 2022/12/21 20:42
+ * @since 2022/12/24 13:01
*/
@Data
-public class SysUser extends BaseEntity {
+public class LoginUser implements Serializable {
private static final long serialVersionUID = 1L;
@@ -41,11 +41,6 @@ public class SysUser extends BaseEntity {
*/
private String username;
- /**
- * 密码
- */
- private String password;
-
/**
* 昵称
*/
@@ -57,10 +52,25 @@ public class SysUser extends BaseEntity {
private Integer gender;
/**
- * 头像
+ * 手机号码
+ */
+ private String phone;
+
+ /**
+ * 邮箱
+ */
+ private String email;
+
+ /**
+ * 头像地址
*/
private String avatar;
+ /**
+ * 备注
+ */
+ private String notes;
+
/**
* 状态(1启用 2禁用)
*/
diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/entity/BaseEntity.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/entity/BaseEntity.java
index 669d76f5..40fbd4be 100644
--- a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/entity/BaseEntity.java
+++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/model/entity/BaseEntity.java
@@ -21,6 +21,9 @@ import java.util.Date;
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;
/**
* 创建时间
*/
+ @TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 修改人
*/
+ @TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
/**
* 修改时间
*/
+ @TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/StreamUtils.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/StreamUtils.java
new file mode 100644
index 00000000..429fc02b
--- /dev/null
+++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/StreamUtils.java
@@ -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
+ * /
+ * @return 拼接结果
+ */
+ public static String join(Collection collection, Function function, CharSequence delimiter) {
+ if (CollUtil.isEmpty(collection)) {
+ return StringUtils.EMPTY;
+ }
+ return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
+ }
+}
diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/helper/LoginHelper.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/helper/LoginHelper.java
new file mode 100644
index 00000000..19c2e75d
--- /dev/null
+++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/helper/LoginHelper.java
@@ -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());
+ }
+}
diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java
index 16b6c8a7..207ab80c 100644
--- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java
+++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java
@@ -21,13 +21,16 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
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.UserService;
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.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(), "此账号已被禁用,如有疑问,请联系管理员");
// 登录
- StpUtil.login(userId);
+ LoginUser loginUser = BeanUtil.copyProperties(sysUser, LoginUser.class);
+ LoginHelper.login(loginUser);
// 返回令牌
return StpUtil.getTokenValue();
diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/UserMapper.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/UserMapper.java
new file mode 100644
index 00000000..cee2f7f9
--- /dev/null
+++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/UserMapper.java
@@ -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 {}
diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/SysUser.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/SysUser.java
new file mode 100644
index 00000000..134266ab
--- /dev/null
+++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/SysUser.java
@@ -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;
+}
diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/UserService.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java
similarity index 89%
rename from continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/UserService.java
rename to continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java
index 85e77ee3..a0e42f1c 100644
--- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/UserService.java
+++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java
@@ -14,9 +14,9 @@
* 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;
/**
* 用户业务接口
diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/UserServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java
similarity index 53%
rename from continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/UserServiceImpl.java
rename to continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java
index eba6020d..c20de6a7 100644
--- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/UserServiceImpl.java
+++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java
@@ -14,15 +14,17 @@
* 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 top.charles7c.cnadmin.auth.model.entity.SysUser;
-import top.charles7c.cnadmin.auth.service.UserService;
-import top.charles7c.cnadmin.common.util.SecureUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+
+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
*/
@Service
+@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
+ private final UserMapper userMapper;
+
@Override
public SysUser getByUsername(String username) {
- if (!"admin".equals(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;
+ return userMapper.selectOne(Wrappers.lambdaQuery().eq(SysUser::getUsername, username));
}
}
diff --git a/continew-admin-system/src/main/resources/mapper/UserMapper.xml b/continew-admin-system/src/main/resources/mapper/UserMapper.xml
new file mode 100644
index 00000000..1f557b7e
--- /dev/null
+++ b/continew-admin-system/src/main/resources/mapper/UserMapper.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/continew-admin-webapi/pom.xml b/continew-admin-webapi/pom.xml
index 4ece2d89..8cb0cdde 100644
--- a/continew-admin-webapi/pom.xml
+++ b/continew-admin-webapi/pom.xml
@@ -32,6 +32,12 @@ limitations under the License.
API 模块(存放 Controller 层代码,打包部署的模块)
+
+
+ org.liquibase
+ liquibase-core
+
+
org.springframework.boot
spring-boot-starter-test
diff --git a/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/auth/LoginController.java b/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/auth/LoginController.java
index 4f42c99e..775c9a51 100644
--- a/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/auth/LoginController.java
+++ b/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/auth/LoginController.java
@@ -77,7 +77,7 @@ public class LoginController {
@SaIgnore
@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)
@PostMapping("/logout")
public R logout() {
diff --git a/continew-admin-webapi/src/main/resources/application-dev.yml b/continew-admin-webapi/src/main/resources/application-dev.yml
index 2863fc8d..d829d74f 100644
--- a/continew-admin-webapi/src/main/resources/application-dev.yml
+++ b/continew-admin-webapi/src/main/resources/application-dev.yml
@@ -3,6 +3,56 @@ server:
# HTTP 端口(默认 8080)
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 单机配置
spring:
redis:
@@ -23,12 +73,6 @@ spring:
security:
# 排除路径配置
excludes:
- # 静态资源
- - /*.html
- - /**/*.html
- - /**/*.css
- - /**/*.js
- - /webSocket/**
# 接口文档相关资源
- /favicon.ico
- /doc.html
diff --git a/continew-admin-webapi/src/main/resources/application-prod.yml b/continew-admin-webapi/src/main/resources/application-prod.yml
index cd048e59..c4b0c0fe 100644
--- a/continew-admin-webapi/src/main/resources/application-prod.yml
+++ b/continew-admin-webapi/src/main/resources/application-prod.yml
@@ -3,6 +3,56 @@ server:
# HTTP 端口(默认 8080)
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 单机配置
spring:
redis:
@@ -19,17 +69,6 @@ spring:
# 是否开启 SSL
ssl: false
---- ### 安全配置
-security:
- # 排除路径配置
- excludes:
- # 静态资源
- - /*.html
- - /**/*.html
- - /**/*.css
- - /**/*.js
- - /webSocket/**
-
--- ### 非对称加密配置(例如:密码加密传输,前端公钥加密,后端私钥解密;在线生成 RSA 密钥对:http://web.chacuo.net/netrsakeypair)
rsa:
# 私钥
diff --git a/continew-admin-webapi/src/main/resources/application.yml b/continew-admin-webapi/src/main/resources/application.yml
index 551de150..672b0fa3 100644
--- a/continew-admin-webapi/src/main/resources/application.yml
+++ b/continew-admin-webapi/src/main/resources/application.yml
@@ -79,6 +79,54 @@ sa-token:
# JWT秘钥
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:
servlet:
diff --git a/continew-admin-webapi/src/main/resources/db/changelog/db.changelog-master.yaml b/continew-admin-webapi/src/main/resources/db/changelog/db.changelog-master.yaml
new file mode 100644
index 00000000..d6b874ed
--- /dev/null
+++ b/continew-admin-webapi/src/main/resources/db/changelog/db.changelog-master.yaml
@@ -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
diff --git a/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_column.sql b/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_column.sql
new file mode 100644
index 00000000..874085b8
--- /dev/null
+++ b/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_column.sql
@@ -0,0 +1,2 @@
+-- liquibase formatted sql
+
diff --git a/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_data.sql b/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_data.sql
new file mode 100644
index 00000000..a792ac54
--- /dev/null
+++ b/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_data.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());
diff --git a/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_table.sql b/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_table.sql
new file mode 100644
index 00000000..2a8c70e7
--- /dev/null
+++ b/continew-admin-webapi/src/main/resources/db/changelog/v0.0.1/continew-admin_table.sql
@@ -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='用户表';
\ No newline at end of file
diff --git a/continew-admin-webapi/src/main/resources/spy.properties b/continew-admin-webapi/src/main/resources/spy.properties
new file mode 100644
index 00000000..ec1e289b
--- /dev/null
+++ b/continew-admin-webapi/src/main/resources/spy.properties
@@ -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
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index e1dd3c42..636566ec 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -1,5 +1,21 @@
version: '3'
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:
container_name: redis
image: redis:6.2.7
@@ -20,6 +36,11 @@ services:
restart: always
environment:
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_PORT: 6379
REDIS_PWD: 你的 Redis 密码
@@ -30,6 +51,7 @@ services:
- /docker/continew-admin/server/logs:/logs
depends_on:
- redis
+ - mariadb
privileged: true
nginx:
container_name: nginx
diff --git a/pom.xml b/pom.xml
index 1574e3a5..5ab9f3cb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,6 +44,11 @@ limitations under the License.
1.33.0
+
+ 3.5.2
+ 3.6.1
+ 3.9.1
+
4.0.0
3.19.0
@@ -78,7 +83,7 @@ limitations under the License.
cn.hutool
- hutool-all
+ hutool-jwt
@@ -90,6 +95,28 @@ limitations under the License.
${sa-token.version}
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ ${mybatis-plus.version}
+
+
+
+
+ com.baomidou
+ dynamic-datasource-spring-boot-starter
+ ${dynamic-ds.version}
+
+
+
+
+ p6spy
+ p6spy
+ ${p6spy.version}
+
+