Java项目【尚庭公寓】从0开始Java项目实战(一)
1. 项目介绍
1.1 项目业务概述
尚庭公寓是一个公寓租赁平台项目,包含移动端和后台管理系统
-
移动端:面向广大用户,提供找房、看房预约、租约管理等功能
-
后台管理系统:面向管理员,提供公寓(房源)管理、租赁管理、用户管理等功能。
下面分别介绍两端的具体业务功能。
1.2 移动端介绍
各功能模块具体内容如下
-
房源检索
用户可以使用这个功能来搜索和检索符合其需求的房源。他们可以根据不同的条件,如地理位置、租金范围、支付方式等,快速找到适合的房源。
-
看房预约管理
用户可以通过这个功能预约看房。他们可以选择合适的时间,预约在特定的公寓进行实地看房,以便更好地了解房源的情况和环境。
-
租约管理
这个功能允许用户查看和管理他们的租约信息。他们可以在移动端查看租约合同,以及提交租约终止或延长的请求。
-
房源浏览历史
用户可以在这里查看他们曾经浏览过的房源历史记录。这个功能可以帮助用户追踪之前感兴趣的房源,方便他们重新查看或做出决策。
1.3 后台管理系统
各功能模块具体内容如下
-
公寓信息管理
这个模块负责管理所有公寓的基本信息,包括公寓名称、地址、联系方式等。管理员可以在这里添加、编辑、删除公寓信息。
-
房间信息管理
该模块负责管理每个公寓内各个房间的详细信息,包括房间号、户型、面积、租金等。管理员可以在这里进行房间信息的添加、编辑和删除。
-
公寓/房间属性管理
这个模块允许管理员定义公寓和房间的各种属性,比如公寓和房间的配套设施,方便管理员在维护公寓信息和房间信息时进行选择。
-
看房预约管理
该模块用于管理用户的看房预约请求。用户可以在移动端提交看房预约,管理员可以在后台管理系统中查看和处理这些请求,以方便安排人员接待用户。
-
租约管理
这个模块用于管理租约的创建、修改和终止。管理员可以在这里生成租约合同,并发送给用户签约。
-
后台系统用户管理
该模块用于管理后台系统的用户账户信息,管理员可以创建、编辑、删除、禁用账户信息。
-
移动端用户管理
这个模块负责管理移动端用户的信息。管理员可以查看用户信息,处理账户相关问题。
1.4 核心业务流程
本项目的核心业务流程为签约、续约、退租,具体流程如下图所示
在上述的业务流程中,会涉及到租约状态的多次变化,下面详细介绍一下租约状态。租约共有7个状态,分别是签约待确认
、已签约
、已取消
、已到期
、退租待确认
、已退租
、续约待确认
,以下是这些状态的变化流程。
1.5 项目技术概述
本项目的技术架构如下图所示。
项目采用前后端分离的模式,下面介绍各模块用到的技术。
-
前端
- 框架:VUE3
-
后端
-
框架:Spring Boot
-
数据库访问:MyBatis、MyBatis Plus
MyBatis-Plus(简称 MP)是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
-
Web:Spring MVC
-
-
数据存储
-
关系型数据库:MySQL
-
缓存:Redis
-
对象存储:MinIO
MinIO是一个开源的对象存储方案,兼容亚马逊S3协议。
对于对象存储,我们可以选择直接购买各大云厂商提供的服务,也可以选择使用开源的服务,自行安装和维护。本项目采用开源的对象存储Minio来存储图片信息。
-
-
部署
- 前端服务器:Nginx
关于Nginx
Nginx是一个轻量级、高性能、稳定性高、并发性好的HTTP和反向代理服务器。也是由于其的特性,其应用非常广。
主要功能
-
反向代理
- 正向代理:某些情况下,代理我们用户去访问服务器,需要用户手动的设置代理服务器的ip和端口号。
- 反向代理:是用来代理服务器的,代理我们要访问的目标服务器。
- 代理服务器接受请求,然后将请求转发给内部网络的服务器(集群化),并将从服务器上得到的结果返回给客户端,此时代理服务器对外就表现为一个服务器。
- Nginx在反向代理上,提供灵活的功能,可以根据不同的正则采用不同的转发策略,如图设置好后不同的请求就可以走不同的服务器。
-
负载均衡
- 负载均衡:多在高并发情况下需要使用。其原理就是将数据流量分摊到多个服务器执行,减轻每台服务器的压力,多台服务器(集群)共同完成工作任务,从而提高了数据的吞吐量。
- Nginx可使用的负载均衡策略有:轮询(默认)、权重、ip_hash、url_hash(第三方)、fair(第三方)
-
动静分离
-
Nginx提供的动静分离是指把动态请求和静态请求分离开,合适的服务器处理相应的请求,使整个服务器系统的性能、效率更高。
-
Nginx可以根据配置对不同的请求做不同转发,这是动态分离的基础。静态请求对应的静态资源可以直接放在Nginx上做缓冲,更好的做法是放在相应的缓冲服务器上。动态请求由相应的后端服务器处理。
-
1.6 数据库设计
概念模型设计
根据原型可得,本项目包含的实体有公寓、房间、用户(租客)、租约(合同)、看房预约、浏览历史和后台管理系统用户,各实体间的关系如下
逻辑模型设计
根据原型明确各实体所需属性并明确各表关联字段,得到的完整的逻辑模型如下图所示。下面逐一分析。
公寓信息
公寓信息包含的属性有公寓名称
、公寓简介
、公寓地址
、公寓联系方式
、公寓图片
、公寓标签
、公寓杂费
、公寓发布状态
房间信息
房间信息包含的属性有房间号
、房间租金
、房间所属公寓
、房间可选租期
、房间可选支付方式
、房间属性
、房间标签
、房间配套
、房间图片
、房间发布状态
,这部分的逻辑模型如下图所示
用户信息
用户信息包含的属性有手机号码
、密码
、头像
、昵称
、账号状态
看房预约信息
看房预约包含的属性有预约用户信息
、预约公寓信息
、预约时间
、备注信息
、预约状态
,这部分的逻辑模型如下
租约信息
租约信息包含签约用户信息
,签约房间信息
、租期
、支付方式
、租约来源
、租金
、押金
,这部分的逻辑模型如下
浏览历史信息
浏览历史指的是用户浏览房间详情的历史,包含的属性有用户信息
、房间信息
、浏览时间
,这部分的逻辑模型如下
后台管理用户信息
后台管理系统用户包含的属性有,这部分的逻辑模型如下
物理模型设计
本项目采用MySQL数据库,所有表均使用InnoDB存储引擎,完整的物理模型如下图
注意:
- 所有表均省略了
create_time
、update_time
、is_deleted
三个字段。 - 所有的状态或类型字段(例如租约状态),均使用数字表示
2. 项目初始化准备
2.1 导入数据库
在MySQL中创建一个
lease
数据库,建库语句如下
CREATE DATABASE lease CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
导入数据库脚本,将资料中的
lease.sql
脚本导入lease
数据库,其中包含了建表语句和少量的原始数据。
2.2 创建工程
按照如下目录结构创建一个多模块的Maven工程。
lease
├── common(公共模块——工具类、公用配置等)
│ ├── pom.xml
│ └── src
├── model(数据模型——与数据库相对应地实体类)
│ ├── pom.xml
│ └── src
├── web(Web模块)
│ ├── pom.xml
│ ├── web-admin(后台管理系统Web模块——包含mapper、service、controller)
│ │ ├── pom.xml
│ │ └── src
│ └── web-app(移动端Web模块——包含mapper、service、controller)
│ ├── pom.xml
│ └── src
└── pom.xml
各模块的pom.xml文件内容如下:
-
根模块
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.demo</groupId> <artifactId>lease</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>common</module> <module>model</module> <module>web</module> </modules> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>
-
common模块
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.demo</groupId> <artifactId>lease</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>common</artifactId> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>
-
web模块
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.demo</groupId> <artifactId>lease</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>web</artifactId> <packaging>pom</packaging> <modules> <module>web-admin</module> <module>web-app</module> </modules> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.demo</groupId> <artifactId>model</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.demo</groupId> <artifactId>common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
-
web-admin模块
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.demo</groupId> <artifactId>web</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>web-admin</artifactId> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>
-
web-app模块
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.demo</groupId> <artifactId>web</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>web-app</artifactId> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>
2.3 项目初始配置
2.3.1 SpringBoot依赖配置
在父工程的pom.xml文件中增加如下内容 , 进行版本控制
注意:这里出现标红是正常现象,因为你的本地仓库找不到,暂时不需要管理,因为等到子模块使用的时候,再进行导入依赖
<!-- 继承Spring Boot父项目 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.5</version>
</parent>
<!-- 注意:直接替换pom文件中原有的properties -->
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
<swagger.version>2.9.2</swagger.version>
<jwt.version>0.11.2</jwt.version>
<easycaptcha.version>1.6.2</easycaptcha.version>
<minio.version>8.2.0</minio.version>
<knife4j.version>4.1.0</knife4j.version>
<aliyun.sms.version>2.0.23</aliyun.sms.version>
</properties>
<!--配置dependencyManagement统一管理依赖版本-->
<dependencyManagement>
<dependencies>
<!--mybatis-plus-->
<!--官方文档:https://baomidou.com/pages/bab2db/ -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!--knife4j文档-->
<!--官方文档:https://doc.xiaominfo.com/docs/quick-start -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!--JWT登录认证相关-->
<!--官方文档:https://github.com/jwtk/jjwt#install-jdk-maven -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<scope>runtime</scope>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<scope>runtime</scope>
<version>${jwt.version}</version>
</dependency>
<!--图形验证码-->
<!--官方文档:https://gitee.com/ele-admin/EasyCaptcha -->
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>${easycaptcha.version}</version>
</dependency>
<!--对象存储,用于存储图像等非结构化数据-->
<!--官方文档:https://min.io/docs/minio/linux/developers/minio-drivers.html?ref=docs#java-sdk -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
</dependency>
<!--阿里云短信客户端,用于发送短信验证码-->
<!--官方文档:https://help.aliyun.com/document_detail/215759.html?spm=a2c4g.215759.0.0.49f32807f4Yc0y -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>${aliyun.sms.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
在web模块的pom.xml文件中增加如下内容
- 依赖
<!--包含spring web相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--包含spring test相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
- 插件
<!-- Spring Boot Maven插件,用于打包可执行的JAR文件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.3.2 创建application.yml文件
在web-admin模块的
src/main/resources
目录下创建application.yml
配置文件,内容如下:
server:
port: 8080
2.3.3 创建SpringBoot启动类
在web-admin模块下创建
com.demo.lease.AdminWebApplication
类,内容如下:
@SpringBootApplication
public class AdminWebApplication {
public static void main(String[] args) {
SpringApplication.run(AdminWebApplication.class, args);
}
}
2.4 MyBatisPlus配置
Mybatis-Plus为公用工具,故将其配置于common模块。具体配置可参考其官方文档。
2.4.1 pom文件配置
在common模块的pom.xml文件中增加如下内容:
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
在model模块的pom.xml文件中增加如下内容,因为model模块下的实体类中需要配置Mybatis-Plus相关注解,故也需引入Mybatis-Plus依赖
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
2.4.2 application.yml配置
在web-admin模块的
application.yml
文件增加如下内容:
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://<hostname>:<port>/<database>?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2b8
username: <username>
password: <password>
hikari:
connection-test-query: SELECT 1 # 自动检测连接
connection-timeout: 60000 #数据库连接超时时间,默认30秒
idle-timeout: 500000 #空闲连接存活最大时间,默认600000(10分钟)
max-lifetime: 540000 #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
maximum-pool-size: 12 #连接池最大连接数,默认是10
minimum-idle: 10 #最小空闲连接数量
pool-name: SPHHikariPool # 连接池名称
#用于打印框架生成的sql语句,便于调试
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
注意:需根据实际情况修改hostname
、port
、database
、username
、password
。
2.4.3 配置扫包
在common模块下创建
com.demo.lease.common.mybatisplus.MybatisPlusConfiguration
类,内容如下:
@Configuration
@MapperScan("com.atguigu.lease.web.*.mapper")
public class MybatisPlusConfiguration {
}
注意:@MapperScan()
的包路径需要根据实际情况进行修改。
2.4.4 Knife4j配置
pom文件配置
在web模块的pom.xml文件添加如下内容
因为web-app模块同样需要Knife4j依赖,故在两个的父工程引入依赖即可
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
在model模块的pom.xml文件添加上述内容
因为model模块下的实体类需要配置Knife4j相关注解,故也需引入Knife4j依赖
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
配置类
后台管理系统和移动端的接口配置并不相同,所以需各自编写一个配置类。在web-admin模块下创建
com.atguigu.lease.web.admin.custom.config.Knife4jConfiguration
类,内容如下:
@Configuration
public class Knife4jConfiguration {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().info(
new Info()
.title("后台管理系统API")
.version("1.0")
.description("后台管理系统API"));
}
@Bean
public GroupedOpenApi systemAPI() {
return GroupedOpenApi.builder().group("系统信息管理").
pathsToMatch(
"/admin/system/**"
).
build();
}
@Bean
public GroupedOpenApi loginAPI() {
return GroupedOpenApi.builder().group("后台登录管理").
pathsToMatch(
"/admin/login/**",
"/admin/info"
).
build();
}
@Bean
public GroupedOpenApi apartmentAPI() {
return GroupedOpenApi.builder().group("公寓信息管理").
pathsToMatch(
"/admin/apartment/**",
"/admin/room/**",
"/admin/label/**",
"/admin/facility/**",
"/admin/fee/**",
"/admin/attr/**",
"/admin/payment/**",
"/admin/region/**",
"/admin/term/**",
"/admin/file/**"
).build();
}
@Bean
public GroupedOpenApi leaseAPI() {
return GroupedOpenApi.builder().group("租赁信息管理").
pathsToMatch(
"/admin/appointment/**",
"/admin/agreement/**"
).build();
}
@Bean
public GroupedOpenApi userAPI() {
return GroupedOpenApi.builder().group("平台用户管理").
pathsToMatch(
"/admin/user/**"
).build();
}
}
注意:pathsToMatch
参数需要根据实际情况进行配置。
2.4.5 生成或导入基础代码
在完成上述配置后,便可使用一些逆向工具自动生成基础代码了(例如实体类、mapper、service等),在使用Mybatis-Plus作为存储层框架时,推荐使用IDEA中的Mybatis X插件。除了可自动生成这些代码,也可直接导入资料中提供的代码。推荐大家直接导入。
导入的代码和目标位置如下:
导入代码 | 模块 | 包名/路径 | 说明 |
---|---|---|---|
实体类 | model | com.atguigu.lease.model.entity | 与数据库表一一对应 |
枚举类 | model | com.atguigu.lease.model.enums | 实体类中的某些状态类字段,使用枚举类型 |
mapper接口 | web-admin | com.atguigu.lease.web.admin.mapper | 略 |
mapper xml | web-admin | src/main/resources/mapper | 略 |
service | web-admin | com.atguigu.lease.web.admin.service | 略 |
serviceImpl | web-admin | com.atguigu.lease.web.admin.service.impl | 略 |
知识点:
-
实体类中的公共字段(例如
id
、create_time
、update_time
、is_deleted
)抽取到一个基类,进行统一管理,然后让各实体类继承该基类。 -
实体类中的状态字段(例如
status
)或类型字段(例如type
),全部使用枚举类型。状态(类型)字段,在数据库中通常用一个数字表示一个状态(类型)。例如:订单状态(1:待支付,2:待发货,3:待收货,4:已收货,5:已完结)。若实体类中对应的字段也用数字类型,例如
int
,那么程序中就会有大量的如下代码:order.setStatus(1); if (order.getStatus() == 1) { order.setStatus(2); }
这些代码后期维护起来会十分麻烦,所以本项目中所有的此类字段均使用枚举类型。例如上述订单状态可定义为以下枚举:
public enum Status { CANCEL(0, "已取消"), WAIT_PAY(1, "待支付"), WAIT_TRANSFER(2, "待发货"), WAIT_RECEIPT(3, "待收货"), RECEIVE(4, "已收货"), COMPLETE(5, "已完结"); private final Integer value; private final String desc; public Integer value() { return value; } public String desc() { return desc; } }
订单实体类中的状态字段定义为
Status
类型:@Data public class Order{ private Integer id; private Integer userId; private Status status; ... }
这样上述代码便可调整为如下效果,后期维护起来会容易许多。
order.setStatus(Status.WAIT_PAY);
-
所有的实体类均实现了
Serializable
接口,方便对实体对象进行缓存。 -
所有的
Mapper
接口均没有使用@Mapper
注解,而是使用@MapperScan
注解统一扫描。
2.4.6 导入接口定义代码
资料中提供了所有的Controller代码,并且Controller中定义好了每个接口(只有定义,没有实现),大家可直接导入接口定义相关的代码,然后只专注于接口逻辑的实现。
导入的代码和目标位置如下:
导入代码 | 模块 | 包名/路径 | 说明 |
---|---|---|---|
controller | web-admin | com.atguigu.lease.web.admin.controller | 略 |
vo | web-admin | com.atguigu.lease.web.admin.vo | View Object,用于封装或定义接口接受及返回的数据结构 |
result | common | com.atguigu.lease.common.result | 统一定义接口返回的数据结构 |
导入完成后,便可启动SpringBoot项目,并访问接口文档了,Knife4j文档的url为:http://localhost:8080/doc.html。
知识点:
-
vo(View Object):用于封装或定义接口接收及返回的数据的结构。
-
统一接口返回数据结构:为方便前端对接口数据进行处理,统一接口返回数据结构是一个良好的习惯。
以下是所有接口统一返回的数据结构
{ "code": 200, "message": "正常", "data": { "id": "1", "name": "zhangsan", "age": 10 } }
以下是与上述结构相对应的Java类
-
Result
@Data public class Result<T> { //返回码 private Integer code; //返回消息 private String message; //返回数据 private T data; public Result() { } private static <T> Result<T> build(T data) { Result<T> result = new Result<>(); if (data != null) result.setData(data); return result; } public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) { Result<T> result = build(body); result.setCode(resultCodeEnum.getCode()); result.setMessage(resultCodeEnum.getMessage()); return result; } public static <T> Result<T> ok(T data) { return build(data, ResultCodeEnum.SUCCESS); } public static <T> Result<T> ok() { return Result.ok(null); } public static <T> Result<T> fail() { return build(null, ResultCodeEnum.FAIL); } public static <T> Result<T> fail(Integer code, String message) { Result<T> result = build(null); result.setCode(code); result.setMessage(message); return result; } }
-
ResultCodeEnum
为方便管理,可将返回码
code
和返回消息message
封装到枚举类。@Getter public enum ResultCodeEnum { SUCCESS(200, "成功"), FAIL(201, "失败"), PARAM_ERROR(202, "参数不正确"), SERVICE_ERROR(203, "服务异常"), DATA_ERROR(204, "数据异常"), ILLEGAL_REQUEST(205, "非法请求"), REPEAT_SUBMIT(206, "重复提交"), DELETE_ERROR(207, "请先删除子集"), ADMIN_ACCOUNT_EXIST_ERROR(301, "账号已存在"), ADMIN_CAPTCHA_CODE_ERROR(302, "验证码错误"), ADMIN_CAPTCHA_CODE_EXPIRED(303, "验证码已过期"), ADMIN_CAPTCHA_CODE_NOT_FOUND(304, "未输入验证码"), ADMIN_LOGIN_AUTH(305, "未登陆"), ADMIN_ACCOUNT_NOT_EXIST_ERROR(306, "账号不存在"), ADMIN_ACCOUNT_ERROR(307, "用户名或密码错误"), ADMIN_ACCOUNT_DISABLED_ERROR(308, "该用户已被禁用"), ADMIN_ACCESS_FORBIDDEN(309, "无访问权限"), APP_LOGIN_AUTH(501, "未登陆"), APP_LOGIN_PHONE_EMPTY(502, "手机号码为空"), APP_LOGIN_CODE_EMPTY(503, "验证码为空"), APP_SEND_SMS_TOO_OFTEN(504, "验证法发送过于频繁"), APP_LOGIN_CODE_EXPIRED(505, "验证码已过期"), APP_LOGIN_CODE_ERROR(506, "验证码错误"), APP_ACCOUNT_DISABLED_ERROR(507, "该用户已被禁用"), TOKEN_EXPIRED(601, "token过期"), TOKEN_INVALID(602, "token非法"); private final Integer code; private final String message; ResultCodeEnum(Integer code, String message) { this.code = code; this.message = message; } }
注意:
由于
Result
和ResultCodeEnum
中使用@Data
、@Getter
注解,因此需要再common模块中引入lombok
依赖。<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
-