当前位置: 首页 > news >正文

保定哪家公司做网站wordpress显示当前文章的子分类

保定哪家公司做网站,wordpress显示当前文章的子分类,欧洲cn2 vps,网站上线稳定后工作我的课表 需求分析 原型图 管理后台 用户端 流程图 数据设计 接口设计 支付成功报名课程后, 加入到我的课表(MQ)分页查询我的课表查询我正在学习的课程根据id查询指定课程的学习状态删除课表中的某课程 代码实现 数据表设计 添加课程到课表(非标准接口&#x…

我的课表

需求分析

原型图

管理后台

用户端

流程图

数据设计

接口设计

  1. 支付成功报名课程后, 加入到我的课表(MQ)
  2. 分页查询我的课表
  3. 查询我正在学习的课程
  4. 根据id查询指定课程的学习状态
  5. 删除课表中的某课程

代码实现

数据表设计

添加课程到课表(非标准接口)

需求:用户购买/报名课程后,交易服务会通过MQ通知学习服务,学习服务将课程加入用户课表中

接口设计

首先写Listener,定义好RabbitMQ,对DTO数据校验后调用lessonService

@Component
@RequiredArgsConstructor
@Slf4j
public class LessonChangeListener {private final ILearningLessonService lessonService;@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "learning.lesson.pay.queue", durable = "true"),exchange = @Exchange(name = MqConstants.Exchange.ORDER_EXCHANGE, type = ExchangeTypes.TOPIC),key = MqConstants.Key.ORDER_PAY_KEY))public void listenLessonPay(OrderBasicDTO dto) {//1.非空判断if(dto==null || dto.getOrderId()==null || CollUtils.isEmpty(dto.getCourseIds())){log.error("接收到MQ的消息有误,订单数据为空");return;}//2.调用业务lessonService.addLesson(dto);}}
@Service
@RequiredArgsConstructor
public class LearningLessonServiceImpl extends ServiceImpl<LearningLessonMapper, LearningLesson> implements ILearningLessonService {private final CourseClient courseClient;@Overridepublic void addLesson(OrderBasicDTO dto) {//1.远程调用tj-course微服务,根据课程id查询出课程信息(课程有效期)List<Long> courseIds = dto.getCourseIds();List<CourseSimpleInfoDTO> courseList = courseClient.getSimpleInfoList(courseIds);if (CollUtils.isEmpty(courseList)) {throw new BadRequestException("课程不存在");}//2.遍历课程信息,封装LearningLesson(用户id,课程id,过期时间)List<LearningLesson> lessonList = new ArrayList<>();for (CourseSimpleInfoDTO course : courseList) {LearningLesson lesson = new LearningLesson();//2.1 填充userId和courseIdlesson.setUserId(dto.getUserId());lesson.setCourseId(course.getId());//2.2 算出过期时间lesson.setExpireTime(LocalDateTime.now().plusMonths(course.getValidDuration())); lessonList.add(lesson);}//3.批量保存saveBatch(lessonList);}
}

Q1: 过期时间怎么计算?

加入课表的时间(LocalDateTime.now())+课程有效期

Q2: 课程信息是怎么获得的?

远程调用课程微服务tj-course,根据课程id查询课程信息

Q3: 当前添加课表的业务是怎么保证幂等性?

当前业务靠MySQL,在DDL中把(user id ,course id)设置唯一约束

通用做法:在DTO中找个唯一标识,判断Redis里面是否有

分页查询我的课表

需求: 在个人中心-我的课程页面,可以分页查询当前用户的课表及学习状态信息。

接口设计

分页用到的类如下

PageQuery

public class PageQuery {public static final Integer DEFAULT_PAGE_SIZE = 20;public static final Integer DEFAULT_PAGE_NUM = 1;@ApiModelProperty(value = "页码", example = "1")@Min(value = 1, message = "页码不能小于1")private Integer pageNo = DEFAULT_PAGE_NUM;@ApiModelProperty(value = "每页大小", example = "5")@Min(value = 1, message = "每页查询数量不能小于1")private Integer pageSize = DEFAULT_PAGE_SIZE;@ApiModelProperty(value = "是否升序", example = "true")private Boolean isAsc = true;@ApiModelProperty(value = "排序字段", example = "id")private String sortBy;
}

返回的分页结果PageDTO

public class PageDTO<T> {@ApiModelProperty("总条数")protected Long total;@ApiModelProperty("总页码数")protected Long pages;@ApiModelProperty("当前页数据")protected List<T> list;
}

接口

@RestController
@RequestMapping("/lessons")
@Api(tags = "我的课表相关的接口")
@RequiredArgsConstructor
public class LearningLessonController {private final ILearningLessonService lessonService;@GetMapping("/page")@ApiOperation("分页查询我的课表")public PageDTO<LearningLessonVO> queryMyLesson(@Validated PageQuery query){return lessonService.queryMyLesson(query);}}
    /*** 分页查询我的课表** @param query* @return*/@Overridepublic PageDTO<LearningLessonVO> queryMyLesson(PageQuery query) {// 1. 分页查询出当前用户的课表信息Long userId = UserContext.getUser();Page<LearningLesson> pageResult = lambdaQuery().eq(LearningLesson::getUserId, userId).page(query.toMpPageDefaultSortByCreateTimeDesc());List<LearningLesson> lessonList = pageResult.getRecords();if (CollUtils.isEmpty(lessonList)) {return PageDTO.empty(pageResult);}// 2. 根据courseId查询出课程信息List<Long> cIds = lessonList.stream().map(LearningLesson::getCourseId).collect(Collectors.toList());List<CourseSimpleInfoDTO> courseList = courseClient.getSimpleInfoList(cIds);if (CollUtils.isEmpty(courseList)) {throw new BadRequestException("课程信息不存在");}Map<Long, CourseSimpleInfoDTO> courseMap = courseList.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, c -> c));// 3. 遍历课表List,封装LearningLessonVOList<LearningLessonVO> voList = new ArrayList<>();for (LearningLesson lesson : lessonList) {LearningLessonVO vo = BeanUtils.copyBean(lesson, LearningLessonVO.class);//封装课程信息CourseSimpleInfoDTO course = courseMap.get(lesson.getCourseId());if (course!=null){vo.setCourseName(course.getName());vo.setCourseCoverUrl(course.getCoverUrl());vo.setSections(course.getSectionNum());}voList.add(vo);}// 4. 封装PageDTOreturn PageDTO.of(pageResult,voList);}

Q1: 为什么把courseList转成了courseMap

Map中Key是课程id,Value是课程对象,从而可以通过课程id拿到课程对象                                                            

查询最近正在学习的课程

需求: 在首页、个人中心-课程表页,需要查询并展示当前用户最近一次学习的课程

接口设计

这次代码是个标准的三层都写案例了

@GetMapping("/now")
@ApiOperation("查询当前用户正在学习的课程")
public LearningLessonVO queryCurrent() {return lessonService.queryCurrent();
}
    /*** 查询当前用户正在学习的课程** @return*/@Overridepublic LearningLessonVO queryCurrent() {//1.获得当前用户IdLong userId = UserContext.getUser();//2.查询课表,当前用户正在学习的课程 SELECT * FROM   learning_lesson WHERE user_id =2 AND status  = 1 ORDER BY latest_learn_time  DESC  limit 0,1;LearningLesson lesson = getBaseMapper().queryCurrent(userId);if(lesson == null){return null;}LearningLessonVO vo = BeanUtils.copyBean(lesson, LearningLessonVO.class);//3.根据课程id查询出课程信息CourseFullInfoDTO course = courseClient.getCourseInfoById(lesson.getCourseId(), false, false);if(course == null){throw new BadRequestException("课程不存在");}vo.setCourseName(course.getName());vo.setCourseCoverUrl(course.getCoverUrl());vo.setSections(course.getSectionNum());//4.统计课程中的课程Integer courseAmount = lambdaQuery().eq(LearningLesson::getUserId, userId).count();vo.setCourseAmount(courseAmount);//5.根据最近学习的章节id查询章节信息List<CataSimpleInfoDTO> catalogueList = catalogueClient.batchQueryCatalogue(List.of(lesson.getLatestSectionId()));if(!CollUtils.isEmpty(catalogueList)){CataSimpleInfoDTO cata = catalogueList.get(0);vo.setLatestSectionIndex(cata.getCIndex());vo.setLatestSectionName(cata.getName());}return vo;}
public interface LearningLessonMapper extends BaseMapper<LearningLesson> {@Select("SELECT * FROM learning_lesson WHERE user_id = #{userId} AND status=1 ORDER BY latest_learn_time DESC limit 0,1")LearningLesson queryCurrent(@Param("userId") Long userId);
}

根据id查询指定课程的学习状态

需求: 在课程详情页需要查询用户是否购买了指定课程,如果购买了则要返回学习状态信息

接口设计

代码最简单的一集

@GetMapping("/{courseId}")
@ApiOperation("根据课程id查询课程状态")
public LearningLessonVO queryByCourseId(@PathVariable("courseId") Long courseId) {return lessonService.queryByCourseId(courseId);
}
    /*** 根据课程id查询出课程状态** @param courseId* @return*/@Overridepublic LearningLessonVO queryByCourseId(Long courseId) {// 1. 根据用户id和课程id查询出课表LearningLessonLearningLesson lesson = lambdaQuery().eq(LearningLesson::getUserId, UserContext.getUser()).eq(LearningLesson::getCourseId, courseId).one();if (lesson == null) {return null;}// 2. 根据课程id查询出课程信息CourseFullInfoDTO course = courseClient.getCourseInfoById(courseId, false, false);if(course==null){throw new BadRequestException("课程不存在");}// 3. 封装voLearningLessonVO vo = BeanUtils.copyBean(lesson, LearningLessonVO.class);vo.setCourseName(course.getName());vo.setCourseCoverUrl(course.getCoverUrl());vo.setSections(course.getSectionNum());return vo;}

Q1: 为什么不能直接使用courseId查询课表?

还需要userid的约束

检查课程是否有效(作业)

这是一个微服务内部接口,当用户学习课程时,可能需要播放课程视频。此时提供视频播放功能的媒资系统就需要校验用户是否有播放视频的资格。所以,开发媒资服务(tj-media)的同事就请你提供这样一个接口。

    @ApiOperation("校验当前课程是否已经报名")@GetMapping("/{courseId}/valid")public Long isLessonValid(@ApiParam(value = "课程id" ,example = "1") @PathVariable("courseId") Long courseId){return lessonService.isLessonValid(courseId);}
    @Overridepublic Long isLessonValid(Long courseId) {// 1.获取登录用户Long userId = UserContext.getUser();if (userId == null) {return null;}// 2.查询课程LearningLesson lesson = lambdaQuery().eq(LearningLesson::getUserId, UserContext.getUser()).eq(LearningLesson::getCourseId, courseId).one();if (lesson == null) {return null;}return lesson.getId();}

删除课表中课程(作业)

删除课表中的课程有两种场景:

  • 用户直接删除已失效的课程
  • 用户退款后触发课表自动删除
    @DeleteMapping("/{courseId}")@ApiOperation("删除指定课程信息")public void deleteCourseFromLesson(@ApiParam(value = "课程id" ,example = "1") @PathVariable("courseId") Long courseId) {lessonService.deleteCourseFromLesson(null, courseId);}
@Overridepublic void deleteCourseFromLesson(Long userId, Long courseId) {// 1.获取当前登录用户if (userId == null) {userId = UserContext.getUser();}// 2.删除课程remove(buildUserIdAndCourseIdWrapper(userId, courseId));}private LambdaQueryWrapper<LearningLesson> buildUserIdAndCourseIdWrapper(Long userId, Long courseId) {LambdaQueryWrapper<LearningLesson> queryWrapper = new QueryWrapper<LearningLesson>().lambda().eq(LearningLesson::getUserId, userId).eq(LearningLesson::getCourseId, courseId);return queryWrapper;}

http://www.yayakq.cn/news/199184/

相关文章:

  • 主机宝怎么设置网站主页免费中学网站模板
  • 西安建设网站制作购物网站支付页面制作
  • 毕设做网站 方面的论文陶瓷网站源码
  • 网站建设及安全管理文档登封网站建设
  • 武鸣网站建设实惠网外贸论坛
  • wordpress会员制网站单职业传奇网站
  • 西安煤炭建设监理中心网站重庆网站建设c
  • 上海网站建设caiyiduo免费注册个人邮箱申请
  • 广州网站开发服务扁平化中文网站模板下载
  • 网站首页导航栏wordpress删除前缀
  • 北京做网站建设公司哪家好百度搜索引擎营销如何实现
  • 网站文章内容页keyword设置网络推广和优化是什么意思
  • 官方网站建设 找磐石网络一流it服务公司
  • 东莞网站建设公司招聘信息网站建设中服务器搭建方式
  • 开淘宝店要自己做网站吗网站模板 哪个好
  • 中学网上做试卷的网站西安网页设计培训班价格
  • 做旅游那些网站好给网站栏目页做反链好吗
  • 北京公司模板网站好做一个网站的建设过程
  • 织梦 响应式网站做网站的时候旋转图片
  • 湖南网站建设哪家专业手机运用网站
  • 外国人做的关于中国的视频网站江阴网站建设推广
  • 如何利用网站来提升企业形象网站后台上传软件
  • 免费发布信息网站大全666怎么看网站域名
  • 网站建设课设心得南宁网络推广平台有哪些
  • seo品牌优化整站优化wordpress 新闻插件
  • 做凉菜的网站小影 wordpress
  • dw做单页网站教程企业注册信息查询单怎么打印
  • 短网址网站建设郑州建设局官方网站
  • 网站制作有限公司网站怎么做移动图片大全
  • 正规东莞网站建设谷歌浏览器在线打开