让天下没有难学的技术
需求
积分等级CRUD列表和表单
_103-创建基本的项目结构
一、创建父工程srb
=============
1、创建SpringBoot项目
Group:com.atguigu
Artifact:srb
2、删除src目录
3、配置SpringBoot版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
4、配置pom依赖版本号
<properties>
<java.version>1.8</java.version>
<spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
<mybatis-plus.version>3.4.1</mybatis-plus.version>
<velocity.version>2.0</velocity.version>
<swagger.version>2.9.2</swagger.version>
<swagger-bootstrap-ui.version>1.9.2</swagger-bootstrap-ui.version>
<commons-lang3.version>3.9</commons-lang3.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-io.version>2.6</commons-io.version>
<alibaba.easyexcel.version>2.1.1</alibaba.easyexcel.version>
<apache.xmlbeans.version>3.1.0</apache.xmlbeans.version>
<fastjson.version>1.2.28</fastjson.version>
<gson.version>2.8.2</gson.version>
<json.version>20170516</json.version>
<aliyun-java-sdk-core.version>4.3.3</aliyun-java-sdk-core.version>
<aliyun-sdk-oss.version>3.10.2</aliyun-sdk-oss.version>
<jodatime.version>2.10.1</jodatime.version>
<jwt.version>0.7.0</jwt.version>
<httpclient.version>4.5.1</httpclient.version>
</properties>
5、配置pom依赖
<dependencyManagement>
<dependencies>
<!--Spring Cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Cloud Alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!--mybatis-plus 代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- Mybatis Plus 代码生成器模板引擎, -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--swagger-bootstrap-ui-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${swagger-bootstrap-ui.version}</version>
</dependency>
<!--commons-lang3-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<!--commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!--excel解析-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${alibaba.easyexcel.version}</version>
</dependency>
<!--excel解析依赖-->
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>${apache.xmlbeans.version}</version>
</dependency>
<!--json-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<!--阿里云SDK远程调用-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>${aliyun-java-sdk-core.version}</version>
</dependency>
<!--阿里云文件管理-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun-sdk-oss.version}</version>
</dependency>
<!--日期时间工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${jodatime.version}</version>
</dependency>
<!--jwt工具-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
二、创建模块guigu-common
1、创建Maven模块
在srb下创建普通maven模块
Group:com.atguigu
Artifact:guigu-common
2、配置pom
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--lombok用来简化实体类:需要安装lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
三、创建模块service-base
1、创建Maven模块
在srb下创建普通maven模块
Group:com.atguigu
Artifact:service-base
2、配置pom
注意:依赖guigu-common
<dependencies>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>guigu-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
</dependencies>
四、创建模块service-core
1、创建Maven模块
在srb下创建普通maven模块
Group:com.atguigu
Artifact:service-core
2、配置pom
注意:依赖service-base
<dependencies>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--mybatis-plus 代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</dependency>
<!-- Mybatis Plus 代码生成器模板引擎, -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
</dependency>
</dependencies>
_104-代码生成器
一、代码生成器
1、创建数据库
创建数据库srb_core
并执行sql脚本初始化数据结构和数据
1.1 数据库sql脚本:
/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version : 50721
Source Host : localhost:3306
Source Schema : srb_core
Target Server Type : MySQL
Target Server Version : 50721
File Encoding : 65001
Date: 21/03/2021 22:39:29
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for borrow_info
-- ----------------------------
DROP TABLE IF EXISTS `borrow_info`;
CREATE TABLE `borrow_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '借款用户id',
`amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '借款金额',
`period` int(11) NULL DEFAULT NULL COMMENT '借款期限',
`borrow_year_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '年化利率',
`return_method` tinyint(3) NULL DEFAULT NULL COMMENT '还款方式 1-等额本息 2-等额本金 3-每月还息一次还本 4-一次还本',
`money_use` tinyint(3) NULL DEFAULT NULL COMMENT '资金用途',
`status` tinyint(3) NOT NULL DEFAULT 0 COMMENT '状态(0:未提交,1:审核中, 2:审核通过, -1:审核不通过)',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_user_id`(`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '借款信息表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of borrow_info
-- ----------------------------
-- ----------------------------
-- Table structure for borrower
-- ----------------------------
DROP TABLE IF EXISTS `borrower`;
CREATE TABLE `borrower` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '用户id',
`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
`id_card` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '身份证号',
`mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手机',
`sex` tinyint(3) NULL DEFAULT NULL COMMENT '性别(1:男 0:女)',
`age` tinyint(3) NULL DEFAULT NULL COMMENT '年龄',
`education` tinyint(3) NULL DEFAULT NULL COMMENT '学历',
`is_marry` tinyint(1) NULL DEFAULT NULL COMMENT '是否结婚(1:是 0:否)',
`industry` tinyint(3) NULL DEFAULT NULL COMMENT '行业',
`income` tinyint(3) NULL DEFAULT NULL COMMENT '月收入',
`return_source` tinyint(3) NULL DEFAULT NULL COMMENT '还款来源',
`contacts_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人名称',
`contacts_mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人手机',
`contacts_relation` tinyint(3) NULL DEFAULT NULL COMMENT '联系人关系',
`status` tinyint(3) NOT NULL DEFAULT 0 COMMENT '状态(0:未认证,1:认证中, 2:认证通过, -1:认证失败)',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_user_id`(`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '借款人' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of borrower
-- ----------------------------
-- ----------------------------
-- Table structure for borrower_attach
-- ----------------------------
DROP TABLE IF EXISTS `borrower_attach`;
CREATE TABLE `borrower_attach` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`borrower_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '借款人id',
`image_type` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片类型(idCard1:身份证正面,idCard2:身份证反面,house:房产证,car:车)',
`image_url` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片路径',
`image_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片名称',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_borrower_id`(`borrower_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '借款人上传资源表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of borrower_attach
-- ----------------------------
-- ----------------------------
-- Table structure for dict
-- ----------------------------
DROP TABLE IF EXISTS `dict`;
CREATE TABLE `dict` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`parent_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '上级id',
`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '名称',
`value` int(11) NULL DEFAULT NULL COMMENT '值',
`dict_code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '编码',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '删除标记(0:不可用 1:可用)',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_parent_id_value`(`parent_id`, `value`) USING BTREE,
INDEX `idx_parent_id`(`parent_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 82008 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '数据字典' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of dict
-- ----------------------------
INSERT INTO `dict` VALUES (1, 0, '全部分类', NULL, 'ROOT', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (20000, 1, '行业', NULL, 'industry', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (20001, 20000, 'IT', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (20002, 20000, '医生', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (20003, 20000, '教师', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (20004, 20000, '导游', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (20005, 20000, '律师', 5, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (20006, 20000, '其他', 6, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (30000, 1, '学历', NULL, 'education', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (30001, 30000, '高中', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (30002, 30000, '大专', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (30003, 30000, '本科', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (30004, 30000, '研究生', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (30005, 30000, '其他', 5, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (40000, 1, '收入', NULL, 'income', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (40001, 40000, '0-3000', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (40002, 40000, '3000-5000', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (40003, 40000, '5000-10000', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (40004, 40000, '10000以上', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (50000, 1, '收入来源', NULL, 'returnSource', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (50001, 50000, '工资', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (50002, 50000, '股票', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (50003, 50000, '兼职', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (60000, 1, '关系', NULL, 'relation', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (60001, 60000, '夫妻', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (60002, 60000, '兄妹', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (60003, 60000, '父母', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (60004, 60000, '其他', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (70000, 1, '还款方式', NULL, 'returnMethod', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (70001, 70000, '等额本息', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (70002, 70000, '等额本金', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (70003, 70000, '每月还息一次还本', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (70004, 70000, '一次还本还息', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (80000, 1, '资金用途', NULL, 'moneyUse', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (80001, 80000, '旅游', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (80002, 80000, '买房', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (80003, 80000, '装修', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (80004, 80000, '医疗', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (80005, 80000, '美容', 5, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (80006, 80000, '其他', 6, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (81000, 1, '借款状态', NULL, 'borrowStatus', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (81001, 81000, '待审核', 0, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (81002, 81000, '审批通过', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (81003, 81000, '还款中', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (81004, 81000, '结束', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (81005, 81000, '审批不通过', -1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (82000, 1, '学校性质', NULL, 'SchoolStatus', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (82001, 82000, '211/985', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (82002, 82000, '一本', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (82003, 82000, '二本', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (82004, 82000, '三本', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (82005, 82000, '高职高专', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (82006, 82000, '中职中专', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
INSERT INTO `dict` VALUES (82007, 82000, '高中及以下', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0);
-- ----------------------------
-- Table structure for integral_grade
-- ----------------------------
DROP TABLE IF EXISTS `integral_grade`;
CREATE TABLE `integral_grade` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`integral_start` int(11) NULL DEFAULT NULL COMMENT '积分区间开始',
`integral_end` int(11) NULL DEFAULT NULL COMMENT '积分区间结束',
`borrow_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '借款额度',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '积分等级表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of integral_grade
-- ----------------------------
INSERT INTO `integral_grade` VALUES (1, 10, 50, 10000.00, '2020-12-08 17:02:29', '2021-02-19 17:58:10', 0);
INSERT INTO `integral_grade` VALUES (2, 51, 100, 30000.00, '2020-12-08 17:02:42', '2021-02-19 18:00:25', 0);
INSERT INTO `integral_grade` VALUES (3, 101, 2000, 100000.00, '2020-12-08 17:02:57', '2021-02-23 21:03:03', 0);
-- ----------------------------
-- Table structure for lend
-- ----------------------------
DROP TABLE IF EXISTS `lend`;
CREATE TABLE `lend` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`user_id` bigint(20) NULL DEFAULT NULL COMMENT '借款用户id',
`borrow_info_id` bigint(20) NULL DEFAULT NULL COMMENT '借款信息id',
`lend_no` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标的编号',
`title` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标题',
`amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '标的金额',
`period` int(11) NULL DEFAULT NULL COMMENT '投资期数',
`lend_year_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '年化利率',
`service_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '平台服务费率',
`return_method` tinyint(3) NULL DEFAULT NULL COMMENT '还款方式',
`lowest_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '最低投资金额',
`invest_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '已投金额',
`invest_num` int(11) NULL DEFAULT NULL COMMENT '投资人数',
`publish_date` datetime(0) NULL DEFAULT NULL COMMENT '发布日期',
`lend_start_date` date NULL DEFAULT NULL COMMENT '开始日期',
`lend_end_date` date NULL DEFAULT NULL COMMENT '结束日期',
`lend_info` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '说明',
`expect_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '平台预期收益',
`real_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '实际收益',
`status` tinyint(3) NOT NULL DEFAULT 0 COMMENT '状态',
`check_time` datetime(0) NULL DEFAULT NULL COMMENT '审核时间',
`check_admin_id` bigint(1) NULL DEFAULT NULL COMMENT '审核用户id',
`payment_time` datetime(0) NULL DEFAULT NULL COMMENT '放款时间',
`payment_admin_id` datetime(0) NULL DEFAULT NULL COMMENT '放款人id',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_lend_no`(`lend_no`) USING BTREE,
INDEX `idx_user_id`(`user_id`) USING BTREE,
INDEX `idx_borrow_info_id`(`borrow_info_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '标的准备表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of lend
-- ----------------------------
-- ----------------------------
-- Table structure for lend_item
-- ----------------------------
DROP TABLE IF EXISTS `lend_item`;
CREATE TABLE `lend_item` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`lend_item_no` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '投资编号',
`lend_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '标的id',
`invest_user_id` bigint(20) NULL DEFAULT NULL COMMENT '投资用户id',
`invest_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '投资人名称',
`invest_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '投资金额',
`lend_year_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '年化利率',
`invest_time` datetime(0) NULL DEFAULT NULL COMMENT '投资时间',
`lend_start_date` date NULL DEFAULT NULL COMMENT '开始日期',
`lend_end_date` date NULL DEFAULT NULL COMMENT '结束日期',
`expect_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '预期收益',
`real_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '实际收益',
`status` tinyint(3) NULL DEFAULT NULL COMMENT '状态(0:默认 1:已支付 2:已还款)',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_lend_item_no`(`lend_item_no`) USING BTREE,
INDEX `idx_lend_id`(`lend_id`) USING BTREE,
INDEX `idx_invest_user_id`(`invest_user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '标的出借记录表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of lend_item
-- ----------------------------
-- ----------------------------
-- Table structure for lend_item_return
-- ----------------------------
DROP TABLE IF EXISTS `lend_item_return`;
CREATE TABLE `lend_item_return` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`lend_return_id` bigint(20) NULL DEFAULT NULL COMMENT '标的还款id',
`lend_item_id` bigint(20) NULL DEFAULT NULL COMMENT '标的项id',
`lend_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '标的id',
`invest_user_id` bigint(1) NULL DEFAULT NULL COMMENT '出借用户id',
`invest_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '出借金额',
`current_period` int(11) NULL DEFAULT NULL COMMENT '当前的期数',
`lend_year_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '年化利率',
`return_method` tinyint(3) NULL DEFAULT NULL COMMENT '还款方式 1-等额本息 2-等额本金 3-每月还息一次还本 4-一次还本',
`principal` decimal(10, 2) NULL DEFAULT NULL COMMENT '本金',
`interest` decimal(10, 2) NULL DEFAULT NULL COMMENT '利息',
`total` decimal(10, 2) NULL DEFAULT NULL COMMENT '本息',
`fee` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '手续费',
`return_date` date NULL DEFAULT NULL COMMENT '还款时指定的还款日期',
`real_return_time` datetime(0) NULL DEFAULT NULL COMMENT '实际发生的还款时间',
`is_overdue` tinyint(1) NULL DEFAULT NULL COMMENT '是否逾期',
`overdue_total` decimal(10, 2) NULL DEFAULT NULL COMMENT '逾期金额',
`status` tinyint(3) NULL DEFAULT NULL COMMENT '状态(0-未归还 1-已归还)',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_lend_return_id`(`lend_return_id`) USING BTREE,
INDEX `idx_lend_item_id`(`lend_item_id`) USING BTREE,
INDEX `idx_lend_id`(`lend_id`) USING BTREE,
INDEX `idx_invest_user_id`(`invest_user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '标的出借回款记录表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of lend_item_return
-- ----------------------------
-- ----------------------------
-- Table structure for lend_return
-- ----------------------------
DROP TABLE IF EXISTS `lend_return`;
CREATE TABLE `lend_return` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`lend_id` bigint(20) NULL DEFAULT NULL COMMENT '标的id',
`borrow_info_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '借款信息id',
`return_no` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '还款批次号',
`user_id` bigint(20) NULL DEFAULT NULL COMMENT '借款人用户id',
`amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '借款金额',
`base_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '计息本金额',
`current_period` int(11) NULL DEFAULT NULL COMMENT '当前的期数',
`lend_year_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '年化利率',
`return_method` tinyint(3) NULL DEFAULT NULL COMMENT '还款方式 1-等额本息 2-等额本金 3-每月还息一次还本 4-一次还本',
`principal` decimal(10, 2) NULL DEFAULT NULL COMMENT '本金',
`interest` decimal(10, 2) NULL DEFAULT NULL COMMENT '利息',
`total` decimal(10, 2) NULL DEFAULT NULL COMMENT '本息',
`fee` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '手续费',
`return_date` date NULL DEFAULT NULL COMMENT '还款时指定的还款日期',
`real_return_time` datetime(0) NULL DEFAULT NULL COMMENT '实际发生的还款时间',
`is_overdue` tinyint(1) NULL DEFAULT NULL COMMENT '是否逾期',
`overdue_total` decimal(10, 2) NULL DEFAULT NULL COMMENT '逾期金额',
`is_last` tinyint(1) NULL DEFAULT NULL COMMENT '是否最后一次还款',
`status` tinyint(3) NULL DEFAULT NULL COMMENT '状态(0-未归还 1-已归还)',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_return_no`(`return_no`) USING BTREE,
INDEX `idx_lend_id`(`lend_id`) USING BTREE,
INDEX `idx_borrow_info_id`(`borrow_info_id`) USING BTREE,
INDEX `idx_user_id`(`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '还款记录表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of lend_return
-- ----------------------------
-- ----------------------------
-- Table structure for trans_flow
-- ----------------------------
DROP TABLE IF EXISTS `trans_flow`;
CREATE TABLE `trans_flow` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '用户id',
`user_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名称',
`trans_no` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '交易单号',
`trans_type` tinyint(3) NOT NULL DEFAULT 0 COMMENT '交易类型(1:充值 2:提现 3:投标 4:投资回款 ...)',
`trans_type_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '交易类型名称',
`trans_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '交易金额',
`memo` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_trans_no`(`trans_no`) USING BTREE,
INDEX `idx_user_id`(`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 57 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '交易流水表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of trans_flow
-- ----------------------------
-- ----------------------------
-- Table structure for user_account
-- ----------------------------
DROP TABLE IF EXISTS `user_account`;
CREATE TABLE `user_account` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '用户id',
`amount` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '帐户可用余额',
`freeze_amount` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '冻结金额',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
`version` int(11) NOT NULL DEFAULT 0 COMMENT '版本号',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_user_id`(`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户账户' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of user_account
-- ----------------------------
-- ----------------------------
-- Table structure for user_bind
-- ----------------------------
DROP TABLE IF EXISTS `user_bind`;
CREATE TABLE `user_bind` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '用户id',
`name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户姓名',
`id_card` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '身份证号',
`bank_no` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '银行卡号',
`bank_type` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '银行类型',
`mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '手机号',
`bind_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '绑定账户协议号',
`status` tinyint(3) NULL DEFAULT NULL COMMENT '状态',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_user_id`(`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户绑定表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of user_bind
-- ----------------------------
-- ----------------------------
-- Table structure for user_info
-- ----------------------------
DROP TABLE IF EXISTS `user_info`;
CREATE TABLE `user_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`user_type` tinyint(3) NOT NULL DEFAULT 0 COMMENT '1:出借人 2:借款人',
`mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '手机号',
`password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户密码',
`nick_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户昵称',
`name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户姓名',
`id_card` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '身份证号',
`email` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
`openid` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '微信用户标识openid',
`head_img` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '头像',
`bind_status` tinyint(3) NOT NULL DEFAULT 0 COMMENT '绑定状态(0:未绑定,1:绑定成功 -1:绑定失败)',
`borrow_auth_status` tinyint(3) NOT NULL DEFAULT 0 COMMENT '借款人认证状态(0:未认证 1:认证中 2:认证通过 -1:认证失败)',
`bind_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '绑定账户协议号',
`integral` int(11) NOT NULL DEFAULT 0 COMMENT '用户积分',
`status` tinyint(3) NOT NULL DEFAULT 1 COMMENT '状态(0:锁定 1:正常)',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
INDEX `uk_mobile`(`mobile`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户基本信息' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of user_info
-- ----------------------------
-- ----------------------------
-- Table structure for user_integral
-- ----------------------------
DROP TABLE IF EXISTS `user_integral`;
CREATE TABLE `user_integral` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户id',
`integral` int(11) NULL DEFAULT NULL COMMENT '积分',
`content` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '获取积分说明',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_user_id`(`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户积分记录表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of user_integral
-- ----------------------------
-- ----------------------------
-- Table structure for user_login_record
-- ----------------------------
DROP TABLE IF EXISTS `user_login_record`;
CREATE TABLE `user_login_record` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
`user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户id',
`ip` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'ip',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_user_id`(`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 29 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户登录记录表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of user_login_record
-- ----------------------------
SET FOREIGN_KEY_CHECKS = 1;
2、创建代码生成器
在test目录中创建测试用例,并执行
test目录下面新建包: com.atguigu.srb.core
然后新建生成类:
package com.atguigu.srb.core;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;
public class CodeGenerator {
@Test
public void genCode() {
// 1、创建代码生成器
AutoGenerator mpg = new AutoGenerator();
// 2、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("Helen");
gc.setOpen(false); //生成后是否打开资源管理器
gc.setServiceName("%sService"); //去掉Service接口的首字母I
gc.setIdType(IdType.AUTO); //主键策略
gc.setSwagger2(true);//开启Swagger2模式
mpg.setGlobalConfig(gc);
// 3、数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/srb_core?serverTimezone=GMT%2B8&characterEncoding=utf-8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
// 4、包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.atguigu.srb.core");
pc.setEntity("pojo.entity"); //此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
mpg.setPackageInfo(pc);
// 5、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
strategy.setEntityLombokModel(true); // lombok
strategy.setLogicDeleteFieldName("is_deleted");//逻辑删除字段名
strategy.setEntityBooleanColumnRemoveIsPrefix(true);//去掉布尔值的is_前缀(确保tinyint(1))
strategy.setRestControllerStyle(true); //restful api风格控制器
mpg.setStrategy(strategy);
// 6、执行
mpg.execute();
}
}
_105-配置并启动项目
一、启动应用程序
===========
1、创建application.yml
server:
port: 8110 # 服务端口
spring:
profiles:
active: dev # 环境设置
application:
name: service-core # 服务名
datasource: # mysql数据库连接
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/srb_core?serverTimezone=GMT%2B8&characterEncoding=utf-8
username: root
password: 123456
mybatis-plus: #mybatis
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:com/atguigu/srb/core/mapper/xml/*.xml
2、创建SpringBoot配置文件
在service-core中创建config包,创建MybatisPlusConfig类
package com.atguigu.srb.core.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@MapperScan("com.atguigu.srb.core.mapper")
@EnableTransactionManagement //事务处理
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//分页
return interceptor;
}
}
3、创建SpringBoot启动类
注意:扫描com.atguigu.srb
package com.atguigu.srb.core;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan({"com.atguigu.srb"})
public class ServiceCoreApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceCoreApplication.class, args);
}
}
4、运行启动类
查看控制台8110端口是否成功启动
让天下没有难学的技术
_106-积分列表接口的开发
一、积分等级列表接口
1、编写积分等级管理接口
在controller中添加admin包,添加AdminIntegralGradeController类
package com.atguigu.srb.core.controller.admin;
import com.atguigu.srb.core.pojo.entity.IntegralGrade;
import com.atguigu.srb.core.service.IntegralGradeService;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@CrossOrigin
@RestController
@RequestMapping("/admin/core/integralGrade")
public class AdminIntegralGradeController {
@Resource
private IntegralGradeService integralGradeService;
@GetMapping("/list")
public List<IntegralGrade> listAll(){
return integralGradeService.list();
}
}
2、测试
重启服务,访问: http://localhost:8110/admin/core/integralGrade/list 查看结果json数据
_107-删除接口的实现和使用postman测试
逻辑删除接口
1、添加删除方法
AdminIntegralGradeController添加removeById方法
@DeleteMapping("/remove/{id}")
public boolean removeById(@PathVariable Long id){
return integralGradeService.removeById(id);
}
2、使用postman测试删除
_108-配置和使用Swagger进行单元测试
1、Swagger2配置文件
在service-base中创建Swagger2Config
package com.atguigu.srb.base.config;
import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket adminApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("adminApi")
.apiInfo(adminApiInfo())
.select()
//只显示admin路径下的页面
.paths(Predicates.and(PathSelectors.regex("/admin/.*")))
.build();
}
private ApiInfo adminApiInfo(){
return new ApiInfoBuilder()
.title("尚融宝后台管理系统-API文档")
.description("本文档描述了尚融宝后台管理系统接口")
.version("1.0")
.contact(new Contact("Bliss", "http://atguigu.com", "55317332@qq.com"))
.build();
}
}
2、查看Swagger文档
重启服务器查看接口文档:http://localhost:8110/swagger-ui.html
_109-Swagger的常见注解
1、常见注解
**实体类注解:**entity的实体类中可以添加一些自定义设置,例如:
@ApiModelProperty(value = "创建时间", example = "2019-01-01 8:00:00")
private LocalDateTime createTime;
@ApiModelProperty(value = "更新时间", example = "2019-01-01 8:00:00")
private LocalDateTime updateTime;
controller注解:
定义在类上
@Api(tags = "积分等级管理")
定义在方法上
@ApiOperation("积分等级列表")
@ApiOperation(value = "根据id删除积分等级", notes = "逻辑删除")
定义在参数上
@ApiParam(value = "数据id", required = true, example = "100")
_110-Swagger的接口分组配置
修改 service-base 服务中的 Swagger2Config 配置文件
这里分了两个组: adminApi 和 webApi
package com.atguigu.srb.base.config;
import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket adminApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("adminApi")
.apiInfo(adminApiInfo())
.select()
//只显示admin路径下的页面
.paths(Predicates.and(PathSelectors.regex("/admin/.*")))
.build();
}
private ApiInfo adminApiInfo(){
return new ApiInfoBuilder()
.title("尚融宝后台管理系统-AdminAPI文档")
.description("本文档描述了尚融宝后台管理系统Admin接口")
.version("1.0")
.contact(new Contact("Bliss", "http://atguigu.com", "55317332@qq.com"))
.build();
}
@Bean
public Docket webApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("webApi")
.apiInfo(webApiInfo())
.select()
//只显示admin路径下的页面
.paths(Predicates.and(PathSelectors.regex("/api/.*")))
.build();
}
private ApiInfo webApiInfo(){
return new ApiInfoBuilder()
.title("尚融宝后台管理系统-WebAPI文档")
.description("本文档描述了尚融宝后台管理系统Web接口")
.version("1.0")
.contact(new Contact("Bliss", "http://atguigu.com", "55317332@qq.com"))
.build();
}
}
_111-Swagger文档描述信息的配置
上面已经加了 信息配置:adminApiInfo 和 webApiInfo 就是
_112-统一返回结果的定义和使用
1、数据格式的定义
项目中我们会将响应封装成json返回,一般我们会将所有接口的数据格式统一, 使前端对数据的操作更一致、轻松。
一般情况下,统一返回数据格式没有固定的格式,只要能描述清楚返回的数据状态以及要返回的具体数据就可以。但是一般会包含状态码、返回消息、数据这几部分内容
例如,我们的系统要求返回的基本数据格式如下:
成功:
{
"code": 0,
"message": "成功",
"data": 数据
}
失败:
{
"code": -1,
"message": "失败",
"data": null
}
因此,我们定义统一结果
{
"code": 数字, //业务响应码
"message": 字符串, //返回消息
"data": 对象 //返回数据
}
2、创建枚举
在guigu-common中创建result包,创建枚举 ResponseEnum
package com.atguigu.common.result;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
@Getter
@AllArgsConstructor
@ToString
public enum ResponseEnum {
SUCCESS(0, "成功"),
ERROR(-1, "服务器内部错误");
// 响应状态码
private Integer code;
// 响应信息
private String message;
}
3、定义同统一结果类
package com.atguigu.common.result;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public class R {
private Integer code;
private String message;
private Map<String, Object> data = new HashMap();
/**
* 构造器私有
*/
private R(){}
/**
* 返回成功
*/
public static R ok(){
R r = new R();
r.setCode(ResponseEnum.SUCCESS.getCode());
r.setMessage(ResponseEnum.SUCCESS.getMessage());
return r;
}
/**
* 返回失败
*/
public static R error(){
R r = new R();
r.setCode(ResponseEnum.ERROR.getCode());
r.setMessage(ResponseEnum.ERROR.getMessage());
return r;
}
/**
* 设置特定结果
*/
public static R setResult(ResponseEnum responseEnum){
R r = new R();
r.setCode(responseEnum.getCode());
r.setMessage(responseEnum.getMessage());
return r;
}
public R message(String message){
this.setMessage(message);
return this;
}
public R code(Integer code){
this.setCode(code);
return this;
}
public R data(String key, Object value){
this.data.put(key, value);
return this;
}
public R data(Map<String, Object> map){
this.setData(map);
return this;
}
}
4.使用统一返回结果
1.修改listAll
@ApiOperation("积分等级列表")
@GetMapping("/list")
public R listAll(){
List<IntegralGrade> list = integralGradeService.list();
return R.ok().data("list",list);
}
2.修改removeById
@ApiOperation(value = "根据id删除积分等级", notes = "逻辑删除")
@DeleteMapping("/remove/{id}")
public R removeById(@ApiParam(value = "数据id", required = true, example = "100") @PathVariable Long id){
boolean result = integralGradeService.removeById(id);
if (result){
return R.ok().message("删除成功");
}else {
return R.error().message("删除失败");
}
}
5.添加枚举
修改枚举类
package com.atguigu.common.result;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
@Getter
@AllArgsConstructor
@ToString
public enum ResponseEnum {
SUCCESS(0, "成功"),
ERROR(-1, "服务器内部错误"),
//-1xx 服务器错误
BAD_SQL_GRAMMAR_ERROR(-101, "sql语法错误"),
SERVLET_ERROR(-102, "servlet请求异常"), //-2xx 参数校验
UPLOAD_ERROR(-103, "文件上传错误"),
EXPORT_DATA_ERROR(104, "数据导出失败"),
//-2xx 参数校验
BORROW_AMOUNT_NULL_ERROR(-201, "借款额度不能为空"),
MOBILE_NULL_ERROR(-202, "手机号码不能为空"),
MOBILE_ERROR(-203, "手机号码不正确"),
PASSWORD_NULL_ERROR(204, "密码不能为空"),
CODE_NULL_ERROR(205, "验证码不能为空"),
CODE_ERROR(206, "验证码错误"),
MOBILE_EXIST_ERROR(207, "手机号已被注册"),
LOGIN_MOBILE_ERROR(208, "用户不存在"),
LOGIN_PASSWORD_ERROR(209, "密码错误"),
LOGIN_LOKED_ERROR(210, "用户被锁定"),
LOGIN_AUTH_ERROR(-211, "未登录"),
USER_BIND_IDCARD_EXIST_ERROR(-301, "身份证号码已绑定"),
USER_NO_BIND_ERROR(302, "用户未绑定"),
USER_NO_AMOUNT_ERROR(303, "用户信息未审核"),
USER_AMOUNT_LESS_ERROR(304, "您的借款额度不足"),
LEND_INVEST_ERROR(305, "当前状态无法投标"),
LEND_FULL_SCALE_ERROR(306, "已满标,无法投标"),
NOT_SUFFICIENT_FUNDS_ERROR(307, "余额不足,请充值"),
PAY_UNIFIEDORDER_ERROR(401, "统一下单错误"),
ALIYUN_SMS_LIMIT_CONTROL_ERROR(-502, "短信发送过于频繁"),//业务限流
ALIYUN_SMS_ERROR(-503, "短信发送失败"),//其他失败
WEIXIN_CALLBACK_PARAM_ERROR(-601, "回调参数不正确"),
WEIXIN_FETCH_ACCESSTOKEN_ERROR(-602, "获取access_token失败"),
WEIXIN_FETCH_USERINFO_ERROR(-603, "获取用户信息失败"),
;
// 响应状态码
private Integer code;
// 响应信息
private String message;
}
_113-统一返回结果的CRUD实现
继续在 service-core 服务 的 AdminIntegralGradeController 操作
1.新增数据
@ApiOperation("新增积分等级")
@PostMapping("/save")
public R save(
@ApiParam(value = "积分等级对象", required = true)
@RequestBody IntegralGrade integralGrade){
boolean result = integralGradeService.save(integralGrade);
if (result) {
return R.ok().message("保存成功");
} else {
return R.error().message("保存失败");
}
}
2.根据id查询
@ApiOperation("根据id获取积分等级")
@GetMapping("/get/{id}")
public R getById(
@ApiParam(value = "数据id", required = true, example = "1")
@PathVariable Long id
){
IntegralGrade integralGrade = integralGradeService.getById(id);
if(integralGrade != null){
return R.ok().data("record", integralGrade);
}else{
return R.error().message("数据不存在");
}
}
根据id修改
@ApiOperation("更新积分等级")
@PutMapping("/update")
public R updateById(
@ApiParam(value = "积分等级对象", required = true)
@RequestBody IntegralGrade integralGrade){
boolean result = integralGradeService.updateById(integralGrade);
if(result){
return R.ok().message("修改成功");
}else{
return R.error().message("修改失败");
}
}
_114-统一异常处理
统一异常处理
目标:我们想让异常结果也显示为统一的返回结果对象,并且统一处理系统的异常信息,那么需要进行统一异常处理。
创建统一异常处理器
guigu-common中创建exception包,创建统一异常处理器类UnifiedExceptionHandler
package com.atguigu.common.exception;
import com.atguigu.common.result.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @auth Baiqing Wu
* @create 2022-07-14 21:07
* @className com.atguigu.common.exception.UnifiedExceptionHandler
* @versions 1.0
*/
@Slf4j
@Component //Spring容易自动管理
@RestControllerAdvice //在controller层添加通知。如果使用@ControllerAdvice,则方法上需要添加@ResponseBody
public class UnifiedExceptionHandler {
/**
* 未定义异常
*/
@ExceptionHandler(value = Exception.class) //当controller中抛出Exception,则捕获
public R handleException(Exception e) {
log.error(e.getMessage(), e);
return R.error();
}
}
service-core 启动类添加扫描
添加 “com.atguigu.common”
package com.atguigu.srb.core;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan({"com.atguigu.srb", "com.atguigu.common"})
public class ServiceCoreApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceCoreApplication.class, args);
}
}
_115-处理特定异常
添加依赖
在guigu-common中添加jdbc依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
添加异常处理方法
在 UnifiedExceptionHandler 中添加
/**
* 特定异常
*/
@ExceptionHandler(BadSqlGrammarException.class)
public R handleBadSqlGrammarException(BadSqlGrammarException e){
log.error(e.getMessage(), e);
return R.setResult(ResponseEnum.BAD_SQL_GRAMMAR_ERROR);
}
测试,把 IntegralGrade 实体类的@TableField(“is_deleted”) 注解 注释
调用删除接口
_116-自定义异常处理方案
目标:使用一个或较少的异常类,可以捕获和显示所有的异常信息。
方案:因此,我们可以创建一个自定义异常类(必须是运行时异常),在程序中抛出这个自定义异常对象,并在统一异常处理器中捕获自定义异常对象
创建自定义异常类
package com.atguigu.common.exception;
import com.atguigu.common.result.ResponseEnum;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class BusinessException extends RuntimeException {
//状态码
private Integer code;
//错误消息
private String message;
/**
*
* @param message 错误消息
*/
public BusinessException(String message) {
this.message = message;
}
/**
*
* @param message 错误消息
* @param code 错误码
*/
public BusinessException(String message, Integer code) {
this.message = message;
this.code = code;
}
/**
*
* @param message 错误消息
* @param code 错误码
* @param cause 原始异常对象
*/
public BusinessException(String message, Integer code, Throwable cause) {
super(cause);
this.message = message;
this.code = code;
}
/**
*
* @param resultCodeEnum 接收枚举类型
*/
public BusinessException(ResponseEnum resultCodeEnum) {
this.message = resultCodeEnum.getMessage();
this.code = resultCodeEnum.getCode();
}
/**
*
* @param resultCodeEnum 接收枚举类型
* @param cause 原始异常对象
*/
public BusinessException(ResponseEnum resultCodeEnum, Throwable cause) {
super(cause);
this.message = resultCodeEnum.getMessage();
this.code = resultCodeEnum.getCode();
}
}
添加异常处理方法
在 UnifiedExceptionHandler 类中添加 下面这段代码
/**
* 自定义异常
*/
@ExceptionHandler(BusinessException.class)
public R handleBusinessException(BusinessException e){
log.error(e.getMessage(), e);
return R.error().message(e.getMessage()).code(e.getCode());
}
修改Controller
在AdminIntegralGradeController的方法中添加异常处理,业务中需要的位置抛出BusinessException自定义异常。
修改 save 方法:
@ApiOperation("新增积分等级")
@PostMapping("/save")
public R save(
@ApiParam(value = "积分等级对象", required = true)
@RequestBody IntegralGrade integralGrade){
//如果借款额度为空就手动抛出一个自定义的异常!
if(integralGrade.getBorrowAmount() == null){
//BORROW_AMOUNT_NULL_ERROR(-201, "借款额度不能为空"),
throw new BusinessException(ResponseEnum.BORROW_AMOUNT_NULL_ERROR);
}
boolean result = integralGradeService.save(integralGrade);
if (result) {
return R.ok().message("保存成功");
} else {
return R.error().message("保存失败");
}
}
测试 save 方法:故意不传借款额度
_117-异常处理优化,使用断言
目标:以优雅的 Assert(断言) 方式来校验业务的异常情况,消除 if else
什么是断言
在 service-core服务 的 test模块创建测试类
package com.atguigu.srb.core;
import org.junit.jupiter.api.Test;
import org.springframework.util.Assert;
/**
* @auth Baiqing Wu
* @create 2022-07-16 10:04
* @className com.atguigu.srb.core.AssertTests
* @versions 1.0
*/
public class AssertTests {
//if else的用法
@Test
public void test1() {
Object o = null;
if (o == null) {
throw new IllegalArgumentException("用户不存在.");
}
}
//断言的用法:更为简洁
@Test
public void test2() {
// 另一种写法
Object o = null;
Assert.notNull(o, "用户不存在.");
}
}
自定义断言
用断言的方式封装异常的抛出
在 guigu-common 服务模块中 com.atguigu.common.exception 下加入Assert类
package com.atguigu.common.exception;
import com.atguigu.common.result.ResponseEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
/**
* @auth Baiqing Wu
* @create 2022-07-16 10:09
* @className com.atguigu.common.exception.Assert
* @versions 1.0
*/
@Slf4j
public abstract class Assert {
/**
* 断言对象不为空
* 如果对象obj为空,则抛出异常
* @param obj 待判断对象
*/
public static void notNull(Object obj, ResponseEnum responseEnum) {
if (obj == null) {
log.info("obj is null...............");
throw new BusinessException(responseEnum);
}
}
/**
* 断言对象为空
* 如果对象obj不为空,则抛出异常
* @param object
* @param responseEnum
*/
public static void isNull(Object object, ResponseEnum responseEnum) {
if (object != null) {
log.info("obj is not null......");
throw new BusinessException(responseEnum);
}
}
/**
* 断言表达式为真
* 如果不为真,则抛出异常
*
* @param expression 是否成功
*/
public static void isTrue(boolean expression, ResponseEnum responseEnum) {
if (!expression) {
log.info("fail...............");
throw new BusinessException(responseEnum);
}
}
/**
* 断言两个对象不相等
* 如果相等,则抛出异常
* @param m1
* @param m2
* @param responseEnum
*/
public static void notEquals(Object m1, Object m2, ResponseEnum responseEnum) {
if (m1.equals(m2)) {
log.info("equals...............");
throw new BusinessException(responseEnum);
}
}
/**
* 断言两个对象相等
* 如果不相等,则抛出异常
* @param m1
* @param m2
* @param responseEnum
*/
public static void equals(Object m1, Object m2, ResponseEnum responseEnum) {
if (!m1.equals(m2)) {
log.info("not equals...............");
throw new BusinessException(responseEnum);
}
}
/**
* 断言参数不为空
* 如果为空,则抛出异常
* @param s
* @param responseEnum
*/
public static void notEmpty(String s, ResponseEnum responseEnum) {
if (StringUtils.isEmpty(s)) {
log.info("is empty...............");
throw new BusinessException(responseEnum);
}
}
}
修改controller
修改实体类 createTime、updateTime 字段加入注解
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新时间")
private LocalDateTime updateTime;
修改 AdminIntegralGradeController 的 save 接口
@ApiOperation("新增积分等级")
@PostMapping("/save")
public R save(
@ApiParam(value = "积分等级对象", required = true)
@RequestBody IntegralGrade integralGrade){
//如果借款额度为空就手动抛出一个自定义的异常!
//if(integralGrade.getBorrowAmount() == null){
// //BORROW_AMOUNT_NULL_ERROR(-201, "借款额度不能为空"),
// throw new BusinessException(ResponseEnum.BORROW_AMOUNT_NULL_ERROR);
//}
Assert.notNull(integralGrade.getBorrowAmount(), ResponseEnum.BORROW_AMOUNT_NULL_ERROR);
boolean result = integralGradeService.save(integralGrade);
if (result) {
return R.ok().message("保存成功");
} else {
return R.error().message("保存失败");
}
}
_118-Controller 上层异常
异常分类
对异常按阶段进行分类,大体可以分成:进入Controller前的异常 和 业务层异常,具体可以参考下图:
处理Controller上层异常
UnifiedExceptionHandler中 最下面添加:
/**
* Controller上一层相关异常
*/
@ExceptionHandler({
NoHandlerFoundException.class,
HttpRequestMethodNotSupportedException.class,
HttpMediaTypeNotSupportedException.class,
MissingPathVariableException.class,
MissingServletRequestParameterException.class,
TypeMismatchException.class,
HttpMessageNotReadableException.class,
HttpMessageNotWritableException.class,
MethodArgumentNotValidException.class,
HttpMediaTypeNotAcceptableException.class,
ServletRequestBindingException.class,
ConversionNotSupportedException.class,
MissingServletRequestPartException.class,
AsyncRequestTimeoutException.class
})
public R handleServletException(Exception e) {
log.error(e.getMessage(), e);
//SERVLET_ERROR(-102, "servlet请求异常"),
return R.error().message(ResponseEnum.SERVLET_ERROR.getMessage()).code(ResponseEnum.SERVLET_ERROR.getCode());
}
测试
在save测试用例中输入非法的json参数,则得到下面的结果。我们可以在控制台日志中查看具体的错误原因。前端只需要返回相对简单友好的提示即可。
_119-统一日志处理说明
日志级别
日志记录器(Logger)的行为是分等级的。如下表所示:
分为:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
默认情况下,spring boot从控制台打印出来的日志级别只有INFO及以上级别,可以配置日志级别
service-core 服务模块 yml 加入
# 设置日志级别
logging:
level:
root: ERROR
这种方式能将ERROR级别以及以上级别的日志输出到控制台上,其他级别将不会输出
创建日志文件
spring boot内部使用Logback作为日志实现的框架。
先删除前面在application.yml中的日志级别配置
resources 中创建 logback-spring.xml (默认日志文件的名字)
yml 注释
# 设置日志级别
#logging:
# level:
# root: ERROR
service-core 服务模块 resources 加入 logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
</configuration>
创建测试日志输出
将以下日志输出到任意controller的方法中即可,例如list方法中
AdminIntegralGradeController 上面 加入 @Slf4j 注解
@ApiOperation("积分等级列表")
@GetMapping("/list")
public R listAll(){
log.info("hi i'm helen");
log.warn("warning!!!");
log.error("it's a error");
List<IntegralGrade> list = integralGradeService.list();
return R.ok().data("list", list);
}
_120-logback日志的主要节点配置
logback-spring.xml 文件里面加入
configuration
日志配置的根节点
<configuration></configuration>
contextName
是的子节点。
每个logger都关联到logger上下文,默认上下文名称为“default”。但可以使用设置成其他名字,用于区分不同的应用程序。
<contextName>atguiguSrb</contextName>
property
< property> 是 < configuration> 的子节点,用来定义变量。
< property> 有两个属性,name和value:name的值是变量的名称,value是变量的值。
通过 < property> 定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。
<!-- 日志的输出目录-->
<property name="log.path" value="F:/前后端练习/尚融宝微服务/自己源码/srb_log/core"/>
<!--控制台日志格式:彩色日志-->
<!-- magenta:洋红 -->
<!-- boldMagenta:粗红-->
<!-- cyan:青色 -->
<!-- white:白色 -->
<!-- magenta:洋红 -->
<property name="CONSOLE_LOG_PATTERN"
value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) %highlight([%-5level]) %green(%logger) %msg%n"/>
<!--文件日志格式-->
<property name="FILE_LOG_PATTERN"
value="%date{yyyy-MM-dd HH:mm:ss} [%-5level] %thread %file:%line %logger %msg%n"/>
<!--编码-->
<property name="ENCODING"
value="UTF-8"/>
appender
< appender> 是 < configuration> 的子节点,是负责写日志的组件
< appender> 有两个必要属性name和class:name指定appender名称,class指定appender的全限定名
< encoder> 对日志进行格式化
< pattern> 定义日志的具体输出格式
< charset> 编码方式
控制台日志配置
<!-- 控制台日志-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
文件日志配置
< file> 表示日志文件的位置,如果上级目录不存在会自动创建,没有默认值。
< append> 默认 true,日志被追加到文件结尾,如果是 false,服务重启后清空现存文件。
<!-- 文件日志 -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${log.path}/log.log</file>
<append>true</append>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
logger
< logger> 可以是 < configuration> 的子节点,用来设置某一个包或具体某一个类的日志打印级别、指定
name:用来指定受此logger约束的某一个包或者具体的某一个类
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF。默认继承上级的级别
< logger> 可以包含零个或多个元素,标识这个appender将会添加到这个logger
<!-- 日志记录器 -->
<logger name="com.atguigu" level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</logger>
测试
测试日志记录的控制台输出、文件输出、以及日志级别
_121-日志的多环境配置
SpringProfile
在一个基于Spring boot开发的项目里,常常需要有多套环境的配置:开发,测试以及产品。使用springProfile 可以分别配置开发(dev),测试(test)以及生产(prod)等不同的环境
把日志记录器那个配置注释
<!-- 日志记录器 -->
<!-- <logger name="com.atguigu" level="INFO">-->
<!-- <appender-ref ref="CONSOLE" />-->
<!-- <appender-ref ref="FILE" />-->
<!-- </logger>-->
<!-- 开发环境和测试环境 -->
<springProfile name="dev,test">
<logger name="com.atguigu" level="INFO">
<appender-ref ref="CONSOLE"/>
</logger>
</springProfile>
<!-- 生产环境 -->
<springProfile name="prod">
<logger name="com.atguigu" level="ERROR">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</logger>
</springProfile>
_122-滚动日志的配置
问题:生产环境下,如果系统长时间运行,那么日志文件会变得越来越大,系统读取和写入日志的时间会越来越慢,严重的情况会耗尽系统内存,导致系统宕机。
解决方案:可以设置滚动日志。
设置时间滚动策略
RollingFileAppender是Appender的另一个实现,表示滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将旧日志备份到其他文件
< rollingPolicy> 是 < appender> 的子节点,用来定义滚动策略。
TimeBasedRollingPolicy:最常用的滚动策略,根据时间来制定滚动策略。
< fileNamePattern> :包含文件名及转换符, “%d”可以包含指定的时间格式,如:%d{yyyy-MM-dd}。如果直接使用 %d,默认格式是 yyyy-MM-dd。
< maxHistory> :可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,且**< maxHistory>**是6,则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除。
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 要区别于其他的appender中的文件名字 -->
<file>${log.path}/log-rolling.log</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
<!-- 设置滚动日志记录的滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.log</fileNamePattern>
<!--归档日志文件保留的最大数量-->
<maxHistory>15</maxHistory>
</rollingPolicy>
</appender>
修改 开发环境和测试环境 配置
<!-- 开发环境和测试环境 -->
<springProfile name="dev,test">
<logger name="com.atguigu" level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ROLLING_FILE"/>
</logger>
</springProfile>
设置触发滚动时机
放在 < rollingPolicy> 的子节点的位置,基于实践策略的触发滚动策略
< maxFileSize> 设置触发滚动条件:单个文件大于100M时生成新的文件
注意:修改日志文件名 此时 < fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1KB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
上面这个代码加到滚动日志里面,滚动日志配置完整如下:
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 要区别于其他的appender中的文件名字 -->
<file>${log.path}/log-rolling.log</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
<!-- 设置滚动日志记录的滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--归档日志文件保留的最大数量-->
<maxHistory>15</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1KB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
完整的日志配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<contextName>atguiguSrb</contextName>
<!-- 日志的输出目录-->
<property name="log.path" value="F:/前后端练习/尚融宝微服务/自己源码/srb_log/core"/>
<!--控制台日志格式:彩色日志-->
<!-- magenta:洋红 -->
<!-- boldMagenta:粗红-->
<!-- cyan:青色 -->
<!-- white:白色 -->
<!-- magenta:洋红 -->
<property name="CONSOLE_LOG_PATTERN"
value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) %highlight([%-5level]) %green(%logger) %msg%n"/>
<!--文件日志格式-->
<property name="FILE_LOG_PATTERN"
value="%date{yyyy-MM-dd HH:mm:ss} [%-5level] %thread %file:%line %logger %msg%n"/>
<!--编码-->
<property name="ENCODING"
value="UTF-8"/>
<!-- 控制台日志-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<!-- 文件日志 -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${log.path}/log.log</file>
<append>true</append>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
</appender>
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 要区别于其他的appender中的文件名字 -->
<file>${log.path}/log-rolling.log</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
<!-- 设置滚动日志记录的滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--归档日志文件保留的最大数量-->
<maxHistory>15</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1KB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- 日志记录器 -->
<!-- <logger name="com.atguigu" level="INFO">-->
<!-- <appender-ref ref="CONSOLE" />-->
<!-- <appender-ref ref="FILE" />-->
<!-- </logger>-->
<!-- 开发环境和测试环境 -->
<springProfile name="dev,test">
<logger name="com.atguigu" level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ROLLING_FILE"/>
</logger>
</springProfile>
<!-- 生产环境 -->
<springProfile name="prod">
<logger name="com.atguigu" level="ERROR">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</logger>
</springProfile>
</configuration>