32583 字
约 108 分钟
44
appendix_F
2026-09-26
无标签
附录F 学习服务模块源码详解
模块概览(面向 0 基础读者):
- 负责学员选课、课程表、学习记录以及播放鉴权。
- 整合支付回调、课程服务,实现学习资格校验。
- 提供学习端 API,支持 PC/移动端统一调用。
核心目录:
xuecheng-plus-learning/xuecheng-plus-learning-api/src/main/java/com/xuecheng/learning/apixuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/servicexuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/feignclientxuecheng-plus-learning/xuecheng-plus-learning-model/src/main/java/com/xuecheng/learning/modelxuecheng-plus-learning/xuecheng-plus-learning-api/src/main/resources
文件:xuecheng-plus-learning/api/main/com/xuecheng/learning/api/MyCourseTablesController.java
package com.xuecheng.learning.api; // 声明类所在的包路径
import com.xuecheng.base.exception.XueChengPlusException; // 导入 XueChengPlusException 类
import com.xuecheng.base.model.PageResult; // 导入 PageResult 类
import com.xuecheng.learning.model.dto.MyCourseTableParams; // 导入 MyCourseTableParams 类
import com.xuecheng.learning.model.dto.XcChooseCourseDto; // 导入 XcChooseCourseDto 类
import com.xuecheng.learning.model.dto.XcCourseTablesDto; // 导入 XcCourseTablesDto 类
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
import com.xuecheng.learning.service.MyCourseTablesService; // 导入 MyCourseTablesService 类
import com.xuecheng.learning.util.SecurityUtil; // 导入 SecurityUtil 类
import io.swagger.annotations.Api; // 导入 Api 类
import io.swagger.annotations.ApiOperation; // 导入 ApiOperation 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 类
import org.springframework.web.bind.annotation.PathVariable; // 导入 PathVariable 类
import org.springframework.web.bind.annotation.PostMapping; // 导入 PostMapping 类
import org.springframework.web.bind.annotation.RestController; // 导入 RestController 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 我的课程表接口 // 保留原作者写的块注释
* @date 2022/10/25 9:40 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Api(value = "我的课程表接口", tags = "我的课程表接口") // 使用注解 @Api(value = "我的课程表接口", tags = "我的课程表接口")
@Slf4j // 使用注解 @Slf4j
@RestController // 使用注解 @RestController
public class MyCourseTablesController { // 定义 class MyCourseTablesController
@Autowired // 使用注解 @Autowired
MyCourseTablesService myCourseTablesService; // 执行语句
@ApiOperation("添加选课") // 使用注解 @ApiOperation("添加选课")
@PostMapping("/choosecourse/{courseId}") // 使用注解 @PostMapping("/choosecourse/{courseId}")
public XcChooseCourseDto addChooseCourse(@PathVariable("courseId") Long courseId) { // 定义方法 addChooseCourse(...)
//当前登录的用户 // 保留原作者写的行内注释
SecurityUtil.XcUser user = SecurityUtil.getUser(); // 把 SecurityUtil.getUser() 的返回值赋给 user
if(user == null){ // 定义方法 方法(...)
XueChengPlusException.cast("请登录"); // 执行语句
} // 代码块结束
//用户id // 保留原作者写的行内注释
String userId = user.getId(); // 把 user.getId() 的返回值赋给 userId
//添加选课 // 保留原作者写的行内注释
XcChooseCourseDto xcChooseCourseDto = myCourseTablesService.addChooseCourse(userId, courseId); // 把 myCourseTablesService.addChooseCourse(userId, courseId) 赋值给 xcChooseCourseDto
return xcChooseCourseDto; // 返回 xcChooseCourseDto
} // 代码块结束
@ApiOperation("查询学习资格") // 使用注解 @ApiOperation("查询学习资格")
@PostMapping("/choosecourse/learnstatus/{courseId}") // 使用注解 @PostMapping("/choosecourse/learnstatus/{courseId}")
public XcCourseTablesDto getLearnstatus(@PathVariable("courseId") Long courseId) { // 定义方法 getLearnstatus(...)
//当前登录的用户 // 保留原作者写的行内注释
SecurityUtil.XcUser user = SecurityUtil.getUser(); // 把 SecurityUtil.getUser() 的返回值赋给 user
if(user == null){ // 定义方法 方法(...)
XueChengPlusException.cast("请登录"); // 执行语句
} // 代码块结束
//用户id // 保留原作者写的行内注释
String userId = user.getId(); // 把 user.getId() 的返回值赋给 userId
XcCourseTablesDto learningStatus = myCourseTablesService.getLearningStatus(userId, courseId); // 把 myCourseTablesService.getLearningStatus(userId, courseId) 赋值给 learningStatus
return learningStatus; // 返回 learningStatus
} // 代码块结束
@ApiOperation("我的课程表") // 使用注解 @ApiOperation("我的课程表")
@GetMapping("/mycoursetable") // 使用注解 @GetMapping("/mycoursetable")
public PageResult<XcCourseTables> mycoursetable(MyCourseTableParams params) { // 定义方法 mycoursetable(...)
//当前登录的用户 // 保留原作者写的行内注释
SecurityUtil.XcUser user = SecurityUtil.getUser(); // 把 SecurityUtil.getUser() 的返回值赋给 user
if(user == null){ // 定义方法 方法(...)
XueChengPlusException.cast("请登录"); // 执行语句
} // 代码块结束
//用户id // 保留原作者写的行内注释
String userId = user.getId(); // 把 user.getId() 的返回值赋给 userId
params.setUserId(userId); // 执行语句
PageResult<XcCourseTables> mycoursetables = myCourseTablesService.mycoursetables(params); // 把 myCourseTablesService.mycoursetables(params) 赋值给 mycoursetables
return mycoursetables; // 返回 mycoursetables
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/api/main/com/xuecheng/learning/api/MyLearningController.java
package com.xuecheng.learning.api; // 声明类所在的包路径
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类
import com.xuecheng.learning.service.LearningService; // 导入 LearningService 类
import com.xuecheng.learning.util.SecurityUtil; // 导入 SecurityUtil 类
import io.swagger.annotations.Api; // 导入 Api 类
import io.swagger.annotations.ApiOperation; // 导入 ApiOperation 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 类
import org.springframework.web.bind.annotation.PathVariable; // 导入 PathVariable 类
import org.springframework.web.bind.annotation.RestController; // 导入 RestController 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 我的学习接口 // 保留原作者写的块注释
* @date 2022/10/27 8:59 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Api(value = "学习过程管理接口", tags = "学习过程管理接口") // 使用注解 @Api(value = "学习过程管理接口", tags = "学习过程管理接口")
@Slf4j // 使用注解 @Slf4j
@RestController // 使用注解 @RestController
public class MyLearningController { // 定义 class MyLearningController
@Autowired // 使用注解 @Autowired
LearningService learningService; // 执行语句
/** // 保留原作者写的块注释
* // 保留原作者写的块注释
* @param courseId 课程id // 保留原作者写的块注释
* @param teachplanId 课程计划id // 保留原作者写的块注释
* @param mediaId 媒资文件id // 保留原作者写的块注释
* @return // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@ApiOperation("获取视频") // 使用注解 @ApiOperation("获取视频")
@GetMapping("/open/learn/getvideo/{courseId}/{teachplanId}/{mediaId}") // 使用注解 @GetMapping("/open/learn/getvideo/{courseId}/{teachplanId}/{mediaId}")
public RestResponse<String> getvideo(@PathVariable("courseId") Long courseId, @PathVariable("teachplanId") Long teachplanId, @PathVariable("mediaId") String mediaId) { // 定义方法 getvideo(...)
SecurityUtil.XcUser user = SecurityUtil.getUser(); // 把 SecurityUtil.getUser() 的返回值赋给 user
String userId = user.getId(); // 把 user.getId() 的返回值赋给 userId
//获取视频 // 保留原作者写的行内注释
RestResponse<String> restResponse = learningService.getVideo(userId, courseId, teachplanId, mediaId); // 把 learningService.getVideo(userId, courseId, teachplanId, mediaId) 赋值给 restResponse
return restResponse; // 返回 restResponse
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/api/main/com/xuecheng/learning/config/ResouceServerConfig.java
package com.xuecheng.learning.config; // 声明类所在的包路径
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; // 导入 EnableGlobalMethodSecurity 类
import org.springframework.security.config.annotation.web.builders.HttpSecurity; // 导入 HttpSecurity 类
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; // 导入 EnableResourceServer 类
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; // 导入 ResourceServerConfigurerAdapter 类
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; // 导入 ResourceServerSecurityConfigurer 类
import org.springframework.security.oauth2.provider.token.TokenStore; // 导入 TokenStore 类
/** // 保留原作者写的块注释
* @author Administrator // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
**/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
@EnableResourceServer // 使用注解 @EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) // 使用注解 @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class ResouceServerConfig extends ResourceServerConfigurerAdapter { // 定义 class ResouceServerConfig
//资源服务标识 // 保留原作者写的行内注释
public static final String RESOURCE_ID = "xuecheng-plus"; // 把 "xuecheng-plus" 赋值给 RESOURCE_ID
@Autowired // 使用注解 @Autowired
TokenStore tokenStore; // 执行语句
@Override // 使用注解 @Override
public void configure(ResourceServerSecurityConfigurer resources) { // 定义方法 configure(...)
resources.resourceId(RESOURCE_ID)//资源 id // 代码逻辑
.tokenStore(tokenStore) // 代码逻辑
.stateless(true); // 执行语句
} // 代码块结束
@Override // 使用注解 @Override
public void configure(HttpSecurity http) throws Exception { // 定义方法 configure(...)
http.csrf().disable() // 代码逻辑
.authorizeRequests() // 代码逻辑
// .antMatchers("/r/**","/course/**").authenticated()//所有/r/**的请求必须认证通过 // 保留原作者写的行内注释
.anyRequest().permitAll() // 代码逻辑
; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/api/main/com/xuecheng/learning/config/TokenConfig.java
package com.xuecheng.learning.config; // 声明类所在的包路径
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.security.oauth2.provider.token.TokenStore; // 导入 TokenStore 类
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; // 导入 JwtAccessTokenConverter 类
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; // 导入 JwtTokenStore 类
/** // 保留原作者写的块注释
* @author Administrator // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
**/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
public class TokenConfig { // 定义 class TokenConfig
//jwt签名密钥,与认证服务保持一致 // 保留原作者写的行内注释
private String SIGNING_KEY = "mq123"; // 把 "mq123" 赋值给 SIGNING_KEY
@Bean // 使用注解 @Bean
public TokenStore tokenStore() { // 定义方法 tokenStore(...)
//JWT令牌存储方案 // 保留原作者写的行内注释
return new JwtTokenStore(accessTokenConverter()); // 返回 new JwtTokenStore(accessTokenConverter())
} // 代码块结束
@Bean // 使用注解 @Bean
public JwtAccessTokenConverter accessTokenConverter() { // 定义方法 accessTokenConverter(...)
JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); // 创建 JwtAccessTokenConverter 对象并赋值给 converter
converter.setSigningKey(SIGNING_KEY); // 执行语句
return converter; // 返回 converter
} // 代码块结束
/* @Bean // 保留原作者写的块注释
public TokenStore tokenStore() { // 定义方法 tokenStore(...)
//使用内存存储令牌(普通令牌) // 保留原作者写的行内注释
return new InMemoryTokenStore(); // 返回 new InMemoryTokenStore()
}*/ // 代码逻辑
} // 代码块结束
文件:xuecheng-plus-learning/api/main/com/xuecheng/learning/util/SecurityUtil.java
package com.xuecheng.learning.util; // 声明类所在的包路径
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import lombok.Data; // 导入 Data 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.security.core.context.SecurityContextHolder; // 导入 SecurityContextHolder 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 用户身份信息获取工具类 // 保留原作者写的块注释
* @date 2022/10/20 11:41 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
public class SecurityUtil { // 定义 class SecurityUtil
public static XcUser getUser() { // 定义方法 getUser(...)
//拿jwt中的用户身份 // 保留原作者写的行内注释
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); // 把 SecurityContextHolder.getContext().getAuthentication().getPrincipal() 的返回值赋给 principal
if (principal instanceof String){ // 定义方法 方法(...)
String jsonString = (String) principal; // 把 (String) principal 赋值给 jsonString
XcUser xcUser = null; // 把变量 xcUser 初始化为 null
try { // 尝试执行可能抛出异常的代码
xcUser = JSON.parseObject(jsonString, XcUser.class); // 把 JSON.parseObject(jsonString, XcUser.class) 赋值给 xcUser
} catch (Exception e) { // 定义方法 catch(...)
log.debug("解析jwt中的用户身份无法转成XcUser对象:{}",jsonString); // 执行语句
} // 代码块结束
return xcUser; // 返回 xcUser
} // 代码块结束
return null; // 返回 null
} // 代码块结束
@Data // 使用注解 @Data
public static class XcUser implements Serializable { // 代码逻辑
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
private String id; // 执行语句
private String username; // 执行语句
private String password; // 执行语句
private String salt; // 执行语句
private String name; // 执行语句
private String nickname; // 执行语句
private String wxUnionid; // 执行语句
private String companyId; // 执行语句
/** // 保留原作者写的块注释
* 头像 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userpic; // 执行语句
private String utype; // 执行语句
private LocalDateTime birthday; // 执行语句
private String sex; // 执行语句
private String email; // 执行语句
private String cellphone; // 执行语句
private String qq; // 执行语句
/** // 保留原作者写的块注释
* 用户状态 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String status; // 执行语句
private LocalDateTime createTime; // 执行语句
private LocalDateTime updateTime; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/api/main/com/xuecheng/LearningApiApplication.java
package com.xuecheng; // 声明类所在的包路径
import org.springframework.boot.SpringApplication; // 导入 SpringApplication 类
import org.springframework.boot.autoconfigure.SpringBootApplication; // 导入 SpringBootApplication 类
import org.springframework.cloud.openfeign.EnableFeignClients; // 导入 EnableFeignClients 类
@EnableFeignClients(basePackages={"com.xuecheng.*.feignclient"}) // 使用注解 @EnableFeignClients(basePackages={"com.xuecheng.*.feignclient"})
@SpringBootApplication // 使用注解 @SpringBootApplication
public class LearningApiApplication { // 定义 class LearningApiApplication
public static void main(String[] args) { // 定义方法 main(...)
SpringApplication.run(LearningApiApplication.class, args); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/api/resources/bootstrap.yml
#微服务配置
spring:
application:
name: learning-api
cloud:
nacos:
server-addr: 192.168.101.65:8848
discovery:
namespace: dev402
group: xuecheng-plus-project
config:
namespace: dev402
group: xuecheng-plus-project
file-extension: yaml
refresh-enabled: true
extension-configs:
- data-id: learning-service-${spring.profiles.active}.yaml
group: xuecheng-plus-project
refresh: true
shared-configs:
- data-id: swagger-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: logging-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: feign-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: rabbitmq-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
profiles:
active: dev
文件:xuecheng-plus-learning/api/resources/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>
文件:xuecheng-plus-learning/api_pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- 学习服务 API -->
<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-learning</artifactId>
<groupId>com.xuecheng</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>xuecheng-plus-learning-api</artifactId>
<dependencies>
<dependency>
<groupId>com.xuecheng</groupId>
<artifactId>xuecheng-plus-learning-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId> <!-- 接入统一认证 -->
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
</dependencies>
</project>
文件:xuecheng-plus-learning/model/com/xuecheng/learning/model/dto/MyCourseTableItemDto.java
package com.xuecheng.learning.model.dto; // 声明类所在的包路径
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 我的课程查询条件 // 保留原作者写的块注释
* @date 2022/10/6 9:42 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class MyCourseTableItemDto extends XcCourseTables { // 定义 class MyCourseTableItemDto
/** // 保留原作者写的块注释
* 最近学习时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime learnDate; // 执行语句
/** // 保留原作者写的块注释
* 学习时长 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long learnLength; // 执行语句
/** // 保留原作者写的块注释
* 章节id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long teachplanId; // 执行语句
/** // 保留原作者写的块注释
* 章节名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String teachplanName; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/model/com/xuecheng/learning/model/dto/MyCourseTableParams.java
package com.xuecheng.learning.model.dto; // 声明类所在的包路径
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @description 我的课程查询条件 // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/6 9:42 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class MyCourseTableParams { // 定义 class MyCourseTableParams
String userId; // 执行语句
//课程类型 [{"code":"700001","desc":"免费课程"},{"code":"700002","desc":"收费课程"}] // 保留原作者写的行内注释
private String courseType; // 执行语句
//排序 1按学习时间进行排序 2按加入时间进行排序 // 保留原作者写的行内注释
private String sortType; // 执行语句
//1即将过期、2已经过期 // 保留原作者写的行内注释
private String expiresType; // 执行语句
int page=1; // 把 1 赋值给 page
int startIndex; // 执行语句
int size=4; // 把 4 赋值给 size
} // 代码块结束
文件:xuecheng-plus-learning/model/com/xuecheng/learning/model/dto/XcChooseCourseDto.java
package com.xuecheng.learning.model.dto; // 声明类所在的包路径
import com.xuecheng.learning.model.po.XcChooseCourse; // 导入 XcChooseCourse 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2022/10/2 16:10 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class XcChooseCourseDto extends XcChooseCourse { // 定义 class XcChooseCourseDto
//学习资格,[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}] // 保留原作者写的行内注释
public String learnStatus; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/model/com/xuecheng/learning/model/dto/XcCourseTablesDto.java
package com.xuecheng.learning.model.dto; // 声明类所在的包路径
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @description 我的课程表模型类 // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/2 16:09 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class XcCourseTablesDto extends XcCourseTables { // 定义 class XcCourseTablesDto
//学习资格,[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}] // 保留原作者写的行内注释
public String learnStatus; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/model/com/xuecheng/learning/model/po/XcChooseCourse.java
package com.xuecheng.learning.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.*; // 导入 * 类
import lombok.Data; // 导入 Data 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_choose_course") // 使用注解 @TableName("xc_choose_course")
public class XcChooseCourse implements Serializable { // 定义 class XcChooseCourse
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
/** // 保留原作者写的块注释
* 主键 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@TableId(value = "id", type = IdType.AUTO) // 使用注解 @TableId(value = "id", type = IdType.AUTO)
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 课程id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long courseId; // 执行语句
/** // 保留原作者写的块注释
* 课程名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String courseName; // 执行语句
/** // 保留原作者写的块注释
* 用户id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userId; // 执行语句
/** // 保留原作者写的块注释
* 机构id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long companyId; // 执行语句
/** // 保留原作者写的块注释
* 选课类型 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderType; // 执行语句
/** // 保留原作者写的块注释
* 添加时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@TableField(fill = FieldFill.INSERT) // 使用注解 @TableField(fill = FieldFill.INSERT)
private LocalDateTime createDate; // 执行语句
/** // 保留原作者写的块注释
* 课程有效期(天) // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Integer validDays; // 执行语句
private Float coursePrice; // 执行语句
/** // 保留原作者写的块注释
* 选课状态 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String status; // 执行语句
/** // 保留原作者写的块注释
* 开始服务时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime validtimeStart; // 执行语句
/** // 保留原作者写的块注释
* 结束服务时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime validtimeEnd; // 执行语句
/** // 保留原作者写的块注释
* 备注 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String remarks; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/model/com/xuecheng/learning/model/po/XcCourseTables.java
package com.xuecheng.learning.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.*; // 导入 * 类
import lombok.Data; // 导入 Data 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_course_tables") // 使用注解 @TableName("xc_course_tables")
public class XcCourseTables implements Serializable { // 定义 class XcCourseTables
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
@TableId(value = "id", type = IdType.AUTO) // 使用注解 @TableId(value = "id", type = IdType.AUTO)
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 选课记录id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long chooseCourseId; // 执行语句
/** // 保留原作者写的块注释
* 用户id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userId; // 执行语句
/** // 保留原作者写的块注释
* 课程id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long courseId; // 执行语句
/** // 保留原作者写的块注释
* 机构id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long companyId; // 执行语句
/** // 保留原作者写的块注释
* 课程名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String courseName; // 执行语句
/** // 保留原作者写的块注释
* 课程名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String courseType; // 执行语句
/** // 保留原作者写的块注释
* 添加时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@TableField(fill = FieldFill.INSERT) // 使用注解 @TableField(fill = FieldFill.INSERT)
private LocalDateTime createDate; // 执行语句
/** // 保留原作者写的块注释
* 开始服务时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime validtimeStart; // 执行语句
/** // 保留原作者写的块注释
* 到期时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime validtimeEnd; // 执行语句
/** // 保留原作者写的块注释
* 更新时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime updateDate; // 执行语句
/** // 保留原作者写的块注释
* 备注 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String remarks; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/model/com/xuecheng/learning/model/po/XcLearnRecord.java
package com.xuecheng.learning.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.IdType; // 导入 IdType 类
import com.baomidou.mybatisplus.annotation.TableId; // 导入 TableId 类
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_learn_record") // 使用注解 @TableName("xc_learn_record")
public class XcLearnRecord implements Serializable { // 定义 class XcLearnRecord
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
@TableId(value = "id", type = IdType.AUTO) // 使用注解 @TableId(value = "id", type = IdType.AUTO)
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 课程id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long courseId; // 执行语句
/** // 保留原作者写的块注释
* 课程名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String courseName; // 执行语句
/** // 保留原作者写的块注释
* 用户id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userId; // 执行语句
/** // 保留原作者写的块注释
* 最近学习时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime learnDate; // 执行语句
/** // 保留原作者写的块注释
* 学习时长 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long learnLength; // 执行语句
/** // 保留原作者写的块注释
* 章节id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long teachplanId; // 执行语句
/** // 保留原作者写的块注释
* 章节名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String teachplanName; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/model_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-learning</artifactId>
<groupId>com.xuecheng</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>xuecheng-plus-learning-model</artifactId>
<dependencies>
<dependency>
<groupId>com.xuecheng</groupId>
<artifactId>xuecheng-plus-base</artifactId> <!-- 复用通用响应/异常工具 -->
<version>0.0.1-SNAPSHOT</version>
</dependency>
<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> <!-- 使用 Lombok 简化 PO/DTO -->
</dependency>
</dependencies>
</project>
文件:xuecheng-plus-learning/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- SQL 语句片段 -->
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- SQL 语句片段 -->
<modelVersion>4.0.0</modelVersion> <!-- SQL 语句片段 -->
<parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-parent</artifactId> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
<relativePath>../xuecheng-plus-parent</relativePath> <!-- SQL 语句片段 -->
</parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-learning</artifactId> <!-- SQL 语句片段 -->
<packaging>pom</packaging> <!-- SQL 语句片段 -->
<modules> <!-- SQL 语句片段 -->
<module>xuecheng-plus-learning-api</module> <!-- SQL 语句片段 -->
<module>xuecheng-plus-learning-service</module> <!-- SQL 语句片段 -->
<module>xuecheng-plus-learning-model</module> <!-- SQL 语句片段 -->
</modules> <!-- SQL 语句片段 -->
</project> <!-- SQL 语句片段 -->
文件:xuecheng-plus-learning/root_pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- 学习模块聚合 POM -->
<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>
<packaging>pom</packaging> <!-- 聚合模块本身不打包 -->
<artifactId>xuecheng-plus-learning</artifactId> <!-- 学习服务父工程 -->
<modules> <!-- 子模块列表 -->
<module>xuecheng-plus-learning-api</module>
<module>xuecheng-plus-learning-model</module>
<module>xuecheng-plus-learning-service</module>
</modules>
</project>
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/config/MybatisPlusConfig.java
package com.xuecheng.learning.config; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.DbType; // 导入 DbType 类
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; // 导入 MybatisPlusInterceptor 类
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; // 导入 PaginationInnerInterceptor 类
import org.mybatis.spring.annotation.MapperScan; // 导入 MapperScan 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
/** // 保留原作者写的块注释
* <P> // 保留原作者写的块注释
* Mybatis-Plus 配置 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
@MapperScan("com.xuecheng.learning.mapper") // 使用注解 @MapperScan("com.xuecheng.learning.mapper")
public class MybatisPlusConfig { // 定义 class MybatisPlusConfig
/** // 保留原作者写的块注释
* 新的分页插件 // 保留原作者写的块注释
* 需要设置 MybatisConfiguration#useDeprecatedExecutor = false // 保留原作者写的块注释
* 避免缓存出现问题(该属性会在旧插件移除后一同移除) // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Bean // 使用注解 @Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() { // 定义方法 mybatisPlusInterceptor(...)
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 创建 MybatisPlusInterceptor 对象并赋值给 interceptor
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 执行语句
return interceptor; // 返回 interceptor
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/config/PayNotifyConfig.java
package com.xuecheng.learning.config; // 声明类所在的包路径
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.amqp.core.*; // 导入 * 类
import org.springframework.beans.factory.annotation.Qualifier; // 导入 Qualifier 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2023/2/23 16:59 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Configuration // 使用注解 @Configuration
public class PayNotifyConfig { // 定义 class PayNotifyConfig
//交换机 // 保留原作者写的行内注释
public static final String PAYNOTIFY_EXCHANGE_FANOUT = "paynotify_exchange_fanout"; // 把 "paynotify_exchange_fanout" 赋值给 PAYNOTIFY_EXCHANGE_FANOUT
//支付结果通知消息类型 // 保留原作者写的行内注释
public static final String MESSAGE_TYPE = "payresult_notify"; // 把 "payresult_notify" 赋值给 MESSAGE_TYPE
//支付通知队列 // 保留原作者写的行内注释
public static final String PAYNOTIFY_QUEUE = "paynotify_queue"; // 把 "paynotify_queue" 赋值给 PAYNOTIFY_QUEUE
//声明交换机,且持久化 // 保留原作者写的行内注释
@Bean(PAYNOTIFY_EXCHANGE_FANOUT) // 使用注解 @Bean(PAYNOTIFY_EXCHANGE_FANOUT)
public FanoutExchange paynotify_exchange_fanout() { // 定义方法 paynotify_exchange_fanout(...)
// 三个参数:交换机名称、是否持久化、当没有queue与其绑定时是否自动删除 // 保留原作者写的行内注释
return new FanoutExchange(PAYNOTIFY_EXCHANGE_FANOUT, true, false); // 返回 new FanoutExchange(PAYNOTIFY_EXCHANGE_FANOUT, true, false)
} // 代码块结束
//支付通知队列,且持久化 // 保留原作者写的行内注释
@Bean(PAYNOTIFY_QUEUE) // 使用注解 @Bean(PAYNOTIFY_QUEUE)
public Queue course_publish_queue() { // 定义方法 course_publish_queue(...)
return QueueBuilder.durable(PAYNOTIFY_QUEUE).build(); // 返回 QueueBuilder.durable(PAYNOTIFY_QUEUE).build()
} // 代码块结束
//交换机和支付通知队列绑定 // 保留原作者写的行内注释
@Bean // 使用注解 @Bean
public Binding binding_course_publish_queue(@Qualifier(PAYNOTIFY_QUEUE) Queue queue, @Qualifier(PAYNOTIFY_EXCHANGE_FANOUT) FanoutExchange exchange) { // 定义方法 binding_course_publish_queue(...)
return BindingBuilder.bind(queue).to(exchange); // 返回 BindingBuilder.bind(queue).to(exchange)
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/feignclient/ContentServiceClient.java
package com.xuecheng.learning.feignclient; // 声明类所在的包路径
import com.xuecheng.content.model.po.CoursePublish; // 导入 CoursePublish 类
import org.springframework.cloud.openfeign.FeignClient; // 导入 FeignClient 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 类
import org.springframework.web.bind.annotation.PathVariable; // 导入 PathVariable 类
import org.springframework.web.bind.annotation.ResponseBody; // 导入 ResponseBody 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 内容管理远程接口 // 保留原作者写的块注释
* @date 2022/10/25 9:13 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@FeignClient(value = "content-api",fallbackFactory = ContentServiceClientFallbackFactory.class) // 使用注解 @FeignClient(value = "content-api",fallbackFactory = ContentServiceClientFallbackFactory.class)
public interface ContentServiceClient { // 定义 interface ContentServiceClient
//查询已经发布的课程 // 保留原作者写的行内注释
@ResponseBody // 使用注解 @ResponseBody
@GetMapping("/content/r/coursepublish/{courseId}") // 使用注解 @GetMapping("/content/r/coursepublish/{courseId}")
public CoursePublish getCoursepublish(@PathVariable("courseId") Long courseId); // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/feignclient/ContentServiceClientFallbackFactory.java
package com.xuecheng.learning.feignclient; // 声明类所在的包路径
import com.xuecheng.content.model.po.CoursePublish; // 导入 CoursePublish 类
import feign.hystrix.FallbackFactory; // 导入 FallbackFactory 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.stereotype.Component; // 导入 Component 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2022/10/25 9:14 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Component // 使用注解 @Component
public class ContentServiceClientFallbackFactory implements FallbackFactory<ContentServiceClient> { // 定义 class ContentServiceClientFallbackFactory
@Override // 使用注解 @Override
public ContentServiceClient create(Throwable throwable) { // 定义方法 create(...)
return new ContentServiceClient() { // 定义方法 ContentServiceClient(...)
@Override // 使用注解 @Override
public CoursePublish getCoursepublish(Long courseId) { // 定义方法 getCoursepublish(...)
log.error("调用内容管理服务发生熔断:{}", throwable.toString(),throwable); // 执行语句
return null; // 返回 null
} // 代码块结束
}; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/feignclient/MediaServiceClient.java
package com.xuecheng.learning.feignclient; // 声明类所在的包路径
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类
import org.springframework.cloud.openfeign.FeignClient; // 导入 FeignClient 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 类
import org.springframework.web.bind.annotation.PathVariable; // 导入 PathVariable 类
import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 类
/** // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/27 9:04 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@FeignClient(value = "media-api",fallbackFactory = MediaServiceClientFallbackFactory.class) // 使用注解 @FeignClient(value = "media-api",fallbackFactory = MediaServiceClientFallbackFactory.class)
@RequestMapping("/media") // 使用注解 @RequestMapping("/media")
public interface MediaServiceClient { // 定义 interface MediaServiceClient
@GetMapping("/open/preview/{mediaId}") // 使用注解 @GetMapping("/open/preview/{mediaId}")
public RestResponse<String> getPlayUrlByMediaId(@PathVariable("mediaId") String mediaId); // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/feignclient/MediaServiceClientFallbackFactory.java
package com.xuecheng.learning.feignclient; // 声明类所在的包路径
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类
import feign.hystrix.FallbackFactory; // 导入 FallbackFactory 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.stereotype.Component; // 导入 Component 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2022/10/27 9:05 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Component // 使用注解 @Component
public class MediaServiceClientFallbackFactory implements FallbackFactory<MediaServiceClient> { // 定义 class MediaServiceClientFallbackFactory
@Override // 使用注解 @Override
public MediaServiceClient create(Throwable throwable) { // 定义方法 create(...)
return new MediaServiceClient() { // 定义方法 MediaServiceClient(...)
@Override // 使用注解 @Override
public RestResponse<String> getPlayUrlByMediaId(String mediaId) { // 定义方法 getPlayUrlByMediaId(...)
log.error("远程调用媒资管理服务熔断异常:{}", throwable.getMessage()); // 执行语句
return null; // 返回 null
} // 代码块结束
}; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/mapper/XcChooseCourseMapper.java
package com.xuecheng.learning.mapper; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.learning.model.po.XcChooseCourse; // 导入 XcChooseCourse 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* Mapper 接口 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface XcChooseCourseMapper extends BaseMapper<XcChooseCourse> { // 定义 interface XcChooseCourseMapper
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/mapper/XcChooseCourseMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.learning.mapper.XcChooseCourseMapper"> <!-- MyBatis 映射文件的根标签 -->
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.xuecheng.learning.model.po.XcChooseCourse"> <!-- 定义结果映射 -->
<id column="id" property="id" /> <!-- 主键列的映射规则 -->
<result column="course_id" property="courseId" /> <!-- 字段与属性的映射规则 -->
<result column="course_name" property="courseName" /> <!-- 字段与属性的映射规则 -->
<result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
<result column="company_id" property="companyId" /> <!-- 字段与属性的映射规则 -->
<result column="order_type" property="orderType" /> <!-- 字段与属性的映射规则 -->
<result column="create_date" property="createDate" /> <!-- 字段与属性的映射规则 -->
<result column="valid_days" property="validDays" /> <!-- 字段与属性的映射规则 -->
<result column="status" property="status" /> <!-- 字段与属性的映射规则 -->
<result column="validtime_start" property="validtimeStart" /> <!-- 字段与属性的映射规则 -->
<result column="validtime_end" property="validtimeEnd" /> <!-- 字段与属性的映射规则 -->
<result column="remarks" property="remarks" /> <!-- 字段与属性的映射规则 -->
</resultMap> <!-- 结束 resultMap 区块 -->
<!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
id, course_id, course_name, user_id, company_id, order_type, create_date, valid_days, status, validtime_start, validtime_end, remarks <!-- SQL 语句片段 -->
</sql> <!-- 结束 SQL 片段 -->
</mapper> <!-- 结束 mapper 标签 -->
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/mapper/XcCourseTablesMapper.java
package com.xuecheng.learning.mapper; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* Mapper 接口 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface XcCourseTablesMapper extends BaseMapper<XcCourseTables> { // 定义 interface XcCourseTablesMapper
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/mapper/XcCourseTablesMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.learning.mapper.XcCourseTablesMapper"> <!-- MyBatis 映射文件的根标签 -->
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.xuecheng.learning.model.po.XcCourseTables"> <!-- 定义结果映射 -->
<id column="id" property="id" /> <!-- 主键列的映射规则 -->
<result column="choose_course_id" property="chooseCourseId" /> <!-- 字段与属性的映射规则 -->
<result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
<result column="course_id" property="courseId" /> <!-- 字段与属性的映射规则 -->
<result column="company_id" property="companyId" /> <!-- 字段与属性的映射规则 -->
<result column="course_name" property="courseName" /> <!-- 字段与属性的映射规则 -->
<result column="create_date" property="createDate" /> <!-- 字段与属性的映射规则 -->
<result column="validtime_end" property="validtimeEnd" /> <!-- 字段与属性的映射规则 -->
<result column="update_date" property="updateDate" /> <!-- 字段与属性的映射规则 -->
<result column="remarks" property="remarks" /> <!-- 字段与属性的映射规则 -->
</resultMap> <!-- 结束 resultMap 区块 -->
<!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
id, choose_course_id, user_id, course_id, company_id, course_name, create_date, validtime_end, update_date, remarks <!-- SQL 语句片段 -->
</sql> <!-- 结束 SQL 片段 -->
</mapper> <!-- 结束 mapper 标签 -->
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/service/impl/LearningServiceImpl.java
package com.xuecheng.learning.service.impl; // 声明类所在的包路径
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类
import com.xuecheng.content.model.po.CoursePublish; // 导入 CoursePublish 类
import com.xuecheng.learning.feignclient.ContentServiceClient; // 导入 ContentServiceClient 类
import com.xuecheng.learning.feignclient.MediaServiceClient; // 导入 MediaServiceClient 类
import com.xuecheng.learning.model.dto.XcCourseTablesDto; // 导入 XcCourseTablesDto 类
import com.xuecheng.learning.service.LearningService; // 导入 LearningService 类
import com.xuecheng.learning.service.MyCourseTablesService; // 导入 MyCourseTablesService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.apache.commons.lang3.StringUtils; // 导入 StringUtils 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.stereotype.Service; // 导入 Service 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 在线学习接口 // 保留原作者写的块注释
* @date 2023/2/28 10:20 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Service // 使用注解 @Service
public class LearningServiceImpl implements LearningService { // 定义 class LearningServiceImpl
@Autowired // 使用注解 @Autowired
MyCourseTablesService myCourseTablesService; // 执行语句
@Autowired // 使用注解 @Autowired
ContentServiceClient contentServiceClient; // 执行语句
@Autowired // 使用注解 @Autowired
MediaServiceClient mediaServiceClient; // 执行语句
@Override // 使用注解 @Override
public RestResponse<String> getVideo(String userId, Long courseId, Long teachplanId, String mediaId) { // 定义方法 getVideo(...)
//查询课程信息 // 保留原作者写的行内注释
CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId); // 把 contentServiceClient.getCoursepublish(courseId) 赋值给 coursepublish
//判断如果为null不再继续 // 保留原作者写的行内注释
if(coursepublish == null){ // 定义方法 方法(...)
return RestResponse.validfail("课程不存在"); // 返回 RestResponse.validfail("课程不存在")
} // 代码块结束
//远程调用内容管理服务根据课程计划id(teachplanId)去查询课程计划信息,如果is_preview的值为1表示支持试学 // 保留原作者写的行内注释
//也可以从coursepublish对象中解析出课程计划信息去判断是否支持试学 // 保留原作者写的行内注释
//todo:如果支持试学调用媒资服务查询视频的播放地址,返回 // 保留原作者写的行内注释
//用户已登录 // 保留原作者写的行内注释
if(StringUtils.isNotEmpty(userId)){ // 定义方法 方法(...)
//获取学习资格 // 保留原作者写的行内注释
XcCourseTablesDto learningStatus = myCourseTablesService.getLearningStatus(userId, courseId); // 把 myCourseTablesService.getLearningStatus(userId, courseId) 赋值给 learningStatus
//学习资格,[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}] // 保留原作者写的行内注释
String learnStatus = learningStatus.getLearnStatus(); // 把 learningStatus.getLearnStatus() 的返回值赋给 learnStatus
if("702002".equals(learnStatus)){ // 定义方法 方法(...)
return RestResponse.validfail("无法学习,因为没有选课或选课后没有支付"); // 返回 RestResponse.validfail("无法学习,因为没有选课或选课后没有支付")
}else if("702003".equals(learnStatus)){ // 定义方法 if(...)
return RestResponse.validfail("已过期需要申请续期或重新支付"); // 返回 RestResponse.validfail("已过期需要申请续期或重新支付")
}else{ // 代码逻辑
//有资格学习,要返回视频的播放地址 // 保留原作者写的行内注释
//程调用媒资获取视频播放地址 // 保留原作者写的行内注释
RestResponse<String> playUrlByMediaId = mediaServiceClient.getPlayUrlByMediaId(mediaId); // 把 mediaServiceClient.getPlayUrlByMediaId(mediaId) 赋值给 playUrlByMediaId
return playUrlByMediaId; // 返回 playUrlByMediaId
} // 代码块结束
} // 代码块结束
//如果用户没有登录 // 保留原作者写的行内注释
//取出课程的收费规则 // 保留原作者写的行内注释
String charge = coursepublish.getCharge(); // 把 coursepublish.getCharge() 的返回值赋给 charge
if("201000".equals(charge)){ // 定义方法 方法(...)
//有资格学习,要返回视频的播放地址 // 保留原作者写的行内注释
//远程调用媒资获取视频播放地址 // 保留原作者写的行内注释
RestResponse<String> playUrlByMediaId = mediaServiceClient.getPlayUrlByMediaId(mediaId); // 把 mediaServiceClient.getPlayUrlByMediaId(mediaId) 赋值给 playUrlByMediaId
return playUrlByMediaId; // 返回 playUrlByMediaId
} // 代码块结束
return RestResponse.validfail("课程需要购买"); // 返回 RestResponse.validfail("课程需要购买")
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/service/impl/MyCourseTablesServiceImpl.java
package com.xuecheng.learning.service.impl; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 导入 LambdaQueryWrapper 类
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 Page 类
import com.xuecheng.base.exception.XueChengPlusException; // 导入 XueChengPlusException 类
import com.xuecheng.base.model.PageResult; // 导入 PageResult 类
import com.xuecheng.content.model.po.CoursePublish; // 导入 CoursePublish 类
import com.xuecheng.learning.feignclient.ContentServiceClient; // 导入 ContentServiceClient 类
import com.xuecheng.learning.mapper.XcChooseCourseMapper; // 导入 XcChooseCourseMapper 类
import com.xuecheng.learning.mapper.XcCourseTablesMapper; // 导入 XcCourseTablesMapper 类
import com.xuecheng.learning.model.dto.MyCourseTableParams; // 导入 MyCourseTableParams 类
import com.xuecheng.learning.model.dto.XcChooseCourseDto; // 导入 XcChooseCourseDto 类
import com.xuecheng.learning.model.dto.XcCourseTablesDto; // 导入 XcCourseTablesDto 类
import com.xuecheng.learning.model.po.XcChooseCourse; // 导入 XcChooseCourse 类
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
import com.xuecheng.learning.service.MyCourseTablesService; // 导入 MyCourseTablesService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.BeanUtils; // 导入 BeanUtils 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.stereotype.Service; // 导入 Service 类
import org.springframework.transaction.annotation.Transactional; // 导入 Transactional 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
import java.util.List; // 导入 List 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 选课相关接口实现 // 保留原作者写的块注释
* @date 2023/2/25 12:02 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Service // 使用注解 @Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService { // 定义 class MyCourseTablesServiceImpl
@Autowired // 使用注解 @Autowired
XcChooseCourseMapper chooseCourseMapper; // 执行语句
@Autowired // 使用注解 @Autowired
XcCourseTablesMapper courseTablesMapper; // 执行语句
@Autowired // 使用注解 @Autowired
ContentServiceClient contentServiceClient; // 执行语句
// 添加选课 // 保留原作者写的行内注释
@Transactional // 使用注解 @Transactional
@Override // 使用注解 @Override
public XcChooseCourseDto addChooseCourse(String userId, Long courseId) { // 定义方法 addChooseCourse(...)
//选课调用内容管理查询课程的收费规则 // 保留原作者写的行内注释
CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId); // 把 contentServiceClient.getCoursepublish(courseId) 赋值给 coursepublish
if(coursepublish == null){ // 定义方法 方法(...)
XueChengPlusException.cast("课程不存在"); // 执行语句
} // 代码块结束
//收费规则 // 保留原作者写的行内注释
String charge = coursepublish.getCharge(); // 把 coursepublish.getCharge() 的返回值赋给 charge
//选课记录 // 保留原作者写的行内注释
XcChooseCourse chooseCourse = null; // 把变量 chooseCourse 初始化为 null
if("201000".equals(charge)){//免费课程 // 定义方法 方法(...)
//向选课记录表写 // 保留原作者写的行内注释
chooseCourse = addFreeCoruse(userId, coursepublish); // 把 addFreeCoruse(userId, coursepublish) 赋值给 chooseCourse
//向我的课程表写 // 保留原作者写的行内注释
XcCourseTables xcCourseTables = addCourseTabls(chooseCourse); // 把 addCourseTabls(chooseCourse) 赋值给 xcCourseTables
}else{ // 代码逻辑
//如果收费课程,会向选课记录表写数据 // 保留原作者写的行内注释
chooseCourse = addChargeCoruse(userId, coursepublish); // 把 addChargeCoruse(userId, coursepublish) 赋值给 chooseCourse
} // 代码块结束
//判断学生的学习资格 // 保留原作者写的行内注释
XcCourseTablesDto xcCourseTablesDto = getLearningStatus(userId, courseId); // 把 getLearningStatus(userId, courseId) 赋值给 xcCourseTablesDto
//构造返回值 // 保留原作者写的行内注释
XcChooseCourseDto xcChooseCourseDto = new XcChooseCourseDto(); // 创建 XcChooseCourseDto 对象并赋值给 xcChooseCourseDto
BeanUtils.copyProperties(chooseCourse,xcChooseCourseDto); // 执行语句
//设置学习资格状态 // 保留原作者写的行内注释
xcChooseCourseDto.setLearnStatus(xcCourseTablesDto.getLearnStatus()); // 执行语句
return xcChooseCourseDto; // 返回 xcChooseCourseDto
} // 代码块结束
//返回//学习资格,[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}] // 保留原作者写的行内注释
@Override // 使用注解 @Override
public XcCourseTablesDto getLearningStatus(String userId, Long courseId) { // 定义方法 getLearningStatus(...)
//返回的结果 // 保留原作者写的行内注释
XcCourseTablesDto courseTablesDto = new XcCourseTablesDto(); // 创建 XcCourseTablesDto 对象并赋值给 courseTablesDto
//查询我的课程表,如果查不到说明没有选课 // 保留原作者写的行内注释
XcCourseTables xcCourseTables = getXcCourseTables(userId, courseId); // 把 getXcCourseTables(userId, courseId) 赋值给 xcCourseTables
if(xcCourseTables == null){ // 定义方法 方法(...)
//"code":"702002","desc":"没有选课或选课后没有支付" // 保留原作者写的行内注释
courseTablesDto.setLearnStatus("702002"); // 执行语句
return courseTablesDto; // 返回 courseTablesDto
} // 代码块结束
//如果查到了,判断是否过期,如果过期不能继续学习,没有过期可以继续学习 // 保留原作者写的行内注释
boolean before = xcCourseTables.getValidtimeEnd().isBefore(LocalDateTime.now()); // 把 xcCourseTables.getValidtimeEnd().isBefore(LocalDateTime.now()) 赋值给 before
if(before){ // 定义方法 方法(...)
//"code":"702003","desc":"已过期需要申请续期或重新支付" // 保留原作者写的行内注释
BeanUtils.copyProperties(xcCourseTables,courseTablesDto); // 执行语句
courseTablesDto.setLearnStatus("702003"); // 执行语句
return courseTablesDto; // 返回 courseTablesDto
}else{ // 代码逻辑
//"code":"702001","desc":"正常学习" // 保留原作者写的行内注释
BeanUtils.copyProperties(xcCourseTables,courseTablesDto); // 执行语句
courseTablesDto.setLearnStatus("702001"); // 执行语句
return courseTablesDto; // 返回 courseTablesDto
} // 代码块结束
} // 代码块结束
// 支付完毕添加到课程表 // 保留原作者写的行内注释
@Override // 使用注解 @Override
public boolean saveChooseCourseSuccess(String chooseCourseId) { // 定义方法 saveChooseCourseSuccess(...)
//根据选课id查询选课表 // 保留原作者写的行内注释
XcChooseCourse chooseCourse = chooseCourseMapper.selectById(chooseCourseId); // 把 chooseCourseMapper.selectById(chooseCourseId) 赋值给 chooseCourse
if(chooseCourse == null){ // 定义方法 方法(...)
log.debug("接收购买课程的消息,根据选课id从数据库找不到选课记录,选课id:{}",chooseCourseId); // 执行语句
return false; // 返回 false
} // 代码块结束
//选课状态 // 保留原作者写的行内注释
String status = chooseCourse.getStatus(); // 把 chooseCourse.getStatus() 的返回值赋给 status
//只有当未支付时才更新为已支付 // 保留原作者写的行内注释
if("701002".equals(status)){ // 定义方法 方法(...)
//更新选课记录的状态为支付成功 // 保留原作者写的行内注释
chooseCourse.setStatus("701001"); // 执行语句
int i = chooseCourseMapper.updateById(chooseCourse); // 把 chooseCourseMapper.updateById(chooseCourse) 赋值给 i
if(i<=0){ // 定义方法 方法(...)
log.debug("添加选课记录失败:{}",chooseCourse); // 执行语句
XueChengPlusException.cast("添加选课记录失败"); // 执行语句
} // 代码块结束
//向我的课程表插入记录 // 保留原作者写的行内注释
XcCourseTables xcCourseTables = addCourseTabls(chooseCourse); // 把 addCourseTabls(chooseCourse) 赋值给 xcCourseTables
return true; // 返回 true
} // 代码块结束
return false; // 返回 false
} // 代码块结束
// 分页 // 保留原作者写的行内注释
@Override // 使用注解 @Override
public PageResult<XcCourseTables> mycoursetables(MyCourseTableParams params) { // 定义方法 mycoursetables(...)
//用户id // 保留原作者写的行内注释
String userId = params.getUserId(); // 把 params.getUserId() 的返回值赋给 userId
//当前页码 // 保留原作者写的行内注释
int pageNo = params.getPage(); // 把 params.getPage() 的返回值赋给 pageNo
//每页记录数 // 保留原作者写的行内注释
int size = params.getSize(); // 把 params.getSize() 的返回值赋给 size
Page<XcCourseTables> courseTablesPage = new Page<>(pageNo, size); // 创建 Page<> 对象并赋值给 courseTablesPage
LambdaQueryWrapper<XcCourseTables> lambdaQueryWrapper = new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId); // 创建 LambdaQueryWrapper<XcCourseTables> 对象并赋值给 lambdaQueryWrapper
//查询数据 // 保留原作者写的行内注释
Page<XcCourseTables> result = courseTablesMapper.selectPage(courseTablesPage, lambdaQueryWrapper); // 把 courseTablesMapper.selectPage(courseTablesPage, lambdaQueryWrapper) 赋值给 result
//数据列表 // 保留原作者写的行内注释
List<XcCourseTables> records = result.getRecords(); // 把 result.getRecords() 的返回值赋给 records
//总记录数 // 保留原作者写的行内注释
long total = result.getTotal(); // 把 result.getTotal() 的返回值赋给 total
//List<T> items, long counts, long page, long pageSize // 保留原作者写的行内注释
PageResult pageResult = new PageResult(records, total, pageNo, size); // 创建 PageResult 对象并赋值给 pageResult
return pageResult; // 返回 pageResult
} // 代码块结束
//添加免费课程,免费课程加入选课记录表、我的课程表 // 保留原作者写的行内注释
public XcChooseCourse addFreeCoruse(String userId, CoursePublish coursepublish) { // 定义方法 addFreeCoruse(...)
//课程id // 保留原作者写的行内注释
Long courseId = coursepublish.getId(); // 把 coursepublish.getId() 的返回值赋给 courseId
//判断,如果存在免费的选课记录且选课状态为成功,直接返回了 // 保留原作者写的行内注释
LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<XcChooseCourse>().eq(XcChooseCourse::getUserId, userId) // 代码逻辑
.eq(XcChooseCourse::getCourseId, courseId) // 代码逻辑
.eq(XcChooseCourse::getOrderType, "700001")//免费课程 // 代码逻辑
.eq(XcChooseCourse::getStatus, "701001");//选课成功 // 执行语句
List<XcChooseCourse> xcChooseCourses = chooseCourseMapper.selectList(queryWrapper); // 把 chooseCourseMapper.selectList(queryWrapper) 赋值给 xcChooseCourses
if(xcChooseCourses.size()>0){ // 定义方法 方法(...)
return xcChooseCourses.get(0); // 返回 xcChooseCourses.get(0)
} // 代码块结束
//向选课记录表写数据 // 保留原作者写的行内注释
XcChooseCourse chooseCourse = new XcChooseCourse(); // 创建 XcChooseCourse 对象并赋值给 chooseCourse
chooseCourse.setCourseId(courseId); // 执行语句
chooseCourse.setCourseName(coursepublish.getName()); // 执行语句
chooseCourse.setUserId(userId); // 执行语句
chooseCourse.setCompanyId(coursepublish.getCompanyId()); // 执行语句
chooseCourse.setOrderType("700001");//免费课程 // 执行语句
chooseCourse.setCreateDate(LocalDateTime.now()); // 执行语句
chooseCourse.setCoursePrice(coursepublish.getPrice()); // 执行语句
chooseCourse.setValidDays(365); // 执行语句
chooseCourse.setStatus("701001");//选课成功 // 执行语句
chooseCourse.setValidtimeStart(LocalDateTime.now());//有效期的开始时间 // 执行语句
chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));//有效期的结束时间 // 执行语句
int insert = chooseCourseMapper.insert(chooseCourse); // 把 chooseCourseMapper.insert(chooseCourse) 赋值给 insert
if(insert<=0){ // 定义方法 方法(...)
XueChengPlusException.cast("添加选课记录失败"); // 执行语句
} // 代码块结束
return chooseCourse; // 返回 chooseCourse
} // 代码块结束
//添加到我的课程表 // 保留原作者写的行内注释
public XcCourseTables addCourseTabls(XcChooseCourse xcChooseCourse){ // 定义方法 addCourseTabls(...)
//选课成功了才可以向我的课程表添加 // 保留原作者写的行内注释
String status = xcChooseCourse.getStatus(); // 把 xcChooseCourse.getStatus() 的返回值赋给 status
if(!"701001".equals(status)){ // 定义方法 方法(...)
XueChengPlusException.cast("选课没有成功无法添加到课程表"); // 执行语句
} // 代码块结束
XcCourseTables xcCourseTables = getXcCourseTables(xcChooseCourse.getUserId(), xcChooseCourse.getCourseId()); // 把 getXcCourseTables(xcChooseCourse.getUserId(), xcChooseCourse.getCourseId()) 赋值给 xcCourseTables
if(xcCourseTables!=null){ // 定义方法 方法(...)
return xcCourseTables; // 返回 xcCourseTables
} // 代码块结束
xcCourseTables = new XcCourseTables(); // 创建 XcCourseTables 对象并赋值给 xcCourseTables
BeanUtils.copyProperties(xcChooseCourse,xcCourseTables); // 执行语句
xcCourseTables.setChooseCourseId(xcChooseCourse.getId());//记录选课表的逐渐 // 执行语句
xcCourseTables.setCourseType(xcChooseCourse.getOrderType());//选课类型 // 执行语句
xcCourseTables.setUpdateDate(LocalDateTime.now()); // 执行语句
int insert = courseTablesMapper.insert(xcCourseTables); // 把 courseTablesMapper.insert(xcCourseTables) 赋值给 insert
if(insert<=0){ // 定义方法 方法(...)
XueChengPlusException.cast("添加我的课程表失败"); // 执行语句
} // 代码块结束
return xcCourseTables; // 返回 xcCourseTables
} // 代码块结束
/** // 保留原作者写的块注释
* @description 根据课程和用户查询我的课程表中某一门课程 // 保留原作者写的块注释
* @param userId // 保留原作者写的块注释
* @param courseId // 保留原作者写的块注释
* @return com.xuecheng.learning.model.po.XcCourseTables // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/2 17:07 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcCourseTables getXcCourseTables(String userId,Long courseId){ // 定义方法 getXcCourseTables(...)
XcCourseTables xcCourseTables = courseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId).eq(XcCourseTables::getCourseId, courseId)); // 把 courseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId).eq(XcCourseTables::getCourseId, courseId)) 赋值给 xcCourseTables
return xcCourseTables; // 返回 xcCourseTables
} // 代码块结束
//添加收费课程 // 保留原作者写的行内注释
public XcChooseCourse addChargeCoruse(String userId,CoursePublish coursepublish){ // 定义方法 addChargeCoruse(...)
//课程id // 保留原作者写的行内注释
Long courseId = coursepublish.getId(); // 把 coursepublish.getId() 的返回值赋给 courseId
//判断,如果存在收费的选课记录且选课状态为待支付,直接返回了 // 保留原作者写的行内注释
LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<XcChooseCourse>().eq(XcChooseCourse::getUserId, userId) // 代码逻辑
.eq(XcChooseCourse::getCourseId, courseId) // 代码逻辑
.eq(XcChooseCourse::getOrderType, "700002")//收费课程 // 代码逻辑
.eq(XcChooseCourse::getStatus, "701002");//待支付 // 执行语句
List<XcChooseCourse> xcChooseCourses = chooseCourseMapper.selectList(queryWrapper); // 把 chooseCourseMapper.selectList(queryWrapper) 赋值给 xcChooseCourses
if(xcChooseCourses.size()>0){ // 定义方法 方法(...)
return xcChooseCourses.get(0); // 返回 xcChooseCourses.get(0)
} // 代码块结束
//向选课记录表写数据 // 保留原作者写的行内注释
XcChooseCourse chooseCourse = new XcChooseCourse(); // 创建 XcChooseCourse 对象并赋值给 chooseCourse
chooseCourse.setCourseId(courseId); // 执行语句
chooseCourse.setCourseName(coursepublish.getName()); // 执行语句
chooseCourse.setUserId(userId); // 执行语句
chooseCourse.setCompanyId(coursepublish.getCompanyId()); // 执行语句
chooseCourse.setOrderType("700002");//收费课程 // 执行语句
chooseCourse.setCreateDate(LocalDateTime.now()); // 执行语句
chooseCourse.setCoursePrice(coursepublish.getPrice()); // 执行语句
chooseCourse.setValidDays(365); // 执行语句
chooseCourse.setStatus("701002");//待支付 // 执行语句
chooseCourse.setValidtimeStart(LocalDateTime.now());//有效期的开始时间 // 执行语句
chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));//有效期的结束时间 // 执行语句
int insert = chooseCourseMapper.insert(chooseCourse); // 把 chooseCourseMapper.insert(chooseCourse) 赋值给 insert
if(insert<=0){ // 定义方法 方法(...)
XueChengPlusException.cast("添加选课记录失败"); // 执行语句
} // 代码块结束
return chooseCourse; // 返回 chooseCourse
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/service/impl/ReceivePayNotifyService.java
package com.xuecheng.learning.service.impl; // 声明类所在的包路径
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.xuecheng.base.exception.XueChengPlusException; // 导入 XueChengPlusException 类
import com.xuecheng.learning.config.PayNotifyConfig; // 导入 PayNotifyConfig 类
import com.xuecheng.learning.service.MyCourseTablesService; // 导入 MyCourseTablesService 类
import com.xuecheng.messagesdk.model.po.MqMessage; // 导入 MqMessage 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.amqp.core.Message; // 导入 Message 类
import org.springframework.amqp.rabbit.annotation.RabbitListener; // 导入 RabbitListener 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.stereotype.Service; // 导入 Service 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 接收消息通知处理类 // 保留原作者写的块注释
* @date 2023/2/26 16:42 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Service // 使用注解 @Service
public class ReceivePayNotifyService { // 定义 class ReceivePayNotifyService
@Autowired // 使用注解 @Autowired
MyCourseTablesService myCourseTablesService; // 执行语句
@RabbitListener(queues = PayNotifyConfig.PAYNOTIFY_QUEUE) // 使用注解 @RabbitListener(queues = PayNotifyConfig.PAYNOTIFY_QUEUE)
public void receive(Message message) { // 定义方法 receive(...)
try { // 尝试执行可能抛出异常的代码
Thread.sleep(5000); // 执行语句
} catch (InterruptedException e) { // 定义方法 catch(...)
e.printStackTrace(); // 执行语句
} // 代码块结束
//解析出消息 // 保留原作者写的行内注释
byte[] body = message.getBody(); // 把 message.getBody() 的返回值赋给 body
String jsonString = new String(body); // 创建 String 对象并赋值给 jsonString
//转成对象 // 保留原作者写的行内注释
MqMessage mqMessage = JSON.parseObject(jsonString, MqMessage.class); // 把 JSON.parseObject(jsonString, MqMessage.class) 赋值给 mqMessage
//解析消息的内容 // 保留原作者写的行内注释
//选课id // 保留原作者写的行内注释
String chooseCourseId = mqMessage.getBusinessKey1(); // 把 mqMessage.getBusinessKey1() 的返回值赋给 chooseCourseId
//订单类型 // 保留原作者写的行内注释
String orderType = mqMessage.getBusinessKey2(); // 把 mqMessage.getBusinessKey2() 的返回值赋给 orderType
//学习中心服务只要购买课程类的支付订单的结果 // 保留原作者写的行内注释
if (orderType.equals("60201")) { // 定义方法 方法(...)
//根据消息内容,更新选课记录、向我的课程表插入记录 // 保留原作者写的行内注释
boolean b = myCourseTablesService.saveChooseCourseSuccess(chooseCourseId); // 把 myCourseTablesService.saveChooseCourseSuccess(chooseCourseId) 赋值给 b
if (!b) { // 定义方法 方法(...)
XueChengPlusException.cast("保证选课记录状态失败"); // 执行语句
} // 代码块结束
} // 代码块结束
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/service/LearningService.java
package com.xuecheng.learning.service; // 声明类所在的包路径
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 在线学习相关的接口 // 保留原作者写的块注释
* @date 2023/2/28 10:17 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface LearningService { // 定义 interface LearningService
/** // 保留原作者写的块注释
* @description 获取教学视频 // 保留原作者写的块注释
* @param courseId 课程id // 保留原作者写的块注释
* @param teachplanId 课程计划id // 保留原作者写的块注释
* @param mediaId 视频文件id // 保留原作者写的块注释
* @return com.xuecheng.base.model.RestResponse<java.lang.String> // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/5 9:08 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public RestResponse<String> getVideo(String userId, Long courseId, Long teachplanId, String mediaId); // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/service/main/com/xuecheng/learning/service/MyCourseTablesService.java
package com.xuecheng.learning.service; // 声明类所在的包路径
import com.xuecheng.base.model.PageResult; // 导入 PageResult 类
import com.xuecheng.learning.model.dto.MyCourseTableParams; // 导入 MyCourseTableParams 类
import com.xuecheng.learning.model.dto.XcChooseCourseDto; // 导入 XcChooseCourseDto 类
import com.xuecheng.learning.model.dto.XcCourseTablesDto; // 导入 XcCourseTablesDto 类
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 选课相关的接口 // 保留原作者写的块注释
* @date 2023/2/25 12:00 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface MyCourseTablesService { // 定义 interface MyCourseTablesService
/** // 保留原作者写的块注释
* @description 添加选课 // 保留原作者写的块注释
* @param userId 用户id // 保留原作者写的块注释
* @param courseId 课程id // 保留原作者写的块注释
* @return com.xuecheng.learning.model.dto.XcChooseCourseDto // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* 响应选课结果 // 保留原作者写的块注释
* @date 2022/10/24 17:33 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcChooseCourseDto addChooseCourse(String userId, Long courseId); // 执行语句
/** // 保留原作者写的块注释
* @description 判断学习资格 // 保留原作者写的块注释
* @param userId // 保留原作者写的块注释
* @param courseId // 保留原作者写的块注释
* @return XcCourseTablesDto 学习资格状态 [{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}] // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/3 7:37 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcCourseTablesDto getLearningStatus(String userId, Long courseId); // 执行语句
/** // 保留原作者写的块注释
* 保存选课成功状态 // 保留原作者写的块注释
* @param chooseCourseId // 保留原作者写的块注释
* @return // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public boolean saveChooseCourseSuccess(String chooseCourseId); // 执行语句
/** // 保留原作者写的块注释
* @description 我的课程表 // 保留原作者写的块注释
* @param params // 保留原作者写的块注释
* @return com.xuecheng.base.model.PageResult<com.xuecheng.learning.model.po.XcCourseTables> // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/27 9:24 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public PageResult<XcCourseTables> mycoursetables(MyCourseTableParams params); // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/service_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-learning</artifactId>
<groupId>com.xuecheng</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>xuecheng-plus-learning-service</artifactId>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <!-- 读取远程配置 -->
</dependency>
<dependency>
<groupId>com.xuecheng</groupId>
<artifactId>xuecheng-plus-learning-model</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.xuecheng</groupId>
<artifactId>xuecheng-plus-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId> <!-- 调用内容/媒资接口 -->
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
文件:xuecheng-plus-learning/test_service/com/xuecheng/learning/FeignClientTest.java
package com.xuecheng.learning; // 声明类所在的包路径
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; // 导入 LocalDateTimeSerializer 类
import com.xuecheng.content.model.po.CoursePublish; // 导入 CoursePublish 类
import com.xuecheng.learning.feignclient.ContentServiceClient; // 导入 ContentServiceClient 类
import org.junit.jupiter.api.Assertions; // 导入 Assertions 类
import org.junit.jupiter.api.Test; // 导入 Test 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.boot.test.context.SpringBootTest; // 导入 SpringBootTest 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2023/2/22 20:14 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@SpringBootTest // 使用注解 @SpringBootTest
public class FeignClientTest { // 定义 class FeignClientTest
@Autowired // 使用注解 @Autowired
ContentServiceClient contentServiceClient; // 执行语句
@Test // 使用注解 @Test
public void testContentServiceClient() { // 定义方法 testContentServiceClient(...)
CoursePublish coursepublish = contentServiceClient.getCoursepublish(120L); // 把 contentServiceClient.getCoursepublish(120L) 赋值给 coursepublish
Assertions.assertNotNull(coursepublish); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/test_service/com/xuecheng/learning/LearningApplication.java
package com.xuecheng.learning; // 声明类所在的包路径
import org.springframework.boot.SpringApplication; // 导入 SpringApplication 类
import org.springframework.boot.autoconfigure.SpringBootApplication; // 导入 SpringBootApplication 类
import org.springframework.cloud.openfeign.EnableFeignClients; // 导入 EnableFeignClients 类
@EnableFeignClients(basePackages={"com.xuecheng.*.feignclient"}) // 使用注解 @EnableFeignClients(basePackages={"com.xuecheng.*.feignclient"})
@SpringBootApplication // 使用注解 @SpringBootApplication
public class LearningApplication { // 定义 class LearningApplication
public static void main(String[] args) { // 定义方法 main(...)
SpringApplication.run(LearningApplication.class, args); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/test_service/com/xuecheng/learning/Test1.java
package com.xuecheng.learning; // 声明类所在的包路径
import com.xuecheng.learning.mapper.XcChooseCourseMapper; // 导入 XcChooseCourseMapper 类
import org.junit.jupiter.api.Test; // 导入 Test 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.boot.test.context.SpringBootTest; // 导入 SpringBootTest 类
/** // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/2 10:32 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@SpringBootTest // 使用注解 @SpringBootTest
public class Test1 { // 定义 class Test1
@Autowired // 使用注解 @Autowired
XcChooseCourseMapper xcChooseCourseMapper; // 执行语句
@Test // 使用注解 @Test
public void test(){ // 定义方法 test(...)
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/test_service/resources/bootstrap.yml
#微服务配置
spring:
application:
name: learning-service
cloud:
nacos:
server-addr: 192.168.101.65:8848
discovery:
namespace: dev402
group: xuecheng-plus-project
config:
namespace: dev402
group: xuecheng-plus-project
file-extension: yaml
refresh-enabled: true
extension-configs:
- data-id: learning-service-${spring.profiles.active}.yaml
group: xuecheng-plus-project
refresh: true
shared-configs:
- data-id: swagger-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: logging-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: feign-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
profiles:
active: dev
文件:xuecheng-plus-learning/test_service/resources/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>
文件:xuecheng-plus-learning/xuecheng-plus-learning-api/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- SQL 语句片段 -->
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- SQL 语句片段 -->
<modelVersion>4.0.0</modelVersion> <!-- SQL 语句片段 -->
<parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-learning</artifactId> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-learning-api</artifactId> <!-- SQL 语句片段 -->
<dependencies> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.alibaba.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.alibaba.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!--认证相关-->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-security</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-oauth2</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-learning-model</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-learning-service</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!--cloud的基础环境包-->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-context</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 的 Spring Web MVC 集成 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-web</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-validation</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- 排除 Spring Boot 依赖的日志包冲突 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter</artifactId> <!-- SQL 语句片段 -->
<exclusions> <!-- SQL 语句片段 -->
<exclusion> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-logging</artifactId> <!-- SQL 语句片段 -->
</exclusion> <!-- SQL 语句片段 -->
</exclusions> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 集成 log4j2 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-log4j2</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 集成 swagger -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.spring4all</groupId> <!-- SQL 语句片段 -->
<artifactId>swagger-spring-boot-starter</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
</dependencies> <!-- SQL 语句片段 -->
</project> <!-- SQL 语句片段 -->
文件:xuecheng-plus-learning/xuecheng-plus-learning-api/src/main/java/com/xuecheng/learning/api/MyCourseTablesController.java
package com.xuecheng.learning.api; // 声明类所在的包路径
import com.xuecheng.base.exception.XueChengPlusException; // 导入 XueChengPlusException 类
import com.xuecheng.base.model.PageResult; // 导入 PageResult 类
import com.xuecheng.learning.model.dto.MyCourseTableParams; // 导入 MyCourseTableParams 类
import com.xuecheng.learning.model.dto.XcChooseCourseDto; // 导入 XcChooseCourseDto 类
import com.xuecheng.learning.model.dto.XcCourseTablesDto; // 导入 XcCourseTablesDto 类
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
import com.xuecheng.learning.service.MyCourseTablesService; // 导入 MyCourseTablesService 类
import com.xuecheng.learning.util.SecurityUtil; // 导入 SecurityUtil 类
import io.swagger.annotations.Api; // 导入 Api 类
import io.swagger.annotations.ApiOperation; // 导入 ApiOperation 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 类
import org.springframework.web.bind.annotation.PathVariable; // 导入 PathVariable 类
import org.springframework.web.bind.annotation.PostMapping; // 导入 PostMapping 类
import org.springframework.web.bind.annotation.RestController; // 导入 RestController 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 我的课程表接口 // 保留原作者写的块注释
* @date 2022/10/25 9:40 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Api(value = "我的课程表接口", tags = "我的课程表接口") // 使用注解 @Api(value = "我的课程表接口", tags = "我的课程表接口")
@Slf4j // 使用注解 @Slf4j
@RestController // 使用注解 @RestController
public class MyCourseTablesController { // 定义 class MyCourseTablesController
@Autowired // 使用注解 @Autowired
MyCourseTablesService myCourseTablesService; // 执行语句
@ApiOperation("添加选课") // 使用注解 @ApiOperation("添加选课")
@PostMapping("/choosecourse/{courseId}") // 使用注解 @PostMapping("/choosecourse/{courseId}")
public XcChooseCourseDto addChooseCourse(@PathVariable("courseId") Long courseId) { // 定义方法 addChooseCourse(...)
//当前登录的用户 // 保留原作者写的行内注释
SecurityUtil.XcUser user = SecurityUtil.getUser(); // 把 SecurityUtil.getUser() 的返回值赋给 user
if(user == null){ // 定义方法 方法(...)
XueChengPlusException.cast("请登录"); // 执行语句
} // 代码块结束
//用户id // 保留原作者写的行内注释
String userId = user.getId(); // 把 user.getId() 的返回值赋给 userId
//添加选课 // 保留原作者写的行内注释
XcChooseCourseDto xcChooseCourseDto = myCourseTablesService.addChooseCourse(userId, courseId); // 把 myCourseTablesService.addChooseCourse(userId, courseId) 赋值给 xcChooseCourseDto
return xcChooseCourseDto; // 返回 xcChooseCourseDto
} // 代码块结束
@ApiOperation("查询学习资格") // 使用注解 @ApiOperation("查询学习资格")
@PostMapping("/choosecourse/learnstatus/{courseId}") // 使用注解 @PostMapping("/choosecourse/learnstatus/{courseId}")
public XcCourseTablesDto getLearnstatus(@PathVariable("courseId") Long courseId) { // 定义方法 getLearnstatus(...)
//当前登录的用户 // 保留原作者写的行内注释
SecurityUtil.XcUser user = SecurityUtil.getUser(); // 把 SecurityUtil.getUser() 的返回值赋给 user
if(user == null){ // 定义方法 方法(...)
XueChengPlusException.cast("请登录"); // 执行语句
} // 代码块结束
//用户id // 保留原作者写的行内注释
String userId = user.getId(); // 把 user.getId() 的返回值赋给 userId
XcCourseTablesDto learningStatus = myCourseTablesService.getLearningStatus(userId, courseId); // 把 myCourseTablesService.getLearningStatus(userId, courseId) 赋值给 learningStatus
return learningStatus; // 返回 learningStatus
} // 代码块结束
@ApiOperation("我的课程表") // 使用注解 @ApiOperation("我的课程表")
@GetMapping("/mycoursetable") // 使用注解 @GetMapping("/mycoursetable")
public PageResult<XcCourseTables> mycoursetable(MyCourseTableParams params) { // 定义方法 mycoursetable(...)
//当前登录的用户 // 保留原作者写的行内注释
SecurityUtil.XcUser user = SecurityUtil.getUser(); // 把 SecurityUtil.getUser() 的返回值赋给 user
if(user == null){ // 定义方法 方法(...)
XueChengPlusException.cast("请登录"); // 执行语句
} // 代码块结束
//用户id // 保留原作者写的行内注释
String userId = user.getId(); // 把 user.getId() 的返回值赋给 userId
params.setUserId(userId); // 执行语句
PageResult<XcCourseTables> mycoursetables = myCourseTablesService.mycoursetables(params); // 把 myCourseTablesService.mycoursetables(params) 赋值给 mycoursetables
return mycoursetables; // 返回 mycoursetables
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-api/src/main/java/com/xuecheng/learning/api/MyLearningController.java
package com.xuecheng.learning.api; // 声明类所在的包路径
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类
import com.xuecheng.learning.service.LearningService; // 导入 LearningService 类
import com.xuecheng.learning.util.SecurityUtil; // 导入 SecurityUtil 类
import io.swagger.annotations.Api; // 导入 Api 类
import io.swagger.annotations.ApiOperation; // 导入 ApiOperation 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 类
import org.springframework.web.bind.annotation.PathVariable; // 导入 PathVariable 类
import org.springframework.web.bind.annotation.RestController; // 导入 RestController 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 我的学习接口 // 保留原作者写的块注释
* @date 2022/10/27 8:59 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Api(value = "学习过程管理接口", tags = "学习过程管理接口") // 使用注解 @Api(value = "学习过程管理接口", tags = "学习过程管理接口")
@Slf4j // 使用注解 @Slf4j
@RestController // 使用注解 @RestController
public class MyLearningController { // 定义 class MyLearningController
@Autowired // 使用注解 @Autowired
LearningService learningService; // 执行语句
/** // 保留原作者写的块注释
* // 保留原作者写的块注释
* @param courseId 课程id // 保留原作者写的块注释
* @param teachplanId 课程计划id // 保留原作者写的块注释
* @param mediaId 媒资文件id // 保留原作者写的块注释
* @return // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@ApiOperation("获取视频") // 使用注解 @ApiOperation("获取视频")
@GetMapping("/open/learn/getvideo/{courseId}/{teachplanId}/{mediaId}") // 使用注解 @GetMapping("/open/learn/getvideo/{courseId}/{teachplanId}/{mediaId}")
public RestResponse<String> getvideo(@PathVariable("courseId") Long courseId, @PathVariable("teachplanId") Long teachplanId, @PathVariable("mediaId") String mediaId) { // 定义方法 getvideo(...)
SecurityUtil.XcUser user = SecurityUtil.getUser(); // 把 SecurityUtil.getUser() 的返回值赋给 user
String userId = user.getId(); // 把 user.getId() 的返回值赋给 userId
//获取视频 // 保留原作者写的行内注释
RestResponse<String> restResponse = learningService.getVideo(userId, courseId, teachplanId, mediaId); // 把 learningService.getVideo(userId, courseId, teachplanId, mediaId) 赋值给 restResponse
return restResponse; // 返回 restResponse
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-api/src/main/java/com/xuecheng/learning/config/ResouceServerConfig.java
package com.xuecheng.learning.config; // 声明类所在的包路径
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; // 导入 EnableGlobalMethodSecurity 类
import org.springframework.security.config.annotation.web.builders.HttpSecurity; // 导入 HttpSecurity 类
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; // 导入 EnableResourceServer 类
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; // 导入 ResourceServerConfigurerAdapter 类
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; // 导入 ResourceServerSecurityConfigurer 类
import org.springframework.security.oauth2.provider.token.TokenStore; // 导入 TokenStore 类
/** // 保留原作者写的块注释
* @author Administrator // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
**/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
@EnableResourceServer // 使用注解 @EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) // 使用注解 @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class ResouceServerConfig extends ResourceServerConfigurerAdapter { // 定义 class ResouceServerConfig
//资源服务标识 // 保留原作者写的行内注释
public static final String RESOURCE_ID = "xuecheng-plus"; // 把 "xuecheng-plus" 赋值给 RESOURCE_ID
@Autowired // 使用注解 @Autowired
TokenStore tokenStore; // 执行语句
@Override // 使用注解 @Override
public void configure(ResourceServerSecurityConfigurer resources) { // 定义方法 configure(...)
resources.resourceId(RESOURCE_ID)//资源 id // 代码逻辑
.tokenStore(tokenStore) // 代码逻辑
.stateless(true); // 执行语句
} // 代码块结束
@Override // 使用注解 @Override
public void configure(HttpSecurity http) throws Exception { // 定义方法 configure(...)
http.csrf().disable() // 代码逻辑
.authorizeRequests() // 代码逻辑
// .antMatchers("/r/**","/course/**").authenticated()//所有/r/**的请求必须认证通过 // 保留原作者写的行内注释
.anyRequest().permitAll() // 代码逻辑
; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-api/src/main/java/com/xuecheng/learning/config/TokenConfig.java
package com.xuecheng.learning.config; // 声明类所在的包路径
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.security.oauth2.provider.token.TokenStore; // 导入 TokenStore 类
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; // 导入 JwtAccessTokenConverter 类
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; // 导入 JwtTokenStore 类
/** // 保留原作者写的块注释
* @author Administrator // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
**/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
public class TokenConfig { // 定义 class TokenConfig
//jwt签名密钥,与认证服务保持一致 // 保留原作者写的行内注释
private String SIGNING_KEY = "mq123"; // 把 "mq123" 赋值给 SIGNING_KEY
@Bean // 使用注解 @Bean
public TokenStore tokenStore() { // 定义方法 tokenStore(...)
//JWT令牌存储方案 // 保留原作者写的行内注释
return new JwtTokenStore(accessTokenConverter()); // 返回 new JwtTokenStore(accessTokenConverter())
} // 代码块结束
@Bean // 使用注解 @Bean
public JwtAccessTokenConverter accessTokenConverter() { // 定义方法 accessTokenConverter(...)
JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); // 创建 JwtAccessTokenConverter 对象并赋值给 converter
converter.setSigningKey(SIGNING_KEY); // 执行语句
return converter; // 返回 converter
} // 代码块结束
/* @Bean // 保留原作者写的块注释
public TokenStore tokenStore() { // 定义方法 tokenStore(...)
//使用内存存储令牌(普通令牌) // 保留原作者写的行内注释
return new InMemoryTokenStore(); // 返回 new InMemoryTokenStore()
}*/ // 代码逻辑
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-api/src/main/java/com/xuecheng/learning/util/SecurityUtil.java
package com.xuecheng.learning.util; // 声明类所在的包路径
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import lombok.Data; // 导入 Data 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.security.core.context.SecurityContextHolder; // 导入 SecurityContextHolder 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 用户身份信息获取工具类 // 保留原作者写的块注释
* @date 2022/10/20 11:41 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
public class SecurityUtil { // 定义 class SecurityUtil
public static XcUser getUser() { // 定义方法 getUser(...)
//拿jwt中的用户身份 // 保留原作者写的行内注释
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); // 把 SecurityContextHolder.getContext().getAuthentication().getPrincipal() 的返回值赋给 principal
if (principal instanceof String){ // 定义方法 方法(...)
String jsonString = (String) principal; // 把 (String) principal 赋值给 jsonString
XcUser xcUser = null; // 把变量 xcUser 初始化为 null
try { // 尝试执行可能抛出异常的代码
xcUser = JSON.parseObject(jsonString, XcUser.class); // 把 JSON.parseObject(jsonString, XcUser.class) 赋值给 xcUser
} catch (Exception e) { // 定义方法 catch(...)
log.debug("解析jwt中的用户身份无法转成XcUser对象:{}",jsonString); // 执行语句
} // 代码块结束
return xcUser; // 返回 xcUser
} // 代码块结束
return null; // 返回 null
} // 代码块结束
@Data // 使用注解 @Data
public static class XcUser implements Serializable { // 代码逻辑
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
private String id; // 执行语句
private String username; // 执行语句
private String password; // 执行语句
private String salt; // 执行语句
private String name; // 执行语句
private String nickname; // 执行语句
private String wxUnionid; // 执行语句
private String companyId; // 执行语句
/** // 保留原作者写的块注释
* 头像 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userpic; // 执行语句
private String utype; // 执行语句
private LocalDateTime birthday; // 执行语句
private String sex; // 执行语句
private String email; // 执行语句
private String cellphone; // 执行语句
private String qq; // 执行语句
/** // 保留原作者写的块注释
* 用户状态 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String status; // 执行语句
private LocalDateTime createTime; // 执行语句
private LocalDateTime updateTime; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-api/src/main/java/com/xuecheng/LearningApiApplication.java
package com.xuecheng; // 声明类所在的包路径
import org.springframework.boot.SpringApplication; // 导入 SpringApplication 类
import org.springframework.boot.autoconfigure.SpringBootApplication; // 导入 SpringBootApplication 类
import org.springframework.cloud.openfeign.EnableFeignClients; // 导入 EnableFeignClients 类
@EnableFeignClients(basePackages={"com.xuecheng.*.feignclient"}) // 使用注解 @EnableFeignClients(basePackages={"com.xuecheng.*.feignclient"})
@SpringBootApplication // 使用注解 @SpringBootApplication
public class LearningApiApplication { // 定义 class LearningApiApplication
public static void main(String[] args) { // 定义方法 main(...)
SpringApplication.run(LearningApiApplication.class, args); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-api/src/main/resources/bootstrap.yml
#微服务配置
spring:
application:
name: learning-api
cloud:
nacos:
server-addr: 192.168.101.65:8848
discovery:
namespace: dev402
group: xuecheng-plus-project
config:
namespace: dev402
group: xuecheng-plus-project
file-extension: yaml
refresh-enabled: true
extension-configs:
- data-id: learning-service-${spring.profiles.active}.yaml
group: xuecheng-plus-project
refresh: true
shared-configs:
- data-id: swagger-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: logging-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: feign-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: rabbitmq-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
profiles:
active: dev
文件:xuecheng-plus-learning/xuecheng-plus-learning-api/src/main/resources/log4j2-dev.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<Configuration monitorInterval="180" packages=""> <!-- SQL 语句片段 -->
<properties> <!-- SQL 语句片段 -->
<property name="logdir">logs</property> <!-- SQL 语句片段 -->
<property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property> <!-- SQL 语句片段 -->
</properties> <!-- SQL 语句片段 -->
<Appenders> <!-- SQL 语句片段 -->
<Console name="Console" target="SYSTEM_OUT"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
</Console> <!-- SQL 语句片段 -->
<RollingFile name="ErrorAppender" fileName="${logdir}/error.log" <!-- SQL 语句片段 -->
filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/> <!-- SQL 语句片段 -->
<Policies> <!-- SQL 语句片段 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- SQL 语句片段 -->
</Policies> <!-- SQL 语句片段 -->
</RollingFile> <!-- SQL 语句片段 -->
<RollingFile name="DebugAppender" fileName="${logdir}/info.log" <!-- SQL 语句片段 -->
filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> <!-- SQL 语句片段 -->
<Policies> <!-- SQL 语句片段 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- SQL 语句片段 -->
</Policies> <!-- SQL 语句片段 -->
</RollingFile> <!-- SQL 语句片段 -->
<!--异步appender-->
<Async name="AsyncAppender" includeLocation="true"> <!-- SQL 语句片段 -->
<AppenderRef ref="ErrorAppender"/> <!-- SQL 语句片段 -->
<AppenderRef ref="DebugAppender"/> <!-- SQL 语句片段 -->
</Async> <!-- SQL 语句片段 -->
</Appenders> <!-- SQL 语句片段 -->
<Loggers> <!-- SQL 语句片段 -->
<!--过滤掉spring和mybatis的一些无用的debug信息-->
<logger name="org.springframework" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.mybatis" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="cn.itcast.wanxinp2p.consumer.mapper" level="DEBUG"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="springfox" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.apache.http" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="com.netflix.discovery" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqCommon" level="INFO" > <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqRemoting" level="INFO" > <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqClient" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily.lottery" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily.bonuspoint" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<!--OFF 0-->
<!--FATAL 100-->
<!--ERROR 200-->
<!--WARN 300-->
<!--INFO 400-->
<!--DEBUG 500-->
<!--TRACE 600-->
<!--ALL Integer.MAX_VALUE-->
<Root level="DEBUG" includeLocation="true"> <!-- SQL 语句片段 -->
<AppenderRef ref="AsyncAppender"/> <!-- SQL 语句片段 -->
<AppenderRef ref="Console"/> <!-- SQL 语句片段 -->
<AppenderRef ref="DebugAppender"/> <!-- SQL 语句片段 -->
</Root> <!-- SQL 语句片段 -->
</Loggers> <!-- SQL 语句片段 -->
</Configuration> <!-- SQL 语句片段 -->
文件:xuecheng-plus-learning/xuecheng-plus-learning-model/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- SQL 语句片段 -->
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- SQL 语句片段 -->
<modelVersion>4.0.0</modelVersion> <!-- SQL 语句片段 -->
<parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-learning</artifactId> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-learning-model</artifactId> <!-- SQL 语句片段 -->
<dependencies> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-base</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!--存在mybatisplus注解添加相关注解保证不报错-->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.baomidou</groupId> <!-- SQL 语句片段 -->
<artifactId>mybatis-plus-annotation</artifactId> <!-- SQL 语句片段 -->
<version>${mybatis-plus-boot-starter.version}</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.baomidou</groupId> <!-- SQL 语句片段 -->
<artifactId>mybatis-plus-core</artifactId> <!-- SQL 语句片段 -->
<version>${mybatis-plus-boot-starter.version}</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.projectlombok</groupId> <!-- SQL 语句片段 -->
<artifactId>lombok</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
</dependencies> <!-- SQL 语句片段 -->
</project> <!-- SQL 语句片段 -->
文件:xuecheng-plus-learning/xuecheng-plus-learning-model/src/main/java/com/xuecheng/learning/model/dto/MyCourseTableItemDto.java
package com.xuecheng.learning.model.dto; // 声明类所在的包路径
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 我的课程查询条件 // 保留原作者写的块注释
* @date 2022/10/6 9:42 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class MyCourseTableItemDto extends XcCourseTables { // 定义 class MyCourseTableItemDto
/** // 保留原作者写的块注释
* 最近学习时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime learnDate; // 执行语句
/** // 保留原作者写的块注释
* 学习时长 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long learnLength; // 执行语句
/** // 保留原作者写的块注释
* 章节id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long teachplanId; // 执行语句
/** // 保留原作者写的块注释
* 章节名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String teachplanName; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-model/src/main/java/com/xuecheng/learning/model/dto/MyCourseTableParams.java
package com.xuecheng.learning.model.dto; // 声明类所在的包路径
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @description 我的课程查询条件 // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/6 9:42 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class MyCourseTableParams { // 定义 class MyCourseTableParams
String userId; // 执行语句
//课程类型 [{"code":"700001","desc":"免费课程"},{"code":"700002","desc":"收费课程"}] // 保留原作者写的行内注释
private String courseType; // 执行语句
//排序 1按学习时间进行排序 2按加入时间进行排序 // 保留原作者写的行内注释
private String sortType; // 执行语句
//1即将过期、2已经过期 // 保留原作者写的行内注释
private String expiresType; // 执行语句
int page=1; // 把 1 赋值给 page
int startIndex; // 执行语句
int size=4; // 把 4 赋值给 size
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-model/src/main/java/com/xuecheng/learning/model/dto/XcChooseCourseDto.java
package com.xuecheng.learning.model.dto; // 声明类所在的包路径
import com.xuecheng.learning.model.po.XcChooseCourse; // 导入 XcChooseCourse 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2022/10/2 16:10 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class XcChooseCourseDto extends XcChooseCourse { // 定义 class XcChooseCourseDto
//学习资格,[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}] // 保留原作者写的行内注释
public String learnStatus; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-model/src/main/java/com/xuecheng/learning/model/dto/XcCourseTablesDto.java
package com.xuecheng.learning.model.dto; // 声明类所在的包路径
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @description 我的课程表模型类 // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/2 16:09 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class XcCourseTablesDto extends XcCourseTables { // 定义 class XcCourseTablesDto
//学习资格,[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}] // 保留原作者写的行内注释
public String learnStatus; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-model/src/main/java/com/xuecheng/learning/model/po/XcChooseCourse.java
package com.xuecheng.learning.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.*; // 导入 * 类
import lombok.Data; // 导入 Data 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_choose_course") // 使用注解 @TableName("xc_choose_course")
public class XcChooseCourse implements Serializable { // 定义 class XcChooseCourse
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
/** // 保留原作者写的块注释
* 主键 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@TableId(value = "id", type = IdType.AUTO) // 使用注解 @TableId(value = "id", type = IdType.AUTO)
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 课程id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long courseId; // 执行语句
/** // 保留原作者写的块注释
* 课程名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String courseName; // 执行语句
/** // 保留原作者写的块注释
* 用户id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userId; // 执行语句
/** // 保留原作者写的块注释
* 机构id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long companyId; // 执行语句
/** // 保留原作者写的块注释
* 选课类型 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderType; // 执行语句
/** // 保留原作者写的块注释
* 添加时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@TableField(fill = FieldFill.INSERT) // 使用注解 @TableField(fill = FieldFill.INSERT)
private LocalDateTime createDate; // 执行语句
/** // 保留原作者写的块注释
* 课程有效期(天) // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Integer validDays; // 执行语句
private Float coursePrice; // 执行语句
/** // 保留原作者写的块注释
* 选课状态 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String status; // 执行语句
/** // 保留原作者写的块注释
* 开始服务时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime validtimeStart; // 执行语句
/** // 保留原作者写的块注释
* 结束服务时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime validtimeEnd; // 执行语句
/** // 保留原作者写的块注释
* 备注 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String remarks; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-model/src/main/java/com/xuecheng/learning/model/po/XcCourseTables.java
package com.xuecheng.learning.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.*; // 导入 * 类
import lombok.Data; // 导入 Data 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_course_tables") // 使用注解 @TableName("xc_course_tables")
public class XcCourseTables implements Serializable { // 定义 class XcCourseTables
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
@TableId(value = "id", type = IdType.AUTO) // 使用注解 @TableId(value = "id", type = IdType.AUTO)
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 选课记录id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long chooseCourseId; // 执行语句
/** // 保留原作者写的块注释
* 用户id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userId; // 执行语句
/** // 保留原作者写的块注释
* 课程id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long courseId; // 执行语句
/** // 保留原作者写的块注释
* 机构id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long companyId; // 执行语句
/** // 保留原作者写的块注释
* 课程名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String courseName; // 执行语句
/** // 保留原作者写的块注释
* 课程名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String courseType; // 执行语句
/** // 保留原作者写的块注释
* 添加时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@TableField(fill = FieldFill.INSERT) // 使用注解 @TableField(fill = FieldFill.INSERT)
private LocalDateTime createDate; // 执行语句
/** // 保留原作者写的块注释
* 开始服务时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime validtimeStart; // 执行语句
/** // 保留原作者写的块注释
* 到期时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime validtimeEnd; // 执行语句
/** // 保留原作者写的块注释
* 更新时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime updateDate; // 执行语句
/** // 保留原作者写的块注释
* 备注 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String remarks; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-model/src/main/java/com/xuecheng/learning/model/po/XcLearnRecord.java
package com.xuecheng.learning.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.IdType; // 导入 IdType 类
import com.baomidou.mybatisplus.annotation.TableId; // 导入 TableId 类
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@TableName("xc_learn_record") // 使用注解 @TableName("xc_learn_record")
public class XcLearnRecord implements Serializable { // 定义 class XcLearnRecord
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
@TableId(value = "id", type = IdType.AUTO) // 使用注解 @TableId(value = "id", type = IdType.AUTO)
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 课程id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long courseId; // 执行语句
/** // 保留原作者写的块注释
* 课程名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String courseName; // 执行语句
/** // 保留原作者写的块注释
* 用户id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userId; // 执行语句
/** // 保留原作者写的块注释
* 最近学习时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime learnDate; // 执行语句
/** // 保留原作者写的块注释
* 学习时长 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long learnLength; // 执行语句
/** // 保留原作者写的块注释
* 章节id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long teachplanId; // 执行语句
/** // 保留原作者写的块注释
* 章节名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String teachplanName; // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- SQL 语句片段 -->
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- SQL 语句片段 -->
<modelVersion>4.0.0</modelVersion> <!-- SQL 语句片段 -->
<parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-learning</artifactId> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-learning-service</artifactId> <!-- SQL 语句片段 -->
<dependencies> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.alibaba.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.alibaba.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-message-sdk</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-learning-model</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-content-model</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- MySQL 驱动 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>mysql</groupId> <!-- SQL 语句片段 -->
<artifactId>mysql-connector-java</artifactId> <!-- SQL 语句片段 -->
<scope>runtime</scope> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- mybatis plus的依赖 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.baomidou</groupId> <!-- SQL 语句片段 -->
<artifactId>mybatis-plus-boot-starter</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 集成 Junit -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-test</artifactId> <!-- SQL 语句片段 -->
<scope>test</scope> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- 排除 Spring Boot 依赖的日志包冲突 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter</artifactId> <!-- SQL 语句片段 -->
<exclusions> <!-- SQL 语句片段 -->
<exclusion> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-logging</artifactId> <!-- SQL 语句片段 -->
</exclusion> <!-- SQL 语句片段 -->
</exclusions> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 集成 log4j2 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-log4j2</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-amqp</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-freemarker</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Cloud 微服务远程调用 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-openfeign</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuxueli</groupId> <!-- SQL 语句片段 -->
<artifactId>xxl-job-core</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-amqp</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
</dependencies> <!-- SQL 语句片段 -->
</project> <!-- SQL 语句片段 -->
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/config/MybatisPlusConfig.java
package com.xuecheng.learning.config; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.DbType; // 导入 DbType 类
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; // 导入 MybatisPlusInterceptor 类
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; // 导入 PaginationInnerInterceptor 类
import org.mybatis.spring.annotation.MapperScan; // 导入 MapperScan 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
/** // 保留原作者写的块注释
* <P> // 保留原作者写的块注释
* Mybatis-Plus 配置 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
@MapperScan("com.xuecheng.learning.mapper") // 使用注解 @MapperScan("com.xuecheng.learning.mapper")
public class MybatisPlusConfig { // 定义 class MybatisPlusConfig
/** // 保留原作者写的块注释
* 新的分页插件 // 保留原作者写的块注释
* 需要设置 MybatisConfiguration#useDeprecatedExecutor = false // 保留原作者写的块注释
* 避免缓存出现问题(该属性会在旧插件移除后一同移除) // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Bean // 使用注解 @Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() { // 定义方法 mybatisPlusInterceptor(...)
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 创建 MybatisPlusInterceptor 对象并赋值给 interceptor
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 执行语句
return interceptor; // 返回 interceptor
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/config/PayNotifyConfig.java
package com.xuecheng.learning.config; // 声明类所在的包路径
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.amqp.core.*; // 导入 * 类
import org.springframework.beans.factory.annotation.Qualifier; // 导入 Qualifier 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2023/2/23 16:59 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Configuration // 使用注解 @Configuration
public class PayNotifyConfig { // 定义 class PayNotifyConfig
//交换机 // 保留原作者写的行内注释
public static final String PAYNOTIFY_EXCHANGE_FANOUT = "paynotify_exchange_fanout"; // 把 "paynotify_exchange_fanout" 赋值给 PAYNOTIFY_EXCHANGE_FANOUT
//支付结果通知消息类型 // 保留原作者写的行内注释
public static final String MESSAGE_TYPE = "payresult_notify"; // 把 "payresult_notify" 赋值给 MESSAGE_TYPE
//支付通知队列 // 保留原作者写的行内注释
public static final String PAYNOTIFY_QUEUE = "paynotify_queue"; // 把 "paynotify_queue" 赋值给 PAYNOTIFY_QUEUE
//声明交换机,且持久化 // 保留原作者写的行内注释
@Bean(PAYNOTIFY_EXCHANGE_FANOUT) // 使用注解 @Bean(PAYNOTIFY_EXCHANGE_FANOUT)
public FanoutExchange paynotify_exchange_fanout() { // 定义方法 paynotify_exchange_fanout(...)
// 三个参数:交换机名称、是否持久化、当没有queue与其绑定时是否自动删除 // 保留原作者写的行内注释
return new FanoutExchange(PAYNOTIFY_EXCHANGE_FANOUT, true, false); // 返回 new FanoutExchange(PAYNOTIFY_EXCHANGE_FANOUT, true, false)
} // 代码块结束
//支付通知队列,且持久化 // 保留原作者写的行内注释
@Bean(PAYNOTIFY_QUEUE) // 使用注解 @Bean(PAYNOTIFY_QUEUE)
public Queue course_publish_queue() { // 定义方法 course_publish_queue(...)
return QueueBuilder.durable(PAYNOTIFY_QUEUE).build(); // 返回 QueueBuilder.durable(PAYNOTIFY_QUEUE).build()
} // 代码块结束
//交换机和支付通知队列绑定 // 保留原作者写的行内注释
@Bean // 使用注解 @Bean
public Binding binding_course_publish_queue(@Qualifier(PAYNOTIFY_QUEUE) Queue queue, @Qualifier(PAYNOTIFY_EXCHANGE_FANOUT) FanoutExchange exchange) { // 定义方法 binding_course_publish_queue(...)
return BindingBuilder.bind(queue).to(exchange); // 返回 BindingBuilder.bind(queue).to(exchange)
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/feignclient/ContentServiceClient.java
package com.xuecheng.learning.feignclient; // 声明类所在的包路径
import com.xuecheng.content.model.po.CoursePublish; // 导入 CoursePublish 类
import org.springframework.cloud.openfeign.FeignClient; // 导入 FeignClient 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 类
import org.springframework.web.bind.annotation.PathVariable; // 导入 PathVariable 类
import org.springframework.web.bind.annotation.ResponseBody; // 导入 ResponseBody 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 内容管理远程接口 // 保留原作者写的块注释
* @date 2022/10/25 9:13 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@FeignClient(value = "content-api",fallbackFactory = ContentServiceClientFallbackFactory.class) // 使用注解 @FeignClient(value = "content-api",fallbackFactory = ContentServiceClientFallbackFactory.class)
public interface ContentServiceClient { // 定义 interface ContentServiceClient
//查询已经发布的课程 // 保留原作者写的行内注释
@ResponseBody // 使用注解 @ResponseBody
@GetMapping("/content/r/coursepublish/{courseId}") // 使用注解 @GetMapping("/content/r/coursepublish/{courseId}")
public CoursePublish getCoursepublish(@PathVariable("courseId") Long courseId); // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/feignclient/ContentServiceClientFallbackFactory.java
package com.xuecheng.learning.feignclient; // 声明类所在的包路径
import com.xuecheng.content.model.po.CoursePublish; // 导入 CoursePublish 类
import feign.hystrix.FallbackFactory; // 导入 FallbackFactory 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.stereotype.Component; // 导入 Component 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2022/10/25 9:14 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Component // 使用注解 @Component
public class ContentServiceClientFallbackFactory implements FallbackFactory<ContentServiceClient> { // 定义 class ContentServiceClientFallbackFactory
@Override // 使用注解 @Override
public ContentServiceClient create(Throwable throwable) { // 定义方法 create(...)
return new ContentServiceClient() { // 定义方法 ContentServiceClient(...)
@Override // 使用注解 @Override
public CoursePublish getCoursepublish(Long courseId) { // 定义方法 getCoursepublish(...)
log.error("调用内容管理服务发生熔断:{}", throwable.toString(),throwable); // 执行语句
return null; // 返回 null
} // 代码块结束
}; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/feignclient/MediaServiceClient.java
package com.xuecheng.learning.feignclient; // 声明类所在的包路径
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类
import org.springframework.cloud.openfeign.FeignClient; // 导入 FeignClient 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 类
import org.springframework.web.bind.annotation.PathVariable; // 导入 PathVariable 类
import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 类
/** // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/27 9:04 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@FeignClient(value = "media-api",fallbackFactory = MediaServiceClientFallbackFactory.class) // 使用注解 @FeignClient(value = "media-api",fallbackFactory = MediaServiceClientFallbackFactory.class)
@RequestMapping("/media") // 使用注解 @RequestMapping("/media")
public interface MediaServiceClient { // 定义 interface MediaServiceClient
@GetMapping("/open/preview/{mediaId}") // 使用注解 @GetMapping("/open/preview/{mediaId}")
public RestResponse<String> getPlayUrlByMediaId(@PathVariable("mediaId") String mediaId); // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/feignclient/MediaServiceClientFallbackFactory.java
package com.xuecheng.learning.feignclient; // 声明类所在的包路径
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类
import feign.hystrix.FallbackFactory; // 导入 FallbackFactory 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.stereotype.Component; // 导入 Component 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2022/10/27 9:05 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Component // 使用注解 @Component
public class MediaServiceClientFallbackFactory implements FallbackFactory<MediaServiceClient> { // 定义 class MediaServiceClientFallbackFactory
@Override // 使用注解 @Override
public MediaServiceClient create(Throwable throwable) { // 定义方法 create(...)
return new MediaServiceClient() { // 定义方法 MediaServiceClient(...)
@Override // 使用注解 @Override
public RestResponse<String> getPlayUrlByMediaId(String mediaId) { // 定义方法 getPlayUrlByMediaId(...)
log.error("远程调用媒资管理服务熔断异常:{}", throwable.getMessage()); // 执行语句
return null; // 返回 null
} // 代码块结束
}; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/mapper/XcChooseCourseMapper.java
package com.xuecheng.learning.mapper; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.learning.model.po.XcChooseCourse; // 导入 XcChooseCourse 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* Mapper 接口 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface XcChooseCourseMapper extends BaseMapper<XcChooseCourse> { // 定义 interface XcChooseCourseMapper
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/mapper/XcChooseCourseMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.learning.mapper.XcChooseCourseMapper"> <!-- MyBatis 映射文件的根标签 -->
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.xuecheng.learning.model.po.XcChooseCourse"> <!-- 定义结果映射 -->
<id column="id" property="id" /> <!-- 主键列的映射规则 -->
<result column="course_id" property="courseId" /> <!-- 字段与属性的映射规则 -->
<result column="course_name" property="courseName" /> <!-- 字段与属性的映射规则 -->
<result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
<result column="company_id" property="companyId" /> <!-- 字段与属性的映射规则 -->
<result column="order_type" property="orderType" /> <!-- 字段与属性的映射规则 -->
<result column="create_date" property="createDate" /> <!-- 字段与属性的映射规则 -->
<result column="valid_days" property="validDays" /> <!-- 字段与属性的映射规则 -->
<result column="status" property="status" /> <!-- 字段与属性的映射规则 -->
<result column="validtime_start" property="validtimeStart" /> <!-- 字段与属性的映射规则 -->
<result column="validtime_end" property="validtimeEnd" /> <!-- 字段与属性的映射规则 -->
<result column="remarks" property="remarks" /> <!-- 字段与属性的映射规则 -->
</resultMap> <!-- 结束 resultMap 区块 -->
<!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
id, course_id, course_name, user_id, company_id, order_type, create_date, valid_days, status, validtime_start, validtime_end, remarks <!-- SQL 语句片段 -->
</sql> <!-- 结束 SQL 片段 -->
</mapper> <!-- 结束 mapper 标签 -->
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/mapper/XcCourseTablesMapper.java
package com.xuecheng.learning.mapper; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* Mapper 接口 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface XcCourseTablesMapper extends BaseMapper<XcCourseTables> { // 定义 interface XcCourseTablesMapper
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/mapper/XcCourseTablesMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.learning.mapper.XcCourseTablesMapper"> <!-- MyBatis 映射文件的根标签 -->
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.xuecheng.learning.model.po.XcCourseTables"> <!-- 定义结果映射 -->
<id column="id" property="id" /> <!-- 主键列的映射规则 -->
<result column="choose_course_id" property="chooseCourseId" /> <!-- 字段与属性的映射规则 -->
<result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
<result column="course_id" property="courseId" /> <!-- 字段与属性的映射规则 -->
<result column="company_id" property="companyId" /> <!-- 字段与属性的映射规则 -->
<result column="course_name" property="courseName" /> <!-- 字段与属性的映射规则 -->
<result column="create_date" property="createDate" /> <!-- 字段与属性的映射规则 -->
<result column="validtime_end" property="validtimeEnd" /> <!-- 字段与属性的映射规则 -->
<result column="update_date" property="updateDate" /> <!-- 字段与属性的映射规则 -->
<result column="remarks" property="remarks" /> <!-- 字段与属性的映射规则 -->
</resultMap> <!-- 结束 resultMap 区块 -->
<!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
id, choose_course_id, user_id, course_id, company_id, course_name, create_date, validtime_end, update_date, remarks <!-- SQL 语句片段 -->
</sql> <!-- 结束 SQL 片段 -->
</mapper> <!-- 结束 mapper 标签 -->
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/service/impl/LearningServiceImpl.java
package com.xuecheng.learning.service.impl; // 声明类所在的包路径
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类
import com.xuecheng.content.model.po.CoursePublish; // 导入 CoursePublish 类
import com.xuecheng.learning.feignclient.ContentServiceClient; // 导入 ContentServiceClient 类
import com.xuecheng.learning.feignclient.MediaServiceClient; // 导入 MediaServiceClient 类
import com.xuecheng.learning.model.dto.XcCourseTablesDto; // 导入 XcCourseTablesDto 类
import com.xuecheng.learning.service.LearningService; // 导入 LearningService 类
import com.xuecheng.learning.service.MyCourseTablesService; // 导入 MyCourseTablesService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.apache.commons.lang3.StringUtils; // 导入 StringUtils 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.stereotype.Service; // 导入 Service 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 在线学习接口 // 保留原作者写的块注释
* @date 2023/2/28 10:20 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Service // 使用注解 @Service
public class LearningServiceImpl implements LearningService { // 定义 class LearningServiceImpl
@Autowired // 使用注解 @Autowired
MyCourseTablesService myCourseTablesService; // 执行语句
@Autowired // 使用注解 @Autowired
ContentServiceClient contentServiceClient; // 执行语句
@Autowired // 使用注解 @Autowired
MediaServiceClient mediaServiceClient; // 执行语句
@Override // 使用注解 @Override
public RestResponse<String> getVideo(String userId, Long courseId, Long teachplanId, String mediaId) { // 定义方法 getVideo(...)
//查询课程信息 // 保留原作者写的行内注释
CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId); // 把 contentServiceClient.getCoursepublish(courseId) 赋值给 coursepublish
//判断如果为null不再继续 // 保留原作者写的行内注释
if(coursepublish == null){ // 定义方法 方法(...)
return RestResponse.validfail("课程不存在"); // 返回 RestResponse.validfail("课程不存在")
} // 代码块结束
//远程调用内容管理服务根据课程计划id(teachplanId)去查询课程计划信息,如果is_preview的值为1表示支持试学 // 保留原作者写的行内注释
//也可以从coursepublish对象中解析出课程计划信息去判断是否支持试学 // 保留原作者写的行内注释
//todo:如果支持试学调用媒资服务查询视频的播放地址,返回 // 保留原作者写的行内注释
//用户已登录 // 保留原作者写的行内注释
if(StringUtils.isNotEmpty(userId)){ // 定义方法 方法(...)
//获取学习资格 // 保留原作者写的行内注释
XcCourseTablesDto learningStatus = myCourseTablesService.getLearningStatus(userId, courseId); // 把 myCourseTablesService.getLearningStatus(userId, courseId) 赋值给 learningStatus
//学习资格,[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}] // 保留原作者写的行内注释
String learnStatus = learningStatus.getLearnStatus(); // 把 learningStatus.getLearnStatus() 的返回值赋给 learnStatus
if("702002".equals(learnStatus)){ // 定义方法 方法(...)
return RestResponse.validfail("无法学习,因为没有选课或选课后没有支付"); // 返回 RestResponse.validfail("无法学习,因为没有选课或选课后没有支付")
}else if("702003".equals(learnStatus)){ // 定义方法 if(...)
return RestResponse.validfail("已过期需要申请续期或重新支付"); // 返回 RestResponse.validfail("已过期需要申请续期或重新支付")
}else{ // 代码逻辑
//有资格学习,要返回视频的播放地址 // 保留原作者写的行内注释
//程调用媒资获取视频播放地址 // 保留原作者写的行内注释
RestResponse<String> playUrlByMediaId = mediaServiceClient.getPlayUrlByMediaId(mediaId); // 把 mediaServiceClient.getPlayUrlByMediaId(mediaId) 赋值给 playUrlByMediaId
return playUrlByMediaId; // 返回 playUrlByMediaId
} // 代码块结束
} // 代码块结束
//如果用户没有登录 // 保留原作者写的行内注释
//取出课程的收费规则 // 保留原作者写的行内注释
String charge = coursepublish.getCharge(); // 把 coursepublish.getCharge() 的返回值赋给 charge
if("201000".equals(charge)){ // 定义方法 方法(...)
//有资格学习,要返回视频的播放地址 // 保留原作者写的行内注释
//远程调用媒资获取视频播放地址 // 保留原作者写的行内注释
RestResponse<String> playUrlByMediaId = mediaServiceClient.getPlayUrlByMediaId(mediaId); // 把 mediaServiceClient.getPlayUrlByMediaId(mediaId) 赋值给 playUrlByMediaId
return playUrlByMediaId; // 返回 playUrlByMediaId
} // 代码块结束
return RestResponse.validfail("课程需要购买"); // 返回 RestResponse.validfail("课程需要购买")
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/service/impl/MyCourseTablesServiceImpl.java
package com.xuecheng.learning.service.impl; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 导入 LambdaQueryWrapper 类
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 Page 类
import com.xuecheng.base.exception.XueChengPlusException; // 导入 XueChengPlusException 类
import com.xuecheng.base.model.PageResult; // 导入 PageResult 类
import com.xuecheng.content.model.po.CoursePublish; // 导入 CoursePublish 类
import com.xuecheng.learning.feignclient.ContentServiceClient; // 导入 ContentServiceClient 类
import com.xuecheng.learning.mapper.XcChooseCourseMapper; // 导入 XcChooseCourseMapper 类
import com.xuecheng.learning.mapper.XcCourseTablesMapper; // 导入 XcCourseTablesMapper 类
import com.xuecheng.learning.model.dto.MyCourseTableParams; // 导入 MyCourseTableParams 类
import com.xuecheng.learning.model.dto.XcChooseCourseDto; // 导入 XcChooseCourseDto 类
import com.xuecheng.learning.model.dto.XcCourseTablesDto; // 导入 XcCourseTablesDto 类
import com.xuecheng.learning.model.po.XcChooseCourse; // 导入 XcChooseCourse 类
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
import com.xuecheng.learning.service.MyCourseTablesService; // 导入 MyCourseTablesService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.BeanUtils; // 导入 BeanUtils 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.stereotype.Service; // 导入 Service 类
import org.springframework.transaction.annotation.Transactional; // 导入 Transactional 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
import java.util.List; // 导入 List 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 选课相关接口实现 // 保留原作者写的块注释
* @date 2023/2/25 12:02 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Service // 使用注解 @Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService { // 定义 class MyCourseTablesServiceImpl
@Autowired // 使用注解 @Autowired
XcChooseCourseMapper chooseCourseMapper; // 执行语句
@Autowired // 使用注解 @Autowired
XcCourseTablesMapper courseTablesMapper; // 执行语句
@Autowired // 使用注解 @Autowired
ContentServiceClient contentServiceClient; // 执行语句
// 添加选课 // 保留原作者写的行内注释
@Transactional // 使用注解 @Transactional
@Override // 使用注解 @Override
public XcChooseCourseDto addChooseCourse(String userId, Long courseId) { // 定义方法 addChooseCourse(...)
//选课调用内容管理查询课程的收费规则 // 保留原作者写的行内注释
CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId); // 把 contentServiceClient.getCoursepublish(courseId) 赋值给 coursepublish
if(coursepublish == null){ // 定义方法 方法(...)
XueChengPlusException.cast("课程不存在"); // 执行语句
} // 代码块结束
//收费规则 // 保留原作者写的行内注释
String charge = coursepublish.getCharge(); // 把 coursepublish.getCharge() 的返回值赋给 charge
//选课记录 // 保留原作者写的行内注释
XcChooseCourse chooseCourse = null; // 把变量 chooseCourse 初始化为 null
if("201000".equals(charge)){//免费课程 // 定义方法 方法(...)
//向选课记录表写 // 保留原作者写的行内注释
chooseCourse = addFreeCoruse(userId, coursepublish); // 把 addFreeCoruse(userId, coursepublish) 赋值给 chooseCourse
//向我的课程表写 // 保留原作者写的行内注释
XcCourseTables xcCourseTables = addCourseTabls(chooseCourse); // 把 addCourseTabls(chooseCourse) 赋值给 xcCourseTables
}else{ // 代码逻辑
//如果收费课程,会向选课记录表写数据 // 保留原作者写的行内注释
chooseCourse = addChargeCoruse(userId, coursepublish); // 把 addChargeCoruse(userId, coursepublish) 赋值给 chooseCourse
} // 代码块结束
//判断学生的学习资格 // 保留原作者写的行内注释
XcCourseTablesDto xcCourseTablesDto = getLearningStatus(userId, courseId); // 把 getLearningStatus(userId, courseId) 赋值给 xcCourseTablesDto
//构造返回值 // 保留原作者写的行内注释
XcChooseCourseDto xcChooseCourseDto = new XcChooseCourseDto(); // 创建 XcChooseCourseDto 对象并赋值给 xcChooseCourseDto
BeanUtils.copyProperties(chooseCourse,xcChooseCourseDto); // 执行语句
//设置学习资格状态 // 保留原作者写的行内注释
xcChooseCourseDto.setLearnStatus(xcCourseTablesDto.getLearnStatus()); // 执行语句
return xcChooseCourseDto; // 返回 xcChooseCourseDto
} // 代码块结束
//返回//学习资格,[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}] // 保留原作者写的行内注释
@Override // 使用注解 @Override
public XcCourseTablesDto getLearningStatus(String userId, Long courseId) { // 定义方法 getLearningStatus(...)
//返回的结果 // 保留原作者写的行内注释
XcCourseTablesDto courseTablesDto = new XcCourseTablesDto(); // 创建 XcCourseTablesDto 对象并赋值给 courseTablesDto
//查询我的课程表,如果查不到说明没有选课 // 保留原作者写的行内注释
XcCourseTables xcCourseTables = getXcCourseTables(userId, courseId); // 把 getXcCourseTables(userId, courseId) 赋值给 xcCourseTables
if(xcCourseTables == null){ // 定义方法 方法(...)
//"code":"702002","desc":"没有选课或选课后没有支付" // 保留原作者写的行内注释
courseTablesDto.setLearnStatus("702002"); // 执行语句
return courseTablesDto; // 返回 courseTablesDto
} // 代码块结束
//如果查到了,判断是否过期,如果过期不能继续学习,没有过期可以继续学习 // 保留原作者写的行内注释
boolean before = xcCourseTables.getValidtimeEnd().isBefore(LocalDateTime.now()); // 把 xcCourseTables.getValidtimeEnd().isBefore(LocalDateTime.now()) 赋值给 before
if(before){ // 定义方法 方法(...)
//"code":"702003","desc":"已过期需要申请续期或重新支付" // 保留原作者写的行内注释
BeanUtils.copyProperties(xcCourseTables,courseTablesDto); // 执行语句
courseTablesDto.setLearnStatus("702003"); // 执行语句
return courseTablesDto; // 返回 courseTablesDto
}else{ // 代码逻辑
//"code":"702001","desc":"正常学习" // 保留原作者写的行内注释
BeanUtils.copyProperties(xcCourseTables,courseTablesDto); // 执行语句
courseTablesDto.setLearnStatus("702001"); // 执行语句
return courseTablesDto; // 返回 courseTablesDto
} // 代码块结束
} // 代码块结束
// 支付完毕添加到课程表 // 保留原作者写的行内注释
@Override // 使用注解 @Override
public boolean saveChooseCourseSuccess(String chooseCourseId) { // 定义方法 saveChooseCourseSuccess(...)
//根据选课id查询选课表 // 保留原作者写的行内注释
XcChooseCourse chooseCourse = chooseCourseMapper.selectById(chooseCourseId); // 把 chooseCourseMapper.selectById(chooseCourseId) 赋值给 chooseCourse
if(chooseCourse == null){ // 定义方法 方法(...)
log.debug("接收购买课程的消息,根据选课id从数据库找不到选课记录,选课id:{}",chooseCourseId); // 执行语句
return false; // 返回 false
} // 代码块结束
//选课状态 // 保留原作者写的行内注释
String status = chooseCourse.getStatus(); // 把 chooseCourse.getStatus() 的返回值赋给 status
//只有当未支付时才更新为已支付 // 保留原作者写的行内注释
if("701002".equals(status)){ // 定义方法 方法(...)
//更新选课记录的状态为支付成功 // 保留原作者写的行内注释
chooseCourse.setStatus("701001"); // 执行语句
int i = chooseCourseMapper.updateById(chooseCourse); // 把 chooseCourseMapper.updateById(chooseCourse) 赋值给 i
if(i<=0){ // 定义方法 方法(...)
log.debug("添加选课记录失败:{}",chooseCourse); // 执行语句
XueChengPlusException.cast("添加选课记录失败"); // 执行语句
} // 代码块结束
//向我的课程表插入记录 // 保留原作者写的行内注释
XcCourseTables xcCourseTables = addCourseTabls(chooseCourse); // 把 addCourseTabls(chooseCourse) 赋值给 xcCourseTables
return true; // 返回 true
} // 代码块结束
return false; // 返回 false
} // 代码块结束
// 分页 // 保留原作者写的行内注释
@Override // 使用注解 @Override
public PageResult<XcCourseTables> mycoursetables(MyCourseTableParams params) { // 定义方法 mycoursetables(...)
//用户id // 保留原作者写的行内注释
String userId = params.getUserId(); // 把 params.getUserId() 的返回值赋给 userId
//当前页码 // 保留原作者写的行内注释
int pageNo = params.getPage(); // 把 params.getPage() 的返回值赋给 pageNo
//每页记录数 // 保留原作者写的行内注释
int size = params.getSize(); // 把 params.getSize() 的返回值赋给 size
Page<XcCourseTables> courseTablesPage = new Page<>(pageNo, size); // 创建 Page<> 对象并赋值给 courseTablesPage
LambdaQueryWrapper<XcCourseTables> lambdaQueryWrapper = new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId); // 创建 LambdaQueryWrapper<XcCourseTables> 对象并赋值给 lambdaQueryWrapper
//查询数据 // 保留原作者写的行内注释
Page<XcCourseTables> result = courseTablesMapper.selectPage(courseTablesPage, lambdaQueryWrapper); // 把 courseTablesMapper.selectPage(courseTablesPage, lambdaQueryWrapper) 赋值给 result
//数据列表 // 保留原作者写的行内注释
List<XcCourseTables> records = result.getRecords(); // 把 result.getRecords() 的返回值赋给 records
//总记录数 // 保留原作者写的行内注释
long total = result.getTotal(); // 把 result.getTotal() 的返回值赋给 total
//List<T> items, long counts, long page, long pageSize // 保留原作者写的行内注释
PageResult pageResult = new PageResult(records, total, pageNo, size); // 创建 PageResult 对象并赋值给 pageResult
return pageResult; // 返回 pageResult
} // 代码块结束
//添加免费课程,免费课程加入选课记录表、我的课程表 // 保留原作者写的行内注释
public XcChooseCourse addFreeCoruse(String userId, CoursePublish coursepublish) { // 定义方法 addFreeCoruse(...)
//课程id // 保留原作者写的行内注释
Long courseId = coursepublish.getId(); // 把 coursepublish.getId() 的返回值赋给 courseId
//判断,如果存在免费的选课记录且选课状态为成功,直接返回了 // 保留原作者写的行内注释
LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<XcChooseCourse>().eq(XcChooseCourse::getUserId, userId) // 代码逻辑
.eq(XcChooseCourse::getCourseId, courseId) // 代码逻辑
.eq(XcChooseCourse::getOrderType, "700001")//免费课程 // 代码逻辑
.eq(XcChooseCourse::getStatus, "701001");//选课成功 // 执行语句
List<XcChooseCourse> xcChooseCourses = chooseCourseMapper.selectList(queryWrapper); // 把 chooseCourseMapper.selectList(queryWrapper) 赋值给 xcChooseCourses
if(xcChooseCourses.size()>0){ // 定义方法 方法(...)
return xcChooseCourses.get(0); // 返回 xcChooseCourses.get(0)
} // 代码块结束
//向选课记录表写数据 // 保留原作者写的行内注释
XcChooseCourse chooseCourse = new XcChooseCourse(); // 创建 XcChooseCourse 对象并赋值给 chooseCourse
chooseCourse.setCourseId(courseId); // 执行语句
chooseCourse.setCourseName(coursepublish.getName()); // 执行语句
chooseCourse.setUserId(userId); // 执行语句
chooseCourse.setCompanyId(coursepublish.getCompanyId()); // 执行语句
chooseCourse.setOrderType("700001");//免费课程 // 执行语句
chooseCourse.setCreateDate(LocalDateTime.now()); // 执行语句
chooseCourse.setCoursePrice(coursepublish.getPrice()); // 执行语句
chooseCourse.setValidDays(365); // 执行语句
chooseCourse.setStatus("701001");//选课成功 // 执行语句
chooseCourse.setValidtimeStart(LocalDateTime.now());//有效期的开始时间 // 执行语句
chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));//有效期的结束时间 // 执行语句
int insert = chooseCourseMapper.insert(chooseCourse); // 把 chooseCourseMapper.insert(chooseCourse) 赋值给 insert
if(insert<=0){ // 定义方法 方法(...)
XueChengPlusException.cast("添加选课记录失败"); // 执行语句
} // 代码块结束
return chooseCourse; // 返回 chooseCourse
} // 代码块结束
//添加到我的课程表 // 保留原作者写的行内注释
public XcCourseTables addCourseTabls(XcChooseCourse xcChooseCourse){ // 定义方法 addCourseTabls(...)
//选课成功了才可以向我的课程表添加 // 保留原作者写的行内注释
String status = xcChooseCourse.getStatus(); // 把 xcChooseCourse.getStatus() 的返回值赋给 status
if(!"701001".equals(status)){ // 定义方法 方法(...)
XueChengPlusException.cast("选课没有成功无法添加到课程表"); // 执行语句
} // 代码块结束
XcCourseTables xcCourseTables = getXcCourseTables(xcChooseCourse.getUserId(), xcChooseCourse.getCourseId()); // 把 getXcCourseTables(xcChooseCourse.getUserId(), xcChooseCourse.getCourseId()) 赋值给 xcCourseTables
if(xcCourseTables!=null){ // 定义方法 方法(...)
return xcCourseTables; // 返回 xcCourseTables
} // 代码块结束
xcCourseTables = new XcCourseTables(); // 创建 XcCourseTables 对象并赋值给 xcCourseTables
BeanUtils.copyProperties(xcChooseCourse,xcCourseTables); // 执行语句
xcCourseTables.setChooseCourseId(xcChooseCourse.getId());//记录选课表的逐渐 // 执行语句
xcCourseTables.setCourseType(xcChooseCourse.getOrderType());//选课类型 // 执行语句
xcCourseTables.setUpdateDate(LocalDateTime.now()); // 执行语句
int insert = courseTablesMapper.insert(xcCourseTables); // 把 courseTablesMapper.insert(xcCourseTables) 赋值给 insert
if(insert<=0){ // 定义方法 方法(...)
XueChengPlusException.cast("添加我的课程表失败"); // 执行语句
} // 代码块结束
return xcCourseTables; // 返回 xcCourseTables
} // 代码块结束
/** // 保留原作者写的块注释
* @description 根据课程和用户查询我的课程表中某一门课程 // 保留原作者写的块注释
* @param userId // 保留原作者写的块注释
* @param courseId // 保留原作者写的块注释
* @return com.xuecheng.learning.model.po.XcCourseTables // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/2 17:07 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcCourseTables getXcCourseTables(String userId,Long courseId){ // 定义方法 getXcCourseTables(...)
XcCourseTables xcCourseTables = courseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId).eq(XcCourseTables::getCourseId, courseId)); // 把 courseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId).eq(XcCourseTables::getCourseId, courseId)) 赋值给 xcCourseTables
return xcCourseTables; // 返回 xcCourseTables
} // 代码块结束
//添加收费课程 // 保留原作者写的行内注释
public XcChooseCourse addChargeCoruse(String userId,CoursePublish coursepublish){ // 定义方法 addChargeCoruse(...)
//课程id // 保留原作者写的行内注释
Long courseId = coursepublish.getId(); // 把 coursepublish.getId() 的返回值赋给 courseId
//判断,如果存在收费的选课记录且选课状态为待支付,直接返回了 // 保留原作者写的行内注释
LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<XcChooseCourse>().eq(XcChooseCourse::getUserId, userId) // 代码逻辑
.eq(XcChooseCourse::getCourseId, courseId) // 代码逻辑
.eq(XcChooseCourse::getOrderType, "700002")//收费课程 // 代码逻辑
.eq(XcChooseCourse::getStatus, "701002");//待支付 // 执行语句
List<XcChooseCourse> xcChooseCourses = chooseCourseMapper.selectList(queryWrapper); // 把 chooseCourseMapper.selectList(queryWrapper) 赋值给 xcChooseCourses
if(xcChooseCourses.size()>0){ // 定义方法 方法(...)
return xcChooseCourses.get(0); // 返回 xcChooseCourses.get(0)
} // 代码块结束
//向选课记录表写数据 // 保留原作者写的行内注释
XcChooseCourse chooseCourse = new XcChooseCourse(); // 创建 XcChooseCourse 对象并赋值给 chooseCourse
chooseCourse.setCourseId(courseId); // 执行语句
chooseCourse.setCourseName(coursepublish.getName()); // 执行语句
chooseCourse.setUserId(userId); // 执行语句
chooseCourse.setCompanyId(coursepublish.getCompanyId()); // 执行语句
chooseCourse.setOrderType("700002");//收费课程 // 执行语句
chooseCourse.setCreateDate(LocalDateTime.now()); // 执行语句
chooseCourse.setCoursePrice(coursepublish.getPrice()); // 执行语句
chooseCourse.setValidDays(365); // 执行语句
chooseCourse.setStatus("701002");//待支付 // 执行语句
chooseCourse.setValidtimeStart(LocalDateTime.now());//有效期的开始时间 // 执行语句
chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));//有效期的结束时间 // 执行语句
int insert = chooseCourseMapper.insert(chooseCourse); // 把 chooseCourseMapper.insert(chooseCourse) 赋值给 insert
if(insert<=0){ // 定义方法 方法(...)
XueChengPlusException.cast("添加选课记录失败"); // 执行语句
} // 代码块结束
return chooseCourse; // 返回 chooseCourse
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/service/impl/ReceivePayNotifyService.java
package com.xuecheng.learning.service.impl; // 声明类所在的包路径
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.xuecheng.base.exception.XueChengPlusException; // 导入 XueChengPlusException 类
import com.xuecheng.learning.config.PayNotifyConfig; // 导入 PayNotifyConfig 类
import com.xuecheng.learning.service.MyCourseTablesService; // 导入 MyCourseTablesService 类
import com.xuecheng.messagesdk.model.po.MqMessage; // 导入 MqMessage 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.amqp.core.Message; // 导入 Message 类
import org.springframework.amqp.rabbit.annotation.RabbitListener; // 导入 RabbitListener 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.stereotype.Service; // 导入 Service 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 接收消息通知处理类 // 保留原作者写的块注释
* @date 2023/2/26 16:42 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Service // 使用注解 @Service
public class ReceivePayNotifyService { // 定义 class ReceivePayNotifyService
@Autowired // 使用注解 @Autowired
MyCourseTablesService myCourseTablesService; // 执行语句
@RabbitListener(queues = PayNotifyConfig.PAYNOTIFY_QUEUE) // 使用注解 @RabbitListener(queues = PayNotifyConfig.PAYNOTIFY_QUEUE)
public void receive(Message message) { // 定义方法 receive(...)
try { // 尝试执行可能抛出异常的代码
Thread.sleep(5000); // 执行语句
} catch (InterruptedException e) { // 定义方法 catch(...)
e.printStackTrace(); // 执行语句
} // 代码块结束
//解析出消息 // 保留原作者写的行内注释
byte[] body = message.getBody(); // 把 message.getBody() 的返回值赋给 body
String jsonString = new String(body); // 创建 String 对象并赋值给 jsonString
//转成对象 // 保留原作者写的行内注释
MqMessage mqMessage = JSON.parseObject(jsonString, MqMessage.class); // 把 JSON.parseObject(jsonString, MqMessage.class) 赋值给 mqMessage
//解析消息的内容 // 保留原作者写的行内注释
//选课id // 保留原作者写的行内注释
String chooseCourseId = mqMessage.getBusinessKey1(); // 把 mqMessage.getBusinessKey1() 的返回值赋给 chooseCourseId
//订单类型 // 保留原作者写的行内注释
String orderType = mqMessage.getBusinessKey2(); // 把 mqMessage.getBusinessKey2() 的返回值赋给 orderType
//学习中心服务只要购买课程类的支付订单的结果 // 保留原作者写的行内注释
if (orderType.equals("60201")) { // 定义方法 方法(...)
//根据消息内容,更新选课记录、向我的课程表插入记录 // 保留原作者写的行内注释
boolean b = myCourseTablesService.saveChooseCourseSuccess(chooseCourseId); // 把 myCourseTablesService.saveChooseCourseSuccess(chooseCourseId) 赋值给 b
if (!b) { // 定义方法 方法(...)
XueChengPlusException.cast("保证选课记录状态失败"); // 执行语句
} // 代码块结束
} // 代码块结束
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/service/LearningService.java
package com.xuecheng.learning.service; // 声明类所在的包路径
import com.xuecheng.base.model.RestResponse; // 导入 RestResponse 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 在线学习相关的接口 // 保留原作者写的块注释
* @date 2023/2/28 10:17 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface LearningService { // 定义 interface LearningService
/** // 保留原作者写的块注释
* @description 获取教学视频 // 保留原作者写的块注释
* @param courseId 课程id // 保留原作者写的块注释
* @param teachplanId 课程计划id // 保留原作者写的块注释
* @param mediaId 视频文件id // 保留原作者写的块注释
* @return com.xuecheng.base.model.RestResponse<java.lang.String> // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/5 9:08 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public RestResponse<String> getVideo(String userId, Long courseId, Long teachplanId, String mediaId); // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/main/java/com/xuecheng/learning/service/MyCourseTablesService.java
package com.xuecheng.learning.service; // 声明类所在的包路径
import com.xuecheng.base.model.PageResult; // 导入 PageResult 类
import com.xuecheng.learning.model.dto.MyCourseTableParams; // 导入 MyCourseTableParams 类
import com.xuecheng.learning.model.dto.XcChooseCourseDto; // 导入 XcChooseCourseDto 类
import com.xuecheng.learning.model.dto.XcCourseTablesDto; // 导入 XcCourseTablesDto 类
import com.xuecheng.learning.model.po.XcCourseTables; // 导入 XcCourseTables 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 选课相关的接口 // 保留原作者写的块注释
* @date 2023/2/25 12:00 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface MyCourseTablesService { // 定义 interface MyCourseTablesService
/** // 保留原作者写的块注释
* @description 添加选课 // 保留原作者写的块注释
* @param userId 用户id // 保留原作者写的块注释
* @param courseId 课程id // 保留原作者写的块注释
* @return com.xuecheng.learning.model.dto.XcChooseCourseDto // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* 响应选课结果 // 保留原作者写的块注释
* @date 2022/10/24 17:33 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcChooseCourseDto addChooseCourse(String userId, Long courseId); // 执行语句
/** // 保留原作者写的块注释
* @description 判断学习资格 // 保留原作者写的块注释
* @param userId // 保留原作者写的块注释
* @param courseId // 保留原作者写的块注释
* @return XcCourseTablesDto 学习资格状态 [{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}] // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/3 7:37 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcCourseTablesDto getLearningStatus(String userId, Long courseId); // 执行语句
/** // 保留原作者写的块注释
* 保存选课成功状态 // 保留原作者写的块注释
* @param chooseCourseId // 保留原作者写的块注释
* @return // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public boolean saveChooseCourseSuccess(String chooseCourseId); // 执行语句
/** // 保留原作者写的块注释
* @description 我的课程表 // 保留原作者写的块注释
* @param params // 保留原作者写的块注释
* @return com.xuecheng.base.model.PageResult<com.xuecheng.learning.model.po.XcCourseTables> // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/27 9:24 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public PageResult<XcCourseTables> mycoursetables(MyCourseTableParams params); // 执行语句
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/test/java/com/xuecheng/learning/FeignClientTest.java
package com.xuecheng.learning; // 声明类所在的包路径
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; // 导入 LocalDateTimeSerializer 类
import com.xuecheng.content.model.po.CoursePublish; // 导入 CoursePublish 类
import com.xuecheng.learning.feignclient.ContentServiceClient; // 导入 ContentServiceClient 类
import org.junit.jupiter.api.Assertions; // 导入 Assertions 类
import org.junit.jupiter.api.Test; // 导入 Test 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.boot.test.context.SpringBootTest; // 导入 SpringBootTest 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2023/2/22 20:14 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@SpringBootTest // 使用注解 @SpringBootTest
public class FeignClientTest { // 定义 class FeignClientTest
@Autowired // 使用注解 @Autowired
ContentServiceClient contentServiceClient; // 执行语句
@Test // 使用注解 @Test
public void testContentServiceClient() { // 定义方法 testContentServiceClient(...)
CoursePublish coursepublish = contentServiceClient.getCoursepublish(120L); // 把 contentServiceClient.getCoursepublish(120L) 赋值给 coursepublish
Assertions.assertNotNull(coursepublish); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/test/java/com/xuecheng/learning/LearningApplication.java
package com.xuecheng.learning; // 声明类所在的包路径
import org.springframework.boot.SpringApplication; // 导入 SpringApplication 类
import org.springframework.boot.autoconfigure.SpringBootApplication; // 导入 SpringBootApplication 类
import org.springframework.cloud.openfeign.EnableFeignClients; // 导入 EnableFeignClients 类
@EnableFeignClients(basePackages={"com.xuecheng.*.feignclient"}) // 使用注解 @EnableFeignClients(basePackages={"com.xuecheng.*.feignclient"})
@SpringBootApplication // 使用注解 @SpringBootApplication
public class LearningApplication { // 定义 class LearningApplication
public static void main(String[] args) { // 定义方法 main(...)
SpringApplication.run(LearningApplication.class, args); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/test/java/com/xuecheng/learning/Test1.java
package com.xuecheng.learning; // 声明类所在的包路径
import com.xuecheng.learning.mapper.XcChooseCourseMapper; // 导入 XcChooseCourseMapper 类
import org.junit.jupiter.api.Test; // 导入 Test 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.boot.test.context.SpringBootTest; // 导入 SpringBootTest 类
/** // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/2 10:32 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@SpringBootTest // 使用注解 @SpringBootTest
public class Test1 { // 定义 class Test1
@Autowired // 使用注解 @Autowired
XcChooseCourseMapper xcChooseCourseMapper; // 执行语句
@Test // 使用注解 @Test
public void test(){ // 定义方法 test(...)
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/test/resources/bootstrap.yml
#微服务配置
spring:
application:
name: learning-service
cloud:
nacos:
server-addr: 192.168.101.65:8848
discovery:
namespace: dev402
group: xuecheng-plus-project
config:
namespace: dev402
group: xuecheng-plus-project
file-extension: yaml
refresh-enabled: true
extension-configs:
- data-id: learning-service-${spring.profiles.active}.yaml
group: xuecheng-plus-project
refresh: true
shared-configs:
- data-id: swagger-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: logging-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: feign-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
profiles:
active: dev
文件:xuecheng-plus-learning/xuecheng-plus-learning-service/src/test/resources/log4j2-dev.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<Configuration monitorInterval="180" packages=""> <!-- SQL 语句片段 -->
<properties> <!-- SQL 语句片段 -->
<property name="logdir">logs</property> <!-- SQL 语句片段 -->
<property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property> <!-- SQL 语句片段 -->
</properties> <!-- SQL 语句片段 -->
<Appenders> <!-- SQL 语句片段 -->
<Console name="Console" target="SYSTEM_OUT"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
</Console> <!-- SQL 语句片段 -->
<RollingFile name="ErrorAppender" fileName="${logdir}/error.log" <!-- SQL 语句片段 -->
filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/> <!-- SQL 语句片段 -->
<Policies> <!-- SQL 语句片段 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- SQL 语句片段 -->
</Policies> <!-- SQL 语句片段 -->
</RollingFile> <!-- SQL 语句片段 -->
<RollingFile name="DebugAppender" fileName="${logdir}/info.log" <!-- SQL 语句片段 -->
filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> <!-- SQL 语句片段 -->
<Policies> <!-- SQL 语句片段 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- SQL 语句片段 -->
</Policies> <!-- SQL 语句片段 -->
</RollingFile> <!-- SQL 语句片段 -->
<!--异步appender-->
<Async name="AsyncAppender" includeLocation="true"> <!-- SQL 语句片段 -->
<AppenderRef ref="ErrorAppender"/> <!-- SQL 语句片段 -->
<AppenderRef ref="DebugAppender"/> <!-- SQL 语句片段 -->
</Async> <!-- SQL 语句片段 -->
</Appenders> <!-- SQL 语句片段 -->
<Loggers> <!-- SQL 语句片段 -->
<!--过滤掉spring和mybatis的一些无用的debug信息-->
<logger name="org.springframework" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.mybatis" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="cn.itcast.wanxinp2p.consumer.mapper" level="DEBUG"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="springfox" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.apache.http" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="com.netflix.discovery" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqCommon" level="INFO" > <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqRemoting" level="INFO" > <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqClient" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily.lottery" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily.bonuspoint" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<!--OFF 0-->
<!--FATAL 100-->
<!--ERROR 200-->
<!--WARN 300-->
<!--INFO 400-->
<!--DEBUG 500-->
<!--TRACE 600-->
<!--ALL Integer.MAX_VALUE-->
<Root level="DEBUG" includeLocation="true"> <!-- SQL 语句片段 -->
<AppenderRef ref="AsyncAppender"/> <!-- SQL 语句片段 -->
<AppenderRef ref="Console"/> <!-- SQL 语句片段 -->
<AppenderRef ref="DebugAppender"/> <!-- SQL 语句片段 -->
</Root> <!-- SQL 语句片段 -->
</Loggers> <!-- SQL 语句片段 -->
</Configuration> <!-- SQL 语句片段 -->
评论
0 条
还没有评论,先写一条吧。