Browse Source

Merge branch 'master' of http://git.dayaedu.com/yonge/cooleshow

liujunchi 3 years ago
parent
commit
b43820efd2
13 changed files with 672 additions and 29 deletions
  1. 1 1
      audio-analysis/src/main/resources/bootstrap-dev.yml
  2. 0 3
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/provider/PhoneAuthenticationProvider.java
  3. 20 8
      cooleshow-bbs/src/main/java/com/yonge/cooleshow/bbs/service/impl/BbsArticleServiceImpl.java
  4. 1 0
      cooleshow-gateway/gateway-web/src/main/java/com/yonge/gateway/web/config/SwaggerDocumentConfig.java
  5. 25 8
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java
  6. 4 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImUserFriendServiceImpl.java
  7. 7 3
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  8. 89 0
      cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/CourseGroupController.java
  9. 88 0
      cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/SmsCodeController.java
  10. 63 0
      cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/TeacherFreeTimeController.java
  11. 155 0
      cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/VideoGroupController.java
  12. 144 0
      cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/VideoLessonGroupDetailController.java
  13. 75 0
      cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/open/OpenVideoGroupController.java

+ 1 - 1
audio-analysis/src/main/resources/bootstrap-dev.yml

@@ -5,7 +5,7 @@ spring:
         server-addr: 47.114.1.200:8848
         namespace: 6f8374a9-598f-4889-bb17-476070ffb8de
         group: DEFAULT_GROUP
-        prefix: audio-analysis-dev
+        prefix: audio-analysis
         file-extension: yaml
         enabled: true
         refresh-enabled: true

+ 0 - 3
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/provider/PhoneAuthenticationProvider.java

@@ -33,7 +33,6 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
 
     @Override
     protected void additionalAuthenticationChecks(UserDetails userDetails, Authentication authentication) throws AuthenticationException {
-
         if (authentication.getCredentials() == null) {
             throw new BadCredentialsException(this.messages.getMessage("PhoneAuthenticationProvider.badCredentials", "Bad credentials"));
         }
@@ -75,7 +74,6 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
             if (isRegister == false || StringUtils.equals("SYSTEM", clientId)) {
                 throw new LockedException("用户不存在");
             }
-
             userInfo = sysUserService.registerUser(loginEntity.getPhone(), clientId, loginUserType);
 
             if (StringUtils.isNotBlank(deviceNum)) {
@@ -120,7 +118,6 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
                     sysUserService.update(user);
                 }
             }
-
         }
 
         UserDetails loadedUser;

+ 20 - 8
cooleshow-bbs/src/main/java/com/yonge/cooleshow/bbs/service/impl/BbsArticleServiceImpl.java

@@ -13,6 +13,7 @@ import com.yonge.cooleshow.bbs.enums.ArticleEnum;
 import com.yonge.cooleshow.bbs.enums.YesOrNoEnum;
 import com.yonge.cooleshow.bbs.vo.BbsReplyVo;
 import com.yonge.toolset.base.exception.BizException;
+import javafx.scene.Parent;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
@@ -166,18 +167,29 @@ public class BbsArticleServiceImpl extends ServiceImpl<BbsArticleDao, BbsArticle
     public IPage<BbsReplyVo> articleReply(IPage<BbsReplyVo> page, BbsReplySearch query) {
         query.setStatus(ArticleEnum.PASS);
         List<BbsReplyVo> allReply = baseMapper.articleReply(null, query);
-        for (BbsReplyVo replyVo : allReply) {
+
+        List<BbsReplyVo> tree = allReply.stream().filter((parentReply) -> {
+            return parentReply.getParentId() == 0;
+        }).map((p) -> {
             List<BbsReplyVo> list = new ArrayList<>();
 
-            findChildren(replyVo, list);
-            replyVo.setChildren(list);
-        }
 
-        return page.setRecords(allReply);
+            List<BbsReplyVo> childrens = getChildren(p, allReply, list);
+            List<BbsReplyVo> collect = childrens.stream().sorted(Comparator.comparing(BbsReplyVo::getCreatedTime)).collect(Collectors.toList());
+            p.setChildren(collect);
+            return p;
+        }).collect(Collectors.toList());
+        return page.setRecords(tree);
     }
 
-
-    public void findChildren(BbsReplyVo replyVo, List<BbsReplyVo> list) {
-
+    private List<BbsReplyVo> getChildren(BbsReplyVo rootReply, List<BbsReplyVo> allReply, List<BbsReplyVo> list) {
+        allReply.stream().filter(categoryEntity -> {
+            return categoryEntity.getParentId().equals(rootReply.getId());
+        }).map(child -> {
+            list.add(child);
+            getChildren(child, allReply, list);
+            return child;
+        }).collect(Collectors.toList());
+        return list;
     }
 }

+ 1 - 0
cooleshow-gateway/gateway-web/src/main/java/com/yonge/gateway/web/config/SwaggerDocumentConfig.java

@@ -24,6 +24,7 @@ public class SwaggerDocumentConfig implements SwaggerResourcesProvider {
 		resources.add(swaggerResource("STUDENT服务", "/student-server/v2/api-docs", "2.0"));
 		resources.add(swaggerResource("TEACHER服务", "/teacher-server/v2/api-docs", "2.0"));
 		resources.add(swaggerResource("ADMIN服务", "/admin-server/v2/api-docs", "2.0"));
+		resources.add(swaggerResource("WEBSITE服务", "/website-server/v2/api-docs", "2.0"));
 		resources.add(swaggerResource("MALL_ADMIN服务", "/mall-admin-server/v2/api-docs", "2.0"));
 		resources.add(swaggerResource("MALL_PORTAL服务", "/mall-portal-server/v2/api-docs", "2.0"));
 		resources.add(swaggerResource("网络教室", "/classroom-server/v2/api-docs", "2.0"));

+ 25 - 8
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java

@@ -86,6 +86,8 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
     private UserOrderService userOrderService;
     @Autowired
     private SysMessageService sysMessageService;
+    @Autowired
+    private ImGroupMemberService imGroupMemberService;
 
     @Autowired
     private UserOrderRefundService userOrderRefundService;
@@ -359,7 +361,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         timeList.forEach(o -> {
             boolean checkDataTime = courseScheduleService.checkStudentCourseTime(studentId, startTimeFun.apply(o), endTimeFun.apply(o));
             if (checkDataTime) {
-                throw new BizException("学生id:"+studentId+",预计安排在" + DateUtil.dateToString(startTimeFun.apply(o), "yyyy年MM月dd号 HH点mm分") + "的课程时间存在冲突!");
+                throw new BizException("学生id:" + studentId + ",预计安排在" + DateUtil.dateToString(startTimeFun.apply(o), "yyyy年MM月dd号 HH点mm分") + "的课程时间存在冲突!");
             }
         });
     }
@@ -541,7 +543,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         // 获取课程组声部
         List<LiveCourseGroupVo> subjectList = baseMapper.selectCourseGroupSubject(courseGroupIdList);
         Map<Long, List<LiveCourseGroupVo>> collect = subjectList.stream()
-                                .collect(Collectors.groupingBy( LiveCourseGroupVo::getCourseGroupId));
+                .collect(Collectors.groupingBy(LiveCourseGroupVo::getCourseGroupId));
         for (LiveCourseGroupVo record : records) {
             List<LiveCourseGroupVo> liveCourseGroupVos = collect.get(record.getCourseGroupId());
             if (CollectionUtils.isEmpty(liveCourseGroupVos)) {
@@ -740,6 +742,21 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         log.info("buyLiveCourseSuccess ok");
         //课程购买成功后进行消息推送
         buyLiveSendMessage(studentPayment, courseGroup);
+
+        //创建群聊
+        try {
+            ImGroup imGroup = imGroupService.getDao().selectOne(Wrappers.<ImGroup>lambdaQuery().eq(ImGroup::getCourseGroupId, courseGroup.getId()));
+            if (imGroup == null) {//群组不存在->创建群组
+                imGroupService.autoCreate(courseGroup.getId(), CourseScheduleEnum.LIVE.getCode());
+            } else {//存在->加入当前学员
+                String imGroupId = imGroup.getId();
+                Set<Long> userIds = new HashSet<>(Arrays.asList(studentPayment.getUserId()));
+                imGroupMemberService.initGroupMembers(imGroupId, userIds, ImGroupMemberRoleType.STUDENT);
+            }
+        } catch (Exception e) {
+            log.error("直播课程组id:{},创建群聊失败:{}", courseGroup.getId(), e);
+            e.printStackTrace();
+        }
     }
 
     /**
@@ -923,32 +940,32 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
 
     @Override
     public IPage<CourseGroupLiveVo> selectLiveGroup(IPage<CourseGroupLiveVo> page, CourseGroupSearch search) {
-        return baseMapper.selectLiveGroup(page,search);
+        return baseMapper.selectLiveGroup(page, search);
     }
 
     @Override
     public IPage<CourseSchedulePaymentVo> selectLiveGroupStudent(IPage<CourseSchedulePaymentVo> page, CourseGroupSearch search) {
-        return baseMapper.selectLiveGroupStudent(page,search);
+        return baseMapper.selectLiveGroupStudent(page, search);
     }
 
     @Override
     public IPage<CourseSchedulePlanVo> selectLiveGroupPlan(IPage<CourseSchedulePlanVo> page, CourseGroupSearch search) {
-        return baseMapper.selectLiveGroupPlan(page,search);
+        return baseMapper.selectLiveGroupPlan(page, search);
     }
 
     @Override
     public IPage<CourseGroupVideoVo> selectVideoGroup(IPage<CourseGroupVideoVo> page, CourseGroupSearch search) {
-        return baseMapper.selectVideoGroup(page,search);
+        return baseMapper.selectVideoGroup(page, search);
     }
 
     @Override
     public IPage<CourseGroupStudentVo> selectVideoGroupStudent(IPage<CourseGroupStudentVo> page, CourseGroupSearch search) {
-        return baseMapper.selectVideoGroupStudent(page,search);
+        return baseMapper.selectVideoGroupStudent(page, search);
     }
 
     @Override
     public IPage<VideoLessonGroupDetail> selectVideoGroupPlan(IPage<VideoLessonGroupDetail> page, CourseGroupSearch search) {
-        return baseMapper.selectVideoGroupPlan(page,search);
+        return baseMapper.selectVideoGroupPlan(page, search);
     }
 
     @Override

+ 4 - 6
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImUserFriendServiceImpl.java

@@ -9,11 +9,9 @@ import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
 import com.yonge.cooleshow.biz.dal.entity.ImUserFriend;
 import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Service;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
@@ -61,7 +59,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
                 teacherFriend.setFriendAvatar(info.getAvatar());
                 teacherFriend.setFriendNickname(info.getUsername());
                 studentFriend.setFriendAvatar(info.getAvatar());
-                studentFriend.setFriendNickname(info.getRealName());
+                studentFriend.setFriendNickname(info.getUsername());
             }
             teacherFriend.setFriendId(studentId);
             teacherFriend.setUserId(teacherId);
@@ -88,7 +86,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
             if(Objects.nonNull(imUserFriend)){
                 //更新当前用户关联的该用户的详情信息
                 imUserFriend.setFriendAvatar(basicUserInfo.getAvatar());
-                imUserFriend.setFriendNickname(StringUtils.isEmpty(basicUserInfo.getRealName())?basicUserInfo.getUsername():basicUserInfo.getRealName());
+                imUserFriend.setFriendNickname(basicUserInfo.getUsername());
                 imUserFriend.setUpdateTime(new Date());
                 baseMapper.updateById(imUserFriend);
                 return imUserFriend;
@@ -96,7 +94,7 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
         }
         ImUserFriend imUserFriend = new ImUserFriend();
         imUserFriend.setFriendAvatar(basicUserInfo.getAvatar());
-        imUserFriend.setFriendNickname(StringUtils.isEmpty(basicUserInfo.getRealName())?basicUserInfo.getUsername():basicUserInfo.getRealName());
+        imUserFriend.setFriendNickname(basicUserInfo.getUsername());
         imUserFriend.setFriendId(userId);
         return imUserFriend;
     }

+ 7 - 3
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -320,12 +320,14 @@
             g.subject_id_ AS subjectId,
             sb.name_ AS subjectName,
             (r.student_replied_ IS NOT NULL) AS studentReplied,
-            (r.teacher_replied_ IS NOT NULL) AS teacherReplied
+            (r.teacher_replied_ IS NOT NULL) AS teacherReplied,
+            i.id_ AS imGroupId
         FROM course_schedule cs
         LEFT JOIN course_group g ON cs.course_group_id_ = g.id_
         LEFT JOIN (SELECT course_id_ AS pid,count(*) AS payCount FROM course_schedule_student_payment GROUP BY course_id_ ) p ON cs.id_=p.pid
         LEFT JOIN `subject` sb ON g.subject_id_=sb.id_
         LEFT JOIN course_schedule_replied r ON cs.id_ = r.course_schedule_id_
+        LEFT JOIN im_group i ON g.id_ = i.course_group_id_
         WHERE cs.lock_=0
         AND cs.status_ IN ('ING','COMPLETE','NOT_START')
         AND cs.type_ IN ('LIVE','PIANO_ROOM_CLASS')
@@ -357,7 +359,8 @@
             g.subject_id_ AS subjectId,
             sb.name_ AS subjectName,
             (r.student_replied_ IS NOT NULL) AS studentReplied,
-            (r.teacher_replied_ IS NOT NULL) AS teacherReplied
+            (r.teacher_replied_ IS NOT NULL) AS teacherReplied,
+            NULL AS imGroupId
         FROM course_schedule_student_payment p
         LEFT JOIN sys_user u ON p.user_id_ =u.id_
         LEFT JOIN course_schedule cs ON p.course_id_=cs.id_
@@ -816,7 +819,8 @@
     <update id="updateTeacherSalary" parameterType="java.util.List">
         UPDATE course_schedule_teacher_salary
         SET status_='COMPLETE',settlement_time_=NOW()
-        WHERE course_schedule_id_ IN
+        WHERE status_='NOT_START'
+        AND course_schedule_id_ IN
         <foreach collection="list" item="item" open="(" separator="," close=")">
             #{item}
         </foreach>

+ 89 - 0
cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/CourseGroupController.java

@@ -0,0 +1,89 @@
+package com.yonge.cooleshow.website.controller;
+
+
+import com.yonge.cooleshow.biz.dal.dto.CheckCourseTimeDto;
+import com.yonge.cooleshow.biz.dal.dto.LiveCourseGroupDto;
+import com.yonge.cooleshow.biz.dal.entity.CourseTimeEntity;
+import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.LiveCourseInfoVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.*;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 课程组表(CourseGroup)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:29:10
+ */
+@Api(tags = "课程组表")
+@RestController
+@RequestMapping("/courseGroup")
+public class CourseGroupController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private CourseGroupService courseGroupService;
+
+    @ApiOperation("直播课详情")
+    @GetMapping("/queryLiveCourseInfo")
+    public HttpResponseResult<LiveCourseInfoVo> queryLiveCourseInfo(@ApiParam(value = "课程组id", required = true) @RequestParam(value = "groupId") Long groupId) {
+        return succeed(courseGroupService.queryLiveCourseInfo(groupId));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "teacherId", dataType = "Long", value = "老师id"),
+            @ApiImplicitParam(name = "search", dataType = "String", value = "关键字"),
+            @ApiImplicitParam(name = "groupStatus", dataType = "String", value = "课程组状态  ING(进行中)  NOT_SALE(未开售,未上架) APPLY(报名中,销售中) COMPLETE(已完成)"),
+            @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
+            @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
+    })
+    @ApiOperation("分页查询直播课课程组列表")
+    @PostMapping("/queryPageCourseGroup")
+    public HttpResponseResult<PageInfo<CourseGroupVo>> queryPageLiveCourseGroup(@RequestBody Map<String, Object> param) {
+        return succeed(courseGroupService.queryPageLiveCourseGroup(param));
+    }
+
+    @ApiOperation("创建直播课程组-新增课程组")
+    @PostMapping("/addLiveCourse")
+    public HttpResponseResult<Object> addLiveCourse(@RequestBody LiveCourseGroupDto dto) {
+        courseGroupService.addLiveCourse(dto);
+        return succeed();
+    }
+
+    @ApiOperation("创建直播课程组-锁定课程时间-将课时写到缓存当作锁定的时间")
+    @PostMapping("/lockCourseToCache")
+    public HttpResponseResult<List<CourseTimeEntity>> lockCourseToCache(@RequestBody CheckCourseTimeDto dto) {
+        return succeed(courseGroupService.lockCourseToCache(dto));
+    }
+
+    @ApiOperation("创建直播课程组-解除锁定课程时间-删除写到缓存当作锁定的课时")
+    @GetMapping("/unlockCourseToCache")
+    public HttpResponseResult<Object> unlockCourseToCache(@RequestParam("teacherId") Long teacherId) {
+        courseGroupService.unlockCourseToCache(teacherId);
+        return succeed();
+    }
+
+    @ApiOperation("取消课程组-下架课程组")
+    @GetMapping("/cancelCourseGroup")
+    public HttpResponseResult<Object> cancelCourseGroup(@RequestParam("groupId") Long groupId) {
+        courseGroupService.cancelCourseGroup(groupId);
+        return succeed();
+    }
+
+    @ApiOperation("获取老师排直播课时锁定的课时")
+    @GetMapping("/getLockCache")
+    public HttpResponseResult<Object> getLockCache(@RequestParam("teacherId") Long teacherId) {
+        return succeed(courseGroupService.getLiveLockTimeCache(teacherId).get(teacherId));
+    }
+
+}
+

+ 88 - 0
cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/SmsCodeController.java

@@ -0,0 +1,88 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.wf.captcha.SpecCaptcha;
+import com.wf.captcha.utils.CaptchaUtil;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.security.SecurityConstants;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.concurrent.TimeUnit;
+
+@RestController
+@RequestMapping("code")
+@Api(tags = "验证码服务")
+public class SmsCodeController extends BaseController {
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+    @Autowired
+    private RedisTemplate<String,String> redisTemplate;
+
+    @ApiOperation(value = "发送登录短信验证码")
+    @ApiImplicitParams({  @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String"),
+                          @ApiImplicitParam(name = "type", value = "类型(PASSWD:修改密码,LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号)", required = true, dataType = "String") })
+    @PostMapping(value = "/sendSmsCode")
+    public Object sendLoginVerifyCode(String mobile,String type) throws Exception {
+        smsCodeService.sendValidCode(mobile, type, ClientEnum.STUDENT);
+        return succeed();
+    }
+
+    @ApiOperation(value = "校验短信验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+                         @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "String"),
+                         @ApiImplicitParam(name = "type", value = "类型(PASSWD:修改密码,LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号)", required = true, dataType = "String") })
+    @PostMapping(value = "/verifySmsCode")
+    public Object verifySmsCode(String phone,String code,String type) {
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        if(smsCodeService.verifyValidCode(phone, code, type)){
+            return succeed();
+        }
+        return failed("验证码校验失败");
+    }
+
+    @PostMapping(value = "/verifyImageCode")
+    @ApiOperation("校验登录图形验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String") })
+    public Object verifyImageCode(String phone,String code){
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        String redisKey = MessageTypeEnum.KAPTCHA_SESSION_KEY + phone;
+        if(redisTemplate.hasKey(redisKey)){
+            if(StringUtils.equalsIgnoreCase(redisTemplate.opsForValue().get(redisKey),code)){
+                return succeed();
+            }
+        }
+        return failed(SecurityConstants.VERIFY_FAILURE);
+    }
+
+    @RequestMapping("/getImageCode")
+    @ApiOperation("获取登录图片验证码")
+    @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String")
+    public void getLoginImage(HttpServletRequest request, HttpServletResponse response,String phone) throws Exception {
+        if(StringUtils.isEmpty(phone)){
+            throw new BizException("请输入手机号");
+        }
+        SpecCaptcha specCaptcha = new SpecCaptcha(125, 45, 4);
+        redisTemplate.opsForValue().set(MessageTypeEnum.KAPTCHA_SESSION_KEY + phone,specCaptcha.text(),3, TimeUnit.MINUTES);
+        CaptchaUtil.out(specCaptcha, request, response);
+    }
+}

+ 63 - 0
cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/TeacherFreeTimeController.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.PracticeTimesSetting;
+import com.yonge.cooleshow.biz.dal.entity.TeacherFreeTime;
+import com.yonge.cooleshow.biz.dal.service.TeacherFreeTimeService;
+import com.yonge.cooleshow.biz.dal.vo.TeacherFreeTimeVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+/**
+ * 老师可排课时间表(TeacherFreeTime)表控制层
+ *
+ * @author zx
+ * @since 2022-03-25 10:04:26
+ */
+@Api(tags = "老师可排课时间表")
+@RestController
+@RequestMapping("/teacherFreeTime")
+public class TeacherFreeTimeController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private TeacherFreeTimeService teacherFreeTimeService;
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "新增、修改老师陪练课设置")
+    @PostMapping("/upSet")
+    public HttpResponseResult upSet(@Valid @RequestBody TeacherFreeTime teacherFreeTime){
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        teacherFreeTime.setTeacherId(user.getId());
+        teacherFreeTimeService.upSet(teacherFreeTime);
+        return succeed();
+    }
+
+    @ApiOperation(value = "获取老师陪练课设置")
+    @PostMapping("/getDetail")
+    public HttpResponseResult<TeacherFreeTimeVo> getDetail(@RequestBody PracticeTimesSetting practiceTimesSetting){
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        practiceTimesSetting.setUserId(user.getId());
+        return succeed(teacherFreeTimeService.getDetail(practiceTimesSetting));
+    }
+}
+

+ 155 - 0
cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/VideoGroupController.java

@@ -0,0 +1,155 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.VideoLessonGroupSearch;
+import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroup;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupService;
+import com.yonge.cooleshow.biz.dal.support.PageUtil;
+import com.yonge.cooleshow.biz.dal.valid.AddGroup;
+import com.yonge.cooleshow.biz.dal.valid.UpdateGroup;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupUpVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 视频课基本信息表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("/videoLessonGroup")
+@Api(tags = "视频课组")
+public class VideoGroupController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private VideoLessonGroupService videoLessonGroupService;
+
+    /**
+    * @Description: 查询视频课组
+    * @Author: cy
+    * @Date: 2022/3/31
+    */
+    @ApiOperation(value = "查询视频课组")
+    @PostMapping(value = "/page")
+    public HttpResponseResult<PageInfo<VideoLessonGroupVo>> page(@RequestBody VideoLessonGroupSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        query.setTeacherId(sysUser.getId());
+        IPage<VideoLessonGroupVo> pages = videoLessonGroupService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+    * @Description: 新增视频课组
+    * @Author: cy
+    * @Date: 2022/3/31
+    */
+    @ApiOperation(value = "新增视频课组", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/create", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> create(@Validated @RequestBody VideoLessonGroup videoLessonGroup) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        videoLessonGroup.setTeacherId(sysUser.getId());
+        videoLessonGroupService.save(videoLessonGroup);
+        return succeed();
+    }
+
+    /**
+    * @Description: 修改视频课组
+    * @Author: cy
+    * @Date: 2022/3/31
+    */
+    @ApiOperation(value = "修改视频课组", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/updateGroup", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> update(@Validated @RequestBody VideoLessonGroupUpVo lessonGroupUpVo) {
+        videoLessonGroupService.updateGroup(lessonGroupUpVo);
+        return succeed();
+    }
+
+    /**
+    * @Description: 删除视频课组
+    * @Author: cy
+    * @Date: 2022/3/31
+    */
+    @ApiOperation(value = "删除视频课组", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping("/delete/{id}")
+    public Object delete(@PathVariable Long id) {
+        videoLessonGroupService.deleteGroup(id);
+        return succeed();
+    }
+
+    /**
+    * @Description: 新增视频课组&视频课
+    * @Author: cy
+    * @Date: 2022/4/1
+    */
+    @ApiOperation(value = "新增视频课组&视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/add", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> add(@Validated(AddGroup.class) @RequestBody VideoLessonVo lessonVo) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+
+        if (sysUser == null||sysUser.getId()==null) {
+            return failed("用户信息获取失败");
+        }
+        if (CollectionUtils.isEmpty(lessonVo.getLessonList())) {
+            return failed("课程不能为空");
+        }
+        videoLessonGroupService.add(lessonVo,sysUser);
+        return succeed();
+    }
+
+    /**
+     * @Description: 根据组id查询视频课&视频课组
+     * @Author: cy
+     * @Date: 2022/4/2
+     */
+    @ApiOperation(value = "根据组id查询视频课&视频课组")
+    @GetMapping(value="/selectVideoLesson")
+    public HttpResponseResult<VideoLessonStudentVo> selectVideoLesson(@NotNull(message = "视频组id不能为空") Long groupId) {
+        return succeed(videoLessonGroupService.selectVideoLesson(groupId));
+    }
+
+    /**
+     * @Description: 修改视频课组&视频课
+     * @Author: cy
+     * @Date: 2022/4/7
+     */
+    @ApiOperation(value = "修改视频课组&视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/update", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> update(@Validated(UpdateGroup.class) @RequestBody VideoLessonVo lessonVo) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+
+        if (sysUser == null||sysUser.getId()==null) {
+            return failed("用户信息获取失败");
+        }
+        if (CollectionUtils.isEmpty(lessonVo.getLessonList())) {
+            return failed("课程不能为空");
+        }
+        videoLessonGroupService.update(lessonVo,sysUser);
+        return succeed();
+    }
+}

+ 144 - 0
cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/VideoLessonGroupDetailController.java

@@ -0,0 +1,144 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.VideoLessonEvaluateSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.VideoLessonSearch;
+import com.yonge.cooleshow.biz.dal.entity.VideoLessonEvaluate;
+import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroupDetail;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonEvaluateService;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupDetailService;
+import com.yonge.cooleshow.biz.dal.support.PageUtil;
+import com.yonge.cooleshow.biz.dal.valid.impl.ValidList;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonEvaluateVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupDetailUpVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonPurchaseStudent;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 视频课明细表 web 控制层
+ *
+ * @author yzp
+ * @version v1.0
+ * @date 2022-03-26 00:21:46
+ **/
+@RestController
+@RequestMapping("/videoLesson")
+@Api(tags = "视频课")
+public class VideoLessonGroupDetailController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private VideoLessonEvaluateService evaluateService;
+
+    @Autowired
+    private VideoLessonGroupDetailService videoLessonGroupDetailService;
+
+    /**
+     * @Description: 查询视频课
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "查询视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/page", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<PageInfo<VideoLessonGroupDetailVo>> page(@RequestBody VideoLessonSearch query) {
+        IPage<VideoLessonGroupDetailVo> pages = videoLessonGroupDetailService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * @Description: 根据组id查询购买用户
+     * @Author: cy
+     * @Date: 2022/4/1
+     */
+    @ApiOperation(value = "根据组id查询购买用户", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/pageStudent", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<PageInfo<VideoLessonPurchaseStudent>> pageStudent(@RequestBody VideoLessonSearch query) {
+        IPage<VideoLessonPurchaseStudent> pages = videoLessonGroupDetailService.selectPageStudent(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * @Description: 新增视频课
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "新增视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/create", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> create(@Validated @RequestBody ValidList<VideoLessonGroupDetail> videoLessonList) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        videoLessonGroupDetailService.insertVideoLesson(videoLessonList, sysUser);
+        return succeed();
+    }
+
+    /**
+     * @Description: 修改视频课
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "修改视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/update", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> update(@Validated @RequestBody VideoLessonGroupDetailUpVo detailUpVo) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        videoLessonGroupDetailService.updateDetail(detailUpVo, sysUser);
+        return succeed();
+    }
+
+    /**
+     * @Description: 删除视频课
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "删除视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping("/delete/{id}")
+    public Object delete(@PathVariable Long id) {
+        videoLessonGroupDetailService.deleteDetail(id);
+        return succeed();
+    }
+
+    /**
+     * @Description: 视频课评价
+     * @Author: cy
+     * @Date: 2022/4/8
+     */
+    @ApiOperation(value = "视频课评价", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/evaluate", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> evaluate(@Validated @RequestBody VideoLessonEvaluate evaluate) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        evaluateService.evaluate(evaluate, sysUser);
+        return succeed();
+    }
+
+    /**
+     * @Description: 根据视频id查评论
+     * @Author: cy
+     * @Date: 2022/4/11
+     */
+    @ApiOperation(value = "根据视频id查评论")
+    @PostMapping(value = "/page")
+    public HttpResponseResult<PageInfo<VideoLessonEvaluateVo>> selectEvaluate(@RequestBody VideoLessonEvaluateSearch query) {
+        IPage<VideoLessonEvaluateVo> pages = evaluateService.selectEvaluate(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}

+ 75 - 0
cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/open/OpenVideoGroupController.java

@@ -0,0 +1,75 @@
+package com.yonge.cooleshow.website.controller.open;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.VideoLessonGroupSearch;
+import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroup;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupService;
+import com.yonge.cooleshow.biz.dal.support.PageUtil;
+import com.yonge.cooleshow.biz.dal.valid.AddGroup;
+import com.yonge.cooleshow.biz.dal.valid.UpdateGroup;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupUpVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 视频课基本信息表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("/open/videoLessonGroup")
+@Api(tags = "视频课组")
+public class OpenVideoGroupController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private VideoLessonGroupService videoLessonGroupService;
+
+    /**
+    * @Description: 查询视频课组
+    * @Author: cy
+    * @Date: 2022/3/31
+    */
+    @ApiOperation(value = "查询视频课组")
+    @PostMapping(value = "/page")
+    public HttpResponseResult<PageInfo<VideoLessonGroupVo>> page(@RequestBody VideoLessonGroupSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        query.setTeacherId(sysUser.getId());
+        IPage<VideoLessonGroupVo> pages = videoLessonGroupService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+
+    /**
+     * @Description: 根据组id查询视频课&视频课组
+     * @Author: cy
+     * @Date: 2022/4/2
+     */
+    @ApiOperation(value = "根据组id查询视频课&视频课组")
+    @GetMapping(value="/selectVideoLesson")
+    public HttpResponseResult<VideoLessonStudentVo> selectVideoLesson(@NotNull(message = "视频组id不能为空") Long groupId) {
+        return succeed(videoLessonGroupService.selectVideoLesson(groupId));
+    }
+
+}