@FeignClient(contextId = "course", value = "course-service")
public interface CourseClient {
/**
* 根据老师id列表获取老师出题数据和讲课数据
* @param teacherIds 老师id列表
* @return 老师id和老师对应的出题数和教课数
*/
@GetMapping("/course/infoByTeacherIds")
List<SubNumAndCourseNumDTO> infoByTeacherIds(@RequestParam("teacherIds") Iterable<Long> teacherIds);
/**
* 根据小节id获取小节对应的mediaId和课程id
*
* @param sectionId 小节id
* @return 小节对应的mediaId和课程id
*/
@GetMapping("/course/section/{id}")
SectionInfoDTO sectionInfo(@PathVariable("id") Long sectionId);
/**
* 根据媒资Id列表查询媒资被引用的次数
*
* @param mediaIds 媒资id列表
* @return 媒资id和媒资被引用的次数的列表
*/
@GetMapping("/course/media/useInfo")
List<MediaQuoteDTO> mediaUserInfo(@RequestParam("mediaIds") Iterable<Long> mediaIds);
/**
* 根据课程id查询索引库需要的数据
*
* @param id 课程id
* @return 索引库需要的数据
*/
@GetMapping("/course/{id}/searchInfo")
CourseSearchDTO getSearchInfo(@PathVariable("id") Long id);
/**
* 根据课程id集合查询课程简单信息
* @param ids id集合
* @return 课程简单信息的列表
*/
@GetMapping("/courses/simpleInfo/list")
List<CourseSimpleInfoDTO> getSimpleInfoList(@RequestParam("ids") Iterable<Long> ids);
/**
* 根据课程id,获取课程、目录、教师信息
* @param id 课程id
* @return 课程信息、目录信息、教师信息
*/
@GetMapping("/course/{id}")
CourseFullInfoDTO getCourseInfoById(
@PathVariable("id") Long id,
@RequestParam(value = "withCatalogue", required = false) boolean withCatalogue,
@RequestParam(value = "withTeachers", required = false) boolean withTeachers
);
}
day02-我的课表
支付或报名课程后,监听到MQ通知,将课程加入课表。
除此以外,如果用户退款,也应该删除课表中的课程,这里同样是通过MQ通知来实现:
CREATE TABLE learning_lesson (
id bigint NOT NULL COMMENT '主键',
user_id bigint NOT NULL COMMENT '学员id',
course_id bigint NOT NULL COMMENT '课程id',
status tinyint DEFAULT '0' COMMENT '课程状态,0-未学习,1-学习中,2-已学完,3-已失效',
week_freq tinyint DEFAULT NULL COMMENT '每周学习频率,每周3天,每天2节,则频率为6',
plan_status tinyint NOT NULL DEFAULT '0' COMMENT '学习计划状态,0-没有计划,1-计划进行中',
learned_sections int NOT NULL DEFAULT '0' COMMENT '已学习小节数量',
latest_section_id bigint DEFAULT NULL COMMENT '最近一次学习的小节id',
latest_learn_time datetime DEFAULT NULL COMMENT '最近一次学习的时间',
create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
expire_time datetime NOT NULL COMMENT '过期时间',
update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id),
UNIQUE KEY idx_user_id (user_id,course_id) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='学生课表';
package com.tianji.learning.mq;
import cn.hutool.core.collection.CollUtil;
import com.tianji.api.dto.trade.OrderBasicDTO;
import com.tianji.common.constants.MqConstants;
import com.tianji.learning.service.ILearningLessonService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@Slf4j
@RequiredArgsConstructor
public class LessonChangeListener {
private final ILearningLessonService lessonService;
/***
* MQ消息发送相关代码:
* rabbitMqHelper.send(
* MqConstants.Exchange.ORDER_EXCHANGE, // Exchange
* MqConstants.Key.ORDER_PAY_KEY, // Key
* OrderBasicDTO.builder()
* .orderId(orderId)
* .userId(userId)
* .courseIds(cIds)
* .finishTime(order.getFinishTime())
* .build()
* );
*
* @param dto 接受的参数类型为OrderBasicDTO
*/
@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "learning.lesson.pay.queue", durable = "true"),
exchange = @Exchange(value = MqConstants.Exchange.ORDER_EXCHANGE, type = ExchangeTypes.TOPIC),
key = MqConstants.Key.ORDER_PAY_KEY))
public void onMsg(OrderBasicDTO dto) {
log.info("LessonChangeListener接收消息,用户{},添加课程{}", dto.getUserId(), dto.getCourseIds());
// 校验
if (dto.getUserId() == null
|| dto.getOrderId() == null
|| CollUtil.isEmpty(dto.getCourseIds())) {
// 这里是接受MQ消息,中断即可,若抛异常,则自动重试
return;
}
// 保存课程到课表
lessonService.addUserLesson(dto.getUserId(),dto.getCourseIds());
}
/**
* 当用户退款成功时,取消相应课程
*/
@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "learning.lesson.refund.queue ",durable = "true"),
exchange = @Exchange(value = MqConstants.Exchange.ORDER_EXCHANGE,type = ExchangeTypes.TOPIC ),
key = MqConstants.Key.ORDER_REFUND_KEY))
public void receiveMsg(OrderBasicDTO dto){
log.info("LessonChangeListener接收消息,用户{},取消课程{}", dto.getUserId(), dto.getCourseIds());
// 校验
if (dto.getUserId() == null
|| dto.getOrderId() == null
|| CollUtil.isEmpty(dto.getCourseIds(