一、实现课程分类添加功能
使用EasyExcel读取Excel中写好的课程分类来完成,关于EasyExcel可以参考我的博客:
谷粒学苑项目实战(十一):使用EasyExcel实现对Excel表的读写操作
1、引入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.1.1</version> </dependency>
2、使用代码生成器生成逻辑代码
找到之前实现讲师管理功能时使用的代码生成器,由于我们想把课程管理和讲师管理放在一个模块下,所以只需要修改其中的表名就行了。
然后运行代码生成器。
3、创建实体类和Excel表对应
@Data public class SubjectData { @ExcelProperty(index = 0) private String oneSubjectName; @ExcelProperty(index = 1) private String twoSubjectName; }
4、逻辑代码
(1)controller
@RestController @RequestMapping("/eduservice/subject") @CrossOrigin public class EduSubjectController { @Autowired private EduSubjectService eduSubjectService; //添加课程分类 //获取上传过来的文件,把内容读取出来 @PostMapping("/addSubject") public R addSubject(MultipartFile file){ //上传过来的文件 eduSubjectService.saveSuject(file,eduSubjectService); return R.ok(); } }
(2)service
public interface EduSubjectService extends IService<EduSubject> { //添加课程分类 void saveSuject(MultipartFile file, EduSubjectService eduSubjectService); }
(3)impl
@Service public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService { /** * 添加课程分类 * @param file */ @Override public void saveSuject(MultipartFile file, EduSubjectService eduSubjectService) { try { InputStream in = file.getInputStream(); // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 EasyExcel.read(in, SubjectData.class, new SubjectExcelListener(eduSubjectService)).sheet().doRead(); } catch (Exception e){ e.printStackTrace(); } } }
(4)listener
public class SubjectExcelListener extends AnalysisEventListener<SubjectData> { //因为SubjectExcelListener不能交给spring进行管理,需要自己new,不能注入其他对象 //不能实现数据库操作 public EduSubjectService subjectService; public SubjectExcelListener() {} public SubjectExcelListener(EduSubjectService subjectService) { this.subjectService = subjectService; } //读取excel内容,一行一行进行读取 @Override public void invoke(SubjectData subjectData, AnalysisContext analysisContext) { if(subjectData == null) { throw new GuliException(20001,"文件数据为空"); } //一行一行读取,每次读取有两个值,第一个值一级分类,第二个值二级分类 //判断一级分类是否重复 EduSubject existOneSubject = this.existOneSubject(subjectService, subjectData.getOneSubjectName()); if(existOneSubject == null) { //没有相同一级分类,进行添加 existOneSubject = new EduSubject(); existOneSubject.setParentId("0"); existOneSubject.setTitle(subjectData.getOneSubjectName());//一级分类名称 subjectService.save(existOneSubject); } //获取一级分类id值 String pid = existOneSubject.getId(); //添加二级分类 //判断二级分类是否重复 EduSubject existTwoSubject = this.existTwoSubject(subjectService, subjectData.getTwoSubjectName(), pid); if(existTwoSubject == null) { existTwoSubject = new EduSubject(); existTwoSubject.setParentId(pid); existTwoSubject.setTitle(subjectData.getTwoSubjectName());//二级分类名称 subjectService.save(existTwoSubject); } } //判断一级分类不能重复添加 private EduSubject existOneSubject(EduSubjectService subjectService,String name) { QueryWrapper<EduSubject> wrapper = new QueryWrapper<>(); wrapper.eq("title",name); wrapper.eq("parent_id","0"); EduSubject oneSubject = subjectService.getOne(wrapper); return oneSubject; } //判断二级分类不能重复添加 private EduSubject existTwoSubject(EduSubjectService subjectService,String name,String pid) { QueryWrapper<EduSubject> wrapper = new QueryWrapper<>(); wrapper.eq("title",name); wrapper.eq("parent_id",pid); EduSubject twoSubject = subjectService.getOne(wrapper); return twoSubject; } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { } }
这里需要注意:
因为SubjectExcelListener需要new,所以不能交给spring进行管理,不能注入其他对象,我们需要自己写构造方法手动注入。
4、Excel表
5、启动测试
启动,打开swagger-ui,将写好的Excel表上传
后台也没有报错。
再看看数据库的edu_subject表
课程分类的添加功能就实现了。
二、实现课程分类列表显示功能(树形)
1、json数据格式分析
我们需要给前端返回的是这种格式的数据:
根据这个格式我们来建实体类
2、实体类
//一级分类 @Data public class OneSubject { private String id; private String title; //一个一级分类下有多个二级分类 List<TwoSubject> children = new ArrayList<>(); }
//二级分类 @Data public class TwoSubject { private String id; private String title; }
3、controller
//显示课程列表(树形) @GetMapping("/getAllSubject") public R getAllSubject(){ //因为一级分类的实体类中有二级分类,所以泛型写OneSubject就可以了 List<OneSubject> list = eduSubjectService.getAllOneTowSubject(); return R.ok().data("list", list); }
4、service
1. //显示课程分类(树形) 2. List<OneSubject> getAllOneTowSubject();
5、serviceImpl
/** * 显示课程分类列表(树形) * @return */ @Override public List<OneSubject> getAllOneTowSubject() { //1 查询所有一级分类 parentid = 0 QueryWrapper<EduSubject> wrapperOne = new QueryWrapper<>(); wrapperOne.eq("parent_id","0"); List<EduSubject> oneSubjectList = baseMapper.selectList(wrapperOne); //2 查询所有二级分类 parentid != 0 QueryWrapper<EduSubject> wrapperTwo = new QueryWrapper<>(); wrapperTwo.ne("parent_id","0"); List<EduSubject> twoSubjectList = baseMapper.selectList(wrapperTwo); //创建list集合,用于存储最终封装数据 List<OneSubject> finalSubjectList = new ArrayList<>(); //3 封装一级分类 //查询出来所有的一级分类list集合遍历,得到每个一级分类对象,获取每个一级分类对象值, //封装到要求的list集合里面 List<OneSubject> finalSubjectList for (int i = 0; i < oneSubjectList.size(); i++) { //遍历oneSubjectList集合 //得到oneSubjectList每个eduSubject对象 EduSubject eduSubject = oneSubjectList.get(i); //把eduSubject里面值获取出来,放到OneSubject对象里面 OneSubject oneSubject = new OneSubject(); // oneSubject.setId(eduSubject.getId()); // oneSubject.setTitle(eduSubject.getTitle()); //eduSubject值复制到对应oneSubject对象里面 BeanUtils.copyProperties(eduSubject,oneSubject); //多个OneSubject放到finalSubjectList里面 finalSubjectList.add(oneSubject); //在一级分类循环遍历查询所有的二级分类 //创建list集合封装每个一级分类的二级分类 List<TwoSubject> twoFinalSubjectList = new ArrayList<>(); //遍历二级分类list集合 for (int m = 0; m < twoSubjectList.size(); m++) { //获取每个二级分类 EduSubject tSubject = twoSubjectList.get(m); //判断二级分类parentid和一级分类id是否一样 if(tSubject.getParentId().equals(eduSubject.getId())) { //把tSubject值复制到TwoSubject里面,放到twoFinalSubjectList里面 TwoSubject twoSubject = new TwoSubject(); BeanUtils.copyProperties(tSubject,twoSubject); twoFinalSubjectList.add(twoSubject); } } //把一级下面所有二级分类放到一级分类里面 oneSubject.setChildren(twoFinalSubjectList); } return finalSubjectList; }
6、启动测试
启动8001之后,打开swagger-ui,找到这个方法