作业1:课程的发布状态查询
思路:会模仿就行
代码实现
//todo:按课程发布状态查询
queryWrapper.eq(StringUtils.isNotEmpty(courseParamsDto.getPublishStatus()), CourseBase::getStatus, courseParamsDto.getPublishStatus());
作业2:课程分类的名称设置到
思路:courseBase包含了课程分类的id,因为有了id,所以直接根据id查询课程内容即可
代码实现
//todo:课程分类的名称设置到courseBaseInfoDto
// 大分类
CourseCategory courseCategory;
String mt = courseBase.getMt();
courseCategory = courseCategoryMapper.selectById(mt);
if (courseCategory != null) {
courseBaseInfoDto.setMtName(courseCategory.getLabel());
}
courseBaseInfoDto.setMt(mt);
// 小分类
String st = courseBase.getSt();
courseCategory = courseCategoryMapper.selectById(st);
if (courseCategory != null) {
courseBaseInfoDto.setStName(courseCategory.getLabel());
}
courseBaseInfoDto.setSt(st);
作业3:更新课程营销信息
思路:营销信息的id就是课程id,根据课程id查询营销信息进行修改即可
代码实现
//更新营销信息
CourseMarket courseMarket = new CourseMarket();
BeanUtils.copyProperties(editCourseDto, courseMarket);
saveCourseMarket(courseMarket);
作业4:新增大章节
思路:做不出来就挨打,你把黑马老师的笔记仔细阅读几遍看看你会不会
代码实现
left join teachplan two on two.parentid = one.id
作业5:课程计划排序bug
难度:0星
思路:
-
排序使用count+1不可以的:
- 例如:目前的count是5,这个时候添加count+1是6。这个时候进行了删除,再进行添加排序字段还是6
-
解决方案:找到当前节点下最大的orderby+1
-
service
int maxOrderBy = teachplanMapper.getMaxOrderBy(courseId, parentId); // int teachplanCount = getTeachplanCount(courseId, parentid)
-
mapper
<select id="getMaxOrderBy" resultType="java.lang.Integer"> SELECT MAX(orderby) FROM teachplan WHERE (course_id = #{courseId} AND parentid = #{parentId}) </select>
-
作业6:删除课程计划
controller
@ApiOperation("删除课程计划")
@DeleteMapping("/teachplan/{id}")
public void deleteTeachPlan(@PathVariable Long id) {
//获取到用户所属机构的id
Long companyId = 1232141425L;
teachplanService.deleteTeachPlan(id, companyId);
}
service
@Override
public void deleteTeachPlan(Long id) {
Teachplan teachplan = teachplanMapper.selectById(id);
if (teachplan == null) {
throw new XueChengPlusException("系统异常");
}
Integer grade = teachplan.getGrade();
if (grade == 1) {
LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
qw.eq(Teachplan::getParentid, id);
Integer count = teachplanMapper.selectCount(qw);
if (count > 0) {
throw new XueChengPlusException(teachplan.getPname() + "下有未删除的章节");
}
teachplanMapper.deleteById(id);
return;
}
if (grade == 2) {
LambdaQueryWrapper<TeachplanMedia> qw = new LambdaQueryWrapper<>();
qw.eq(TeachplanMedia::getTeachplanId, id);
TeachplanMedia teachplanMedia = teachplanMediaMapper.selectOne(qw);
if (teachplanMedia != null) {
teachplanMediaMapper.deleteById(teachplanMedia.getId());
}
teachplanMapper.deleteById(id);
}
}
作业7: 课程计划排序
向下移动
@Override
public void movedownTeachPlan(Long id) {
Teachplan teachplan = teachplanMapper.selectById(id);
if (teachplan == null) {
throw new XueChengPlusException("系统异常");
}
LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
qw.eq(Teachplan::getCourseId, teachplan.getCourseId());
qw.eq(Teachplan::getParentid, teachplan.getParentid());
qw.orderByAsc(Teachplan::getOrderby);
List<Teachplan> teachplanList = teachplanMapper.selectList(qw);
// List<Integer> orderByList = teachplanMapper.getOrderByList(teachplan.getCourseId(), teachplan.getParentid());
if (teachplanList.size() == 0) {
throw new XueChengPlusException("系统异常");
}
int currentIndex = teachplanList.indexOf(teachplan);
if (currentIndex == -1) {
throw new XueChengPlusException("系统异常");
}
if (currentIndex == teachplanList.size() - 1) {
throw new XueChengPlusException("最后一个无法向下移到");
}
Integer currentOrderby = teachplan.getOrderby();
Integer nextOrderby = teachplanList.get(currentIndex + 1).getOrderby();
teachplan.setOrderby(nextOrderby);
teachplanMapper.updateById(teachplan);
teachplan = teachplanList.get(currentIndex + 1);
teachplan.setOrderby(currentOrderby);
teachplanMapper.updateById(teachplan);
}
向上移动
@Override
public void moveupTeachPlan(Long id) {
// 查询当前课程
Teachplan teachplan = teachplanMapper.selectById(id);
if (teachplan == null) {
throw new XueChengPlusException("系统异常");
}
// 获取当前节点下的所有数据
LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
qw.eq(Teachplan::getCourseId, teachplan.getCourseId());
qw.eq(Teachplan::getParentid, teachplan.getParentid());
qw.orderByAsc(Teachplan::getOrderby);
List<Teachplan> teachplanList = teachplanMapper.selectList(qw);
if (teachplanList.size() == 0) {
throw new XueChengPlusException("系统异常");
}
// 判断当前数据是否存在
int currentIndex = teachplanList.indexOf(teachplan);
if (currentIndex == -1) {
throw new XueChengPlusException("系统异常");
}
// 处理第一个元素
if (currentIndex == 0) {
throw new XueChengPlusException("第一个无法向上移到");
}
// 当前元素的排序值
Integer currentOrderby = teachplan.getOrderby();
// 上一个元素的排序值
Integer beforeOrderby = teachplanList.get(currentIndex - 1).getOrderby();
// 修改当前元素
teachplan.setOrderby(beforeOrderby);
teachplanMapper.updateById(teachplan);
teachplan = teachplanList.get(currentIndex - 1);
// 修改上一个元素
teachplan.setOrderby(currentOrderby);
teachplanMapper.updateById(teachplan);
}
作业8:将系统管理服务的配置信息在nacos上进行配置
#微服务配置
spring:
application:
name: system-api #服务名system-api-dev.yaml
cloud:
nacos:
server-addr: 192.168.101.65:8848
discovery: #服务注册相关配置
namespace: dev
group: xuecheng-plus-project
config: #配置文件相关配置
namespace: dev
group: xuecheng-plus-project
file-extension: yaml
refresh-enabled: true
# 因为api接口工程依赖了service工程 的jar,所以这里使用extension-configs扩展配置文件 的方式引用service工程所用到的配置文件
extension-configs:
- data-id: system-service-${spring.profiles.active}.yaml
group: xuecheng-plus-project
refresh: true
shared-configs:
- data-id: swagger-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: logging-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
profiles:
active: dev #环境名
作业9:根据接口定义实现解除绑定功能
@Override
public void associationDeleteMedia(String teachplanId, String mediaId) {
if (teachplanId == null) {
throw new XueChengPlusException("课程计划id不能为空");
}
if (mediaId == null) {
throw new XueChengPlusException("媒资信息不能为空");
}
LambdaQueryWrapper<TeachplanMedia> qw = new LambdaQueryWrapper<>();
qw.eq(TeachplanMedia::getTeachplanId, teachplanId);
qw.eq(TeachplanMedia::getMediaId, mediaId);
int delete = teachplanMediaMapper.delete(qw);
if (delete == 0) {
throw new XueChengPlusException("删除媒资信息失败,请和核对媒资id和课程计划id");
}
}
编写完成代码之后,发现删除报错,原因是teachplanId为null,说明之前的代码有坑
在多表查询的时候需要查询到课程计划标识
在TeachPlanMapper的selectTreeNodes里添加查询条件
m1.teachplan_id teachplanId
在映射关系里添加对应的映射
<result column="teachplanId" property="teachplanId"/>
作业10:(不是作业,有人反馈的bug)添加课程时,如果课程没有课程就会报错
查询最大字段的时候,把返回值改为Integer
Integer getMaxOrderBy(@Param("courseId") Long courseId, @Param("parentId") Long parentId);
并且加上为空的判断
if (maxOrderBy == null) {
teachplan.setOrderby(0);
} else {
teachplan.setOrderby(maxOrderBy + 1);
}
作业11:找回密码
这里我在工具类里只找到了验证是否为手机的方法,所以我添加了一个是否为邮箱的方法
/**
* 描述:是否是邮箱.
*
* @param str 指定的字符串
* @return 是否是邮箱:是为true,否则false
*/
public static Boolean isEmail(String str) {
Boolean isEmail = false;
String expr = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})$";
if (str.matches(expr)) {
isEmail = true;
}
return isEmail;
}
因为发送手机验证码和发送邮箱消息,需要一些额外的操作,这里不写!!(如果需要了解,可以私信教学【有偿】)
- 这里的有偿教学不仅仅是发送验证码,还包含了如何使用设计模式进行优化!!
@PostMapping(value = "/phone")
public void phone(@RequestParam("param1") String phone) {
picCheckCodeService.phone(phone);
}
@Override
public void phone(String phone) {
// 表示 判断是否为手机或邮箱
String flag = "";
if (PhoneUtil.isMatches(phone)) {
flag = "phone";
}
if (PhoneUtil.isEmail(phone)) {
flag = "email";
}
// 不是邮箱也不是电话
if ("".equals(flag)) {
return;
}
// 生成验证码
Random randObj = new Random();
String code = Integer.toString(100000 + randObj.nextInt(900000));
redisCheckCodeStore.set(phone, code, 60);
if ("phone".equals(flag)) {
// 发送短信
} else {
// 发送邮箱
}
}
找回密码
@Override
public void findpassword(FindPasswordDto findPasswordDto) {
// 验证码的key
String key = "";
XcUser xcUser = null;
LambdaQueryWrapper<XcUser> qw = new LambdaQueryWrapper<>();
if (!org.apache.commons.lang.StringUtils.isEmpty(findPasswordDto.getCellphone())) {
key = findPasswordDto.getCellphone();
qw.eq(XcUser::getCellphone, findPasswordDto.getCellphone());
xcUser = userMapper.selectOne(qw);
if (xcUser == null) {
XueChengPlusException.cast("查询不到用户");
}
} else {
key = findPasswordDto.getEmail();
qw.eq(XcUser::getEmail, findPasswordDto.getEmail());
xcUser = userMapper.selectOne(qw);
if (xcUser == null) {
XueChengPlusException.cast("查询不到用户");
}
}
// 手机或者邮箱都没填
if ("".equals(key)) {
XueChengPlusException.cast("手机或邮箱不正确");
}
// 判断验证码是否正确
Boolean result = checkCodeClient.verify(key, findPasswordDto.getCheckcode());
if (result == null || !result) {
XueChengPlusException.cast("验证码不正确");
}
// 判断密码是否一样
if (!findPasswordDto.getPassword().equals(findPasswordDto.getConfirmpwd())) {
XueChengPlusException.cast("密码和确认密码不一致");
}
xcUser.setPassword(passwordEncoder.encode(findPasswordDto.getPassword()));
userMapper.updateById(xcUser);
}
作业12 用户注册
@Override
public void register(UserRegisterDto userRegisterDto) {
// 验证码的key
String key = "";
XcUser xcUser = null;
LambdaQueryWrapper<XcUser> qw = new LambdaQueryWrapper<>();
if (!org.apache.commons.lang.StringUtils.isEmpty(userRegisterDto.getCellphone())) {
key = userRegisterDto.getCellphone();
qw.eq(XcUser::getCellphone, userRegisterDto.getCellphone());
xcUser = userMapper.selectOne(qw);
if (xcUser != null) {
XueChengPlusException.cast("用户已存在");
}
} else {
key = userRegisterDto.getEmail();
qw.eq(XcUser::getEmail, userRegisterDto.getEmail());
xcUser = userMapper.selectOne(qw);
if (xcUser != null) {
XueChengPlusException.cast("用户已存在");
}
}
// 手机或者邮箱都没填
if ("".equals(key)) {
XueChengPlusException.cast("手机或邮箱不正确");
}
// 判断验证码是否正确
Boolean result = checkCodeClient.verify(key, userRegisterDto.getCheckcode());
if (result == null || !result) {
XueChengPlusException.cast("验证码不正确");
}
// 判断密码是否一样
if (!userRegisterDto.getPassword().equals(userRegisterDto.getConfirmpwd())) {
XueChengPlusException.cast("密码和确认密码不一致");
}
xcUser = new XcUser();
BeanUtils.copyProperties(userRegisterDto, xcUser);
xcUser.setPassword(passwordEncoder.encode(userRegisterDto.getPassword()));
xcUser.setName(userRegisterDto.getUsername());
xcUser.setUtype("101001");
xcUser.setStatus("1");
xcUser.setCreateTime(LocalDateTime.now());
userMapper.insert(xcUser);
LambdaQueryWrapper<XcRole> xcRoleQw = new LambdaQueryWrapper<>();
xcRoleQw.eq(XcRole::getRoleCode, "student");
XcRole xcRole = xcRoleMapper.selectOne(xcRoleQw);
// 保存用户和角色的关系
XcUserRole xcUserRole = new XcUserRole();
xcUserRole.setUserId(xcUser.getId());
xcUserRole.setRoleId(xcRole.getId());
xcUserRoleMapper.insert(xcUserRole);
}