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.mzph.cn/news/225921.shtml

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

相关文章

CSS的盒子模型(重点)

网页布局的三大核心&#xff1a;盒子模型、浮动、定位 网页布局的过程&#xff1a; 1. 先准备好相关的网页元素&#xff0c;网页元素基本都是盒子 Box 。 2. 利用 CSS 设置好盒子样式&#xff0c;然后摆放到相应位置。 3. 往盒子里面装内容.网页布局的核心本质&#xff1a; 就…

python+appium自动化常见操作

1、点击、输入操作 #点击 driver.find_element(id,com.lemon.lemonban:id/navigation_my).click() #输入 driver.find_element(id,com.lemon.lemonban:id/et_password).send_keys(abc)2、隐形等待 driver.implicitly_wait(10)3、显性等待 #显性等待 locator (xpath,xpath) wai…

技术分享 | Appium 用例录制

下载及安装 下载地址&#xff1a; github.com/appium/appi… 下载对应系统的 Appium 版本&#xff0c;安装完成之后&#xff0c;点击 “Start Server”&#xff0c;就启动了 Appium Server。 在启动成功页面点击右上角的放大镜&#xff0c;进入到创建 Session 页面。配置好 …

Python基础学习—Pandas数据分析实战剖析【文末送书-09】

文章目录 一.Pandas数据分析1.1 Pandas的主要应用包括&#xff1a;1.2 Pandas核心数据结构1.3 安装和导入Pandas 二.Pandas数据分析实战&#xff1a;用Python进行数据分析1. 数据集介绍2. 数据加载与初步观察3. 数据清洗4. 数据分析4.1 销售趋势分析4.2 热门商品分析 三.Pandas…

将开源免费进行到底,ThreadX开源电脑端GUIBuilder图形开发工具GUIX Studio

上个月微软刚刚宣布将ThreadX RTOS全家桶贡献给Eclipse基金会&#xff0c;免费供大家商用&#xff0c;宽松的MIT授权方式&#xff0c;就差这个GUIX Studio没有开源了&#xff0c;而且Windows还经常检索不到&#xff0c;并且也不提供离线包。 1、软件包有点大&#xff0c;700MB…

力扣第一题-两数之和[简单]

题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任…

分布式事务--分布式事务理论基础

1.本地事务 本地事务&#xff0c;也就是传统的单机事务。在传统数据库事务中&#xff0c;必须要满足四个原则&#xff1a; 2.分布式事务 分布式事务&#xff0c;就是指不是在单个服务或单个数据库架构下&#xff0c;产生的事务&#xff0c;例如&#xff1a; 跨数据源的分布式…

《人工智能导论》知识思维导图梳理【第6章节】

文章目录 第六章 知识图谱1 知识图谱概述2 知识图谱相关概念3 知识图谱的逻辑结构4 知识图谱的数据存储5 知识图谱的构建过程6 例题 markdown内容的分享 第六章 知识图谱 1 知识图谱概述 2 知识图谱相关概念 3 知识图谱的逻辑结构 4 知识图谱的数据存储 5 知识图谱的构建过程 6…

【LeetCode: 2415. 反转二叉树的奇数层 | BFS + DFS】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

超过 1450 个 pfSense 服务器因错误链而遭受 RCE 攻击

在线暴露的大约 1450 个 pfSense 实例容易受到命令注入和跨站点脚本漏洞的攻击&#xff0c;这些漏洞如果链接起来&#xff0c;可能使攻击者能够在设备上执行远程代码。 pfSense 是一款流行的开源防火墙和路由器软件&#xff0c;允许广泛的定制和部署灵活性。 它是一种经济高效…

ChatGPT在指尖跳舞: open-interpreter实现本地数据采集、处理一条龙

原文&#xff1a;ChatGPT在指尖跳舞: open-interpreter实现本地数据采集、处理一条龙 - 知乎 目录 收起 Part1 前言 Part2 Open - Interpreter 简介 Part3 安装与运行 Part4 工作场景 1获取网页内容 2 pdf 文件批量转换 3 excel 文件合并 Part5总结 参考资料 往期推…

事务--04---分布式系统唯一ID

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 分布式ID一、什么是分布式系统唯一ID2. 二、分布式系统唯一ID的特点 分布式ID-----实现方案1、使用UUID生成分布式ID2、基于数据库自增ID3、Redis生成ID4、号段模式…

人工智能联盟的首件神兵利器——“Purple Llama” 项目,旨为保护工智能模型安全性

Meta公司&#xff08;Meta Platform Inc&#xff09;&#xff0c;原名Facebook&#xff0c;创立于2004年2月4日&#xff0c;市值5321.71亿美元。总部位于美国加利福尼亚州门洛帕克。 Meta 公司推出了名为“Purple Llama”的项目&#xff0c;旨在保护和加固其开源人工智能模型。…

WINCC8.0脚本调试方法

前言 WINCC是西门子推出的过程可视化系统&#xff08;SCADA&#xff09;&#xff0c;是基于PC的HMI系统&#xff0c;兼容WINDOWS各种系统&#xff0c;除了强大的图形系统之外&#xff0c;WINCC还具有在线历史趋势、报警记录、用户管理、用户归档等高级功能&#xff0c;而且WINC…

[Angular] 笔记1:开发设置 , 双向绑定

1 设置开发环境 1.1 安装 node 下载 node&#xff0c;因为要使用 npm 工具&#xff0c;教程中使用 Angualr 14, 最新版 node 20 用不了&#xff0c;安装 node 16 就可以。 1.2 安装 Angular CLI Angular CLI 是用于创建 Angular 工程的工具集&#xff0c;使用如下命令&…

(第61天)多租户架构(CDB/PDB)

背景介绍 Oracle 的 CDB 和 PDB 是 Oracle 12C 及以上版本中引入的新概念,用于管理多租户数据库环境。 Oracle 数据库是商业数据库领域中的翘楚,其强大的功能和高可靠性备受企业用户追捧。而随着云计算和大数据时代的到来,Oracle 也不断推出新的技术以适应这些变化。CDB 技…

【leetcode】链表总结

说明&#xff1a;本文内容来自于代码随想录 链表基本操作 https://leetcode.cn/problems/design-linked-list/ 删除节点 https://leetcode.cn/problems/remove-linked-list-elements/description/&#xff0c;删除节点&#xff0c;虚拟头节点。定义两个节点&#xff0c;分别…

『OPEN3D』1.5.2 动手实现点云栅格/体素最近邻

本专栏地址: https://blog.csdn.net/qq_41366026/category_12186023.html?spm=1001.2014.3001.5482 NEARBY6实现的voxel可视化 一种NEARBY14实现的可视化voxel

每日一博 - Cache Miss Attack

文章目录 概述解决思路缓存空值键并设置短期 TTL&#xff08;生存时间&#xff09;使用布隆过滤器 伪代码1. 缓存空值键并设置短期 TTLa. 缓存空值键b. 设置短期 TTL 2. 使用布隆过滤器a. 集成布隆过滤器b. 查询布隆过滤器 进一步优化系统性能的建议 概述 在缓存管理中&#x…

基于VGG-16+Android+Python的智能车辆驾驶行为分析—深度学习算法应用(含全部工程源码)+数据集+模型(三)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据预处理2. 模型构建3. 模型训练及保存1&#xff09;模型训练2&#xff09;模型保存 4. 模型生成1&#xff09;模型导入及调用2&#xff09;相关代码&#xff08;1&#xff09;布局文件&#xff08;2&#xff…