点播管理模块
- 编写SubjectController
package com.example.zskt.vod.controller;
import com.example.result.Result;
import com.example.zskt.model.vod.Subject;
import com.example.zskt.vod.service.SubjectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@Api(tags = "课程管理接口")
@RestController
@RequestMapping("/admin/vod/subject")
//@CrossOrigin
public class SubjectController {
@Autowired
private SubjectService subjectService;
//查询下一层课程分类
//根据parent_id
@ApiOperation("查询下一层的课程分类")
@GetMapping("getChildSubject/{id}")
public Result getChildSubject(@PathVariable Long id) {
List<Subject> list = subjectService.selectList(id);
return Result.ok(list);
}
//课程分类导出
@ApiOperation(value="导出")
@GetMapping(value = "exportData")
public void exportData(HttpServletResponse response) {
subjectService.exportData(response);
}
//课程分类导入
@ApiOperation(value = "导入")
@PostMapping("importData")
public Result importData(MultipartFile file) {
subjectService.importData(file);
return Result.ok();
}
}
- 编写SubjectServiceImpl
package com.example.zskt.vod.service.impl;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.exception.ZSktException;
import com.example.zskt.model.vod.Subject;
import com.example.zskt.vo.vod.SubjectEeVo;
import com.example.zskt.vod.listener.SubjectListener;
import com.example.zskt.vod.mapper.SubjectMapper;
import com.example.zskt.vod.service.SubjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
@Service
public class SubjectServiceImpl extends ServiceImpl<SubjectMapper, Subject> implements SubjectService {
@Autowired
private SubjectListener subjectListener;
//查询下一层课程分类
@Override
public List<Subject> selectList(Long id) {
QueryWrapper<Subject> wrapper = new QueryWrapper<>();
wrapper.eq("parent_id",id);
List<Subject> subjectList = baseMapper.selectList(wrapper);
//向list集合每个Subject对象中设置hasChildren
for (Subject subject:subjectList) {
Long subjectId = subject.getId();
boolean isChild = this.isChildren(subjectId);
subject.setHasChildren(isChild);
}
return subjectList;
}
//课程分类导出
@Override
public void exportData(HttpServletResponse response) {
try {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("课程分类", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
//查询课程分类表所有数据
List<Subject> dictList = baseMapper.selectList(null);
//List<Subject>---------List<SubjectEeVo>
List<SubjectEeVo> dictVoList = new ArrayList<>(dictList.size());
for(Subject dict : dictList) {
SubjectEeVo dictVo = new SubjectEeVo();
//复制
BeanUtils.copyProperties(dict,dictVo);
dictVoList.add(dictVo);
}
//EasyExcel写操作
EasyExcel.write(response.getOutputStream(), SubjectEeVo.class).sheet("课程分类").doWrite(dictVoList);
} catch (IOException e) {
throw new ZSktException(20001,"导出失败");
}
}
//课程分类导入
@Override
public void importData(MultipartFile file) {
try {
EasyExcel.read(file.getInputStream(),
SubjectEeVo.class,subjectListener).sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
}
}
//判断id下面是否有子节点
private boolean isChildren(Long id) {
QueryWrapper<Subject> wrapper = new QueryWrapper<>();
wrapper.eq("parent_id",id);
Integer count = baseMapper.selectCount(wrapper);
return count>0;
}
}
- 编写前端
- EasyExcel
(1)pom中引入xml相关依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
(2)创建实体类
@Data
public class Stu {
//设置表头名称
@ExcelProperty("学生编号")
private int sno;
//设置表头名称
@ExcelProperty("学生姓名")
private String sname;
}
(3)实现写操作
//循环设置要添加的数据,最终封装到list集合中
private static List<Stu> data() {
List<Stu> list = new ArrayList<Stu>();
for (int i = 0; i < 10; i++) {
Stu data = new Stu();
data.setSno(i);
data.setSname("张三"+i);
list.add(data);
}
return list;
}
(4)创建读取操作的监听器
public class ExcelListener extends AnalysisEventListener<Stu> {
//创建list集合封装最终的数据
List<Stu> list = new ArrayList<Stu>();
//一行一行去读取excle内容
@Override
public void invoke(Stu user, AnalysisContext analysisContext) {
System.out.println("***"+user);
list.add(user);
}
//读取excel表头信息
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
System.out.println("表头信息:"+headMap);
}
//读取完成后执行
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
- 用代码生成器创建课程相关表
- 编写CourseController
package com.example.zskt.vod.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.result.Result;
import com.example.zskt.model.vod.Course;
import com.example.zskt.vo.vod.CourseFormVo;
import com.example.zskt.vo.vod.CoursePublishVo;
import com.example.zskt.vo.vod.CourseQueryVo;
import com.example.zskt.vod.service.CourseService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* <p>
* 课程 前端控制器
* </p>
*
* @author zs
* @since 2023-01-20
*/
@RestController
@RequestMapping(value="/admin/vod/course")
//@CrossOrigin
public class CourseController {
@Autowired
private CourseService courseService;
@ApiOperation(value = "删除课程")
@DeleteMapping("remove/{id}")
public Result remove(@PathVariable Long id) {
courseService.removeCourseById(id);
return Result.ok();
}
//根据id获取课程发布信息
@ApiOperation("根据id获取课程发布信息")
@GetMapping("getCoursePublishVo/{id}")
public Result getCoursePublishVoById(
@ApiParam(value = "课程ID", required = true)
@PathVariable Long id){
CoursePublishVo coursePublishVo;
coursePublishVo = courseService.getCoursePublishVo(id);
return Result.ok(coursePublishVo);
}
//根据id发布课程
@ApiOperation("根据id发布课程")
@PutMapping("publishCourseById/{id}")
public Result publishCourseById(
@ApiParam(value = "课程ID", required = true)
@PathVariable Long id){
boolean result = courseService.publishCourseById(id);
return Result.ok();
}
根据id获取课程信息
@ApiOperation(value = "获取")
@GetMapping("get/{id}")
public Result get(@PathVariable Long id) {
CourseFormVo course = courseService.getCourseFormVoById(id);
return Result.ok(course);
}
根据id修改课程信息
@ApiOperation(value = "修改")
@PutMapping("update")
public Result updateById(@RequestBody CourseFormVo courseFormVo) {
courseService.updateCourseById(courseFormVo);
return Result.ok();
}
//添加课程基本信息
@ApiOperation(value = "新增")
@PostMapping("save")
public Result save(@RequestBody CourseFormVo courseFormVo) {
Long courseId = courseService.saveCourseInfo(courseFormVo);
return Result.ok(courseId);
}
//获取点播课程分页列表
@ApiOperation(value = "获取分页列表")
@GetMapping("{page}/{limit}")
public Result index(
@ApiParam(name = "page", value = "当前页码", required = true)
@PathVariable Long page,
@ApiParam(name = "limit", value = "每页记录数", required = true)
@PathVariable Long limit,
@ApiParam(name = "courseVo", value = "查询对象", required = false)
CourseQueryVo courseQueryVo) {
Page<Course> pageParam = new Page<>(page, limit);
Map<String,Object> map = courseService.findPage(pageParam, courseQueryVo);
return Result.ok(map);
}
}
- 编写CourseServiceImpl
package com.example.zskt.vod.service.impl;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.zskt.model.vod.Course;
import com.example.zskt.model.vod.CourseDescription;
import com.example.zskt.model.vod.Subject;
import com.example.zskt.model.vod.Teacher;
import com.example.zskt.vo.vod.CourseFormVo;
import com.example.zskt.vo.vod.CoursePublishVo;
import com.example.zskt.vo.vod.CourseQueryVo;
import com.example.zskt.vod.mapper.CourseMapper;
import com.example.zskt.vod.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* 课程 服务实现类
* </p>
*
* @author atguigu
* @since 2023-01-20
*/
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {
@Autowired
private TeacherService teacherService;
@Autowired
private SubjectService subjectService;
@Autowired
private CourseDescriptionService descriptionService;
@Autowired
private CourseMapper courseMapper;
@Autowired
private VideoService videoService;
@Autowired
private ChapterService chapterService;
//获取点播课程分页列表
@Override
public Map<String,Object> findPage(Page<Course> pageParam, CourseQueryVo courseQueryVo) {
//获取条件值
String title = courseQueryVo.getTitle();//名称
Long subjectId = courseQueryVo.getSubjectId();//二级分类
Long subjectParentId = courseQueryVo.getSubjectParentId();//一级分类
Long teacherId = courseQueryVo.getTeacherId();//讲师
//封装条件
QueryWrapper<Course> wrapper = new QueryWrapper<>();
if(!StringUtils.isEmpty(title)) {
wrapper.like("title",title);
}
if(!StringUtils.isEmpty(subjectId)) {
wrapper.eq("subject_id",subjectId);
}
if(!StringUtils.isEmpty(subjectParentId)) {
wrapper.eq("subject_parent_id",subjectParentId);
}
if(!StringUtils.isEmpty(teacherId)) {
wrapper.eq("teacher_id",teacherId);
}
//调用方法查询
Page<Course> pages = baseMapper.selectPage(pageParam, wrapper);
long totalCount = pages.getTotal();//总记录数
long totalPage = pages.getPages();//总页数
//每页数据集合
List<Course> records = pages.getRecords();
//遍历封装讲师和分类名称
records.stream().forEach(item -> {
this.getTeacherOrSubjectName(item);
});
//封装返回数据
Map<String,Object> map = new HashMap<>();
map.put("totalCount",totalCount);
map.put("totalPage",totalPage);
map.put("records",records);
return map;
}
添加课程基本信息
@Override
public Long saveCourseInfo(CourseFormVo courseFormVo) {
//保存课程基本信息
Course course = new Course();
BeanUtils.copyProperties(courseFormVo, course);
baseMapper.insert(course);
//保存课程详情信息
CourseDescription courseDescription = new CourseDescription();
courseDescription.setDescription(courseFormVo.getDescription());
courseDescription.setCourseId(course.getId());
descriptionService.save(courseDescription);
//返回课程id
return course.getId();
}
//根据id获取课程信息
@Override
public CourseFormVo getCourseFormVoById(Long id) {
//从course表中取数据
Course course = baseMapper.selectById(id);
if(course == null){
return null;
}
//从course_description表中取数据
CourseDescription courseDescription = descriptionService.getById(id);
//创建courseInfoForm对象
CourseFormVo courseFormVo = new CourseFormVo();
BeanUtils.copyProperties(course, courseFormVo);
if(courseDescription != null){
courseFormVo.setDescription(courseDescription.getDescription());
}
return courseFormVo;
}
//根据id修改课程信息
@Override
public void updateCourseById(CourseFormVo courseFormVo) {
//修改课程基本信息
Course course = new Course();
BeanUtils.copyProperties(courseFormVo, course);
baseMapper.updateById(course);
//修改课程详情信息
CourseDescription courseDescription = descriptionService.getById(course.getId());
courseDescription.setDescription(courseFormVo.getDescription());
// description.setId(course.getId());
descriptionService.updateById(courseDescription);
}
//根据id获取课程发布信息
@Override
public CoursePublishVo getCoursePublishVo(Long id) {
return courseMapper.selectCoursePublishVoById(id);
}
//根据id发布课程
@Override
public boolean publishCourseById(Long id) {
Course course = new Course();
course.setId(id);
course.setPublishTime(new Date());
course.setStatus(1);
return this.updateById(course);
}
//删除课程
@Override
public void removeCourseById(Long id) {
//根据课程id删除小节
videoService.removeVideoByCourseId(id);
//根据课程id删除章节
chapterService.removeChapterByCourseId(id);
//根据课程id删除描述
descriptionService.removeById(id);
//根据课程id删除课程
baseMapper.deleteById(id);
}
//获取讲师和分类名称
private Course getTeacherOrSubjectName(Course course) {
//查询讲师名称
Teacher teacher = teacherService.getById(course.getTeacherId());
if(teacher != null) {
course.getParam().put("teacherName",teacher.getName());
}
//查询分类名称
Subject subjectOne = subjectService.getById(course.getSubjectParentId());
if(subjectOne != null) {
course.getParam().put("subjectParentTitle",subjectOne.getTitle());
}
Subject subjectTwo = subjectService.getById(course.getSubjectId());
if(subjectTwo != null) {
course.getParam().put("subjectTitle",subjectTwo.getTitle());
}
return course;
}
}
- 编写前端
- 编写章节Controller
package com.example.zskt.vod.controller;
import com.example.result.Result;
import com.example.zskt.model.vod.Chapter;
import com.example.zskt.vo.vod.ChapterVo;
import com.example.zskt.vod.service.ChapterService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 课程 前端控制器
* </p>
*
* @author atguigu
* @since 2023-01-20
*/
@RestController
@RequestMapping(value="/admin/vod/chapter")
//@CrossOrigin
public class ChapterController {
@Autowired
private ChapterService chapterService;
//获取章节小结列表
@ApiOperation("嵌套章节数据列表")
@GetMapping("getNestedTreeList/{courseId}")
public Result getNestedTreeList(
@ApiParam(value = "课程ID", required = true)
@PathVariable Long courseId){
List<ChapterVo> chapterVoList = chapterService.getNestedTreeList(courseId);
return Result.ok(chapterVoList);
}
//2 添加章节
@PostMapping("save")
public Result save(@RequestBody Chapter chapter) {
chapterService.save(chapter);
return Result.ok(null);
}
//3 修改-根据id查询
@GetMapping("get/{id}")
public Result get(@PathVariable Long id) {
Chapter chapter = chapterService.getById(id);
return Result.ok(chapter);
}
//4 修改-最终实现
@PostMapping("update")
public Result update(@RequestBody Chapter chapter) {
chapterService.updateById(chapter);
return Result.ok(null);
}
//5 删除章节
@DeleteMapping("remove/{id}")
public Result remove(@PathVariable Long id) {
chapterService.removeById(id);
return Result.ok(null);
}
}
- 编写ChapterServiceImpl
package com.example.zskt.vod.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.zskt.model.vod.Chapter;
import com.example.zskt.model.vod.Video;
import com.example.zskt.vo.vod.ChapterVo;
import com.example.zskt.vo.vod.VideoVo;
import com.example.zskt.vod.mapper.ChapterMapper;
import com.example.zskt.vod.service.ChapterService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.zskt.vod.service.VideoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 课程 服务实现类
* </p>
*
* @author atguigu
* @since 2023-01-20
*/
@Service
public class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> implements ChapterService {
@Autowired
private VideoService videoService;
//章节小结列表封装
@Override
public List<ChapterVo> getNestedTreeList(Long courseId) {
List<ChapterVo> chapterVoList = new ArrayList<>();
//获取章信息
LambdaQueryWrapper<Chapter> queryWrapperChapter = new LambdaQueryWrapper<>();
queryWrapperChapter.eq(Chapter::getCourseId, courseId);
queryWrapperChapter.orderByAsc(Chapter::getSort, Chapter::getId);
List<Chapter> chapterList = baseMapper.selectList(queryWrapperChapter);
//获取课时信息
LambdaQueryWrapper<Video> queryWrapperVideo = new LambdaQueryWrapper<>();
queryWrapperVideo.eq(Video::getCourseId, courseId);
queryWrapperVideo.orderByAsc(Video::getSort, Video::getId);
List<Video> videoList = videoService.list(queryWrapperVideo);
//填充列表数据:Chapter列表
for (int i = 0; i < chapterList.size(); i++) {
Chapter chapter = chapterList.get(i);
//创建ChapterVo对象
ChapterVo chapterVo = new ChapterVo();
BeanUtils.copyProperties(chapter, chapterVo);
chapterVoList.add(chapterVo);
//填充列表数据:Video列表
List<VideoVo> videoVoList = new ArrayList<>();
for (int j = 0; j < videoList.size(); j++) {
Video video = videoList.get(j);
if(chapter.getId().equals(video.getChapterId())){
VideoVo videoVo = new VideoVo();
BeanUtils.copyProperties(video, videoVo);
videoVoList.add(videoVo);
}
}
chapterVo.setChildren(videoVoList);
}
return chapterVoList;
}
//根据课程id删除章节
@Override
public void removeChapterByCourseId(Long id) {
QueryWrapper<Chapter> wrapper = new QueryWrapper<>();
wrapper.eq("course_id",id);
baseMapper.delete(wrapper);
}
}
- 编写VideoVisitorController
package com.example.zskt.vod.controller;
import com.example.result.Result;
import com.example.zskt.vod.service.VideoVisitorService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* <p>
* 视频来访者记录表 前端控制器
* </p>
*
* @author zs
* @since 2023-01-20
*/
@Api(value = "VideoVisitor管理", tags = "VideoVisitor管理")
@RestController
@RequestMapping(value="/admin/vod/videoVisitor")
//@CrossOrigin
public class VideoVisitorController {
@Autowired
private VideoVisitorService videoVisitorService;
//显示统计数据
@ApiOperation("显示统计数据")
@GetMapping("findCount/{courseId}/{startDate}/{endDate}")
public Result showChart(
@ApiParam("开始时间") @PathVariable Long courseId,
@ApiParam("开始时间") @PathVariable String startDate,
@ApiParam("结束时间") @PathVariable String endDate){
Map<String, Object> map = videoVisitorService.findCount(courseId, startDate, endDate);
return Result.ok(map);
}
}
- 编写VideoVisitorServiceImpl
package com.example.zskt.vod.service.impl;
import com.example.zskt.model.vod.VideoVisitor;
import com.example.zskt.vo.vod.VideoVisitorCountVo;
import com.example.zskt.vod.mapper.VideoVisitorMapper;
import com.example.zskt.vod.service.VideoVisitorService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* <p>
* 视频来访者记录表 服务实现类
* </p>
*
* @author zs
* @since 2023-01-20
*/
@Service
public class VideoVisitorServiceImpl extends ServiceImpl<VideoVisitorMapper, VideoVisitor> implements VideoVisitorService {
//课程统计的接口
@Override
public Map<String, Object> findCount(Long courseId, String startDate, String endDate) {
//调用mapper的方法
List<VideoVisitorCountVo> videoVisitorVoList =
baseMapper.findCount(courseId,startDate,endDate);
//创建map集合
Map<String, Object> map = new HashMap<>();
//创建两个list集合,一个代表所有日期,一个代表日期对应数量
//封装数据 代表所有日期
List<String> dateList = videoVisitorVoList.stream().map(VideoVisitorCountVo::getJoinTime)
.collect(Collectors.toList());
//代表日期对应数量
List<Integer> countList = videoVisitorVoList.stream().map(VideoVisitorCountVo::getUserCount)
.collect(Collectors.toList());
//放到map集合
map.put("xData", dateList);
map.put("yData", countList);
return map;
}
}
- 整合腾讯云点播
整合网关与实现订单和营销管理模块
- 服务注册
1.1 把service_vod微服务注册到注册中心,其他模块注册步骤相同
配置Nacos客户端的pom依赖
<!-- 服务注册 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 服务调用feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1.2配置service_vod
配置application.properties,在客户端微服务中添加注册Nacos服务的配置信息
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
1.3添加Nacos客户端注解
在service_vod微服务启动类中添加注解
@EnableDiscoveryClient
1.4 启动客户端微服务
启动注册中心
启动已注册的微服务,可以在Nacos服务列表中看到被注册的微服务
- 整合Spring Cloud GateWay网关
2.1 创建网关模块
2.2 引入网关依赖
<dependencies>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service_util</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 网关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 服务注册 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
2.3 创建启动类
@SpringBootApplication
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
2.4 配置路由规则
# 服务端口
server.port=8333
# 服务名
spring.application.name=service-gateway
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#使用服务发现路由
spring.cloud.gateway.discovery.locator.enabled=true
#service-vod模块配置
#设置路由id
spring.cloud.gateway.routes[0].id=service-vod
#设置路由的uri
spring.cloud.gateway.routes[0].uri=lb://service-vod
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[0].predicates= Path=/*/vod/**
2.5跨域概述
跨域本质是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是与当前页域名相同的路径,这能有效的阻止跨站攻击。因此:跨域问题 是针对ajax的一种限制。但是这却给我们的开发带来了不便,而且在实际生产环境中,肯定会有很多台服务器之间交互,地址和端口都可能不同。
之前我们通过服务器添加注解实现,现在我们跨域通过网关来解决跨域问题。
2.6 创建配置类
@Configuration
public class CorsConfig {
//处理跨域
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedMethod("*");
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
后台管理系统-订单管理模块
1、 编写OrderInfoController
package com.example.zskt.order.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.result.Result;
import com.example.zskt.model.order.OrderInfo;
import com.example.zskt.order.service.OrderInfoService;
import com.example.zskt.vo.order.OrderInfoQueryVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* <p>
* 订单表 订单表 前端控制器
* </p>
*
* @author zs
* @since 2023-01-22
*/
@Api(tags = "订单管理")
@RestController
@RequestMapping("/admin/order/orderInfo")
public class OrderInfoController {
@Autowired
private OrderInfoService orderInfoService;
//获取订单列表
@ApiOperation(value = "获取分页列表")
@GetMapping("{page}/{limit}")
public Result index(
@ApiParam(name = "page", value = "当前页码", required = true)
@PathVariable Long page,
@ApiParam(name = "limit", value = "每页记录数", required = true)
@PathVariable Long limit,
@ApiParam(name = "orderInfoVo", value = "查询对象", required = false)
OrderInfoQueryVo orderInfoQueryVo) {
Page<OrderInfo> pageParam = new Page<>(page, limit);
Map<String,Object> map = orderInfoService.findPageOrderInfo(pageParam, orderInfoQueryVo);
return Result.ok(map);
}
}
2、编写OrderInfoServiceImpl
package com.example.zskt.order.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.zskt.model.order.OrderDetail;
import com.example.zskt.model.order.OrderInfo;
import com.example.zskt.order.mapper.OrderInfoMapper;
import com.example.zskt.order.service.OrderDetailService;
import com.example.zskt.order.service.OrderInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.zskt.vo.order.OrderInfoQueryVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* 订单表 订单表 服务实现类
* </p>
*
* @author zs
* @since 2023-01-22
*/
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {
@Autowired
private OrderDetailService orderDetailService;
@Override
public Map<String, Object> findPageOrderInfo(Page<OrderInfo> pageParam, OrderInfoQueryVo orderInfoQueryVo) {
//orderInfoQueryVo获取查询条件
Long userId = orderInfoQueryVo.getUserId();
String outTradeNo = orderInfoQueryVo.getOutTradeNo();
String phone = orderInfoQueryVo.getPhone();
String createTimeEnd = orderInfoQueryVo.getCreateTimeEnd();
String createTimeBegin = orderInfoQueryVo.getCreateTimeBegin();
Integer orderStatus = orderInfoQueryVo.getOrderStatus();
//判断条件值是否为空,不为空,进行条件封装
QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
if(!StringUtils.isEmpty(String.valueOf(orderStatus))) {
wrapper.eq("order_status",orderStatus);
}
if(!StringUtils.isEmpty(String.valueOf(userId))) {
wrapper.eq("user_id",userId);
}
if(!StringUtils.isEmpty(outTradeNo)) {
wrapper.eq("out_trade_no",outTradeNo);
}
if(!StringUtils.isEmpty(phone)) {
wrapper.eq("phone",phone);
}
if(!StringUtils.isEmpty(createTimeBegin)) {
wrapper.ge("create_time",createTimeBegin);
}
if(!StringUtils.isEmpty(createTimeEnd)) {
wrapper.le("create_time",createTimeEnd);
}
//调用实现条件分页查询
Page<OrderInfo> pages = baseMapper.selectPage(pageParam, wrapper);
long totalCount = pages.getTotal();
long pageCount = pages.getPages();
List<OrderInfo> records = pages.getRecords();
//订单里面包含详情内容,封装详情数据,根据订单id查询详情
records.stream().forEach(item -> {
this.getOrderDetail(item);
});
//所有需要数据封装map集合,最终返回
Map<String,Object> map = new HashMap<>();
map.put("total",totalCount);
map.put("pageCount",pageCount);
map.put("records",records);
return map;
}
//查询订单详情数据
private OrderInfo getOrderDetail(OrderInfo orderInfo) {
//订单id
Long id = orderInfo.getId();
//查询订单详情
OrderDetail orderDetail = orderDetailService.getById(id);
if(orderDetail != null) {
String courseName = orderDetail.getCourseName();
orderInfo.getParam().put("courseName",courseName);
}
return orderInfo;
}
}
3、配置网关
#service-order模块配置
#设置路由id
spring.cloud.gateway.routes[1].id=service-order
#设置路由的uri
spring.cloud.gateway.routes[1].uri=lb://service-order
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[1].predicates= Path=/*/order/**
后台管理系统-营销管理模块
1、 编写CouponInfoController
package com.example.zskt.activity.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.result.Result;
import com.example.zskt.activity.service.CouponInfoService;
import com.example.zskt.model.activity.CouponInfo;
import com.example.zskt.model.activity.CouponUse;
import com.example.zskt.vo.activity.CouponUseQueryVo;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 优惠券信息 前端控制器
* </p>
*
* @author zs
* @since 2023-01-22
*/
@RestController
@RequestMapping("/admin/activity/couponInfo")
public class CouponInfoController {
@Autowired
private CouponInfoService couponInfoService;
@ApiOperation(value = "获取分页列表")
@GetMapping("{page}/{limit}")
public Result index(
@ApiParam(name = "page", value = "当前页码", required = true)
@PathVariable Long page,
@ApiParam(name = "limit", value = "每页记录数", required = true)
@PathVariable Long limit) {
Page<CouponInfo> pageParam = new Page<>(page, limit);
IPage<CouponInfo> pageModel = couponInfoService.page(pageParam);
return Result.ok(pageModel);
}
@ApiOperation(value = "获取优惠券")
@GetMapping("get/{id}")
public Result get(@PathVariable String id) {
CouponInfo couponInfo = couponInfoService.getById(id);
return Result.ok(couponInfo);
}
@ApiOperation(value = "新增优惠券")
@PostMapping("save")
public Result save(@RequestBody CouponInfo couponInfo) {
couponInfoService.save(couponInfo);
return Result.ok();
}
@ApiOperation(value = "修改优惠券")
@PutMapping("update")
public Result updateById(@RequestBody CouponInfo couponInfo) {
couponInfoService.updateById(couponInfo);
return Result.ok();
}
@ApiOperation(value = "删除优惠券")
@DeleteMapping("remove/{id}")
public Result remove(@PathVariable String id) {
couponInfoService.removeById(id);
return Result.ok();
}
@ApiOperation(value="根据id列表删除优惠券")
@DeleteMapping("batchRemove")
public Result batchRemove(@RequestBody List<String> idList){
couponInfoService.removeByIds(idList);
return Result.ok();
}
//获取分页列表
@ApiOperation(value = "获取分页列表")
@GetMapping("couponUse/{page}/{limit}")
public Result index(
@ApiParam(name = "page", value = "当前页码", required = true)
@PathVariable Long page,
@ApiParam(name = "limit", value = "每页记录数", required = true)
@PathVariable Long limit,
@ApiParam(name = "couponUseVo", value = "查询对象", required = false)
CouponUseQueryVo couponUseQueryVo) {
Page<CouponUse> pageParam = new Page<>(page, limit);
IPage<CouponUse> pageModel = couponInfoService.selectCouponUsePage(pageParam, couponUseQueryVo);
return Result.ok(pageModel);
}
}
2、编写CouponInfoServiceImpl
package com.example.zskt.activity.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.zskt.activity.mapper.CouponInfoMapper;
import com.example.zskt.activity.service.CouponInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.zskt.activity.service.CouponUseService;
import com.example.zskt.client.user.UserInfoFeignClient;
import com.example.zskt.model.activity.CouponInfo;
import com.example.zskt.model.activity.CouponUse;
import com.example.zskt.model.user.UserInfo;
import com.example.zskt.vo.activity.CouponUseQueryVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 优惠券信息 服务实现类
* </p>
*
* @author zs
* @since 2023-01-22
*/
@Service
public class CouponInfoServiceImpl extends ServiceImpl<CouponInfoMapper, CouponInfo> implements CouponInfoService {
@Autowired
private CouponUseService couponUseService;
@Autowired
private UserInfoFeignClient userInfoFeignClient;
//获取已使用优惠券列表
@Override
public IPage<CouponUse> selectCouponUsePage(Page<CouponUse> pageParam, CouponUseQueryVo couponUseQueryVo) {
//获取条件
Long couponId = couponUseQueryVo.getCouponId();
String couponStatus = couponUseQueryVo.getCouponStatus();
String getTimeBegin = couponUseQueryVo.getGetTimeBegin();
String getTimeEnd = couponUseQueryVo.getGetTimeEnd();
//封装条件
QueryWrapper<CouponUse> wrapper = new QueryWrapper<>();
if(!StringUtils.isEmpty(String.valueOf(couponId))) {
wrapper.eq("coupon_id",couponId);
}
if(!StringUtils.isEmpty(couponStatus)) {
wrapper.eq("coupon_status",couponStatus);
}
if(!StringUtils.isEmpty(getTimeBegin)) {
wrapper.ge("get_time",getTimeBegin);
}
if(!StringUtils.isEmpty(getTimeEnd)) {
wrapper.le("get_time",getTimeEnd);
}
//调用方法查询
IPage<CouponUse> page = couponUseService.page(pageParam, wrapper);
//封装用户昵称和手机号
List<CouponUse> couponUseList = page.getRecords();
couponUseList.stream().forEach(item->{
this.getUserInfoBycouponUse(item);
});
return page;
}
//封装用户昵称和手机号
private CouponUse getUserInfoBycouponUse(CouponUse couponUse) {
Long userId = couponUse.getUserId();
if(!StringUtils.isEmpty(String.valueOf(userId))) {
UserInfo userInfo = userInfoFeignClient.getById(userId);
if(userInfo != null) {
couponUse.getParam().put("nickName", userInfo.getNickName());
couponUse.getParam().put("phone", userInfo.getPhone());
}
}
return couponUse;
}
}
3、配置网关
#service-activity模块配置
#设置路由id
spring.cloud.gateway.routes[2].id=service-activity
#设置路由的uri
spring.cloud.gateway.routes[2].uri=lb://service-activity
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[2].predicates= Path=/*/activity/**
开发过程中遇到的问题
- Process finished with exit code 0
- Invalid bound statement (not found)