3.1 内容管理模块 - 工程搭建、课程查询、配置Swagger、数据字典

文章目录

  • 内容管理模块
  • 一、基础工程搭建
    • 1.1 需求分析
    • 1.2 业务流程
    • 1.3 数据模型
    • 1.4 创建模块工程
      • 1.4.1 介绍
      • 1.4.2 xuecheng-plus-content 聚合工程
      • 1.4.3 模块演示
  • 二、课程查询准备
    • 2.1 需求分析
      • 2.1.1 业务流程
      • 2.1.2 数据模型
    • 2.2 生成PO类
      • 2.2.1 新增Maven配置
      • 2.2.2 课程基本信息表
    • 2.3 接口设计分析
    • 2.4 创建模型类
      • 2.4.1 分页查询公用参数
      • 2.4.2 分页查询结果模型类
      • 2.4.2 查询条件模型类
    • 2.5 LocalDataTime工具类
  • 三、课程查询
    • 3.1Maven依赖
      • 3.1.1 api工程
      • 3.1.2 service工程
    • 3.2 课程查询Controller
    • 3.3 Service
    • 3.4 Mapper接口
      • 3.4.1 分页插件
      • 3.4.2 Mapper接口
    • 3.5 效果图
  • 四、api工程配置文件
    • 4.1 log4j2-dev.xml
    • 4.2 bootstrap.yml
  • 五、Swagger接口文档
    • 5.1 Maven坐标
    • 5.2 配置swagger
    • 5.3 添加接口说明
      • 5.3.1 @Api与@ApiOperation接口注释
      • 5.3.2 @ApiModel与@ApiModelProperty字段注释
      • 5.3.3 其他参数
  • 六、数据字典
    • 6.1 介绍
    • 6.2 创建工程
    • 6.3 Controller
    • 6.4 Service
    • 6.5 Mapper
    • 6.6 实体类
  • 七、解决Swagger报错

内容管理模块

在此模块完成课程及其相关内容管理

一、基础工程搭建

1.1 需求分析

内容管理系统(content management system,CMS),是一种位于WEB前端(Web 服务器)和后端办公系统或流程(内容创作、编辑)之间的软件系统。内容的创作人员、编辑人员、发布人员使用内容管理系统来提交、修改、审批、发布内容。这里指的“内容”可能包括文件、表格、图片、数据库中的数据甚至视频等一切你想要发布到Internet、Intranet以及Extranet网站的信息。

本项目作为一个大型的在线教育平台,其内容管理模块主要对课程及相关内容管理,包括:课程的基本信息、课程图片、课程师资信息、课程的授课计划、课程视频、课程文档等内容的管理。

1.2 业务流程

内容管理的业务由教学机构人员和平台的运营人员共同完成。

教学机构人员的业务流程如下

1、登录教学机构。

2、维护课程信息,添加一门课程需要编辑课程的基本信息、上传课程图片、课程营销信息、课程计划、上传课程视频、课程师资信息等内容。

3、课程信息编辑完成,通过课程预览确认无误后提交课程审核。

4、待运营人员对课程审核通过后方可进行课程发布。

运营人员的业务流程如下

1、查询待审核的课程信息。

2、审核课程信息。

3、提交审核结果。

下图是课程编辑与发布的整体流程。

img

1.3 数据模型

共设计到9张表

image-20231029210826042

1.4 创建模块工程

1.4.1 介绍

我们要创建的就是下面标红的内容管理模块

image-20231029211540123

本项目是一个前后端分离项目,前端与后端开发人员之间主要依据接口进行开发。

下图是前后端交互的流程图

1、前端请求后端服务提供的接口。(通常为http协议 )

2、后端服务的控制层Controller接收前端的请求。

3、Contorller层调用Service层进行业务处理。

4、Service层调用Dao持久层对数据持久化。

image-20231029211908225

对于一个Springcloud工程,对于此模块我们会单独创建一个Controller接口层工程xuecheng-plus-content-api,这个模块里面只是接口,这个工程会调用Service

xuecheng-plus-content-service模块式Service模块,处理业务逻辑

Controller工程调用Service工程时需要传输一些数据,而完成此传输功能的模块式xuecheng-plus-content-mode模块工程,里面都是一些传输对象

总结

xuecheng-plus-content-api:接口工程,为前端提供接口。

xuecheng-plus-content-service: 业务工程,为接口工程提供业务支撑。

xuecheng-plus-content-model: 数据模型工程,存储数据模型类、数据传输类型等。

image-20231029212238183

结合项目父工程、项目基础工程后

假如说我们以后部署jar包时,部署xuecheng-plus-content的jar包即可

xuecheng-plus-parent父工程会管理整个大项目的依赖

xuecheng-plus-content负责聚合xuecheng-plus-content-api、xuecheng-plus-content-service、xuecheng-plus-content-model,而且只负责模块的聚合

image-20231029212840781

1.4.2 xuecheng-plus-content 聚合工程

  • 首先在项目根目录创建内容管理模块的父工程xuecheng-plus-content

image-20231029214827080

image-20231029215219848

  1. 创建完成,只保留pom.xml文件,删除多余的文件

    image-20231029215423159

image-20231029214903484

  1. Maven坐标。内容管理父工程的主要职责是聚合内容管理接口和内容管理接口实现两个工程,它的父工程是xuecheng-plus-parent
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><artifactId>xuecheng-plus-parent</artifactId><groupId>com.xuecheng</groupId><version>0.0.1-SNAPSHOT</version><relativePath>../xuecheng-plus-parent</relativePath></parent><artifactId>xuecheng-plus-content</artifactId><name>xuecheng-plus-content</name><description>xuecheng-plus-content</description><packaging>pom</packaging><modules><module>xuecheng-plus-content-api</module><module>xuecheng-plus-content-model</module><module>xuecheng-plus-content-service</module></modules>
</project>
  • 在xuecheng-plus-content下创建xuecheng-plus-content-model数据模型工程

image-20231029215647710

  1. 创建完成,只保留包和pom.xml文件 ,删除多余的文件。

    比如删除启动类和配置文件

  2. 修改pom.xml文件

    我们在配置文件中并没有配置relativePath,因为此项目和父工程的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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><artifactId>xuecheng-plus-content</artifactId><groupId>com.xuecheng</groupId><version>0.0.1-SNAPSHOT</version></parent><artifactId>xuecheng-plus-content-model</artifactId><dependencies><dependency><groupId>com.xuecheng</groupId><artifactId>xuecheng-plus-base</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies></project>
  • 在xuecheng-plus-content下创建xuecheng-plus-content-service接口实现工程

    这个工程主要是写Service层和Mapper与数据库交互层

image-20231029220130200

  1. 创建完成,只保留包和pom.xml文件 ,删除多余的文件

    比如删除启动类和配置文件

  2. pom.xml如下:

    我们在配置文件中并没有配置relativePath,因为此项目和父工程的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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><artifactId>xuecheng-plus-content</artifactId><groupId>com.xuecheng</groupId><version>0.0.1-SNAPSHOT</version></parent><artifactId>xuecheng-plus-content-service</artifactId><dependencies><dependency><groupId>com.xuecheng</groupId><artifactId>xuecheng-plus-content-model</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies>
</project>
  • 在xuecheng-plus-content下创建xuecheng-plus-content-api接口工程

xuecheng-plus-content-api接口工程的父工程是xuecheng-plus-content,它依赖了xuecheng-plus-base基础工程

image-20231029220529121

  1. 编辑pom.xml

    我们在配置文件中并没有配置relativePath,因为此项目和父工程的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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><artifactId>xuecheng-plus-content</artifactId><groupId>com.xuecheng</groupId><version>0.0.1-SNAPSHOT</version></parent><artifactId>xuecheng-plus-content-api</artifactId><dependencies><dependency><groupId>com.xuecheng</groupId><artifactId>xuecheng-plus-content-service</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies></project>

1.4.3 模块演示

四个功能模块如下所示

image-20231029221637895

二、课程查询准备

2.1 需求分析

2.1.1 业务流程

课程查询的业务流程如下:

1、教学机构人员点击课程管理首先进入课程查询界面,如下:

image-20231029224218893

2.在课程进行列表查询页面输入查询条件查询课程信息

当不输入查询条件时输入全部课程信息。

输入查询条件查询符合条件的课程信息。

约束:本教学机构查询本机构的课程信息。

img

2.1.2 数据模型

下边从查询条件、查询列表两个方面分析数据模型

  • 查询条件

包括:课程名称、课程审核状态、课程发布状态

课程名称:可以模糊搜索

课程审核状态:未提交、已提交、审核通过、审核未通过

课程发布状态:未发布、已发布、已下线

因为是分页查询所以查询条件中还要包括当前页码、每页显示记录数。

  • 查询结果

查询结果中包括:课程id、课程名称、任务数、创建时间、是否付费、审核状态、类型,操作

任务数:该课程所包含的课程计划数,即课程章节数。

是否付费:课程包括免费、收费两种。

类型:录播、直播。

因为是分页查询所以查询结果中还要包括总记录数、当前页、每页显示记录数。

2.2 生成PO类

PO即持久对象(Persistent Object),它们是由一组属性和属性的get和set方法组成,PO对应于数据库的表

我们对应的这些类应该添加在xuecheng-plus-content-model工程中

2.2.1 新增Maven配置

xuecheng-plus-content-model模块引入mybatis的核心包和注解包,保证代码不出错即可,不用将Mybatis的包全部引进来

<!--存在mybatisplus注解添加相关注解保证不报错--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-annotation</artifactId><version>${mybatis-plus-boot-starter.version}</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-core</artifactId><version>${mybatis-plus-boot-starter.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>

2.2.2 课程基本信息表

image-20231029231721091

/*** <p>* 课程基本信息* </p>*/
@Data
@TableName("course_base")
public class CourseBase implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 机构ID*/private Long companyId;/*** 机构名称*/private String companyName;/*** 课程名称*/private String name;/*** 适用人群*/private String users;/*** 课程标签*/private String tags;/*** 大分类*/private String mt;/*** 小分类*/private String st;/*** 课程等级*/private String grade;/*** 教育模式(common普通,record 录播,live直播等)*/private String teachmode;/*** 课程介绍*/private String description;/*** 课程图片*/private String pic;/*** 创建时间*/@TableField(fill = FieldFill.INSERT)private LocalDateTime createDate;/*** 修改时间*/@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime changeDate;/*** 创建人*/private String createPeople;/*** 更新人*/private String changePeople;/*** 审核状态*/private String auditStatus;/*** 课程发布状态 未发布  已发布 下线*/private String status;}

2.3 接口设计分析

设计一个接口需要包括以下几个方面

  • 协议

通常协议采用HTTP,查询类接口通常为get或post,查询条件较少的使用get,较多的使用post。

本接口使用 http post。

还要确定content-type,参数以什么数据格式提交,结果以什么数据格式响应。

一般情况没有特殊情况结果以json 格式响应。

  • 分析请求参数

根据前边对数据模型的分析,请求参数为:课程名称、课程审核状态、当前页码、每页显示记录数。

根据分析的请求参数定义模型类。

  • 分析响应结果

根据前边对数据模型的分析,响应结果为数据列表加一些分页信息(总记录数、当前页、每页显示记录数)。

数据列表中数据的属性包括:课程id、课程名称、任务数、创建时间、审核状态、类型。

注意查询结果中的审核状态为数据字典中的代码字段,前端会根据审核状态代码 找到对应的名称显示

根据分析的响应结果定义模型类。

  • 分析完成,使用SpringBoot注解开发一个Http接口

  • 使用接口文档工具查看接口的内容

  • 接口中调用Service方法完成业务处理

2.4 创建模型类

2.4.1 分页查询公用参数

据接口分析需要定义模型类接收请求的参数,并定义模型类用于响应结果

这些一般是公共使用的,所以放在xuecheng-plus-base工程中

/*** @description 分页查询通用参数*/
@Data
@ToString
public class PageParams {//当前页码private Long pageNo = 1L;//每页记录数默认值private Long pageSize =10L;public PageParams(){}public PageParams(long pageNo,long pageSize){this.pageNo = pageNo;this.pageSize = pageSize;}}

2.4.2 分页查询结果模型类

针对分页查询结果经过分析也存在固定的数据和格式,所以在base工程定义一个基础的模型类

据接口分析需要定义模型类接收请求的参数,并定义模型类用于响应结果

这些一般是公共使用的,所以放在xuecheng-plus-base工程中

/*** @description 分页查询结果模型类*/
@Data
@ToString
public class PageResult<T> implements Serializable {// 数据列表private List<T> items;//总记录数private long counts;//当前页码private long page;//每页记录数private long pageSize;public PageResult(List<T> items, long counts, long page, long pageSize) {this.items = items;this.counts = counts;this.page = page;this.pageSize = pageSize;}}

2.4.2 查询条件模型类

这个类只有在是在xuecheng-plus-content工程模块中使用,所以我们把下面这个类添加在xuecheng-plus-content-model模块即可

/*** @description 课程查询参数Dto*/@Data@ToString
public class QueryCourseParamsDto {//审核状态private String auditStatus;//课程名称private String courseName;//发布状态private String publishStatus;}

2.5 LocalDataTime工具类

不管在前端向后端传输时间相关参数,还是后端向前端响应参数,时间格式都是如下所示:

image-20231030232503171

为了解决上面默认的时间格式,我们在xuecheng-plus-base工程中添加如下所示配置类

@Configuration
public class LocalDateTimeConfig {/** 序列化内容*   LocalDateTime -> String* 服务端返回给客户端内容* */@Beanpublic LocalDateTimeSerializer localDateTimeSerializer() {return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));}/** 反序列化内容*   String -> LocalDateTime* 客户端传入服务端数据* */@Beanpublic LocalDateTimeDeserializer localDateTimeDeserializer() {return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));}// 配置@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {return builder -> {builder.serializerByType(LocalDateTime.class, localDateTimeSerializer());builder.deserializerByType(LocalDateTime.class, localDateTimeDeserializer());};}}

三、课程查询

3.1Maven依赖

3.1.1 api工程

<dependencies><dependency><groupId>com.xuecheng</groupId><artifactId>xuecheng-plus-content-service</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!--cloud的基础环境包--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-context</artifactId></dependency><!-- Spring Boot 的 Spring Web MVC 集成 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 排除 Spring Boot 依赖的日志包冲突 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><!-- Spring Boot 集成 log4j2 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><!-- Spring Boot 集成 swagger --><dependency><groupId>com.spring4all</groupId><artifactId>swagger-spring-boot-starter</artifactId><version>1.9.0.RELEASE</version></dependency></dependencies>

3.1.2 service工程

<dependencies><dependency><groupId>com.xuecheng</groupId><artifactId>xuecheng-plus-content-model</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!-- MySQL 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- mybatis plus的依赖 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-context</artifactId></dependency><!-- Spring Boot 集成 Junit --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 排除 Spring Boot 依赖的日志包冲突 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!-- Spring Boot 集成 log4j2 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency></dependencies>

3.2 课程查询Controller

我们定义的接口要写在xuecheng-plus-content-api工程中

接口描述图

PageParams对象接收pageNo字段和pageSize字段

QueryCourseParamsDto对象接收请求体中的auditStatus审核状态字段,courseName课程名称字段,publishStatus发布状态字段

image-20231030213209269

/*** 课程内容管理*/
@Api(value = "课程信息编辑接口",tags = "课程信息编辑接口")
@Slf4j
@RequestMapping
@RestController //@Controller+@Response
public class CourseBaseInfoController {@Autowiredprivate CourseBaseInfoService courseBaseInfoService;/*** 课程分页查询接口** @RequestBody(required = false) 含义:不传QueryCourseParamsDto请求体也行** @param pageParams           pageNo字段和pageSize字段* @param queryCourseParamsDto auditStatus审核状态字段,courseName课程名称字段,publishStatus发布状态字段* @return 分页结果*/@ApiOperation("课程查询接口")@PostMapping("/course/list")public PageResult<CourseBase> list(PageParams pageParams, @RequestBody(required = false) QueryCourseParamsDto queryCourseParamsDto) {PageResult<CourseBase> pageResult = courseBaseInfoService.queryCourseBaseList(pageParams, queryCourseParamsDto);return pageResult;}}

3.3 Service

在xuecheng-plus-content-service层

/*** 课程信息管理业务接口实现类*/
@Service
public class CourseBaseInfoServiceImpl implements CourseBaseInfoService {@AutowiredCourseBaseMapper courseBaseMapper;@Overridepublic PageResult<CourseBase> queryCourseBaseList(PageParams pageParams, QueryCourseParamsDto queryCourseParamsDto) {//构建查询条件对象LambdaQueryWrapper<CourseBase> queryWrapper = new LambdaQueryWrapper<>();//构建查询条件,根据课程名称查询queryWrapper.like(StringUtils.isNotEmpty(queryCourseParamsDto.getCourseName()), CourseBase::getName, queryCourseParamsDto.getCourseName());//构建查询条件,根据课程审核状态查询queryWrapper.eq(StringUtils.isNotEmpty(queryCourseParamsDto.getAuditStatus()), CourseBase::getAuditStatus, queryCourseParamsDto.getAuditStatus());//构建查询条件,根据课程发布状态查询queryWrapper.eq(StringUtils.isNotEmpty(queryCourseParamsDto.getPublishStatus()), CourseBase::getStatus, queryCourseParamsDto.getPublishStatus());//分页对象Page<CourseBase> page = new Page<>(pageParams.getPageNo(), pageParams.getPageSize());// 查询数据内容获得结果Page<CourseBase> pageResult = courseBaseMapper.selectPage(page, queryWrapper);// 获取数据列表List<CourseBase> list = pageResult.getRecords();// 获取数据总数long total = pageResult.getTotal();// 构建结果集PageResult<CourseBase> courseBasePageResult = new PageResult<>(list, total, pageParams.getPageNo(), pageParams.getPageSize());return courseBasePageResult;}
}

3.4 Mapper接口

在xuecheng-plus-content-service层,不在model层

我们要实现课程查询的功能

3.4.1 分页插件

/*** <P>*        Mybatis-Plus 配置* </p>*/
@Configuration
@MapperScan("com.xuecheng.content.mapper")//不加这个配置,后面可能会报错
public class MybatisPlusConfig {/*** 定义分页拦截器*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}}

分页插件的原理

首先分页参数放到ThreadLocal中,拦截执行的sql,根据数据库类型添加对应的分页语句重写sql,例如:(select * from table where a) 转换为 (select count(*) from table where a)和(select * from table where a limit ,)

计算出了total总条数、pageNum当前第几页、pageSize每页大小和当前页的数据,是否为首页,是否为尾页,总页数等。

3.4.2 Mapper接口

public interface CourseBaseMapper extends BaseMapper<CourseBase> {}

3.5 效果图

image-20231101235720152

四、api工程配置文件

4.1 log4j2-dev.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="180" packages=""><properties><property name="logdir">logs</property><property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property></properties><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="${PATTERN}"/></Console><RollingFile name="ErrorAppender" fileName="${logdir}/error.log"filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true"><PatternLayout pattern="${PATTERN}"/><ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/><Policies><TimeBasedTriggeringPolicy interval="1" modulate="true" /></Policies></RollingFile><RollingFile name="DebugAppender" fileName="${logdir}/info.log"filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true"><PatternLayout pattern="${PATTERN}"/><ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/><Policies><TimeBasedTriggeringPolicy interval="1" modulate="true" /></Policies></RollingFile><!--异步appender--><Async name="AsyncAppender" includeLocation="true"><AppenderRef ref="ErrorAppender"/><AppenderRef ref="DebugAppender"/></Async></Appenders><Loggers><!--过滤掉spring和mybatis的一些无用的debug信息<logger name="org.springframework" level="INFO"></logger><logger name="org.mybatis" level="INFO"></logger>--><logger name="cn.itcast.wanxinp2p.consumer.mapper" level="DEBUG"></logger><logger name="springfox" level="INFO"></logger><logger name="org.apache.http" level="INFO"></logger><logger name="com.netflix.discovery" level="INFO"></logger><logger name="RocketmqCommon"  level="INFO" ></logger><logger name="RocketmqRemoting" level="INFO"  ></logger><logger name="RocketmqClient" level="WARN"></logger><logger name="org.dromara.hmily" level="WARN"></logger><logger name="org.dromara.hmily.lottery" level="WARN"></logger><logger name="org.dromara.hmily.bonuspoint" level="WARN"></logger><!--OFF   0--><!--FATAL   100--><!--ERROR   200--><!--WARN   300--><!--INFO   400--><!--DEBUG   500--><!--TRACE   600--><!--ALL   Integer.MAX_VALUE--><Root level="DEBUG" includeLocation="true"><AppenderRef ref="AsyncAppender"/><AppenderRef ref="Console"/><AppenderRef ref="DebugAppender"/></Root></Loggers>
</Configuration>

4.2 bootstrap.yml

下面的文件是springcloud识别出来的文件

server:servlet:context-path: /contentport: 63040
#微服务配置
spring:application:name: content-apidatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.101.65:3306/xcplus_content?serverTimezone=UTC&userUnicode=true&useSSL=false&username: rootpassword: mysql
# 日志文件配置路径
logging:config: classpath:log4j2-dev.xml

五、Swagger接口文档

这是之前在Springboot学习的swaggerSpringboot集成Swagger_springboot项目集成swagger

在前后端分离开发中通常由后端程序员设计接口,完成后需要编写接口文档,最后将文档交给前端工程师,前端工程师参考文档进行开发

可以通过Swagger工具快速生成接口文档

5.1 Maven坐标

添加到内容管理api工程

<!-- Spring Boot 集成 swagger -->
<dependency><groupId>com.spring4all</groupId><artifactId>swagger-spring-boot-starter</artifactId><version>1.9.0.RELEASE</version></dependency>

5.2 配置swagger

在 bootstrap.yml中配置swagger的扫描包路径及其它信息,base-package为扫描的包路径,扫描Controller类

swagger:title: "学成在线内容管理系统"description: "内容系统管理系统对课程相关信息进行管理"base-package: com.xuecheng.contentenabled: trueversion: 1.0.0

在启动类中添加@EnableSwagger2Doc注解

@EnableSwagger2Doc
@SpringBootApplication
public class ContentApplication {public static void main(String[] args) {SpringApplication.run(ContentApplication.class, args);}}

工程启动起来,访问http://localhost:63040/content/swagger-ui.html

image-20231030225305069

这个文档存在两个问题:

1、接口名称显示course-base-info-controller名称不直观

2、课程查询是post方式只显示post /course/list即可。

5.3 添加接口说明

这是之前在Springboot学习的swaggerSpringboot集成Swagger_springboot项目集成swagger

5.3.1 @Api与@ApiOperation接口注释

/*** 课程内容管理*/
@Api(value = "课程信息编辑接口",tags = "课程信息编辑接口")
@Slf4j
@RequestMapping
@RestController //@Controller+@Response
public class CourseBaseInfoController {/*** 课程分页查询接口** @RequestBody(required = false) 含义:不传QueryCourseParamsDto请求体也行** @param pageParams           pageNo字段和pageSize字段* @param queryCourseParamsDto auditStatus审核状态字段,courseName课程名称字段,publishStatus发布状态字段* @return 分页结果*/@ApiOperation("课程查询接口")@PostMapping("/course/list")public PageResult<CourseBase> list(PageParams pageParams, @RequestBody(required = false) QueryCourseParamsDto queryCourseParamsDto) {return null;}}

再次启动服务,工程启动起来,访问http://localhost:63040/content/swagger-ui.html查看接口信息

image-20231030225842129

5.3.2 @ApiModel与@ApiModelProperty字段注释

@ApiModel注解与@ApiModelProperty注解

@ApiModel("分页查询通用参数")
@Data
@ToString
public class PageParams {//当前页码@ApiModelProperty("当前页码")private Long pageNo = 1L;//每页记录数默认值@ApiModelProperty("每页记录数默认值")private Long pageSize =10L;public PageParams(){}public PageParams(long pageNo,long pageSize){this.pageNo = pageNo;this.pageSize = pageSize;}}
/*** @description 课程查询参数Dto*/
@Data
@ApiModel("课程查询参数Dto")
@ToString
public class QueryCourseParamsDto {//审核状态@ApiModelProperty("审核状态")private String auditStatus;//课程名称@ApiModelProperty("课程名称")private String courseName;//发布状态@ApiModelProperty("发布状态")private String publishStatus;}

再次启动服务,工程启动起来,访问http://localhost:63040/content/swagger-ui.html查看接口信息

5.3.3 其他参数

@Api:修饰整个类,描述Controller的作用

@ApiOperation:描述一个类的一个方法,或者说一个接口

@ApiParam:单个参数描述

@ApiModel:用对象来接收参数

@ApiModelProperty:用对象接收参数时,描述对象的一个字段

@ApiResponse:HTTP响应其中1个描述

@ApiResponses:HTTP响应整体描述

@ApiIgnore:使用该注解忽略这个API

@ApiError :发生错误返回的信息

@ApiImplicitParam:一个请求参数

@ApiImplicitParams:多个请求参数


@ApiImplicitParam属性如下

属性取值作用
paramType查询参数类型
path以地址的形式提交数据
query直接跟参数完成自动映射赋值
body以流的形式提交 仅支持POST
header参数在request headers 里边提交
form以form表单的形式提交 仅支持POST
dataType参数的数据类型 只作为标志说明,并没有实际验证
Long
String
name接收参数名
value接收参数的意义描述
required参数是否必填
true必填
false非必填
defaultValue默认值

六、数据字典

6.1 介绍

审核状态在查询条件和查询结果中都存在,审核状态包括:未审核、审核通过、审核未通过三种

思考一个问题:一个课程的审核状态如果是“审核未通过”那么在课程基本信息表记录“审核未通过”三个字合适吗

如下图所示,合适嘛?

显然是不合适的,万一客户要求把“审核未通过”改成“通过”呢?我们要通过update修改,但是入了库的数据再修改会存在一定的风险,就算成功修改了,那以后客户在要求修改呢?

image-20231031224641775

和审核状态同类的有好多这样的信息,比如:课程状态、课程类型、用户类型等等,这一类数据有一个共同点就是它有一些分类项,且这些分类项较为固定

针对这些数据,为了提高系统的可扩展性,专门定义数据字典表去维护

image-20231031225148581

比如课程审核是否通过

[{"code":"202001","desc":"审核未通过"},{"code":"202002","desc":"未提交"},{"code":"202003","desc":"已提交"},{"code":"202004","desc":"审核通过"}]

image-20231031225247347

比如课程发布情况

[{"code":"203001","desc":"未发布"},{"code":"203002","desc":"已发布"},{"code":"203003","desc":"下线"}]

image-20231031225530355

而在我们课程表中会有两个字段与之对应

image-20231031225705184

image-20231031225721109

6.2 创建工程

与之前一样,创建工程

image-20231101224223002

6.3 Controller

@Slf4j
@RestController
public class DictionaryController  {@Autowiredprivate DictionaryService  dictionaryService;//查询数据字典的所有内容@GetMapping("/dictionary/all")public List<Dictionary> queryAll() {return dictionaryService.queryAll();}//查询数据字典代码查询数据字典@GetMapping("/dictionary/code/{code}")public Dictionary getByCode(@PathVariable String code) {return dictionaryService.getByCode(code);}
}

6.4 Service

@Slf4j
@Service
public class DictionaryServiceImpl extends ServiceImpl<DictionaryMapper, Dictionary> implements DictionaryService {@Overridepublic List<Dictionary> queryAll() {List<Dictionary> list = this.list();return list;}@Overridepublic Dictionary getByCode(String code) {LambdaQueryWrapper<Dictionary> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Dictionary::getCode, code);Dictionary dictionary = this.getOne(queryWrapper);return dictionary;}
}

6.5 Mapper

public interface DictionaryMapper extends BaseMapper<Dictionary> {}

6.6 实体类

@Data
@TableName("dictionary")
public class Dictionary implements Serializable {private static final long serialVersionUID = 1L;/*** id标识*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 数据字典名称*/private String name;/*** 数据字典代码*/private String code;/*** 数据字典项--json格式[{"sd_name": "低级","sd_id": "200001","sd_status": "1"}, {"sd_name": "中级","sd_id": "200002","sd_status": "1"}, {"sd_name": "高级","sd_id": "200003","sd_status": "1"}]*/private String itemValues;}

七、解决Swagger报错

swagger2报错Illegal DefaultValue null for parameter type integer…

虽然是报错了,但是并不影响swagger功能的使用,但是每次刷新swagger控制台就会报这个错误,看着控制台的异常比较难受,便搜索了一下

百度的原因是说swagger2官方有bug,下面是解决方法

用到swagger的地方可以酌情的复制下面的坐标或继承

<dependency><groupId>com.spring4all</groupId><artifactId>swagger-spring-boot-starter</artifactId><version>${swagger-spring-boot-starter.version}</version><exclusions><exclusion><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId></exclusion><exclusion><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId></exclusion></exclusions>
</dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId><version>${swagger-annotations.version}</version>
</dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version>
</dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId><version>1.5.22</version>
</dependency>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/221136.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dokit 开源库:简化 Android 应用开发的利器

Dokit 开源库&#xff1a;简化 Android 应用开发的利器 一、Dokit 简介二、Dokit 功能三、Dokit 使用3.1 DoKit Android 最新版本3.2 DoKit Android 接入步骤 四、总结 在 Android 应用开发过程中&#xff0c;我们经常需要处理调试、性能优化和用户体验等方面的问题。然而&…

最新全网整理的7个最佳开源免费库存/仓库管理系统(WMS)都具有高星star

最新全网整理的7个最佳开源免费库存/仓库管理系统&#xff08;WMS)都具有高星star。 库存/仓库管理软件是一种用于帮助企业管理库存、仓储位置和交付过程的软件系统。这种类型的软件对于拥有大量库存和多个仓库的企业非常有用。 库存/仓库管理软件的作用包括以下几个方面&…

竞赛保研 python的搜索引擎系统设计与实现

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python的搜索引擎系统设计与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;5分创新点&#xff1a;3分 该项目较为新颖&#xff…

优维科技荣获第二届中国赛宝信息技术应用创新优秀解决方案三等奖

近日&#xff0c;“第二届中国赛宝信息技术应用创新优秀解决方案”评选活动圆满结束。优维科技所提交的《Hyperlnsight超融合持续观测解决方案》、《EasyOps一体化运维平台》从全国近300份申报方案中脱颖而出&#xff0c;荣获2023中国赛宝信息技术应用创新优秀解决方案奖。 本…

SQL Server 安装教程

安装数据库 1、启动SQL Server2014安装程序&#xff0c;运行setup.exe文件&#xff0c;打开”SQL Server安装中心“对话框&#xff0c;单击左侧 的导航区域中的”安装“选项卡。 2、选择”全新SQL Server独立安装或向现有安装添加功能“&#xff0c;启动SQL Server2014安装向导…

基于Spring Boot 框架的试卷自动生成系统的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题&#xff0c;今天给大家介绍…

SpringBoot actuator应用监控

文章目录 引入依赖端点(Endpoints)端点种类端点开启配置暴露端点手动暴露端点 端点保护引入spring security依赖配置security 端点响应缓存访问端点路径修改CORS跨域支持健康信息(/actuator/health)自定义healthInfo 应用信息(/actuator/info) 监控信息可视化引入依赖配置查看配…

Kioptrix-1

信息收集 # nmap -sn 192.168.1.0/24 -oN live.nmap Starting Nmap 7.94 ( https://nmap.org ) at 2023-12-18 20:02 CST Nmap scan report for 192.168.1.1 (192.168.1.1) Host is up (0.00025s latency). MAC Address: 00:50:56:C0:00:08 (VMware) Nmap scan report for 0bc…

C语言中的一维数组与二维数组

目录 一维数组数组的创建初始化使用在内存中的存储 二维数组创建初始化使用在内存中的存储 数组越界 一维数组 数组的创建 数组是一组相同类型元素的集合。 int arr1[10]; char arr3[10]; float arr4[10]; double arr5[10];下面这个数组能否成功创建&#xff1f; int count…

k8s-ingress特性 9

TLS加密 创建证书 测试访问 auth认证 创建认证文件 rewrite重定向 进入域名时&#xff0c;会自动重定向到hostname.html 示例&#xff1a; 测试 版本的升级迭代&#xff0c;之前利用控制器进行滚动更新&#xff0c;在升级过程中无法做到快速回滚 更加平滑的升级&#xff1…

WinDbg调试异常(!!! second chance !!!)

以前使用windbg调试样本时不时会遇到异常并提示(!!! second chance !!!),之前也尝试查找过原因但是并没有找到,一直十分郁闷。这次又出现了异常,有时间查找原因并发现了问题所在,于是记录下分析过程。 起因 在调试一个样本,每次用windbg调试都会出现: 但是使用x64dbg调…

中国社科院与新加坡新跃社科联合培养工商管理博士

全球经济正在经历由科技进步与创新、政治和人口的剧烈变化所带来的巨大不确定性与挑战。企业的领导者和管理者需要发展出战略性思维和全球洞察力以便面对越来越大的经济波动。中国社科院与新加坡新跃社科联合培养工商管理博士项目的训练能够让学生在一个企业和组织的改变和发展…

AWS 知识一:如何在AWS上启动云AD服务器(详细到极致)

前言&#xff1a; 首先这里指的云AD服务器&#xff0c;只是为了让读友更好理解。云AD服务器在AWS中称为目录。AWS一共提供了4种目录类别&#xff0c;下面我将全程使用AWS托管微软AD这种目录类别进行示例。他完全提供了和Microsoft AD的功能&#xff0c;包括NTLM&#xff0c;Ker…

VS Code配置Go语言开发环境

提示&#xff1a;首先这是一个新型语言&#xff0c;最好把vscode更新到最新版。 1&#xff1a;去官网下载Go语言编译器&#xff0c;之后配置到系统环境中&#xff0c;能看到版本就行。 2&#xff1a;创建一个文件夹&#xff0c;存放go的工具文件&#xff0c;我的在D:\GoFile\G…

npm login报错:Public registration is not allowed

npm login报错:Public registration is not allowed 1.出现场景2.解决 1.出现场景 npm login登录时,出现 2.解决 将自己的npm镜像源改为npm的https://registry.npmjs.org/这个&#xff0c;解决&#xff01;

如何确保游戏翻译的质量

随着全球化的加速和游戏行业的国际化&#xff0c;越来越多的玩家开始接触并喜欢玩国际游戏。然而&#xff0c;由于语言障碍&#xff0c;很多玩家无法理解游戏中的文本和对话&#xff0c;这严重影响了游戏体验。因此&#xff0c;游戏翻译变得尤为重要。那么&#xff0c;如何确保…

C++ Qt开发:TabWidget实现多窗体功能

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍TabWidget标签组件的常用方法及灵活运用。 Q…

山景DU561—32位高性能音频处理器(DSP)芯片

音频处理可以更好地捕捉和处理声音和音乐&#xff1b;而DSP音频处理芯片是一种利用数字信号处理技术进行音频处理的专用芯片&#xff1b;可用于多种应用&#xff0c;从音乐拾音到复杂的音频信号处理&#xff0c;和声音增强。 由工采网代理的山景DU561是一款集成多种音效算法高…

UE5 runtime模式下自定义视口大小和位置并跟随分辨率自适应缩放

本文旨在解决因UI问题导致屏幕中心位置不对的问题 处理前的现象&#xff1a;如果四周UI透明度都为1&#xff0c;那么方块的位置就不太对&#xff0c;没在中心 处理后的现象&#xff1a; 解决办法&#xff1a;自定义大小和视口偏移 创建一个基于子系统的类或者蓝图函数库(什么类…

【TB作品】51单片机,语音出租车计价器

西交大题目 1.语音出租车计价器 一、功能要求: 1.具有可模拟出租车车轮转速传感器的硬件设计,可计量出租车所走的公 里数。 2.显示和语音播报里程、价格和等待红灯或堵车的计时价格: 3.具有等待计时功能 4.具有实时年月日显示和切换功能。 5.操作简单、界面友好。 二、设计建议…