list) {
34 | this.total = total;
35 | this.list = list;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/params/UctrMemberSearchParam.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.params;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 | import lombok.EqualsAndHashCode;
7 | import lombok.ToString;
8 | import lombok.experimental.Accessors;
9 |
10 | import java.time.LocalDateTime;
11 |
12 | /**
13 | * Uctr Member Search Param
14 | *
15 | * @author Myles Yang
16 | */
17 | @EqualsAndHashCode(callSuper = true)
18 | @Data
19 | @Accessors(chain = true)
20 | @ToString(callSuper = true)
21 | @ApiModel("学员搜索参数")
22 | public class UctrMemberSearchParam extends BasePageParam {
23 |
24 | private String nickname;
25 |
26 | private String mobile;
27 |
28 | private Boolean enable;
29 |
30 | @ApiModelProperty("大于该注册时间")
31 | private LocalDateTime beginCreate;
32 |
33 | @ApiModelProperty("小于该注册时间")
34 | private LocalDateTime endCreate;
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/admin/AclRoleVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.admin;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 | import lombok.ToString;
7 | import lombok.experimental.Accessors;
8 | import xyz.refrain.onlineedu.model.base.BeanConvert;
9 |
10 | import java.io.Serializable;
11 |
12 | /**
13 | * Acl Role VO
14 | *
15 | * @author Myles Yang
16 | */
17 | @ApiModel("角色视图对象")
18 | @ToString(callSuper = true)
19 | @Accessors(chain = true)
20 | @Data
21 | public class AclRoleVO implements Serializable, BeanConvert {
22 |
23 | @ApiModelProperty(value = "角色id")
24 | private Integer id;
25 |
26 | @ApiModelProperty(value = "角色名称")
27 | private String name;
28 |
29 | @ApiModelProperty(value = "角色具有的权限ID串")
30 | private String permissionId;
31 |
32 | @ApiModelProperty(value = "是否启用,0否1是")
33 | private Boolean enable;
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/app/MemberOrderVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.app;
2 |
3 | import lombok.Data;
4 | import lombok.ToString;
5 | import lombok.experimental.Accessors;
6 | import xyz.refrain.onlineedu.model.base.BeanConvert;
7 | import xyz.refrain.onlineedu.model.enums.PayTypeEnum;
8 |
9 | import java.io.Serializable;
10 | import java.time.LocalDateTime;
11 |
12 | /**
13 | * 学员订单
14 | *
15 | * @author Myles Yang
16 | */
17 | @ToString(callSuper = true)
18 | @Accessors(chain = true)
19 | @Data
20 | public class MemberOrderVO implements Serializable, BeanConvert {
21 |
22 | private static final long serialVersionUID = -6160895513916507465L;
23 |
24 | private String orderNo;
25 |
26 | private Integer courseId;
27 |
28 | private String courseName;
29 |
30 | private Double totalFee;
31 |
32 | private PayTypeEnum payType;
33 |
34 | private LocalDateTime createTime;
35 |
36 | private LocalDateTime payTime;
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/params/UpdatePasswordParam.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.params;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 | import org.hibernate.validator.constraints.Length;
7 |
8 | import javax.validation.constraints.NotBlank;
9 |
10 | /**
11 | * Update Password Param
12 | *
13 | * @author Myles Yang
14 | */
15 | @Data
16 | @ApiModel("密码更新参数")
17 | public class UpdatePasswordParam {
18 |
19 | @NotBlank(message = "原密码不能为空")
20 | @Length(max = 63, message = "密码长度不能超过63位")
21 | @ApiModelProperty("原密码")
22 | private String oldPassword;
23 |
24 | @NotBlank(message = "新密码不能为空")
25 | @Length(max = 63, message = "密码长度不能超过63位")
26 | @ApiModelProperty("新密码")
27 | private String newPassword;
28 |
29 | @NotBlank(message = "确认的新密码不能为空")
30 | @Length(max = 63, message = "密码长度不能超过63位")
31 | @ApiModelProperty("确认的新密码")
32 | private String confirmNewPassword;
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/params/TOrderSearchParam.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.params;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 | import lombok.EqualsAndHashCode;
7 | import lombok.ToString;
8 | import lombok.experimental.Accessors;
9 | import xyz.refrain.onlineedu.model.enums.PayTypeEnum;
10 |
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | * 订单搜索参数
15 | *
16 | * @author Myles Yang
17 | */
18 | @EqualsAndHashCode(callSuper = true)
19 | @Data
20 | @Accessors(chain = true)
21 | @ToString(callSuper = true)
22 | @ApiModel("订单搜索参数")
23 | public class TOrderSearchParam extends BasePageParam {
24 |
25 | private Integer memberId;
26 |
27 | private String orderNo;
28 |
29 | private PayTypeEnum payType;
30 |
31 | @ApiModelProperty("大于该订单创建时间")
32 | private LocalDateTime beginCreate;
33 |
34 | @ApiModelProperty("小于该订单创建时间")
35 | private LocalDateTime endCreate;
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/params/RegisterParam.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.params;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.experimental.Accessors;
6 | import org.hibernate.validator.constraints.Length;
7 |
8 | import javax.validation.constraints.NotBlank;
9 | import javax.validation.constraints.NotNull;
10 | import javax.validation.constraints.Pattern;
11 |
12 | @Data
13 | @Accessors(chain = true)
14 | public class RegisterParam {
15 |
16 | @NotNull(message = "手机号不能为空")
17 | @Pattern(regexp = "^0?(13[0-9]|15[012356789]|17[013678]|18[0-9]|14[57])[0-9]{8}$", message = "手机号不合法")
18 | private String username;
19 |
20 | @NotBlank(message = "密码不能为空")
21 | @Length(max = 63, message = "密码长度不能超过63位")
22 | @ApiModelProperty("密码")
23 | private String password;
24 |
25 | @NotBlank(message = "确认的新密码不能为空")
26 | @Length(max = 63, message = "密码长度不能超过63位")
27 | @ApiModelProperty("确认的新密码")
28 | private String confirmPassword;
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/resources/application-dev.yaml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 9096
3 |
4 | spring:
5 | config:
6 | name: dev
7 | datasource:
8 | driver-class-name: com.mysql.cj.jdbc.Driver
9 | url: jdbc:mysql://localhost:3306/online_edu?useSSL=false&useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai
10 | username: root
11 | password: root
12 | servlet:
13 | multipart:
14 | max-file-size: 1GB
15 | max-request-size: 1GB
16 | redis:
17 | host: localhost
18 | port: 6379
19 | password: 123456
20 | timeout: 3000
21 |
22 | mybatis-plus:
23 | configuration:
24 | # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
25 | default-enum-type-handler: com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler
26 | mapper-locations:
27 | - classpath:xyz.refrain/onlineedu/mapper/xml/*.xml
28 |
29 | # aliyun
30 | aliyun:
31 | access-key-id:
32 | access-key-secret:
33 | oss:
34 | bucket-name:
35 | endpoint:
36 | vod:
37 | region-id:
38 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/teacher/StatTchVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.teacher;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.experimental.Accessors;
6 |
7 | import java.io.Serializable;
8 | import java.time.LocalDateTime;
9 |
10 | /**
11 | * 讲师的统计字段
12 | *
13 | * @author Myles Yang
14 | */
15 | @Accessors(chain = true)
16 | @Data
17 | public class StatTchVO implements Serializable {
18 |
19 | private static final long serialVersionUID = -6242784993489855119L;
20 |
21 | @ApiModelProperty("发表的课程数量")
22 | private Integer courseCount;
23 |
24 | @ApiModelProperty("发表的课程视频数量")
25 | private Integer videoCount;
26 |
27 | @ApiModelProperty("总评论数量")
28 | private Integer commentCount;
29 |
30 | @ApiModelProperty("待审核的评论数量")
31 | private Integer auditingCommentCount;
32 |
33 | @ApiModelProperty("加入平台的时间")
34 | private LocalDateTime joinDateTime;
35 |
36 | @ApiModelProperty("加入平台的天数")
37 | private Integer joinDaysCount;
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/config/properties/AliyunOssProperties.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.config.properties;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 | import org.springframework.validation.annotation.Validated;
7 |
8 | import javax.validation.constraints.NotBlank;
9 |
10 | /**
11 | * Aliyun Oss Properties
12 | *
13 | * @author Myles Yang
14 | */
15 |
16 | @Setter
17 | @Validated
18 | @ConfigurationProperties(prefix = "aliyun.oss")
19 | public class AliyunOssProperties {
20 |
21 | /**
22 | * 地域访问域名,请不要添加http[s]://前缀
23 | */
24 | @NotBlank
25 | @Getter
26 | private String endpoint;
27 |
28 | /**
29 | * oss Bucket 名称
30 | */
31 | @NotBlank
32 | @Getter
33 | private String bucketName;
34 |
35 | /**
36 | * 访问域名域名,默认根据bucketName与endpoint设置
37 | */
38 | private String accessDomain;
39 |
40 | public String getAccessDomain() {
41 | return accessDomain == null
42 | ? "https://" + getBucketName() + "." + getEndpoint()
43 | : accessDomain;
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/annotation/ActionRecord.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.annotation;
2 |
3 | import org.springframework.core.annotation.AliasFor;
4 | import xyz.refrain.onlineedu.aspect.ActionRecordAspect;
5 |
6 | import java.lang.annotation.ElementType;
7 | import java.lang.annotation.Retention;
8 | import java.lang.annotation.RetentionPolicy;
9 | import java.lang.annotation.Target;
10 |
11 | /**
12 | * 操作记录
13 | *
14 | * @author Myles Yang
15 | */
16 | @Target({ElementType.METHOD})
17 | @Retention(RetentionPolicy.RUNTIME)
18 | public @interface ActionRecord {
19 |
20 | /**
21 | * 操作内容的EL表达式,仅支持方法参数
22 | */
23 | @AliasFor("content")
24 | String value() default "";
25 |
26 | /**
27 | * 操作内容,与 value 互为别名
28 | */
29 | @AliasFor("value")
30 | String content() default "";
31 |
32 | /**
33 | * 操作类型
34 | */
35 | // LogType type() default LogType.COMMON;
36 |
37 | /**
38 | * 生效条件的EL表达式
39 | * 它是通过返回值判断,返回值符号为{@link ActionRecordAspect#METHOD_RETURNING_SIGN}
40 | * 示例(函数返回值为0):
41 | * EL表达式:"#ret > 0",结果 false
42 | */
43 | String condition() default "";
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/interceptor/StatInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.interceptor;
2 |
3 | import org.springframework.web.servlet.HandlerInterceptor;
4 | import xyz.refrain.onlineedu.constant.StatConstant;
5 | import xyz.refrain.onlineedu.utils.IPUtils;
6 | import xyz.refrain.onlineedu.utils.RedisUtils;
7 |
8 | import javax.servlet.http.HttpServletRequest;
9 | import javax.servlet.http.HttpServletResponse;
10 |
11 | /**
12 | * 数据统计拦截器
13 | *
14 | * @author Myles Yang
15 | */
16 | public class StatInterceptor extends AbstractSecurityInterceptor implements HandlerInterceptor {
17 |
18 | public StatInterceptor() {
19 | addPathPatterns("/api/app/**");
20 | excludePathPatterns();
21 | }
22 |
23 | @Override
24 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
25 |
26 | // 统计网站访问人数
27 |
28 | String ipAddress = IPUtils.getIpAddress(request);
29 |
30 | String key = StatConstant.VISIT_COUNT + ipAddress;
31 |
32 | // 统计时统计key的数量,缓存在统计完成时进行删除
33 | RedisUtils.set(key, null);
34 |
35 | return true;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/teacher/EduSubjectController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.teacher;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.RestController;
10 | import xyz.refrain.onlineedu.model.vo.R;
11 | import xyz.refrain.onlineedu.service.EduSubjectService;
12 |
13 | /**
14 | * 讲师端分类控制器
15 | *
16 | * @author Myles Yang
17 | */
18 | @Validated
19 | @RestController("TeacherEduSubjectController")
20 | @RequestMapping("/api/teacher/subject")
21 | @Api(value = "讲师端视频控制器", tags = {"讲师端视频接口"})
22 | public class EduSubjectController {
23 |
24 | @Autowired
25 | private EduSubjectService eduSubjectService;
26 |
27 | @GetMapping("/get")
28 | @ApiOperation("获取所有分类")
29 | public R get() {
30 | return eduSubjectService.get();
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Myles
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/R.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 |
7 | import java.io.Serializable;
8 | import java.time.LocalDateTime;
9 |
10 | /**
11 | * 统一响应体
12 | *
13 | * @author Myles Yang
14 | */
15 | @Data
16 | @ApiModel("统一响应结果")
17 | public class R implements Serializable {
18 |
19 | private static final long serialVersionUID = -637415113996231595L;
20 |
21 | @ApiModelProperty("响应时间")
22 | private LocalDateTime timestamp;
23 |
24 | @ApiModelProperty("响应状态值")
25 | private int status;
26 |
27 | /**
28 | * 响应消息
29 | */
30 | @ApiModelProperty("响应消息")
31 | private String message;
32 |
33 | @ApiModelProperty("响应数据")
34 | private Object data;
35 |
36 |
37 | public R(int status, String message, Object data) {
38 | this.timestamp = LocalDateTime.now();
39 | this.status = status;
40 | this.message = message;
41 | this.data = data;
42 | }
43 |
44 | public R(int status, String message) {
45 | this(status, message, null);
46 | }
47 |
48 | public R() {
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/interceptor/AdminSecurityInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.interceptor;
2 |
3 | import org.springframework.web.servlet.HandlerInterceptor;
4 | import xyz.refrain.onlineedu.constant.RS;
5 | import xyz.refrain.onlineedu.utils.RUtils;
6 | import xyz.refrain.onlineedu.utils.RWriterUtils;
7 | import xyz.refrain.onlineedu.utils.SessionUtils;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 |
12 | /**
13 | * 管理员端登录安全拦截器
14 | *
15 | * @author Myles Yang
16 | */
17 | public class AdminSecurityInterceptor extends AbstractSecurityInterceptor implements HandlerInterceptor {
18 |
19 | public AdminSecurityInterceptor() {
20 | addPathPatterns("/api/admin/**");
21 | excludePathPatterns("/api/admin/user/login");
22 | }
23 |
24 | @Override
25 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
26 |
27 | if (!SessionUtils.checkAclUserLogin(request)) {
28 | RWriterUtils.writeJson(response, RUtils.fail(RS.NOT_LOGIN));
29 | return false;
30 | }
31 |
32 | return true;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/config/MyBatisPlusConfig.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.config;
2 |
3 | import com.baomidou.mybatisplus.annotation.DbType;
4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
5 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
6 | import org.mybatis.spring.annotation.MapperScan;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.transaction.annotation.EnableTransactionManagement;
10 |
11 | @Configuration
12 | @EnableTransactionManagement
13 | @MapperScan("xyz.refrain.onlineedu.mapper")
14 | public class MyBatisPlusConfig {
15 |
16 | /**
17 | * MybatisPlus 拦截器
18 | */
19 | @Bean
20 | public MybatisPlusInterceptor mybatisPlusInterceptor() {
21 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
22 |
23 | // 注册分页插件
24 | PaginationInnerInterceptor pii = new PaginationInnerInterceptor(DbType.MYSQL);
25 | // 最大单页限制数量
26 | pii.setMaxLimit(100L);
27 |
28 | interceptor.addInnerInterceptor(pii);
29 | return interceptor;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/interceptor/TeacherSecurityInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.interceptor;
2 |
3 | import org.springframework.web.servlet.HandlerInterceptor;
4 | import xyz.refrain.onlineedu.constant.RS;
5 | import xyz.refrain.onlineedu.utils.RUtils;
6 | import xyz.refrain.onlineedu.utils.RWriterUtils;
7 | import xyz.refrain.onlineedu.utils.SessionUtils;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 |
12 | /**
13 | * 讲师端登录安全拦截器
14 | *
15 | * @author Myles Yang
16 | */
17 | public class TeacherSecurityInterceptor extends AbstractSecurityInterceptor implements HandlerInterceptor {
18 |
19 | public TeacherSecurityInterceptor() {
20 | addPathPatterns("/api/teacher/**");
21 | excludePathPatterns("/api/teacher/user/login");
22 | }
23 |
24 | @Override
25 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
26 |
27 | if (!SessionUtils.checkTeacherLogin(request)) {
28 | RWriterUtils.writeJson(response, RUtils.fail(RS.NOT_LOGIN));
29 | return false;
30 | }
31 |
32 | return true;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/params/EduCourseSearchParam.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.params;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 | import lombok.EqualsAndHashCode;
7 | import lombok.ToString;
8 | import lombok.experimental.Accessors;
9 | import xyz.refrain.onlineedu.model.enums.CourseStatusEnum;
10 |
11 | /**
12 | * 课程搜索参数
13 | *
14 | * @author Myles Yang
15 | */
16 | @EqualsAndHashCode(callSuper = true)
17 | @Data
18 | @Accessors(chain = true)
19 | @ToString(callSuper = true)
20 | @ApiModel("课程搜索参数")
21 | public class EduCourseSearchParam extends BasePageParam {
22 |
23 | @ApiModelProperty(value = "课程讲师ID")
24 | private Integer teacherId;
25 |
26 | @ApiModelProperty(value = "课程专业ID")
27 | private Integer subjectId;
28 |
29 | @ApiModelProperty(value = "课程标题")
30 | private String title;
31 |
32 | @ApiModelProperty(value = "课程销售价格,设置为0则可免费观看")
33 | private Boolean free;
34 |
35 | @ApiModelProperty(value = "课程状态,草稿 审核 发表")
36 | private CourseStatusEnum status;
37 |
38 | @ApiModelProperty(value = "上架下架,0下架 1上架")
39 | private Boolean enable;
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/exception/ServiceException.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.exception;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import xyz.refrain.onlineedu.constant.RS;
5 |
6 | /**
7 | * 服务异常
8 | */
9 | public class ServiceException extends MyException {
10 |
11 | private static final long serialVersionUID = 7951201720502956459L;
12 |
13 | private final int status;
14 |
15 | public ServiceException() {
16 | super(RS.SYSTEM_ERROR.message());
17 | this.status = RS.SYSTEM_ERROR.status();
18 | }
19 |
20 | public ServiceException(String message) {
21 | super(message);
22 | this.status = RS.SYSTEM_ERROR.status();
23 | }
24 |
25 | public ServiceException(String message, Throwable cause) {
26 | super(message, cause);
27 | this.status = RS.SYSTEM_ERROR.status();
28 | }
29 |
30 | public ServiceException(RS status) {
31 | super(status.message());
32 | this.status = status.status();
33 | }
34 |
35 | public ServiceException(HttpStatus status) {
36 | super(status.getReasonPhrase());
37 | this.status = status.value();
38 | }
39 |
40 | @Override
41 | public int getStatus() {
42 | return status;
43 | }
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/interceptor/AppSecurityInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.interceptor;
2 |
3 | import org.springframework.web.servlet.HandlerInterceptor;
4 | import xyz.refrain.onlineedu.constant.RS;
5 | import xyz.refrain.onlineedu.model.vo.R;
6 | import xyz.refrain.onlineedu.utils.RWriterUtils;
7 | import xyz.refrain.onlineedu.utils.SessionUtils;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 |
12 | /**
13 | * 前台登录安全拦截器
14 | *
15 | * @author Myles Yang
16 | */
17 | public class AppSecurityInterceptor extends AbstractSecurityInterceptor implements HandlerInterceptor {
18 |
19 | public AppSecurityInterceptor() {
20 | addPathPatterns("/api/app/**");
21 | excludePathPatterns("/api/app/member/login", "/api/app/member/register", "/api/app/pub/**");
22 | }
23 |
24 | @Override
25 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
26 |
27 | if (!SessionUtils.checkMemberLogin(request)) {
28 | RWriterUtils.writeJson(response, new R(RS.NOT_LOGIN.status(), "请登录后再操作"));
29 | return false;
30 | }
31 |
32 | return true;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/interceptor/AbstractSecurityInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.interceptor;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | /**
8 | * 抽象的安全拦截器
9 | *
10 | * @author Myles Yang
11 | */
12 | public abstract class AbstractSecurityInterceptor {
13 | /**
14 | * 拦截的 uri
15 | */
16 | protected List pathPatterns;
17 |
18 | /**
19 | * 放行的 uri
20 | */
21 | protected List excludePatterns;
22 |
23 | public AbstractSecurityInterceptor() {
24 | this.pathPatterns = new ArrayList<>();
25 | this.excludePatterns = new ArrayList<>();
26 | }
27 |
28 | protected AbstractSecurityInterceptor addPathPatterns(String... pathPatterns) {
29 | this.pathPatterns.addAll(Arrays.asList(pathPatterns));
30 | return this;
31 | }
32 |
33 | protected AbstractSecurityInterceptor excludePathPatterns(String... excludePatterns) {
34 | this.excludePatterns.addAll(Arrays.asList(excludePatterns));
35 | return this;
36 | }
37 |
38 | public List getPathPatterns() {
39 | return this.pathPatterns;
40 | }
41 |
42 | public List getExcludePatterns() {
43 | return this.excludePatterns;
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/admin/AclRoleController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.admin;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.PathVariable;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RestController;
11 | import xyz.refrain.onlineedu.model.vo.R;
12 | import xyz.refrain.onlineedu.service.AclRoleService;
13 |
14 | /**
15 | * 角色控制器
16 | *
17 | * @author Myles Yang
18 | */
19 | @Validated
20 | @RestController("AdminAclRoleController")
21 | @RequestMapping("/api/admin/role")
22 | @Api(value = "后台角色控制器", tags = {"后台角色接口"})
23 | public class AclRoleController {
24 |
25 | @Autowired
26 | private AclRoleService aclRoleService;
27 |
28 | @GetMapping("/list/all/{enable}")
29 | @ApiOperation("根据获取所有角色")
30 | public R listAll(@PathVariable(value = "enable", required = false) Boolean enable) {
31 | return aclRoleService.listAll(enable);
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/admin/TOrderController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.admin;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.PostMapping;
8 | import org.springframework.web.bind.annotation.RequestBody;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RestController;
11 | import xyz.refrain.onlineedu.model.params.TOrderSearchParam;
12 | import xyz.refrain.onlineedu.model.vo.R;
13 | import xyz.refrain.onlineedu.service.TOrderService;
14 |
15 | import javax.validation.Valid;
16 |
17 | /**
18 | * 订单控制器
19 | *
20 | * @author Myles Yang
21 | */
22 | @Validated
23 | @RestController("AdminTOrderController")
24 | @RequestMapping("/api/admin/order")
25 | @Api(value = "后台首页订单控制器", tags = {"后台首页订单接口"})
26 | public class TOrderController {
27 |
28 | @Autowired
29 | private TOrderService tOrderService;
30 |
31 | @PostMapping("/list")
32 | @ApiOperation("搜索订单")
33 | public R list(@RequestBody @Valid TOrderSearchParam param) {
34 | return tOrderService.list(param);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/admin/StatDailyVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.admin;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 | import lombok.experimental.Accessors;
7 | import xyz.refrain.onlineedu.config.LocalDateTimeSerializerConfig;
8 | import xyz.refrain.onlineedu.model.base.BeanConvert;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | * 每日数据统计信息
15 | *
16 | * @author Myles Yang
17 | */
18 | @Accessors(chain = true)
19 | @Data
20 | public class StatDailyVO implements Serializable, BeanConvert {
21 |
22 | private static final long serialVersionUID = 2634477720113002360L;
23 |
24 | @JsonFormat(pattern = LocalDateTimeSerializerConfig.DEFAULT_DATE_PATTERN)
25 | @ApiModelProperty(value = "统计日期")
26 | private LocalDateTime date;
27 |
28 | @ApiModelProperty(value = "访问人数")
29 | private Integer visitCount;
30 |
31 | @ApiModelProperty(value = "注册人数")
32 | private Integer registerCount;
33 |
34 | @ApiModelProperty(value = "活跃人数")
35 | private Integer loginCount;
36 |
37 | @ApiModelProperty(value = "每日播放视频数")
38 | private Integer videoViewCount;
39 |
40 | @ApiModelProperty(value = "每日新增课程数")
41 | private Integer courseBuyCount;
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/utils/RWriterUtils.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.utils;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 |
5 | import javax.servlet.ServletResponse;
6 | import java.io.IOException;
7 |
8 | /**
9 | * 返回 响应 结果 工具
10 | */
11 | public class RWriterUtils {
12 |
13 | private static final String DEFAULT_ENCODING = "utf-8";
14 |
15 |
16 | public static void writeTextHtml(ServletResponse response, String textHtml) {
17 | writeString(response, "text/html", DEFAULT_ENCODING, textHtml);
18 | }
19 |
20 | public static void writeJson(ServletResponse response, String jsonString) {
21 | writeString(response, "application/json", DEFAULT_ENCODING, jsonString);
22 | }
23 |
24 | public static void writeJson(ServletResponse response, R r) {
25 | try {
26 | writeJson(response, JsonUtils.objectToJson(r));
27 | } catch (JsonProcessingException e) {
28 | e.printStackTrace();
29 | }
30 | }
31 |
32 | public static void writeString(ServletResponse response, String contentType, String encoding, String string) {
33 | try {
34 | response.setContentType(contentType + ";charset=" + encoding);
35 | response.getWriter().write(string);
36 | response.getWriter().close();
37 | } catch (IOException e) {
38 | e.printStackTrace();
39 | }
40 | }
41 |
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/config/HibernateValidationConfig.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.config;
2 |
3 | import org.hibernate.validator.HibernateValidator;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
7 |
8 | import javax.validation.Validation;
9 | import javax.validation.Validator;
10 | import javax.validation.ValidatorFactory;
11 |
12 | /**
13 | * Spring Validation 配置
14 | *
15 | * @author Myles Yang
16 | */
17 | @Configuration
18 | public class HibernateValidationConfig {
19 |
20 | /**
21 | * 开启Fail Fast模式,一旦校验失败就立即返回
22 | * Spring Validation 默认会校验完所有字段,然后才抛出异常。
23 | */
24 | @Bean
25 | public Validator validator() {
26 | ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
27 | .configure()
28 | .failFast(true)
29 | .buildValidatorFactory();
30 | return validatorFactory.getValidator();
31 | }
32 |
33 | /**
34 | * 方法参数检验,注意在类上添加 @Validated 注解
35 | */
36 | @Bean
37 | public MethodValidationPostProcessor methodValidationPostProcessor() {
38 | MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
39 | // 设置validator模式为快速失败返回
40 | postProcessor.setValidator(validator());
41 | return postProcessor;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/teacher/StatController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.teacher;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.RestController;
10 | import xyz.refrain.onlineedu.model.securtiy.EduTeacherDetail;
11 | import xyz.refrain.onlineedu.model.vo.R;
12 | import xyz.refrain.onlineedu.service.StatService;
13 | import xyz.refrain.onlineedu.utils.SessionUtils;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 |
17 | /**
18 | * 讲师端数据统计控制器
19 | *
20 | * @author Myles Yang
21 | */
22 | @Validated
23 | @RestController("TeacherStatController")
24 | @RequestMapping("/api/teacher/stat")
25 | @Api(value = "讲师端数据统计控制器", tags = {"讲师端数据统计接口"})
26 | public class StatController {
27 |
28 | @Autowired
29 | private StatService statService;
30 |
31 | @GetMapping("/get/common")
32 | @ApiOperation("获取讲师数据统计")
33 | public R getCommon(HttpServletRequest request) {
34 | EduTeacherDetail teacher = SessionUtils.getTeacher(request);
35 | return statService.getTchStat(teacher.getId());
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/admin/AclUserVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.admin;
2 |
3 | import lombok.Data;
4 | import lombok.ToString;
5 | import lombok.experimental.Accessors;
6 | import org.hibernate.validator.constraints.Length;
7 | import xyz.refrain.onlineedu.model.base.BeanConvert;
8 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
9 |
10 | import javax.validation.constraints.Min;
11 | import javax.validation.constraints.NotNull;
12 | import java.io.Serializable;
13 |
14 | /**
15 | * User VO
16 | */
17 | @ToString(callSuper = true)
18 | @Accessors(chain = true)
19 | @Data
20 | public class AclUserVO implements Serializable, BeanConvert {
21 |
22 | private static final long serialVersionUID = -938483463348743424L;
23 |
24 | @NotNull(groups = {ValidGroupType.Update.class})
25 | @Min(value = 1, groups = {ValidGroupType.Update.class})
26 | private Integer id;
27 |
28 | @Length(max = 31, message = "用户名长度不能超过31")
29 | private String username;
30 |
31 | @Length(max = 31, message = "昵称长度不能超过31")
32 | private String nickname;
33 |
34 | private String avatar;
35 |
36 | @Length(max = 255, message = "备注长度不能超过255")
37 | private String mark;
38 |
39 | @Length(max = 255, message = "个性签名长度不能超过255")
40 | private String sign;
41 |
42 | @NotNull(groups = {ValidGroupType.Save.class})
43 | private Integer roleId;
44 |
45 | private Boolean enable;
46 |
47 | private String token;
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/common/SysMessageVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.common;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.ToString;
6 | import lombok.experimental.Accessors;
7 | import xyz.refrain.onlineedu.model.base.BeanConvert;
8 | import xyz.refrain.onlineedu.model.enums.MessageRoleEnum;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | * todo
15 | *
16 | * @author Myles Yang
17 | */
18 | @ToString(callSuper = true)
19 | @Accessors(chain = true)
20 | @Data
21 | public class SysMessageVO implements Serializable, BeanConvert {
22 |
23 | private static final long serialVersionUID = -7969573963163929230L;
24 |
25 | @ApiModelProperty(value = "消息id")
26 | private Integer id;
27 |
28 | @ApiModelProperty(value = "发送者角色(管理员、讲师...)")
29 | private MessageRoleEnum fromRole;
30 |
31 | @ApiModelProperty(value = "发送者Id")
32 | private Integer fromId;
33 |
34 | private String fromName;
35 |
36 | @ApiModelProperty(value = "接受者角色(教师、学员...)")
37 | private MessageRoleEnum toRole;
38 |
39 | @ApiModelProperty(value = "接受者id")
40 | private Integer toId;
41 |
42 | @ApiModelProperty(value = "消息标题")
43 | private String title;
44 |
45 | @ApiModelProperty(value = "消息内容")
46 | private String content;
47 |
48 | @ApiModelProperty(value = "是否已读(0未读 1已读)")
49 | private Boolean read;
50 |
51 | @ApiModelProperty(value = "创建时间")
52 | private LocalDateTime createTime;
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/app/UctrMemberSimpleVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.app;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.ToString;
6 | import lombok.experimental.Accessors;
7 | import org.hibernate.validator.constraints.Length;
8 | import xyz.refrain.onlineedu.model.base.BeanConvert;
9 | import xyz.refrain.onlineedu.model.enums.SexEnum;
10 |
11 | import javax.validation.constraints.*;
12 | import java.io.Serializable;
13 | import java.time.LocalDateTime;
14 |
15 | /**
16 | * Member VO
17 | *
18 | * @author Myles Yang
19 | */
20 | @ToString(callSuper = true)
21 | @Accessors(chain = true)
22 | @Data
23 | public class UctrMemberSimpleVO implements Serializable, BeanConvert {
24 |
25 | private static final long serialVersionUID = -6507297250332935599L;
26 |
27 | private Integer id;
28 |
29 | @NotBlank(message = "手机号不能为空")
30 | @Pattern(regexp = "^0?(13[0-9]|15[012356789]|17[013678]|18[0-9]|14[57])[0-9]{8}$", message = "手机号不合法")
31 | @ApiModelProperty(value = "手机号")
32 | private String mobile;
33 |
34 | @NotBlank(message = "邮箱地址不能为空")
35 | @Email(message = "邮箱地址不合法")
36 | @ApiModelProperty(value = "邮箱地址")
37 | private String email;
38 |
39 | @NotBlank(message = "昵称不能为空")
40 | @Length(max = 31)
41 | private String nickname;
42 |
43 | @ApiModelProperty(value = "性别 0 保密 1 女,2 男")
44 | private SexEnum sex;
45 |
46 | @Min(0)
47 | @Max(150)
48 | private Integer age;
49 |
50 | private Boolean enable;
51 |
52 | private LocalDateTime createTime;
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/AclRoleEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 |
9 | import java.io.Serializable;
10 | import java.time.LocalDateTime;
11 |
12 | /**
13 | *
14 | *
15 | *
16 | *
17 | * @author snwjas
18 | * @since 2021-05-02
19 | */
20 | @Data
21 | @EqualsAndHashCode(callSuper = false)
22 | @TableName("acl_role")
23 | @ApiModel(value="AclRoleEntity对象", description="角色")
24 | public class AclRoleEntity implements Serializable {
25 |
26 | private static final long serialVersionUID = 1L;
27 |
28 | @ApiModelProperty(value = "角色id")
29 | @TableId(value = "id", type = IdType.AUTO)
30 | private Integer id;
31 |
32 | @ApiModelProperty(value = "角色名称")
33 | @TableField("name")
34 | private String name;
35 |
36 | @ApiModelProperty(value = "角色具有的权限ID串")
37 | @TableField("permission_id")
38 | private String permissionId;
39 |
40 | @ApiModelProperty(value = "是否启用,0否1是")
41 | @TableField("enable")
42 | private Boolean enable;
43 |
44 | @ApiModelProperty(value = "更新时间")
45 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
46 | private LocalDateTime updateTime;
47 |
48 | @ApiModelProperty(value = "创建时间")
49 | @TableField(value = "create_time", fill = FieldFill.INSERT)
50 | private LocalDateTime createTime;
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/admin/StatController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.admin;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.format.annotation.DateTimeFormat;
7 | import org.springframework.validation.annotation.Validated;
8 | import org.springframework.web.bind.annotation.*;
9 | import xyz.refrain.onlineedu.config.LocalDateTimeSerializerConfig;
10 | import xyz.refrain.onlineedu.model.vo.R;
11 | import xyz.refrain.onlineedu.service.StatService;
12 |
13 | import java.time.LocalDateTime;
14 |
15 | /**
16 | * 数据统计控制器
17 | *
18 | * @author Myles Yang
19 | */
20 | @Validated
21 | @RestController("AdminStatController")
22 | @RequestMapping("/api/admin/stat")
23 | @Api(value = "后台数据统计控制器", tags = {"后台数据统计接口"})
24 | public class StatController {
25 |
26 | @Autowired
27 | private StatService statService;
28 |
29 | @GetMapping("/get/common")
30 | @ApiOperation("获取平台数据统计")
31 | public R getCommon() {
32 | return statService.getCommonStat();
33 | }
34 |
35 | @PostMapping("/get/daily")
36 | @ApiOperation("获取平台每日数据统计")
37 | public R getDaily(@RequestParam("start") @DateTimeFormat(pattern =
38 | LocalDateTimeSerializerConfig.DEFAULT_DATE_TIME_PATTERN) LocalDateTime start,
39 | @RequestParam("end") @DateTimeFormat(pattern =
40 | LocalDateTimeSerializerConfig.DEFAULT_DATE_TIME_PATTERN) LocalDateTime end) {
41 | return statService.getDailyStat(start, end);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/constant/StatConstant.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.constant;
2 |
3 | import xyz.refrain.onlineedu.controller.app.UctrMemberController;
4 | import xyz.refrain.onlineedu.model.params.RegisterParam;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 |
9 | /**
10 | * 统计缓存key前缀
11 | *
12 | * @author Myles Yang
13 | */
14 | public interface StatConstant {
15 |
16 | /**
17 | * 分隔符
18 | */
19 | String SEPARATOR = ":";
20 |
21 | /**
22 | * 一天秒数
23 | */
24 | long ONE_DAY_SECONDS = 86400L;
25 |
26 | /**
27 | * 网站访问量(key+ip)
28 | * {@link xyz.refrain.onlineedu.interceptor.StatInterceptor#preHandle(HttpServletRequest, HttpServletResponse, Object)}
29 | */
30 | String VISIT_COUNT = "visitCount:";
31 |
32 | /**
33 | * 注册量(inc)
34 | * {@link xyz.refrain.onlineedu.controller.app.UctrMemberController#register(RegisterParam)}
35 | */
36 | String REGISTER_COUNT = "registerCount:";
37 |
38 | /**
39 | * 登录量/活跃人数(key+memberId)
40 | * {@link UctrMemberController#info()}
41 | */
42 | String LOGIN_COUNT = "loginCount:";
43 |
44 | /**
45 | * 视频播放量(key+memberId+videoId)
46 | * {@link xyz.refrain.onlineedu.controller.app.ContentController#getVideoPlayAuth(Integer, Integer, String)}
47 | */
48 | String VIDEO_VIEW_COUNT = "videoViewCount:";
49 |
50 | /**
51 | * 课程订阅量(inc)
52 | * {@link xyz.refrain.onlineedu.controller.app.ContentController#orderPaySucceed(String, HttpServletRequest)}
53 | */
54 | String COURSE_BUY_COUNT = "courseBuyCount:";
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/RelCourseMemberEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | *
15 | * 课程订阅-学员关系表
16 | *
17 | *
18 | * @author snwjas
19 | * @since 2021-05-14
20 | */
21 | @Data
22 | @EqualsAndHashCode(callSuper = false)
23 | @TableName("rel_course_member")
24 | @Accessors(chain = true)
25 | @ApiModel(value="RelCourseMemberEntity对象", description="课程订阅-学员关系表")
26 | public class RelCourseMemberEntity implements Serializable {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | @ApiModelProperty(value = "主键")
31 | @TableId(value = "id", type = IdType.AUTO)
32 | private Integer id;
33 |
34 | @ApiModelProperty(value = "课程Id")
35 | @TableField("course_id")
36 | private Integer courseId;
37 |
38 | @ApiModelProperty(value = "学员Id")
39 | @TableField("member_id")
40 | private Integer memberId;
41 |
42 | @ApiModelProperty(value = "更新时间")
43 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
44 | private LocalDateTime updateTime;
45 |
46 | @ApiModelProperty(value = "创建时间")
47 | @TableField(value = "create_time", fill = FieldFill.INSERT)
48 | private LocalDateTime createTime;
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/config/AliyunConfig.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.config;
2 |
3 | import com.aliyun.oss.OSS;
4 | import com.aliyun.oss.OSSClientBuilder;
5 | import com.aliyuncs.DefaultAcsClient;
6 | import com.aliyuncs.profile.DefaultProfile;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.context.annotation.Configuration;
10 | import xyz.refrain.onlineedu.config.properties.AliyunOssProperties;
11 | import xyz.refrain.onlineedu.config.properties.AliyunProperties;
12 | import xyz.refrain.onlineedu.config.properties.AliyunVodProperties;
13 |
14 | /**
15 | * Aliyun Config
16 | *
17 | * @author Myles Yang
18 | */
19 | @Configuration
20 | public class AliyunConfig {
21 |
22 | @Autowired
23 | private AliyunProperties aliyunProperties;
24 |
25 | @Autowired
26 | private AliyunOssProperties aliyunOssProperties;
27 |
28 | @Autowired
29 | private AliyunVodProperties aliyunVodProperties;
30 |
31 | @Bean
32 | public OSS ossClient() {
33 | return new OSSClientBuilder().build(
34 | aliyunOssProperties.getEndpoint(),
35 | aliyunProperties.getAccessKeyId(),
36 | aliyunProperties.getAccessKeySecret()
37 | );
38 | }
39 |
40 | @Bean
41 | public DefaultAcsClient vodClient() {
42 | DefaultProfile vodProfile = DefaultProfile.getProfile(
43 | aliyunVodProperties.getRegionId(),
44 | aliyunProperties.getAccessKeyId(),
45 | aliyunProperties.getAccessKeySecret()
46 | );
47 | return new DefaultAcsClient(vodProfile);
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/service/AclRoleService.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.service;
2 |
3 | import com.baomidou.mybatisplus.core.toolkit.Wrappers;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.stereotype.Service;
6 | import xyz.refrain.onlineedu.mapper.AclRoleMapper;
7 | import xyz.refrain.onlineedu.model.entity.AclRoleEntity;
8 | import xyz.refrain.onlineedu.model.vo.R;
9 | import xyz.refrain.onlineedu.model.vo.admin.AclRoleVO;
10 | import xyz.refrain.onlineedu.utils.RUtils;
11 |
12 | import javax.annotation.Resource;
13 | import java.util.List;
14 | import java.util.Objects;
15 | import java.util.stream.Collectors;
16 |
17 | /**
18 | * AclRole Service
19 | *
20 | * @author Myles Yang
21 | */
22 | @Service
23 | @Slf4j
24 | public class AclRoleService {
25 |
26 | @Resource
27 | private AclRoleMapper aclRoleMapper;
28 |
29 | /**
30 | * 根据条件获取所有角色
31 | *
32 | * @param enable 是否禁用
33 | */
34 | public R listAll(Boolean enable) {
35 | List aclRoleEntityList = aclRoleMapper.selectList(
36 | Wrappers.lambdaQuery(AclRoleEntity.class)
37 | .eq(Objects.nonNull(enable), AclRoleEntity::getEnable, enable)
38 | );
39 | List aclRoleVOList = covertToListVO(aclRoleEntityList);
40 | return RUtils.success("角色列表", aclRoleVOList);
41 | }
42 |
43 |
44 | public List covertToListVO(List aclRoleEntityList) {
45 | return aclRoleEntityList.stream()
46 | .parallel()
47 | .map(e -> (AclRoleVO) new AclRoleVO().convertFrom(e))
48 | .collect(Collectors.toList());
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/securtiy/AclUserDetail.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.securtiy;
2 |
3 | import lombok.Data;
4 | import lombok.ToString;
5 | import lombok.experimental.Accessors;
6 | import org.hibernate.validator.constraints.Length;
7 | import xyz.refrain.onlineedu.model.base.BeanConvert;
8 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
9 |
10 | import javax.validation.constraints.NotNull;
11 | import java.io.Serializable;
12 |
13 | /**
14 | * 用于安全验证的保存的用户信息(session)
15 | *
16 | * @author Myles Yang
17 | */
18 | @ToString(callSuper = true)
19 | @Accessors(chain = true)
20 | @Data
21 | public class AclUserDetail implements Serializable, BeanConvert {
22 |
23 | private static final long serialVersionUID = 7586351918949128658L;
24 |
25 | private Integer id;
26 |
27 | @NotNull(groups = {ValidGroupType.Save.class}, message = "用户名不能为空")
28 | @Length(max = 31, message = "用户名长度不能超过31", groups = {ValidGroupType.Save.class})
29 | private String username;
30 |
31 | @NotNull(groups = {ValidGroupType.Save.class})
32 | @Length(max = 63, message = "密码长度不能超过63位", groups = {ValidGroupType.Save.class})
33 | private String password;
34 |
35 | @Length(max = 31, message = "昵称长度不能超过31")
36 | private String nickname;
37 |
38 | @Length(max = 255, message = "备注长度不能超过255")
39 | private String mark;
40 |
41 | private String avatar;
42 |
43 | @Length(max = 255, message = "个性签名长度不能超过255")
44 | private String sign;
45 |
46 | @NotNull(groups = {ValidGroupType.Save.class})
47 | private Integer roleId;
48 |
49 | private Boolean enable;
50 |
51 | private String token;
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/EduChapterEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | *
15 | * 课程
16 | *
17 | *
18 | * @author Myles Yang
19 | * @since 2021-01-16
20 | */
21 | @Data
22 | @EqualsAndHashCode(callSuper = false)
23 | @Accessors(chain = true)
24 | @TableName("edu_chapter")
25 | @ApiModel(value="EduChapterEntity对象", description="课程")
26 | public class EduChapterEntity implements Serializable {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | @ApiModelProperty(value = "章节ID")
31 | @TableId(value = "id", type = IdType.AUTO)
32 | private Integer id;
33 |
34 | @ApiModelProperty(value = "课程ID")
35 | @TableField("course_id")
36 | private Integer courseId;
37 |
38 | @ApiModelProperty(value = "章节名称")
39 | @TableField("title")
40 | private String title;
41 |
42 | @ApiModelProperty(value = "显示排序")
43 | @TableField("sort")
44 | private Integer sort;
45 |
46 | @ApiModelProperty(value = "更新时间")
47 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
48 | private LocalDateTime updateTime;
49 |
50 | @ApiModelProperty(value = "创建时间")
51 | @TableField(value = "create_time", fill = FieldFill.INSERT)
52 | private LocalDateTime createTime;
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/EduSubjectEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | *
15 | * 课程科目分类
16 | *
17 | *
18 | * @author Myles Yang
19 | * @since 2021-01-16
20 | */
21 | @Data
22 | @EqualsAndHashCode(callSuper = false)
23 | @Accessors(chain = true)
24 | @TableName("edu_subject")
25 | @ApiModel(value = "EduSubjectEntity对象", description = "课程科目")
26 | public class EduSubjectEntity implements Serializable {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | @ApiModelProperty(value = "课程类别ID")
31 | @TableId(value = "id", type = IdType.AUTO)
32 | private Integer id;
33 |
34 | @ApiModelProperty(value = "类别名称")
35 | @TableField("title")
36 | private String title;
37 |
38 | @ApiModelProperty(value = "父ID")
39 | @TableField("parent_id")
40 | private Integer parentId;
41 |
42 | @ApiModelProperty(value = "排序字段")
43 | @TableField("sort")
44 | private Integer sort;
45 |
46 | @ApiModelProperty(value = "是否启用,0否1是")
47 | @TableField("enable")
48 | private Boolean enable;
49 |
50 | @ApiModelProperty(value = "更新时间")
51 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
52 | private LocalDateTime updateTime;
53 |
54 | @ApiModelProperty(value = "创建时间")
55 | @TableField(value = "create_time", fill = FieldFill.INSERT)
56 | private LocalDateTime createTime;
57 |
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/teacher/EduChapterVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.teacher;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.ToString;
6 | import lombok.experimental.Accessors;
7 | import org.hibernate.validator.constraints.Length;
8 | import xyz.refrain.onlineedu.model.base.BeanConvert;
9 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
10 |
11 | import javax.validation.constraints.Min;
12 | import javax.validation.constraints.NotEmpty;
13 | import javax.validation.constraints.NotNull;
14 | import java.io.Serializable;
15 |
16 | /**
17 | * 章节 VO (临时表,二次修改)
18 | *
19 | * @author Myles Yang
20 | */
21 | @ToString(callSuper = true)
22 | @Accessors(chain = true)
23 | @Data
24 | public class EduChapterVO implements Serializable, BeanConvert {
25 |
26 | private static final long serialVersionUID = 8235402058856062220L;
27 |
28 | @NotNull(groups = {ValidGroupType.Update.class}, message = "ID不能为空")
29 | @Min(value = 1, groups = {ValidGroupType.Update.class}, message = "ID需大于1")
30 | @ApiModelProperty(value = "ID")
31 | private Integer id;
32 |
33 | @NotNull(groups = {ValidGroupType.Save.class}, message = "课程ID不能为空")
34 | @Min(value = 1, groups = {ValidGroupType.Save.class}, message = "课程ID需大于1")
35 | @ApiModelProperty(value = "课程ID")
36 | private Integer courseId;
37 |
38 | @NotEmpty(groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "章节名称不能为空")
39 | @Length(max = 63, groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "章节名称长度不能超过63个字符")
40 | @ApiModelProperty(value = "章节名称")
41 | private String title;
42 |
43 | @ApiModelProperty(value = "排序")
44 | private Integer sort;
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/securtiy/UctrMemberDetail.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.securtiy;
2 |
3 | import com.baomidou.mybatisplus.annotation.TableField;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 | import lombok.ToString;
7 | import lombok.experimental.Accessors;
8 | import org.hibernate.validator.constraints.Length;
9 | import xyz.refrain.onlineedu.model.base.BeanConvert;
10 | import xyz.refrain.onlineedu.model.enums.SexEnum;
11 |
12 | import javax.validation.constraints.*;
13 | import java.io.Serializable;
14 |
15 | /**
16 | * 用于安全验证的保存的用户信息(session)
17 | *
18 | * @author Myles Yang
19 | */
20 | @ToString(callSuper = true)
21 | @Accessors(chain = true)
22 | @Data
23 | public class UctrMemberDetail implements Serializable, BeanConvert {
24 |
25 | private static final long serialVersionUID = 8511102543213811902L;
26 |
27 | private Integer id;
28 |
29 | @NotBlank(message = "手机号不能为空")
30 | @Pattern(regexp = "^0?(13[0-9]|15[012356789]|17[013678]|18[0-9]|14[57])[0-9]{8}$", message = "手机号不合法")
31 | @ApiModelProperty(value = "手机号")
32 | private String mobile;
33 |
34 | @NotBlank(message = "邮箱地址不能为空")
35 | @Email(message = "邮箱地址不合法")
36 | @ApiModelProperty(value = "邮箱地址")
37 | private String email;
38 |
39 | @Length(max = 31)
40 | @ApiModelProperty(value = "密码")
41 | private String password;
42 |
43 | @NotBlank(message = "昵称不能为空")
44 | @Length(max = 31)
45 | private String nickname;
46 |
47 | @ApiModelProperty(value = "性别 0 保密 1 女,2 男")
48 | private SexEnum sex;
49 |
50 | @Min(0)
51 | @Max(150)
52 | private Integer age;
53 |
54 | @Length(max = 127)
55 | private String avatar;
56 |
57 | private String sign;
58 |
59 | private Boolean enable;
60 |
61 | private String token;
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/admin/EduSubjectDetailVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.admin;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.ToString;
6 | import lombok.experimental.Accessors;
7 | import org.hibernate.validator.constraints.Length;
8 | import xyz.refrain.onlineedu.model.base.BeanConvert;
9 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
10 |
11 | import javax.validation.constraints.Min;
12 | import javax.validation.constraints.NotEmpty;
13 | import javax.validation.constraints.NotNull;
14 | import java.io.Serializable;
15 | import java.util.List;
16 |
17 | /**
18 | * 课程科目(分类) vo
19 | *
20 | * @author Myles Yang
21 | */
22 | @ToString(callSuper = true)
23 | @Accessors(chain = true)
24 | @Data
25 | public class EduSubjectDetailVO implements Serializable, BeanConvert {
26 |
27 | private static final long serialVersionUID = 8171974963430070292L;
28 |
29 | @NotNull(groups = {ValidGroupType.Update.class}, message = "ID不能为空")
30 | @Min(value = 1, groups = {ValidGroupType.Update.class}, message = "ID需大于1")
31 | @ApiModelProperty(value = "ID")
32 | private Integer id;
33 |
34 | @ApiModelProperty(value = "父ID")
35 | private Integer parentId;
36 |
37 | @NotEmpty(groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "标题不能为空")
38 | @Length(max = 63, groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "标题长度不能超过63个字符")
39 | @ApiModelProperty(value = "标题")
40 | private String title;
41 |
42 | @ApiModelProperty(value = "排序")
43 | private Integer sort;
44 |
45 | @ApiModelProperty(value = "是否启用,0否1是")
46 | private Boolean enable;
47 |
48 | @ApiModelProperty(value = "子分类")
49 | private List children;
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/admin/TOrderVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.admin;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.ToString;
6 | import lombok.experimental.Accessors;
7 | import xyz.refrain.onlineedu.model.base.BeanConvert;
8 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
9 | import xyz.refrain.onlineedu.model.enums.PayTypeEnum;
10 |
11 | import javax.validation.constraints.Min;
12 | import javax.validation.constraints.NotNull;
13 | import java.io.Serializable;
14 | import java.time.LocalDateTime;
15 |
16 | /**
17 | * 订单视图
18 | *
19 | * @author Myles Yang
20 | */
21 | @ToString(callSuper = true)
22 | @Accessors(chain = true)
23 | @Data
24 | public class TOrderVO implements Serializable, BeanConvert {
25 |
26 | private static final long serialVersionUID = 3611684608730777582L;
27 |
28 | @NotNull(groups = {ValidGroupType.Update.class}, message = "ID不能为空")
29 | @Min(value = 1, groups = {ValidGroupType.Update.class}, message = "ID需大于1")
30 | private Integer id;
31 |
32 | private String orderNo;
33 |
34 | @NotNull(message = "课程Id不能为空")
35 | @ApiModelProperty(value = "课程id")
36 | private Integer courseId;
37 |
38 | @NotNull(message = "会员Id不能为空")
39 | @ApiModelProperty(value = "会员id")
40 | private Integer memberId;
41 |
42 | @NotNull(message = "订单金额不能为空")
43 | @ApiModelProperty(value = "订单金额(元)")
44 | private Double totalFee;
45 |
46 | @ApiModelProperty(value = "支付类型(0:未支付 1:微信 2:支付宝)")
47 | private PayTypeEnum payType;
48 |
49 | @ApiModelProperty(value = "支付完成时间")
50 | private LocalDateTime payTime;
51 |
52 | @ApiModelProperty(value = "交易成功的流水号")
53 | private String transactionNum;
54 |
55 | @ApiModelProperty(value = "创建时间")
56 | private LocalDateTime createTime;
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/aspect/TimeCostAspect.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.aspect;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.aspectj.lang.JoinPoint;
5 | import org.aspectj.lang.annotation.AfterReturning;
6 | import org.aspectj.lang.annotation.Aspect;
7 | import org.aspectj.lang.annotation.Before;
8 | import org.aspectj.lang.annotation.Pointcut;
9 | import org.aspectj.lang.reflect.MethodSignature;
10 | import org.springframework.core.annotation.Order;
11 | import org.springframework.stereotype.Component;
12 |
13 | import java.lang.reflect.Method;
14 | import java.time.Instant;
15 | import java.time.temporal.ChronoUnit;
16 | import java.util.Objects;
17 |
18 | /**
19 | * 方法执行计时注解切面
20 | */
21 | @Component
22 | @Aspect
23 | @Slf4j
24 | @Order(1)
25 | public class TimeCostAspect {
26 |
27 | private final ThreadLocal instantThreadLocal = new ThreadLocal<>();
28 |
29 |
30 | @Pointcut("@annotation(xyz.refrain.onlineedu.annotation.TimeCost)")
31 | public void pointCut() {
32 | }
33 |
34 | @Before("pointCut()")
35 | public void before() {
36 | instantThreadLocal.set(Instant.now());
37 | }
38 |
39 | @AfterReturning("pointCut()")
40 | public void afterReturning(JoinPoint point) {
41 | if (Objects.nonNull(instantThreadLocal.get())) {
42 | Instant now = Instant.now();
43 | MethodSignature signature = (MethodSignature) point.getSignature();
44 | Method method = signature.getMethod();
45 | // String methodParameterTypes = StringUtils.join(method.getGenericParameterTypes(), ", ");
46 | log.info("类:{},方法:{},执行耗时:{}毫秒",
47 | method.getDeclaringClass().getName(),
48 | method.getName() /*+ "(" + methodParameterTypes + ")"*/,
49 | ChronoUnit.MILLIS.between(instantThreadLocal.get(), now));
50 | instantThreadLocal.remove();
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/admin/HmBannerVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.admin;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.ToString;
6 | import lombok.experimental.Accessors;
7 | import org.hibernate.validator.constraints.Length;
8 | import xyz.refrain.onlineedu.model.base.BeanConvert;
9 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
10 |
11 | import javax.validation.constraints.Min;
12 | import javax.validation.constraints.NotEmpty;
13 | import javax.validation.constraints.NotNull;
14 | import java.io.Serializable;
15 |
16 | /**
17 | * 首页 banner vo
18 | *
19 | * @author Myles Yang
20 | */
21 | @ToString(callSuper = true)
22 | @Accessors(chain = true)
23 | @Data
24 | public class HmBannerVO implements Serializable, BeanConvert {
25 |
26 | private static final long serialVersionUID = 8171974963430070292L;
27 |
28 | @NotNull(groups = {ValidGroupType.Update.class}, message = "ID不能为空")
29 | @Min(value = 1, groups = {ValidGroupType.Update.class}, message = "ID需大于1")
30 | @ApiModelProperty(value = "ID")
31 | private Integer id;
32 |
33 | @NotEmpty(groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "标题不能为空")
34 | @Length(max = 63, groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "标题长度不能超过63个字符")
35 | @ApiModelProperty(value = "标题")
36 | private String title;
37 |
38 | @ApiModelProperty(value = "图片地址")
39 | private String imageUrl;
40 |
41 | @NotEmpty(groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "链接地址不能为空")
42 | @ApiModelProperty(value = "链接地址")
43 | private String linkUrl;
44 |
45 | @ApiModelProperty(value = "排序")
46 | private Integer sort;
47 |
48 | @ApiModelProperty(value = "是否启用,0否1是")
49 | private Boolean enable;
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/EduChapterTmpEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import com.fasterxml.jackson.annotation.JsonFormat;
5 | import io.swagger.annotations.ApiModel;
6 | import io.swagger.annotations.ApiModelProperty;
7 | import lombok.Data;
8 | import lombok.EqualsAndHashCode;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | *
15 | * 课程章节临时表(用于存放二次修改的数据)
16 | *
17 | *
18 | * @author snwjas
19 | * @since 2021-05-24
20 | */
21 | @Data
22 | @EqualsAndHashCode(callSuper = false)
23 | @TableName("edu_chapter_tmp")
24 | @ApiModel(value="EduChapterTmpEntity对象", description="课程章节临时表(用于存放二次修改的数据)")
25 | public class EduChapterTmpEntity implements Serializable {
26 |
27 | private static final long serialVersionUID = 1L;
28 |
29 | @JsonFormat(shape = JsonFormat.Shape.STRING)
30 | @TableId(value = "id", type = IdType.ASSIGN_ID)
31 | @ApiModelProperty(value = "主键")
32 | private Long id;
33 |
34 | @ApiModelProperty(value = "原章节ID")
35 | @TableField("oid")
36 | private Integer oid;
37 |
38 | @ApiModelProperty(value = "课程ID")
39 | @TableField("course_id")
40 | private Integer courseId;
41 |
42 | @ApiModelProperty(value = "章节名称")
43 | @TableField("title")
44 | private String title;
45 |
46 | @ApiModelProperty(value = "显示排序")
47 | @TableField("sort")
48 | private Integer sort;
49 |
50 | @ApiModelProperty(value = "更新时间")
51 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
52 | private LocalDateTime updateTime;
53 |
54 | @ApiModelProperty(value = "创建时间")
55 | @TableField(value = "create_time", fill = FieldFill.INSERT)
56 | private LocalDateTime createTime;
57 |
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/teacher/EduTeacherController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.teacher;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.*;
8 | import xyz.refrain.onlineedu.annotation.AccessLimit;
9 | import xyz.refrain.onlineedu.annotation.TimeCost;
10 | import xyz.refrain.onlineedu.model.params.LoginParam;
11 | import xyz.refrain.onlineedu.model.params.UpdatePasswordParam;
12 | import xyz.refrain.onlineedu.model.vo.R;
13 | import xyz.refrain.onlineedu.service.EduTeacherService;
14 |
15 | import javax.validation.Valid;
16 |
17 | /**
18 | * 讲师端讲师控制器
19 | *
20 | * @author Myles Yang
21 | */
22 | @Validated
23 | @RestController("TeacherEduTeacherController")
24 | @RequestMapping("/api/teacher/user")
25 | @Api(value = "讲师端讲师控制器", tags = {"讲师端讲师接口"})
26 | public class EduTeacherController {
27 |
28 | @Autowired
29 | private EduTeacherService eduTeacherService;
30 |
31 | @TimeCost
32 | @AccessLimit(maxCount = 3, seconds = 300)
33 | @PostMapping("/login")
34 | @ApiOperation("登录")
35 | public R login(@RequestBody @Valid LoginParam param) {
36 | return eduTeacherService.login(param);
37 | }
38 |
39 | @PostMapping("/logout")
40 | @ApiOperation("登出")
41 | public R logout() {
42 | return eduTeacherService.logout();
43 | }
44 |
45 | @GetMapping("/info")
46 | @ApiOperation("获取登录用户信息")
47 | public R info() {
48 | return eduTeacherService.info();
49 | }
50 |
51 | @PostMapping("/update/password")
52 | @ApiOperation("修改密码")
53 | public R updatePassword(@RequestBody @Valid UpdatePasswordParam param) {
54 | return eduTeacherService.updatePassword(param);
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/constant/RS.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.constant;
2 |
3 | import org.springframework.http.HttpStatus;
4 |
5 | /**
6 | * 自定义状态码
7 | *
8 | * 200 成功
9 | * 1001 - 1999 参数
10 | * 2001 - 2999 用户
11 | * 3001 - 3999 权限
12 | * 4001 - 4999 数据
13 | * 5001 - 5999 业务
14 | * 6001 - 6999 接口
15 | * 7001 - 7999 系统
16 | */
17 | public enum RS {
18 |
19 | SUCCESS(HttpStatus.OK.value(), "成功"),
20 |
21 | /**
22 | * 参数错误
23 | */
24 | ILLEGAL_PARAMETER(1001, "非法参数"),
25 |
26 | FILE_SIZE_LIMIT(1002, "上传文件过大"),
27 |
28 | /**
29 | * 用户错误
30 | */
31 | USERNAME_PASSWORD_ERROR(2001, "用户名或密码错误"),
32 |
33 | USERNAME_ERROR(2002, "用户名错误"),
34 |
35 | PASSWORD_ERROR(2003, "密码错误"),
36 |
37 | INCONSISTENT_PASSWORDS(2004, "两次输入的密码不一致"),
38 |
39 | /**
40 | * 权限
41 | */
42 | NOT_LOGIN(3001, "用户未登录"),
43 |
44 | ACCOUNT_DISABLED(3002, "账户被禁用,请联系管理员"),
45 |
46 | INSUFFICIENT_PERMISSIONS(3003, "权限不足"),
47 |
48 | /**
49 | * 接口错误
50 | */
51 | FREQUENT_OPERATION(6001, "操作过于频繁,请稍后再试"),
52 |
53 | METHOD_NOT_SUPPORTED(6002, "请求方法有误"),
54 |
55 | PAGE_NOT_FOUND(6003, "请求目标不存在"),
56 |
57 | /**
58 | * 系统错误
59 | */
60 | SYSTEM_ERROR(7001,"系统错误"),
61 |
62 | ;
63 |
64 | private final int status;
65 |
66 | private final String message;
67 |
68 | RS(int status, String message) {
69 | this.status = status;
70 | this.message = message;
71 | }
72 |
73 | public int status() {
74 | return status;
75 | }
76 |
77 | public String message() {
78 | return message;
79 | }
80 |
81 | public static RS resolve(int statusCode) {
82 | for (RS rc : values()) {
83 | if (rc.status == statusCode) {
84 | return rc;
85 | }
86 | }
87 | return null;
88 | }
89 |
90 | @Override
91 | public String toString() {
92 | return "{\"status\":" + status + ",\"message\":\"" + message + "\"}";
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/HmBannerEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | *
15 | * 首页banner表
16 | *
17 | *
18 | * @author Myles Yang
19 | * @since 2021-01-16
20 | */
21 | @Data
22 | @EqualsAndHashCode(callSuper = false)
23 | @Accessors(chain = true)
24 | @TableName("hm_banner")
25 | @ApiModel(value="HmBannerEntity对象", description="首页banner表")
26 | public class HmBannerEntity implements Serializable {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | @ApiModelProperty(value = "ID")
31 | @TableId(value = "id", type = IdType.AUTO)
32 | private Integer id;
33 |
34 | @ApiModelProperty(value = "标题")
35 | @TableField("title")
36 | private String title;
37 |
38 | @ApiModelProperty(value = "图片地址")
39 | @TableField("image_url")
40 | private String imageUrl;
41 |
42 | @ApiModelProperty(value = "链接地址")
43 | @TableField("link_url")
44 | private String linkUrl;
45 |
46 | @ApiModelProperty(value = "排序")
47 | @TableField("sort")
48 | private Integer sort;
49 |
50 | @ApiModelProperty(value = "是否启用,0否1是")
51 | @TableField("enable")
52 | private Boolean enable;
53 |
54 | @ApiModelProperty(value = "更新时间")
55 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
56 | private LocalDateTime updateTime;
57 |
58 | @ApiModelProperty(value = "创建时间")
59 | @TableField(value = "create_time", fill = FieldFill.INSERT)
60 | private LocalDateTime createTime;
61 |
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/teacher/EduChapterTmpVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.teacher;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 | import lombok.ToString;
7 | import lombok.experimental.Accessors;
8 | import org.hibernate.validator.constraints.Length;
9 | import xyz.refrain.onlineedu.model.base.BeanConvert;
10 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
11 |
12 | import javax.validation.constraints.Min;
13 | import javax.validation.constraints.NotEmpty;
14 | import javax.validation.constraints.NotNull;
15 | import java.io.Serializable;
16 |
17 | /**
18 | * 章节 VO
19 | *
20 | * @author Myles Yang
21 | */
22 | @ToString(callSuper = true)
23 | @Accessors(chain = true)
24 | @Data
25 | public class EduChapterTmpVO implements Serializable, BeanConvert {
26 |
27 | private static final long serialVersionUID = 119201734493016068L;
28 |
29 | @JsonFormat(shape = JsonFormat.Shape.STRING)
30 | @NotNull(groups = {ValidGroupType.Update.class}, message = "ID不能为空")
31 | @Min(value = 1, groups = {ValidGroupType.Update.class}, message = "ID需大于1")
32 | @ApiModelProperty(value = "ID")
33 | private Long id;
34 |
35 | private Integer oid;
36 |
37 | @NotNull(groups = {ValidGroupType.Save.class}, message = "课程ID不能为空")
38 | @Min(value = 1, groups = {ValidGroupType.Save.class}, message = "课程ID需大于1")
39 | @ApiModelProperty(value = "课程ID")
40 | private Integer courseId;
41 |
42 | @NotEmpty(groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "章节名称不能为空")
43 | @Length(max = 63, groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "章节名称长度不能超过63个字符")
44 | @ApiModelProperty(value = "章节名称")
45 | private String title;
46 |
47 | @ApiModelProperty(value = "排序")
48 | private Integer sort;
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/teacher/EduCommentController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.teacher;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.*;
8 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
9 | import xyz.refrain.onlineedu.model.params.EduCommentSearchParam;
10 | import xyz.refrain.onlineedu.model.vo.R;
11 | import xyz.refrain.onlineedu.model.vo.teacher.EduCommentVO;
12 | import xyz.refrain.onlineedu.service.EduCommentService;
13 |
14 | import javax.validation.Valid;
15 | import javax.validation.constraints.Min;
16 |
17 | /**
18 | * 讲师端评论控制器
19 | *
20 | * @author Myles Yang
21 | */
22 | @Validated
23 | @RestController("TeacherEduCommentController")
24 | @RequestMapping("/api/teacher/comment")
25 | @Api(value = "讲师端评论控制器", tags = {"讲师端评论接口"})
26 | public class EduCommentController {
27 |
28 | @Autowired
29 | private EduCommentService eduCommentService;
30 |
31 | @PostMapping("/list")
32 | @ApiOperation("搜索评论")
33 | public R list(@RequestBody @Valid EduCommentSearchParam param) {
34 | return eduCommentService.list(param);
35 | }
36 |
37 | @PostMapping("/create")
38 | @ApiOperation("创建评论")
39 | public R create(@RequestBody @Validated(ValidGroupType.Save.class) EduCommentVO vo) {
40 | return eduCommentService.create(vo);
41 | }
42 |
43 | @PostMapping("/update")
44 | @ApiOperation("更新评论信息")
45 | public R updateProfile(@RequestBody @Validated(ValidGroupType.Update.class) EduCommentVO vo) {
46 | return eduCommentService.update(vo);
47 | }
48 |
49 | @PostMapping("/delete/{id}")
50 | @ApiOperation("删除评论")
51 | public R delete(@PathVariable("id") @Min(1) Integer id) {
52 | return eduCommentService.delete(id);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/teacher/EduChapterController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.teacher;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.*;
8 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
9 | import xyz.refrain.onlineedu.model.vo.R;
10 | import xyz.refrain.onlineedu.model.vo.teacher.EduChapterVO;
11 | import xyz.refrain.onlineedu.service.EduChapterService;
12 | import xyz.refrain.onlineedu.utils.RUtils;
13 |
14 | import javax.validation.constraints.Min;
15 | import java.util.List;
16 |
17 | /**
18 | * 讲师端章节控制器
19 | *
20 | * @author Myles Yang
21 | */
22 | @Validated
23 | @RestController("TeacherEduChapterController")
24 | @RequestMapping("/api/teacher/chapter")
25 | @Api(value = "讲师端章节控制器", tags = {"讲师端章节接口"})
26 | public class EduChapterController {
27 |
28 | @Autowired
29 | private EduChapterService eduChapterService;
30 |
31 | @GetMapping("/list/{courseId}")
32 | @ApiOperation("获取章节")
33 | public R list(@PathVariable("courseId") @Min(1) Integer courseId) {
34 | List list = eduChapterService.listChapters(courseId);
35 | return RUtils.success("章节列表信息", list);
36 | }
37 |
38 | @PostMapping("/create")
39 | @ApiOperation("创建章节")
40 | public R create(@RequestBody @Validated(ValidGroupType.Save.class) EduChapterVO vo) {
41 | return eduChapterService.create(vo);
42 | }
43 |
44 | @PostMapping("/update")
45 | @ApiOperation("更新章节信息")
46 | public R update(@RequestBody @Validated(ValidGroupType.Update.class) EduChapterVO vo) {
47 | return eduChapterService.update(vo);
48 | }
49 |
50 | @PostMapping("/delete/{id}")
51 | @ApiOperation("删除章节")
52 | public R delete(@PathVariable("id") @Min(1) Integer id) {
53 | return eduChapterService.delete(id);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/admin/EduTeacherSimpleVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.admin;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.ToString;
6 | import lombok.experimental.Accessors;
7 | import org.hibernate.validator.constraints.Length;
8 | import xyz.refrain.onlineedu.model.base.BeanConvert;
9 | import xyz.refrain.onlineedu.model.enums.TeacherStatusEnum;
10 |
11 | import javax.validation.constraints.*;
12 | import java.io.Serializable;
13 |
14 | /**
15 | * Edu Teacher Simple VO
16 | *
17 | * @author Myles Yang
18 | */
19 |
20 | @ToString(callSuper = true)
21 | @Accessors(chain = true)
22 | @Data
23 | public class EduTeacherSimpleVO implements Serializable, BeanConvert {
24 |
25 | private static final long serialVersionUID = -2830795242128760005L;
26 |
27 | @NotNull(message = "用户ID不能为空")
28 | @Min(value = 1, message = "用户ID必须大于1")
29 | private Integer id;
30 |
31 | @NotBlank(message = "手机号不能为空")
32 | @Pattern(regexp = "^0?(13[0-9]|15[012356789]|17[013678]|18[0-9]|14[57])[0-9]{8}$", message = "手机号不合法")
33 | @ApiModelProperty(value = "手机号")
34 | private String mobile;
35 |
36 | @NotBlank(message = "邮箱地址不能为空")
37 | @Email(message = "邮箱地址不合法")
38 | @ApiModelProperty(value = "邮箱地址")
39 | private String email;
40 |
41 | @NotBlank(message = "讲师名称不能为空")
42 | @Length(max = 31, message = "讲师名称不能超过31个字符")
43 | @ApiModelProperty(value = "讲师姓名")
44 | private String name;
45 |
46 | @ApiModelProperty(value = "讲师简历")
47 | private String resume;
48 |
49 | @Min(0)
50 | @Max(100)
51 | @ApiModelProperty(value = "分成比例,0-100")
52 | private Integer division;
53 |
54 | @Min(Integer.MIN_VALUE)
55 | @Max(Integer.MAX_VALUE)
56 | @ApiModelProperty(value = "排序")
57 | private Integer sort;
58 |
59 | @ApiModelProperty(value = "是否启用,0否1是")
60 | private Boolean enable;
61 |
62 | @ApiModelProperty(value = "讲师状态:审核通过;审核不通过;待审核")
63 | private TeacherStatusEnum status;
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/StatDailyEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | *
15 | * 网站统计日数据
16 | *
17 | *
18 | * @author Myles Yang
19 | * @since 2021-01-16
20 | */
21 | @Data
22 | @EqualsAndHashCode(callSuper = false)
23 | @Accessors(chain = true)
24 | @TableName("stat_daily")
25 | @ApiModel(value = "StatDailyEntity对象", description = "网站统计日数据")
26 | public class StatDailyEntity implements Serializable {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | @ApiModelProperty(value = "主键")
31 | @TableId(value = "id", type = IdType.AUTO)
32 | private Integer id;
33 |
34 | @ApiModelProperty(value = "统计日期")
35 | @TableField("date")
36 | private LocalDateTime date;
37 |
38 | @ApiModelProperty(value = "访问人数")
39 | @TableField("visit_count")
40 | private Integer visitCount;
41 |
42 | @ApiModelProperty(value = "注册人数")
43 | @TableField("register_count")
44 | private Integer registerCount;
45 |
46 | @ApiModelProperty(value = "活跃人数")
47 | @TableField("login_count")
48 | private Integer loginCount;
49 |
50 | @ApiModelProperty(value = "每日播放视频数")
51 | @TableField("video_view_count")
52 | private Integer videoViewCount;
53 |
54 | @ApiModelProperty(value = "每日新增课程数")
55 | @TableField("course_buy_count")
56 | private Integer courseBuyCount;
57 |
58 | @ApiModelProperty(value = "更新时间")
59 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
60 | private LocalDateTime updateTime;
61 |
62 | @ApiModelProperty(value = "创建时间")
63 | @TableField(value = "create_time", fill = FieldFill.INSERT)
64 | private LocalDateTime createTime;
65 |
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/EduCommentEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | *
15 | * 评论
16 | *
17 | *
18 | * @author Myles Yang
19 | * @since 2021-01-16
20 | */
21 | @Data
22 | @EqualsAndHashCode(callSuper = false)
23 | @Accessors(chain = true)
24 | @TableName("edu_comment")
25 | @ApiModel(value="EduCommentEntity对象", description="评论")
26 | public class EduCommentEntity implements Serializable {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | @ApiModelProperty(value = "评论ID")
31 | @TableId(value = "id", type = IdType.AUTO)
32 | private Integer id;
33 |
34 | @ApiModelProperty(value = "课程id")
35 | @TableField("course_id")
36 | private Integer courseId;
37 |
38 | @ApiModelProperty(value = "讲师id")
39 | @TableField("teacher_id")
40 | private Integer teacherId;
41 |
42 | @ApiModelProperty(value = "会员id")
43 | @TableField("member_id")
44 | private Integer memberId;
45 |
46 | @ApiModelProperty(value = "评论内容")
47 | @TableField("content")
48 | private String content;
49 |
50 | @ApiModelProperty(value = "评分(满分5.00)")
51 | @TableField("mark")
52 | private Double mark;
53 |
54 | @ApiModelProperty(value = "评论状态 0审核中 1通过")
55 | @TableField("status")
56 | private Boolean status;
57 |
58 | @ApiModelProperty(value = "更新时间")
59 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
60 | private LocalDateTime updateTime;
61 |
62 | @ApiModelProperty(value = "创建时间")
63 | @TableField(value = "create_time", fill = FieldFill.INSERT)
64 | private LocalDateTime createTime;
65 |
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/admin/EduChapterController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.admin;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.PathVariable;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RestController;
11 | import xyz.refrain.onlineedu.model.vo.R;
12 | import xyz.refrain.onlineedu.model.vo.teacher.EduChapterTmpVO;
13 | import xyz.refrain.onlineedu.model.vo.teacher.EduChapterVO;
14 | import xyz.refrain.onlineedu.service.EduChapterService;
15 | import xyz.refrain.onlineedu.service.EduChapterTmpService;
16 | import xyz.refrain.onlineedu.utils.RUtils;
17 |
18 | import javax.validation.constraints.Min;
19 | import java.util.List;
20 |
21 | /**
22 | * 管理员端章节控制器
23 | *
24 | * @author Myles Yang
25 | */
26 | @Validated
27 | @RestController("AdminEduChapterController")
28 | @RequestMapping("/api/admin/chapter")
29 | @Api(value = "管理员端章节控制器", tags = {"管理员端章节接口"})
30 | public class EduChapterController {
31 |
32 | @Autowired
33 | private EduChapterService eduChapterService;
34 |
35 | @Autowired
36 | private EduChapterTmpService eduChapterTmpService;
37 |
38 | @GetMapping("/list/{courseId}")
39 | @ApiOperation("获取章节")
40 | public R list(@PathVariable("courseId") @Min(1) Integer courseId) {
41 | List list = eduChapterService.listChapters(courseId);
42 | return RUtils.success("章节列表信息", list);
43 | }
44 |
45 | @GetMapping("/tmp/list/{courseId}")
46 | @ApiOperation("获取章节")
47 | public R listTmp(@PathVariable("courseId") @Min(1) Integer courseId) {
48 | List list = eduChapterTmpService.listChapters(courseId);
49 | return RUtils.success("章节列表信息", list);
50 | }
51 |
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/teacher/EduChapterTmpController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.teacher;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.*;
8 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
9 | import xyz.refrain.onlineedu.model.vo.R;
10 | import xyz.refrain.onlineedu.model.vo.teacher.EduChapterTmpVO;
11 | import xyz.refrain.onlineedu.service.EduChapterTmpService;
12 | import xyz.refrain.onlineedu.utils.RUtils;
13 |
14 | import javax.validation.constraints.Min;
15 | import java.util.List;
16 |
17 | /**
18 | * 讲师端章节控制器(用于讲师二次修改课程)
19 | *
20 | * @author Myles Yang
21 | */
22 | @Validated
23 | @RestController("TeacherEduChapterTmpController")
24 | @RequestMapping("/api/teacher/chapter/tmp")
25 | @Api(value = "讲师端章节控制器(二次修改)", tags = {"讲师端章节接口(二次修改)"})
26 | public class EduChapterTmpController {
27 |
28 | @Autowired
29 | private EduChapterTmpService eduChapterTmpService;
30 |
31 | @GetMapping("/list/{courseId}")
32 | @ApiOperation("获取章节")
33 | public R list(@PathVariable("courseId") @Min(1) Integer courseId) {
34 | List list = eduChapterTmpService.listChapters(courseId);
35 | return RUtils.success("章节列表信息", list);
36 | }
37 |
38 | @PostMapping("/create")
39 | @ApiOperation("创建章节")
40 | public R create(@RequestBody @Validated(ValidGroupType.Save.class) EduChapterTmpVO vo) {
41 | return eduChapterTmpService.create(vo);
42 | }
43 |
44 | @PostMapping("/update")
45 | @ApiOperation("更新章节信息")
46 | public R update(@RequestBody @Validated(ValidGroupType.Update.class) EduChapterTmpVO vo) {
47 | return eduChapterTmpService.update(vo);
48 | }
49 |
50 | @PostMapping("/delete/{id}")
51 | @ApiOperation("删除章节")
52 | public R delete(@PathVariable("id") @Min(1) Long id) {
53 | return eduChapterTmpService.delete(id);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/admin/StatCommonVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.admin;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.experimental.Accessors;
6 |
7 | import java.io.Serializable;
8 |
9 | /**
10 | * 普通的网站统计字段信息
11 | *
12 | * @author Myles Yang
13 | */
14 | @Accessors(chain = true)
15 | @Data
16 | public class StatCommonVO implements Serializable {
17 |
18 | private static final long serialVersionUID = 5068765125751156940L;
19 |
20 | // 人员
21 |
22 | @ApiModelProperty("管理员数量")
23 | private Integer adminCount;
24 |
25 | @ApiModelProperty("被禁用的管理员数量")
26 | private Integer disabledAdminCount;
27 |
28 | @ApiModelProperty("讲师数量")
29 | private Integer teacherCount;
30 |
31 | @ApiModelProperty("被禁用的讲师数量")
32 | private Integer disabledTeacherCount;
33 |
34 | @ApiModelProperty("学员数量")
35 | private Integer studentCount;
36 |
37 | @ApiModelProperty("被禁用的学员数量")
38 | private Integer disabledStudentCount;
39 |
40 | @ApiModelProperty("男性学员数量")
41 | private Integer MaleStudentCount;
42 |
43 | @ApiModelProperty("女性学员数量")
44 | private Integer femaleStudentCount;
45 |
46 | // 课程
47 |
48 | @ApiModelProperty("课程总数量")
49 | private Integer courseCount;
50 |
51 | @ApiModelProperty("被下架的课程数量")
52 | private Integer disabledCourseCount;
53 |
54 | @ApiModelProperty("上架的课程数量")
55 | private Integer enabledCourseCount;
56 |
57 | @ApiModelProperty("正在编辑的课程数量")
58 | private Integer editingCourseCount;
59 |
60 | @ApiModelProperty("正在审核的课程数量")
61 | private Integer auditingCourseCount;
62 |
63 | @ApiModelProperty("被驳回的课程数量")
64 | private Integer rejectedCourseCount;
65 |
66 | @ApiModelProperty("课程视频数量")
67 | private Integer videoCount;
68 |
69 | @ApiModelProperty("订单总数量")
70 | private Integer orderCount;
71 |
72 | @ApiModelProperty("微信支付订单总数量")
73 | private Integer orderPayByWechatCount;
74 |
75 | @ApiModelProperty("支付宝支付的订单数量")
76 | private Integer orderPayByAlipayCount;
77 |
78 | @ApiModelProperty("未完成的订单数量")
79 | private Integer orderPayByNoneCount;
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/AclUserEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | *
15 | * 用户表
16 | *
17 | *
18 | * @author Myles Yang
19 | * @since 2021-01-16
20 | */
21 | @Data
22 | @EqualsAndHashCode(callSuper = false)
23 | @Accessors(chain = true)
24 | @TableName("acl_user")
25 | @ApiModel(value = "AclUserEntity对象", description = "用户表")
26 | public class AclUserEntity implements Serializable {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | @ApiModelProperty(value = "用户id")
31 | @TableId(value = "id", type = IdType.AUTO)
32 | private Integer id;
33 |
34 | @ApiModelProperty(value = "用户名")
35 | @TableField("username")
36 | private String username;
37 |
38 | @ApiModelProperty(value = "密码")
39 | @TableField("password")
40 | private String password;
41 |
42 | @ApiModelProperty(value = "昵称")
43 | @TableField("nickname")
44 | private String nickname;
45 |
46 | @ApiModelProperty(value = "用户头像")
47 | @TableField("avatar")
48 | private String avatar;
49 |
50 | @ApiModelProperty(value = "备注")
51 | @TableField("mark")
52 | private String mark;
53 |
54 | @ApiModelProperty(value = "用户签名")
55 | @TableField("sign")
56 | private String sign;
57 |
58 | @ApiModelProperty(value = "角色id")
59 | @TableField("roleId")
60 | private Integer roleId;
61 |
62 | @ApiModelProperty(value = "是否启用,0否1是")
63 | @TableField("enable")
64 | private Boolean enable;
65 |
66 | @ApiModelProperty(value = "更新时间")
67 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
68 | private LocalDateTime updateTime;
69 |
70 | @ApiModelProperty(value = "创建时间")
71 | @TableField(value = "create_time", fill = FieldFill.INSERT)
72 | private LocalDateTime createTime;
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/TOrderEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 | import xyz.refrain.onlineedu.model.enums.PayTypeEnum;
10 |
11 | import java.io.Serializable;
12 | import java.time.LocalDateTime;
13 |
14 | /**
15 | *
16 | * 订单
17 | *
18 | *
19 | * @author Myles Yang
20 | * @since 2021-01-16
21 | */
22 | @Data
23 | @EqualsAndHashCode(callSuper = false)
24 | @Accessors(chain = true)
25 | @TableName("t_order")
26 | @ApiModel(value = "TOrderEntity对象", description = "订单")
27 | public class TOrderEntity implements Serializable {
28 |
29 | private static final long serialVersionUID = 1L;
30 |
31 | @TableId(value = "id", type = IdType.AUTO)
32 | private Integer id;
33 |
34 | @ApiModelProperty(value = "订单号(datetime+unsigned int)")
35 | @TableField("order_no")
36 | private String orderNo;
37 |
38 | @ApiModelProperty(value = "课程id")
39 | @TableField("course_id")
40 | private Integer courseId;
41 |
42 | @ApiModelProperty(value = "会员id")
43 | @TableField("member_id")
44 | private Integer memberId;
45 |
46 | @ApiModelProperty(value = "订单金额(分)")
47 | @TableField("total_fee")
48 | private Double totalFee;
49 |
50 | @ApiModelProperty(value = "支付类型(0:未支付 1:微信 2:支付宝)")
51 | @TableField("pay_type")
52 | private PayTypeEnum payType;
53 |
54 | @ApiModelProperty(value = "交易成功的流水号")
55 | @TableField("transaction_num")
56 | private String transactionNum;
57 |
58 | @ApiModelProperty(value = "支付完成时间")
59 | @TableField("pay_time")
60 | private LocalDateTime payTime;
61 |
62 | @ApiModelProperty(value = "更新时间")
63 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
64 | private LocalDateTime updateTime;
65 |
66 | @ApiModelProperty(value = "创建时间")
67 | @TableField(value = "create_time", fill = FieldFill.INSERT)
68 | private LocalDateTime createTime;
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/securtiy/EduTeacherDetail.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.securtiy;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.ToString;
6 | import lombok.experimental.Accessors;
7 | import org.hibernate.validator.constraints.Length;
8 | import xyz.refrain.onlineedu.model.base.BeanConvert;
9 | import xyz.refrain.onlineedu.model.enums.TeacherStatusEnum;
10 |
11 | import javax.validation.constraints.Email;
12 | import javax.validation.constraints.NotBlank;
13 | import javax.validation.constraints.Pattern;
14 | import java.io.Serializable;
15 |
16 | /**
17 | * 用于安全验证的保存的用户信息(session)
18 | *
19 | * @author Myles Yang
20 | */
21 | @ToString(callSuper = true)
22 | @Accessors(chain = true)
23 | @Data
24 | public class EduTeacherDetail implements Serializable, BeanConvert {
25 |
26 | private static final long serialVersionUID = 7584974618137147474L;
27 |
28 | private Integer id;
29 |
30 | @NotBlank(message = "手机号不能为空")
31 | @Pattern(regexp = "^0?(13[0-9]|15[012356789]|17[013678]|18[0-9]|14[57])[0-9]{8}$", message = "手机号不合法")
32 | @ApiModelProperty(value = "手机号")
33 | private String mobile;
34 |
35 | @NotBlank(message = "邮箱地址不能为空")
36 | @Email(message = "邮箱地址不合法")
37 | @ApiModelProperty(value = "邮箱地址")
38 | private String email;
39 |
40 | @Length(max = 31)
41 | @ApiModelProperty(value = "密码")
42 | private String password;
43 |
44 | @NotBlank(message = "讲师名称不能为空")
45 | @Length(max = 31,message = "讲师名称不能超过31个字符")
46 | @ApiModelProperty(value = "讲师名称")
47 | private String name;
48 |
49 | @Length(max = 1023)
50 | @ApiModelProperty(value = "讲师简介")
51 | private String intro;
52 |
53 | @ApiModelProperty(value = "讲师头像")
54 | private String avatar;
55 |
56 | @ApiModelProperty(value = "讲师简历")
57 | private String resume;
58 |
59 | @ApiModelProperty(value = "排序")
60 | private Integer sort;
61 |
62 | @ApiModelProperty(value = "是否启用,0否1是")
63 | private Boolean enable;
64 |
65 | @ApiModelProperty(value = "讲师状态:审核通过;审核不通过;待审核")
66 | private TeacherStatusEnum status;
67 |
68 | private String token;
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/teacher/EduVideoController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.teacher;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.*;
8 | import org.springframework.web.multipart.MultipartFile;
9 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
10 | import xyz.refrain.onlineedu.model.vo.R;
11 | import xyz.refrain.onlineedu.model.vo.teacher.EduVideoVO;
12 | import xyz.refrain.onlineedu.service.EduVideoService;
13 | import xyz.refrain.onlineedu.utils.RUtils;
14 |
15 | import javax.validation.constraints.Min;
16 | import javax.validation.constraints.NotNull;
17 | import java.util.List;
18 |
19 | /**
20 | * 讲师端视频控制器
21 | *
22 | * @author Myles Yang
23 | */
24 | @Validated
25 | @RestController("TeacherEduVideoController")
26 | @RequestMapping("/api/teacher/video")
27 | @Api(value = "讲师端视频控制器", tags = {"讲师端视频接口"})
28 | public class EduVideoController {
29 |
30 | @Autowired
31 | private EduVideoService eduVideoService;
32 |
33 | @GetMapping("/list/{chapterId}")
34 | @ApiOperation("获取章节视频")
35 | public R list(@PathVariable("chapterId") @Min(1) Integer chapterId) {
36 | List list = eduVideoService.listVideos(chapterId);
37 | return RUtils.success("章节视频列表信息", list);
38 | }
39 |
40 | @PostMapping("/create")
41 | @ApiOperation("上传视频")
42 | public R create(@Min(1) @NotNull Integer courseId,
43 | @Min(1) @NotNull Integer chapterId,
44 | @RequestPart("file") MultipartFile file) {
45 | return eduVideoService.create(courseId, chapterId, file);
46 | }
47 |
48 | @PostMapping("/update")
49 | @ApiOperation("更新视频信息")
50 | public R update(@RequestBody @Validated(ValidGroupType.Update.class) EduVideoVO vo) {
51 | return eduVideoService.update(vo);
52 | }
53 |
54 | @PostMapping("/delete/{id}")
55 | @ApiOperation("删除视频")
56 | public R delete(@PathVariable("id") @Min(1) Integer id) {
57 | return eduVideoService.delete(id);
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/utils/RUtils.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.utils;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import xyz.refrain.onlineedu.constant.RS;
5 | import xyz.refrain.onlineedu.model.vo.R;
6 |
7 | /**
8 | * 统一 响应 工具
9 | *
10 | * @author Myles Yang
11 | */
12 | public class RUtils {
13 |
14 | private static final Object EMPTY_DATA = null;
15 |
16 | /**
17 | * 返回 统一 响应体
18 | *
19 | * @param status 状态码
20 | * @param message 消息
21 | * @param obj 数据
22 | * @return R
23 | */
24 | public static R result(int status, String message, Object obj) {
25 | return new R(status, message, obj);
26 | }
27 |
28 | /**
29 | * 普通的成功失败响应
30 | *
31 | * @param i 小于1失败,否则成功
32 | * @param message 消息
33 | */
34 | public static R commonFailOrNot(int i, String message) {
35 | if (i < 1) {
36 | return fail(message + "失败");
37 | }
38 | return success(message + "成功");
39 | }
40 |
41 |
42 | public static R success(String message, Object data) {
43 | return result(RS.SUCCESS.status(), message, data);
44 | }
45 |
46 | public static R success(String message) {
47 | return success(message, EMPTY_DATA);
48 | }
49 |
50 | public static R succeed() {
51 | return success(RS.SUCCESS.message());
52 | }
53 |
54 | ///////////////////////////////////////////////////////////////////////////////
55 |
56 | /**
57 | * 失败,不传 status ,默认系统错误
58 | */
59 | public static R fail(String message, Object data) {
60 | return result(RS.SYSTEM_ERROR.status(), message, data);
61 | }
62 |
63 | public static R fail(String message) {
64 | return fail(message, EMPTY_DATA);
65 | }
66 |
67 |
68 | public static R fail(RS status, Object data) {
69 | return result(status.status(), status.message(), data);
70 | }
71 |
72 | public static R fail(RS status) {
73 | return result(status.status(), status.message(), EMPTY_DATA);
74 | }
75 |
76 |
77 | public static R fail(HttpStatus httpStatus, Object data) {
78 | return result(httpStatus.value(), httpStatus.getReasonPhrase(), data);
79 | }
80 |
81 | public static R fail(HttpStatus httpStatus) {
82 | return fail(httpStatus, EMPTY_DATA);
83 | }
84 |
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/utils/VideoUtil.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.utils;
2 |
3 | import it.sauronsoftware.jave.Encoder;
4 | import it.sauronsoftware.jave.MultimediaInfo;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.springframework.stereotype.Component;
7 | import org.springframework.web.multipart.MultipartFile;
8 |
9 | import java.io.File;
10 | import java.util.UUID;
11 |
12 | @Slf4j
13 | @Component
14 | public class VideoUtil {
15 |
16 | /**
17 | * 获取视频时长(时分秒)
18 | */
19 | public static String ReadVideoTimeMs(MultipartFile file) {
20 | Encoder encoder = new Encoder();
21 | long ms = 0;
22 | try {
23 | // 获取文件类型
24 | String fileName = file.getContentType();
25 | // 获取文件后缀
26 | String pref = fileName.indexOf("/") != -1 ? fileName.substring(fileName.lastIndexOf("/") + 1,
27 | fileName.length()) : null;
28 | String prefix = "." + pref;
29 | // 用uuid作为文件名,防止生成的临时文件重复
30 | final File excelFile = File.createTempFile(UUID.randomUUID().toString().replace("-", ""), prefix);
31 | // MultipartFile to File
32 | file.transferTo(excelFile);
33 | MultimediaInfo m = encoder.getInfo(excelFile);
34 | ms = m.getDuration();
35 | //程序结束时,删除临时文件
36 | VideoUtil.deleteFile(excelFile);
37 | } catch (Exception e) {
38 | e.printStackTrace();
39 | }
40 | int ss = 1000;
41 | int mi = ss * 60;
42 | int hh = mi * 60;
43 | int dd = hh * 24;
44 |
45 | long day = ms / dd;
46 | long hour = (ms - day * dd) / hh;
47 | long minute = (ms - day * dd - hour * hh) / mi;
48 | long second = (ms - day * dd - hour * hh - minute * mi) / ss;
49 |
50 | String strHour = hour < 10 ? "0" + hour : "" + hour;//小时
51 | String strMinute = minute < 10 ? "0" + minute : "" + minute;//分钟
52 | String strSecond = second < 10 ? "0" + second : "" + second;//秒
53 | if (strHour.equals("00")) {
54 | return strMinute + ":" + strSecond;
55 | } else {
56 | return strHour + ":" + strMinute + ":" + strSecond;
57 | }
58 | }
59 |
60 | /**
61 | * 删除文件
62 | */
63 | private static void deleteFile(File... files) {
64 | for (File file : files) {
65 | if (file.exists()) {
66 | file.delete();
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/SysMessageEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 | import xyz.refrain.onlineedu.model.enums.MessageRoleEnum;
10 |
11 | import java.io.Serializable;
12 | import java.time.LocalDateTime;
13 |
14 | /**
15 | *
16 | * 消息表
17 | *
18 | *
19 | * @author snwjas
20 | * @since 2021-05-12
21 | */
22 | @Data
23 | @EqualsAndHashCode(callSuper = false)
24 | @Accessors(chain = true)
25 | @TableName("sys_message")
26 | @ApiModel(value="SysMessageEntity对象", description="消息表")
27 | public class SysMessageEntity implements Serializable {
28 |
29 | private static final long serialVersionUID = 1L;
30 |
31 | @ApiModelProperty(value = "消息id")
32 | @TableId(value = "id", type = IdType.AUTO)
33 | private Integer id;
34 |
35 | @ApiModelProperty(value = "发送者Id")
36 | @TableField("from_id")
37 | private Integer fromId;
38 |
39 | @ApiModelProperty(value = "发送者角色(管理员、讲师...)")
40 | @TableField("from_role")
41 | private MessageRoleEnum fromRole;
42 |
43 | @ApiModelProperty(value = "接受者id")
44 | @TableField("to_id")
45 | private Integer toId;
46 |
47 | @ApiModelProperty(value = "接受者角色(教师、学员...)")
48 | @TableField("to_role")
49 | private MessageRoleEnum toRole;
50 |
51 | @ApiModelProperty(value = "消息标题")
52 | @TableField("title")
53 | private String title;
54 |
55 | @ApiModelProperty(value = "消息内容")
56 | @TableField("content")
57 | private String content;
58 |
59 | @ApiModelProperty(value = "是否已读(0未读 1已读)")
60 | @TableField("has_read")
61 | private Boolean hasRead;
62 |
63 | @ApiModelProperty(value = "更新时间")
64 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
65 | private LocalDateTime updateTime;
66 |
67 | @ApiModelProperty(value = "创建时间")
68 | @TableField(value = "create_time", fill = FieldFill.INSERT)
69 | private LocalDateTime createTime;
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/controller/teacher/EduVideoTmpController.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.controller.teacher;
2 |
3 | import io.swagger.annotations.Api;
4 | import io.swagger.annotations.ApiOperation;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.validation.annotation.Validated;
7 | import org.springframework.web.bind.annotation.*;
8 | import org.springframework.web.multipart.MultipartFile;
9 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
10 | import xyz.refrain.onlineedu.model.vo.R;
11 | import xyz.refrain.onlineedu.model.vo.teacher.EduVideoTmpVO;
12 | import xyz.refrain.onlineedu.service.EduVideoTmpService;
13 | import xyz.refrain.onlineedu.utils.RUtils;
14 |
15 | import javax.validation.constraints.Min;
16 | import javax.validation.constraints.NotNull;
17 | import java.util.List;
18 |
19 | /**
20 | * 讲师端视频控制器(用于讲师二次二次修改课程)
21 | *
22 | * @author Myles Yang
23 | */
24 | @Validated
25 | @RestController("TeacherEduVideoTmpController")
26 | @RequestMapping("/api/teacher/video/tmp")
27 | @Api(value = "讲师端视频控制器(二次修改)", tags = {"讲师端视频接口(二次修改)"})
28 | public class EduVideoTmpController {
29 |
30 | @Autowired
31 | private EduVideoTmpService eduVideoTmpService;
32 |
33 | @GetMapping("/list/{chapterId}")
34 | @ApiOperation("获取章节视频")
35 | public R list(@PathVariable("chapterId") @Min(1) Long chapterId) {
36 | List list = eduVideoTmpService.listVideos(chapterId);
37 | return RUtils.success("章节视频列表信息", list);
38 | }
39 |
40 | @PostMapping("/create")
41 | @ApiOperation("上传视频")
42 | public R create(@Min(1) @NotNull Integer courseId,
43 | @Min(1) @NotNull Long chapterId,
44 | @RequestPart("file") MultipartFile file) {
45 | return eduVideoTmpService.create(courseId, chapterId, file);
46 | }
47 |
48 | @PostMapping("/update")
49 | @ApiOperation("更新视频信息")
50 | public R update(@RequestBody @Validated(ValidGroupType.Update.class) EduVideoTmpVO vo) {
51 | return eduVideoTmpService.update(vo);
52 | }
53 |
54 | @PostMapping("/delete/{id}")
55 | @ApiOperation("删除视频")
56 | public R delete(@PathVariable("id") @Min(1) Long id) {
57 | return eduVideoTmpService.delete(id);
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/EduVideoEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | import java.io.Serializable;
11 | import java.time.LocalDateTime;
12 |
13 | /**
14 | *
15 | * 课程视频
16 | *
17 | *
18 | * @author Myles Yang
19 | * @since 2021-01-16
20 | */
21 | @Data
22 | @EqualsAndHashCode(callSuper = false)
23 | @Accessors(chain = true)
24 | @TableName("edu_video")
25 | @ApiModel(value = "EduVideoEntity对象", description = "课程视频")
26 | public class EduVideoEntity implements Serializable {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | @ApiModelProperty(value = "视频ID")
31 | @TableId(value = "id", type = IdType.AUTO)
32 | private Integer id;
33 |
34 | @ApiModelProperty(value = "课程ID")
35 | @TableField("course_id")
36 | private Integer courseId;
37 |
38 | @ApiModelProperty(value = "章节ID")
39 | @TableField("chapter_id")
40 | private Integer chapterId;
41 |
42 | @ApiModelProperty(value = "视频名称")
43 | @TableField("title")
44 | private String title;
45 |
46 | @ApiModelProperty(value = "云端视频资源")
47 | @TableField("video_id")
48 | private String videoId;
49 |
50 | @ApiModelProperty(value = "排序字段")
51 | @TableField("sort")
52 | private Integer sort;
53 |
54 | @ApiModelProperty(value = "播放次数")
55 | @TableField("play_count")
56 | private Integer playCount;
57 |
58 | @ApiModelProperty(value = "是否可以试听:0免费 1收费")
59 | @TableField("free")
60 | private Boolean free;
61 |
62 | @ApiModelProperty(value = "视频时长(秒)")
63 | @TableField("duration")
64 | private String duration;
65 |
66 | @ApiModelProperty(value = "视频源文件大小(字节)")
67 | @TableField("size")
68 | private Long size;
69 |
70 | @ApiModelProperty(value = "更新时间")
71 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
72 | private LocalDateTime updateTime;
73 |
74 | @ApiModelProperty(value = "创建时间")
75 | @TableField(value = "create_time", fill = FieldFill.INSERT)
76 | private LocalDateTime createTime;
77 |
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/interceptor/AccessLimitInterceptor.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.interceptor;
2 |
3 | import org.springframework.web.method.HandlerMethod;
4 | import org.springframework.web.servlet.HandlerInterceptor;
5 | import xyz.refrain.onlineedu.annotation.AccessLimit;
6 | import xyz.refrain.onlineedu.constant.CacheKeyPrefix;
7 | import xyz.refrain.onlineedu.constant.RS;
8 | import xyz.refrain.onlineedu.utils.IPUtils;
9 | import xyz.refrain.onlineedu.utils.RUtils;
10 | import xyz.refrain.onlineedu.utils.RWriterUtils;
11 | import xyz.refrain.onlineedu.utils.RedisUtils;
12 |
13 | import javax.servlet.http.HttpServletRequest;
14 | import javax.servlet.http.HttpServletResponse;
15 | import java.lang.reflect.Method;
16 | import java.util.Objects;
17 |
18 | /**
19 | * 接口限流防刷拦截器
20 | *
21 | * @author Myles Yang
22 | */
23 | public class AccessLimitInterceptor implements HandlerInterceptor {
24 |
25 | @Override
26 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
27 | if (!(handler instanceof HandlerMethod)) {
28 | return true;
29 | }
30 |
31 | HandlerMethod handlerMethod = (HandlerMethod) handler;
32 | Method method = handlerMethod.getMethod();
33 |
34 | AccessLimit annotation = method.getAnnotation(AccessLimit.class);
35 | if (Objects.nonNull(annotation)) {
36 | return isAccess(annotation, request, response);
37 | }
38 |
39 | return true;
40 | }
41 |
42 | /**
43 | * 是否通行
44 | */
45 | private boolean isAccess(AccessLimit annotation, HttpServletRequest request, HttpServletResponse response) {
46 |
47 | int maxCount = annotation.maxCount();
48 | int seconds = annotation.seconds();
49 |
50 | String key = CacheKeyPrefix.ACCESS_LIMIT_PREFIX
51 | + IPUtils.getIpAddress(request)
52 | + request.getRequestURI();
53 |
54 | Integer count = (Integer) RedisUtils.get(key);
55 | if (Objects.nonNull(count)) {
56 | if (count < maxCount) {
57 | RedisUtils.set(key, count + 1, seconds);
58 | } else {
59 | RWriterUtils.writeJson(response, RUtils.fail(RS.FREQUENT_OPERATION));
60 | return false;
61 | }
62 | } else {
63 | RedisUtils.set(key, 1, seconds);
64 | }
65 |
66 | return true;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/entity/UctrMemberEntity.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.*;
4 | import io.swagger.annotations.ApiModel;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 | import xyz.refrain.onlineedu.model.enums.SexEnum;
10 |
11 | import java.io.Serializable;
12 | import java.time.LocalDateTime;
13 |
14 | /**
15 | *
16 | * 会员表
17 | *
18 | *
19 | * @author Myles Yang
20 | * @since 2021-01-16
21 | */
22 | @Data
23 | @EqualsAndHashCode(callSuper = false)
24 | @Accessors(chain = true)
25 | @TableName("uctr_member")
26 | @ApiModel(value = "UctrMemberEntity对象", description = "会员表")
27 | public class UctrMemberEntity implements Serializable {
28 |
29 | private static final long serialVersionUID = 1L;
30 |
31 | @ApiModelProperty(value = "会员id")
32 | @TableId(value = "id", type = IdType.AUTO)
33 | private Integer id;
34 |
35 | @ApiModelProperty(value = "手机号")
36 | @TableField("mobile")
37 | private String mobile;
38 |
39 | @ApiModelProperty(value = "邮箱地址")
40 | @TableField("email")
41 | private String email;
42 |
43 | @ApiModelProperty(value = "密码")
44 | @TableField("password")
45 | private String password;
46 |
47 | @ApiModelProperty(value = "昵称")
48 | @TableField("nickname")
49 | private String nickname;
50 |
51 | @ApiModelProperty(value = "性别 0 保密 1 女,2 男")
52 | @TableField("sex")
53 | private SexEnum sex;
54 |
55 | @ApiModelProperty(value = "年龄")
56 | @TableField("age")
57 | private Integer age;
58 |
59 | @ApiModelProperty(value = "用户头像")
60 | @TableField("avatar")
61 | private String avatar;
62 |
63 | @ApiModelProperty(value = "用户签名")
64 | @TableField("sign")
65 | private String sign;
66 |
67 | @ApiModelProperty(value = "是否启用,0否1是")
68 | @TableField("enable")
69 | private Boolean enable;
70 |
71 | @ApiModelProperty(value = "更新时间")
72 | @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
73 | private LocalDateTime updateTime;
74 |
75 | @ApiModelProperty(value = "创建时间")
76 | @TableField(value = "create_time", fill = FieldFill.INSERT)
77 | private LocalDateTime createTime;
78 |
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/config/SwaggerConfig.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.config;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.core.env.Environment;
8 | import springfox.documentation.builders.ApiInfoBuilder;
9 | import springfox.documentation.builders.PathSelectors;
10 | import springfox.documentation.builders.RequestHandlerSelectors;
11 | import springfox.documentation.service.ApiInfo;
12 | import springfox.documentation.service.Contact;
13 | import springfox.documentation.spi.DocumentationType;
14 | import springfox.documentation.spring.web.plugins.Docket;
15 | import springfox.documentation.swagger2.annotations.EnableSwagger2;
16 |
17 | import java.time.temporal.Temporal;
18 |
19 | /**
20 | * Swagger 配置
21 | *
22 | * @author Myles Yang
23 | */
24 | @Configuration
25 | @EnableSwagger2
26 | @Slf4j
27 | public class SwaggerConfig {
28 |
29 | @Autowired
30 | private Environment environment;
31 |
32 | @Bean
33 | public Docket docket() {
34 | // boolean isDocEnable = environment.acceptsProfiles(Profiles.of("dev", "test"));
35 | boolean isDocEnable = true;
36 | if (isDocEnable) {
37 | log.debug("Swagger Doc has been disabled.");
38 | }
39 | return buildDocket("Default",
40 | "xyz.refrain.onlineedu.controller",
41 | "/**")
42 | .enable(isDocEnable);
43 | }
44 |
45 | private Docket buildDocket(String groupName, String basePackage, String antPattern) {
46 | return new Docket(DocumentationType.SWAGGER_2)
47 | .groupName(groupName)
48 | .select()
49 | .apis(RequestHandlerSelectors.basePackage(basePackage))
50 | .paths(PathSelectors.ant(antPattern))
51 | .build()
52 | .apiInfo(apiInfo())
53 | .directModelSubstitute(Temporal.class, String.class);
54 |
55 | }
56 |
57 | private ApiInfo apiInfo() {
58 | return new ApiInfoBuilder()
59 | .title("OEP API Documentation.")
60 | .description("The API documentation for OEP.")
61 | .version("1.0.0")
62 | .contact(new Contact("Myles", "https://gitee.com/snwjas", "myles.yang@foxmail.com"))
63 | .license("MIT")
64 | .licenseUrl("")
65 | .build();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/model/vo/teacher/EduVideoVO.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.model.vo.teacher;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 | import lombok.ToString;
6 | import lombok.experimental.Accessors;
7 | import org.hibernate.validator.constraints.Length;
8 | import xyz.refrain.onlineedu.model.base.BeanConvert;
9 | import xyz.refrain.onlineedu.model.base.ValidGroupType;
10 |
11 | import javax.validation.constraints.Min;
12 | import javax.validation.constraints.NotEmpty;
13 | import javax.validation.constraints.NotNull;
14 | import java.io.Serializable;
15 |
16 | /**
17 | * 视频 VO
18 | *
19 | * @author Myles Yang
20 | */
21 | @ToString(callSuper = true)
22 | @Accessors(chain = true)
23 | @Data
24 | public class EduVideoVO implements Serializable, BeanConvert {
25 |
26 | private static final long serialVersionUID = 3611684608730777582L;
27 |
28 | @NotNull(groups = {ValidGroupType.Update.class}, message = "ID不能为空")
29 | @Min(value = 1, groups = {ValidGroupType.Update.class}, message = "ID需大于1")
30 | private Integer id;
31 |
32 | @NotNull(groups = {ValidGroupType.Save.class}, message = "课程ID不能为空")
33 | @Min(value = 1, groups = {ValidGroupType.Save.class}, message = "课程ID需大于1")
34 | @ApiModelProperty(value = "课程id")
35 | private Integer courseId;
36 |
37 | @NotNull(groups = {ValidGroupType.Save.class, ValidGroupType.Update.class}, message = "章节ID不能为空")
38 | @Min(value = 1, groups = {ValidGroupType.Save.class, ValidGroupType.Update.class}, message = "章节ID需大于1")
39 | @ApiModelProperty(value = "章节ID")
40 | private Integer chapterId;
41 |
42 | @NotEmpty(groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "视频名称不能为空")
43 | @Length(max = 63, groups = {ValidGroupType.Update.class, ValidGroupType.Save.class}, message = "视频名称长度不能超过63个字符")
44 | @ApiModelProperty(value = "视频名称")
45 | private String title;
46 |
47 | @ApiModelProperty(value = "云端视频资源")
48 | private String videoId;
49 |
50 | @ApiModelProperty(value = "排序字段")
51 | private Integer sort;
52 |
53 | @ApiModelProperty(value = "播放次数")
54 | private Integer playCount;
55 |
56 | @ApiModelProperty(value = "是否可以试听:0免费 1收费")
57 | private Boolean free;
58 |
59 | @ApiModelProperty(value = "视频时长(秒)")
60 | private String duration;
61 |
62 | @ApiModelProperty(value = "视频源文件大小(字节)")
63 | private Long size;
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/xyz/refrain/onlineedu/config/RedisConfig.java:
--------------------------------------------------------------------------------
1 | package xyz.refrain.onlineedu.config;
2 |
3 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
4 | import com.fasterxml.jackson.annotation.JsonInclude;
5 | import com.fasterxml.jackson.annotation.JsonTypeInfo;
6 | import com.fasterxml.jackson.annotation.PropertyAccessor;
7 | import com.fasterxml.jackson.databind.ObjectMapper;
8 | import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
9 | import org.springframework.context.annotation.Bean;
10 | import org.springframework.context.annotation.Configuration;
11 | import org.springframework.data.redis.connection.RedisConnectionFactory;
12 | import org.springframework.data.redis.core.RedisTemplate;
13 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
14 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
15 | import org.springframework.data.redis.serializer.StringRedisSerializer;
16 |
17 | @Configuration
18 | public class RedisConfig {
19 |
20 | @Bean
21 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
22 | RedisTemplate template = new RedisTemplate<>();
23 | template.setConnectionFactory(factory);
24 |
25 | //解决Redis key的序列化方式
26 | StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
27 | template.setKeySerializer(stringRedisSerializer);
28 | template.setHashKeySerializer(stringRedisSerializer);
29 |
30 | // 配置序列化方式
31 | Jackson2JsonRedisSerializer