learning-online-learning-api工程的com.swx.learning.api包下创建控制类

@Api(value = "我的课程表接口", tags = "我的课程表接口")
@RestController
@RequestMapping("/choosecourse")
public class MyCourseTablesController {

}

learning-online-learning-service工程的com.swx.learning.service包下创建接口类

public interface MyCourseTablesService {

}

实现类

/**
* 选课相关服务
*/
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {

}

查询学习资格

一共有三个状态

{
"702001": "可学习",
"702002": "没支付",
"702003": "已过期",
}

接口信息

路径地址 http://localhost:63020/learning/choosecourse/learnstatus/12
请求方式 POST
请求参数 Long
返回结果 XcCourseTablesVO

返回结果VO

CourseCategoryTreeVO
@Data
@EqualsAndHashCode(callSuper = true)
public class XcCourseTablesVO extends XcCourseTables {
// 学习资格
public String learnStatus;
}

查询资格Service

在 MyCourseTablesService 中定义查询学习资格方法

MyCourseTablesService
public interface MyCourseTablesService {
/**
* 查询学习资格
*
* @param userId 用户ID
* @param courseId 课程ID
* @return com.swx.learning.model.vo.XcChooseCourseVO 选课信息
*/
public XcCourseTablesVO getLearningStatus(String userId, Long courseId);
}

实现该方法

MyCourseTablesServiceImpl
/**
* 选课相关服务
*/
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {
private final XcCourseTablesService xcCourseTablesService;

public MyCourseTablesServiceImpl(XcCourseTablesService xcCourseTablesService) {
this.xcCourseTablesService = xcCourseTablesService;
}

/**
* 查询学习资格
*
* @param userId 用户ID
* @param courseId 课程ID
* @return com.swx.learning.model.vo.XcChooseCourseVO 选课信息
*/
@Override
public XcCourseTablesVO getLearningStatus(String userId, Long courseId) {
// 查询我的课程表,有记录可学习
return xcCourseTablesService.getLearningStatus(userId, courseId);
}
}

查询学习资格

找到 XcCourseTablesService 服务类,定义如下的方法

XcCourseTablesService
public interface XcCourseTablesService extends IService<XcCourseTables> {
/**
* 查询学习资格
*
* @param userId 用户ID
* @param courseId 课程ID
* @return String 学习资格
*/
XcCourseTablesVO getLearningStatus(String userId, Long courseId);
}

实现上述方法:

XcCourseTablesServiceImpl
@Service
public class XcCourseTablesServiceImpl extends ServiceImpl<XcCourseTablesMapper, XcCourseTables> implements XcCourseTablesService {

/**
* 查询学习资格
*
* @param userId 用户ID
* @param courseId 课程ID
* @return String 学习资格
*/
@Override
public XcCourseTablesVO getLearningStatus(String userId, Long courseId) {
XcCourseTables courseTable = getCourseTable(userId, courseId);
XcCourseTablesVO xcCourseTablesVO = new XcCourseTablesVO();
if (courseTable == null) {
// 选课没支付
xcCourseTablesVO.setLearnStatus("702002");
return xcCourseTablesVO;
}
boolean before = courseTable.getValidtimeEnd().isBefore(LocalDateTime.now());
BeanUtils.copyProperties(courseTable, xcCourseTablesVO);
if (before) {
// 已过期
xcCourseTablesVO.setLearnStatus("702003");
} else {
// 可以学习
xcCourseTablesVO.setLearnStatus("702001");
}
return xcCourseTablesVO;
}
}

查询资格Controller

MyCourseTablesController
@Api(value = "我的课程表接口", tags = "我的课程表接口")
@RestController
@RequestMapping("/choosecourse")
public class MyCourseTablesController {

private final MyCourseTablesService myCourseTablesService;

public MyCourseTablesController(MyCourseTablesService myCourseTablesService) {
this.myCourseTablesService = myCourseTablesService;
}

@ApiOperation("查询学习资格")
@PostMapping("/learnstatus/{courseId}")
public XcCourseTablesVO getLearningStatus(@PathVariable("courseId") Long courseId) {
// 获取userId
SecurityUtil.XcUser user = SecurityUtil.getUser();
String userId = user.getId();
return myCourseTablesService.getLearningStatus(userId, courseId);
}
}

添加选课信息

要判断课程是否收费以及详细信息,远程调用内容微服务,查询已发布的课程信息。具体业务流程如下:

接口信息

路径地址 http://localhost:63020/learning/choosecourse/12
请求方式 POST
请求参数 Long
返回结果 XcChooseCourseVO

返回结果VO

CourseCategoryTreeVO
@Data
@EqualsAndHashCode(callSuper = true)
public class XcChooseCourseVO extends XcChooseCourse {
// 学习资格
public String learnStatus;
}

查询已发布课程

修改内容微服务,增加查询已发布课程的接口,新建client包,不使用@ResponseResult注解,可防止返回包装类,直接返回原始类型。

@RestController
public class CoursePublishClient {
private final CoursePublishService coursePublishService;

public CoursePublishClient(CoursePublishService coursePublishService) {
this.coursePublishService = coursePublishService;
}

@ApiOperation("查询课程发布信息")
@GetMapping("/r/coursepublish/{courseId}")
public CoursePublish getCoursePublish(@PathVariable("courseId") Long courseId) {
return coursePublishService.getById(courseId);
}
}

learning-online-learning-service工程下创建Feign的调用接口:

@FeignClient(value = "content-api", fallbackFactory = ContentServiceClientFallbackFactory.class)
public interface ContentServiceClient {
@GetMapping("/content/r/coursepublish/{courseId}")
public CoursePublish getCoursePublish(@PathVariable("courseId") Long courseId);
}

熔断降级

import org.springframework.cloud.openfeign.FallbackFactory;

@Slf4j
@Component
public class ContentServiceClientFallbackFactory implements FallbackFactory<ContentServiceClient> {

@Override
public ContentServiceClient create(Throwable throwable) {
return courseId -> {
log.error("远程调用内容服务熔断降级: 课程ID: {}", courseId);
return null;
};
}
}

添加选课Service

在 MyCourseTablesService 中定义添加选课方法

MyCourseTablesService
public interface MyCourseTablesService {
/**
* 添加选课
*
* @param userId 用户ID
* @param courseId 课程ID
* @return com.swx.learning.model.vo.XcChooseCourseVO 选课信息
*/
public XcChooseCourseVO addChooseCourse(String userId, Long courseId);
}

实现该方法

MyCourseTablesServiceImpl
/**
* 选课相关服务
*/
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {
private final XcChooseCourseService xcChooseCourseService;
private final XcCourseTablesService xcCourseTablesService;
private final ContentServiceClient contentServiceClient;

public MyCourseTablesServiceImpl(XcChooseCourseService xcChooseCourseService, XcCourseTablesService xcCourseTablesService, ContentServiceClient contentServiceClient) {
this.xcChooseCourseService = xcChooseCourseService;
this.xcCourseTablesService = xcCourseTablesService;
this.contentServiceClient = contentServiceClient;
}

/**
* 添加选课
*
* @param userId 用户ID
* @param courseId 课程ID
* @return com.swx.learning.model.vo.XcChooseCourseVO 选课信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public XcChooseCourseVO addChooseCourse(String userId, Long courseId) {
// 远程调用内容管理查询课程的收费规则
CoursePublish coursePublish = Optional.ofNullable(contentServiceClient.getCoursePublish(courseId))
.orElseThrow(() -> new BizException("课程不存在"));

// 收费规则
String charge = coursePublish.getCharge();
// 选课记录
XcChooseCourse chooseCourse = null;
if ("201000".equals(charge)) {
// 免费课程,会向选课记录表和我的课程表写数据
chooseCourse = xcChooseCourseService.addFreeCourse(userId, coursePublish);
XcCourseTables xcCourseTables = xcCourseTablesService.addCourseTables(chooseCourse);
} else {
// 收费课程,选课记录表写入数据
chooseCourse = xcChooseCourseService.addChargeCourse(userId, coursePublish);
}
// 返回选课资格
XcChooseCourseVO xcChooseCourseVO = new XcChooseCourseVO();
BeanUtils.copyProperties(chooseCourse, xcChooseCourseVO);
XcCourseTablesVO xcCourseTablesVO = getLearningStatus(userId, courseId);
xcChooseCourseVO.setLearnStatus(xcCourseTablesVO.getLearnStatus());
return xcChooseCourseVO;
}
}

添加课程记录

这里提供两个方法,分别是添加收费课程的记录和付费课程的记录

找到 XcChooseCourseService 服务类,定义上述两个方法:

XcChooseCourseService
public interface XcChooseCourseService extends IService<XcChooseCourse> {
/**
* 添加免费课程
*
* @param userId 用户ID
* @param coursePublish 课程信息
* @return com.swx.learning.model.po.XcChooseCourse 选课记录
*/
XcChooseCourse addFreeCourse(String userId, CoursePublish coursePublish);

/**
* 添加收费课程
*
* @param userId 用户ID
* @param coursePublish 课程信息
* @return com.swx.learning.model.po.XcChooseCourse 选课记录
*/
XcChooseCourse addChargeCourse(String userId, CoursePublish coursePublish);
}

实现该方法:

XcChooseCourseServiceImpl
@Service
public class XcChooseCourseServiceImpl extends ServiceImpl<XcChooseCourseMapper, XcChooseCourse> implements XcChooseCourseService {


/**
* 添加免费课程
*
* @param userId 用户ID
* @param coursePublish 课程信息
* @return com.swx.learning.model.po.XcChooseCourse 选课记录
*/
@Override
@Transactional(rollbackFor = Exception.class)
public XcChooseCourse addFreeCourse(String userId, CoursePublish coursePublish) {
return addCourse(userId, coursePublish, false);
}

/**
* 添加收费课程
*
* @param userId 用户ID
* @param coursePublish 课程信息
* @return com.swx.learning.model.po.XcChooseCourse 选课记录
*/
@Override
@Transactional(rollbackFor = Exception.class)
public XcChooseCourse addChargeCourse(String userId, CoursePublish coursePublish) {
return addCourse(userId, coursePublish, true);
}


/**
* 添加课程
*
* @param userId 用户ID
* @param coursePublish 课程信息
* @param isCharge 是否收费
* @return com.swx.learning.model.po.XcChooseCourse 选课记录
*/
public XcChooseCourse addCourse(String userId, CoursePublish coursePublish, boolean isCharge) {
String status = "701001"; // 选课成功
String orderType = "700001"; // 免费课程
if (isCharge) {
status = "701002"; // 待支付
orderType = "700002"; // 收费课程
}
Long courseId = coursePublish.getId();
// 查询是否已选
List<XcChooseCourse> chooseCourses = list(Wrappers.<XcChooseCourse>lambdaQuery()
.eq(XcChooseCourse::getUserId, userId)
.eq(XcChooseCourse::getCourseId, courseId)
.eq(XcChooseCourse::getStatus, status) // 待支付
.eq(XcChooseCourse::getOrderType, orderType));// 收费课程
if (!chooseCourses.isEmpty()) {
return chooseCourses.get(0);
}

// 向选课记录表写入数据
XcChooseCourse chooseCourse = new XcChooseCourse();
chooseCourse.setCourseId(courseId);
chooseCourse.setCourseName(coursePublish.getName());
chooseCourse.setCompanyId(coursePublish.getCompanyId());
chooseCourse.setUserId(userId);
chooseCourse.setOrderType(orderType);
chooseCourse.setCreateDate(LocalDateTime.now());
chooseCourse.setCoursePrice(coursePublish.getPrice());
chooseCourse.setValidDays(365);
chooseCourse.setStatus(status);
chooseCourse.setValidtimeStart(LocalDateTime.now());
chooseCourse.setValidtimeEnd(chooseCourse.getValidtimeStart().plusDays(chooseCourse.getValidDays()));
boolean save = save(chooseCourse);
if (!save) {
throw new BizException("添加选课记录失败");
}
return chooseCourse;
}
}

添加我的课程表

免费课程可直接加入我的课程表,收费课程需要支付完成后方可加入我的课程表

找到 XcCourseTablesService 服务类,定义如下的方法

XcCourseTablesService
public interface XcCourseTablesService extends IService<XcCourseTables> {

/**
* 添加到我的课程表
*
* @param xcChooseCourse 选课记录
* @return com.swx.learning.model.po.XcCourseTables 课程表
*/
XcCourseTables addCourseTables(XcChooseCourse xcChooseCourse);

/**
* 是否已存在课程表
*
* @param userId 用户ID
* @param courseId 课程ID
* @return com.swx.learning.model.po.XcChooseCourse 选课表
*/
XcCourseTables getCourseTable(String userId, Long courseId);
}

实现上述方法:

XcCourseTablesServiceImpl
@Service
public class XcCourseTablesServiceImpl extends ServiceImpl<XcCourseTablesMapper, XcCourseTables> implements XcCourseTablesService {

/**
* 添加到我的课程表
*
* @param xcChooseCourse 选课记录
* @return com.swx.learning.model.po.XcCourseTables 课程表
*/
@Override
@Transactional(rollbackFor = Exception.class)
public XcCourseTables addCourseTables(XcChooseCourse xcChooseCourse) {
String status = xcChooseCourse.getStatus();
if (!status.equals("701001")) {
throw new BizException("选课没有成功,无法添加到课程表");
}
XcCourseTables courseTables = getCourseTable(xcChooseCourse.getUserId(), xcChooseCourse.getCourseId());
if (courseTables != null) {
return courseTables;
}
courseTables = new XcCourseTables();
BeanUtils.copyProperties(xcChooseCourse, courseTables);
courseTables.setChooseCourseId(xcChooseCourse.getId()); // 记录选课表的主键
courseTables.setCourseType(xcChooseCourse.getOrderType());
courseTables.setUpdateDate(LocalDateTime.now());
boolean save = save(courseTables);
if (!save) {
throw new BizException("添加我的课程表失败");
}
return courseTables;
}



/**
* 是否已存在课程表
*
* @param userId 用户ID
* @param courseId 课程ID
* @return com.swx.learning.model.po.XcChooseCourse 选课表
*/
@Override
public XcCourseTables getCourseTable(String userId, Long courseId) {
return getOne(Wrappers.<XcCourseTables>lambdaQuery()
.eq(XcCourseTables::getUserId, userId)
.eq(XcCourseTables::getCourseId, courseId));
}

}

添加选课Controller

MyCourseTablesController
@Api(value = "我的课程表接口", tags = "我的课程表接口")
@RestController
@RequestMapping("/choosecourse")
public class MyCourseTablesController {

private final MyCourseTablesService myCourseTablesService;

public MyCourseTablesController(MyCourseTablesService myCourseTablesService) {
this.myCourseTablesService = myCourseTablesService;
}

@ApiOperation("添加选课")
@PostMapping("/{courseId}")
public XcChooseCourseVO addChooseCourse(@PathVariable("courseId") Long courseId) {
// 获取userId
SecurityUtil.XcUser user = SecurityUtil.getUser();
String userId = user.getId();
return myCourseTablesService.addChooseCourse(userId, courseId);
}
}

查询课程表

接口信息

路径地址 http://localhost:63020/learning/mycoursetable
请求方式 POST
请求参数 MyCourseTableParamsDTO
返回结果 PageResult

参数DTO

@Data
public class MyCourseTableParamsDTO {
String userId;
private String courseType;
private String sortType;
private String expiresType;

int page = 1;
int startIndex;
int size = 4;
}

查询Service

在 MyCourseTablesService 中定义查询我的课程表方法

MyCourseTablesService
/**
* 查询我的课程表
* @param dto 查询参数
*/
PageResult<XcCourseTables> getMyCourseTables(MyCourseTableParamsDTO dto);

实现该方法:

MyCourseTablesServiceImpl
/**
* 查询我的课程表
*
* @param dto 查询参数
*/
@Override
public PageResult<XcCourseTables> getMyCourseTables(MyCourseTableParamsDTO dto) {
String userId = dto.getUserId();
int size = dto.getSize();
int pageNo = dto.getPage();
Page<XcCourseTables> iPage = new Page<>(pageNo, size);
Page<XcCourseTables> pageResult = xcCourseTablesService.page(iPage, Wrappers.<XcCourseTables>lambdaQuery()
.eq(XcCourseTables::getUserId, userId));
return new PageResult<>(pageResult.getRecords(), pageResult.getTotal(), pageNo, size);
}

查询Controller

MyCourseTablesController
@ApiOperation("我的课程表")
@GetMapping("/mycoursetable")
public PageResult<XcCourseTables> getMyCourseTables(MyCourseTableParamsDTO dto) {
SecurityUtil.XcUser user = SecurityUtil.getUser();
dto.setUserId(user.getId());
return myCourseTablesService.getMyCourseTables(dto);
}