【在线教育】课程科目入门

文章目录

2.0 分析

2.1 环境搭建

2.1.1 数据库

2.1.2 后端:环境

2.1.3 后端:基本模块

2.1.4 前端

2.2 查询所有

2.2.1 后端实现

2.2.2 前端接口

2.2.3 前端实现

2.3 导入科目

2.3.1 需求

2.3.2 前端

2.3.2 前端:完整版

2.3.4 后端

2.0 分析

 

2.1 环境搭建

2.1.1 数据库

CREATE DATABASE zx_edu_course;
USE zx_edu_course;
​
CREATE TABLE `edu_subject`  (
  `id` VARCHAR(32) NOT NULL PRIMARY KEY COMMENT '课程科目ID',
  `title` VARCHAR(10) NOT NULL COMMENT '科目名称',
  `parent_id` VARCHAR(32) NOT NULL DEFAULT '0' COMMENT '父ID',
  `sort` INT(10)  NOT NULL DEFAULT 0 COMMENT '排序字段',
  `gmt_create` DATETIME NOT NULL COMMENT '创建时间',
  `gmt_modified` DATETIME NOT NULL COMMENT '更新时间'
) COMMENT = '课程科目';
​
INSERT INTO `edu_subject` VALUES ('1', '云计算', '0', 0, '2020-06-26 09:41:21', '2020-02-20 23:25:58');
INSERT INTO `edu_subject` VALUES ('2', '系统/运维', '0', 0, '2020-02-20 23:29:59', '2020-02-20 23:29:59');
INSERT INTO `edu_subject` VALUES ('3', '数据库', '0', 0, '2020-02-20 23:30:13', '2020-02-20 23:30:13');
INSERT INTO `edu_subject` VALUES ('4', '服务器', '0', 0, '2020-02-20 23:30:19', '2020-02-20 23:30:19');
​
INSERT INTO `edu_subject` VALUES ('5', 'MySQL', '3', 1, '2020-02-20 23:30:13', '2020-02-20 23:30:13');
INSERT INTO `edu_subject` VALUES ('6', 'Oracle', '3', 2, '2020-02-20 23:30:13', '2020-02-20 23:30:13');
INSERT INTO `edu_subject` VALUES ('7', 'Tomcat', '4', 1, '2020-02-20 23:30:13', '2020-02-20 23:30:13');
INSERT INTO `edu_subject` VALUES ('8', 'Nginx ', '4', 2, '2020-02-20 23:30:13', '2020-02-20 23:30:13');
​
INSERT INTO `edu_subject` VALUES ('9', 'MySQL优化', '5', 1, '2020-02-20 23:30:13', '2020-02-20 23:30:13');

2.1.2 后端:环境

  • 项目名:zx-service-course

  • pom文件

    <dependencies>
            <!--web起步依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!-- nacos 客户端 -->
            <dependency>
                <groupId>com.alibaba.nacos</groupId>
                <artifactId>nacos-client</artifactId>
            </dependency>
    ​
            <!-- nacos 服务发现 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
    ​
            <!--swagger2-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
            </dependency>
    ​
            <!-- feign 远程调用 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
    ​
            <!--测试-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
    ​
            <!-- mybatis plus-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis.plus.version}</version>
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!--自定义项目-->
            <dependency>
                <groupId>com.czxy.zx</groupId>
                <artifactId>zx-common31</artifactId>
            </dependency>
            <dependency>
                <groupId>com.czxy.zx</groupId>
                <artifactId>zx-domain31</artifactId>
            </dependency>
    ​
            <!-- redis 启动器 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <!-- JavaMail 启动器 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-mail</artifactId>
            </dependency>
            <!-- MQ 启动器 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-amqp</artifactId>
            </dependency>
    ​
            <!-- fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
            </dependency>
    ​
            <!--开发者工具-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <optional>true</optional>
            </dependency>
    ​
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>3.0.5</version>
            </dependency>
    ​
        </dependencies>

  • yml文件

    # 服务端口号
    server:
      port: 9020
    # 服务名
    spring:
      application:
        name: course-service
      datasource:
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/zx_edu_course?useUnicode=true&characterEncoding=utf8
        username: root
        password: 1234
        druid:    #druid 连接池配置
          initial-size: 1       #初始化连接池大小
          min-idle: 1           #最小连接数
          max-active: 20        #最大连接数
          test-on-borrow: true  #获取连接时候验证,会影响性能
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848   #nacos服务地址
      redis:
        database: 0       #数据库索引,取值0-15,表示16个库可选择
        host: 127.0.0.1   #服务器地址
        port: 6379        #服务器连接端口号
      mail:
        host: smtp.126.com          #发送邮件服务器
        username: itcast_lt@126.com #账号
        password: 1qaz2wsx          #密码
        default-encoding: UTF-8     #默认编码时
      rabbitmq:
        host: 127.0.0.1
        port: 5672
        username: guest
        passowrd: guest
        virtualHost: /
      devtools:
        restart:
          enabled: true  #设置开启热部署
          additional-paths: src/main/java #重启目录
          exclude: WEB-INF/**
      freemarker:
        cache: false    #页面不加载缓存,修改即时生效
    ​
    #开启log4j打印SQL语句
    logging:
      level:
        com:
          czxy:
            mapper: debug
    ​
    # mp日志打印
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    ​
    ​

  • 启动类

    package com.czxy.zx;
    ​
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     */
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class CourseServiceApplication {
        public static void main(String[] args) {
            SpringApplication.run(CourseServiceApplication.class,args);
        }
    }
    ​
  • 拷贝配置

     

2.1.3 后端:基本模块

  • 创建JavaBean

    package com.czxy.zx.domain;
    ​
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    import com.fasterxml.jackson.annotation.JsonFormat;
    import lombok.Data;
    import org.springframework.format.annotation.DateTimeFormat;
    ​
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    ​
    /**
     * 课程科目(EduSubject)表实体类
     *
     * @author 桐叔
     */
    @Data
    @TableName("edu_subject")
    public class EduSubject{
        @TableId(type = IdType.ASSIGN_UUID)
        //课程科目ID
        private String id;
        //科目名称
        private String title;
        //父ID
        private String parentId;
        //排序字段
        private Integer sort;
        //创建时间
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
        private Date gmtCreate;
        //更新时间
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
        private Date gmtModified;
    ​
        @TableField(exist = false)
        @JsonInclude(JsonInclude.Include.NON_EMPTY)     //生成json数据,不包含空元素
        private List<EduSubject> children = new ArrayList<>();
    ​
    }

  • 创建mapper

     

    package com.czxy.zx.course.mapper;
    ​
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.czxy.zx.domain.EduSubject;
    import org.apache.ibatis.annotations.Mapper;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     */
    @Mapper
    public interface EduSubjectMapper extends BaseMapper<EduSubject> {
    }
    ​

  • 创建service

     

    • 接口

      package com.czxy.zx.course.service;
      ​
      import com.baomidou.mybatisplus.extension.service.IService;
      import com.czxy.zx.domain.EduSubject;
      ​
      /**
       * @author 桐叔
       * @email liangtong@itcast.cn
       */
      public interface EduSubjectService extends IService<EduSubject> {
      }
      ​

    • 实现类

      package com.czxy.zx.course.service.impl;
      ​
      import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
      import com.czxy.zx.course.mapper.EduSubjectMapper;
      import com.czxy.zx.course.service.EduSubjectService;
      import com.czxy.zx.domain.EduSubject;
      import org.springframework.stereotype.Service;
      import org.springframework.transaction.annotation.Transactional;
      ​
      /**
       * @author 桐叔
       * @email liangtong@itcast.cn
       */
      @Service
      @Transactional
      public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {
      }
      ​

  • 创建controller

     

    package com.czxy.zx.course.controller;
    ​
    import com.czxy.zx.course.service.EduSubjectService;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    ​
    import javax.annotation.Resource;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     */
    @RestController
    @RequestMapping("/subject")
    public class EduSubjectController {
    ​
        @Resource
        private EduSubjectService eduSubjectService;
    ​
        
    }
    ​
    ​

  • 配置类

     

2.1.4 前端

  • 创建路由模块

     

    /** When your routing table is too long, you can split it into small modules **/
    ​
    import Layout from '@/layout'
    ​
    const courseRouter = {
      path: '/course',           // 当前模块前缀路径,必须以/开头
      component: Layout,          // 采用布局组件显示当前模块【默认】
      redirect: '/course/subjectList',  // “教师管理”默认显示路由
      name: '课程管理',            // 路由名称
      meta: {
        title: '课程管理',         // 一级菜单名称,children.length==0 隐藏
        icon: 'table'             // 一级菜单图标,children.length==0 隐藏
      },
      children: [
        {
          path: 'subjectList',
          component: () => import('@/views/edu/course/subjectList.vue'),
          name: '科目列表',
          meta: { title: '科目列表', icon: 'list' }   //二级菜单名称
        }
      ]
    }
    export default courseRouter
    ​
  • 创建 subjectList.vue 页面

     

  • 配置路由

     

2.2 查询所有

  • 以树形table展示数据

 

2.2.1 后端实现

  • 修改 EduSubjectController

package com.czxy.zx.course.controller;
​
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.czxy.zx.course.service.EduSubjectService;
import com.czxy.zx.domain.EduSubject;
import com.czxy.zx.vo.BaseResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
​
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
​
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@RestController
@RequestMapping("/subject")
public class EduSubjectController {
​
    @Resource
    private EduSubjectService eduSubjectService;
​
    @GetMapping
    public BaseResult findAll() {
        //1 查询所有
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.orderByAsc("parent_id");
        List<EduSubject> list = eduSubjectService.list(queryWrapper);
​
        //2 处理父子关系
        List<EduSubject> resultList = new ArrayList<>();
        Map<String,EduSubject> cache = new HashMap<>();
        list.forEach(eduSubject -> {
            // 获得父
            EduSubject parentEduSubject = cache.get(eduSubject.getParentId());
            // 如果没有父表示第一层,如果有父追加
            if(parentEduSubject != null) {
                // 如果有孩子,判断父对象的集合
                List<EduSubject> temp = parentEduSubject.getChildren();
                if(temp == null) {
                    parentEduSubject.setChildren(new ArrayList<>());
                }
                // 将孩子添加到父对象的集合中
                parentEduSubject.getChildren().add(eduSubject);
            } else {
                resultList.add(eduSubject);
            }
            // 缓存当前
            cache.put(eduSubject.getId(),eduSubject);
​
        });
​
        return BaseResult.ok("查询成功", resultList);
    }
​
}
​

2.2.2 前端接口

 

import axios from '@/utils/request'
​
// 查询所有课程科目
export function findAllSub() {
  return axios.get('/course-service/subject');
}

2.2.3 前端实现

  • 修改 @/views/edu/course/subjectList.vue

     

<template>
  <div>
    <el-table
      v-loading="listLoading"
      :data="subjectList"
      border
      fit
      highlight-current-row
      style="width: 100%;"
      row-key="title"
      :tree-props="{children: 'children'}"
    >
      <el-table-column label="科目名称" prop="title" align="center" width="200">
      </el-table-column>
      <el-table-column label="排序" prop="sort" width="80px" min-width="50px">
      </el-table-column>
      <el-table-column label="添加时间" width="200px" align="center">
        <template slot-scope="{row}">
          <span>{{ row.gmtCreate | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="更新时间" width="200px" align="center">
        <template slot-scope="{row}">
          <span>{{ row.gmtModified | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="{row,$index}">
          <el-button type="primary" size="mini">
            修改
          </el-button>
          <el-button v-if="row.status!='deleted'" size="mini" type="danger" >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
​
<script>
import { findAllSub } from '@/api/edu/course'
​
export default {
  data() {
    return {
      subjectList: [] ,
      listLoading: false,
    }
  },
  methods: {
    async findAllSubject() {  // 查询所有
      this.listLoading = true
      let { data } = await findAllSub()
      this.subjectList = data
      this.listLoading = false
    }
  },
  mounted() {
    this.findAllSubject()
  },
}
</script>
​
<style>
​
</style>
​

2.3 导入科目

2.3.1 需求

 

2.3.2 前端

  • 使用 upload组件

        <!-- 文件上传 -->
        <el-upload
          class="upload-demo"
          :action="updateUrl"
          :limit="1"
          :on-exceed="handleExceed"
          :before-upload="beforeUpload"
          :on-remove="handleRemove"
          :on-success="handleSuccess"
          :file-list="fileList">
          <el-button size="small" type="primary">点击上传</el-button>
          <div slot="tip" class="el-upload__tip">只能上传xls或xlsx文件,且不超过500kb</div>
        </el-upload>

  • 声明变量

      data() {
        return {
          fileList: [],     //上传文件列表
          updateUrl: process.env.VUE_APP_BASE_API + '/course-service/subject/upload',   //上传路径
        }
      },

  • 编写处理函数

    handleExceed(files, fileList) {   // 超出个数限制
          this.$message.warning(`当前选择1个文件`);
        },
        beforeUpload(file) {      // 上传文件之前
          // 是否是 xlsx 文件(2003)
          const isXlsx = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
          // 是否是 xls 文件(2010)
          const isXls = file.type === 'application/vnd.ms-excel'
          const isLt2M = file.size / 1024 / 1024 < 2;
    ​
          if (!isXlsx && !isXls) {
            this.$message.error('上传文件不是excel文件!');
          }
          if (!isLt2M) {
            this.$message.error('上传文件大小不能超过 2MB!');
          }
          return (isXlsx || isXls) && isLt2M;
        },
        handleRemove(file, fileList) {  // 文件列表移除文件
          console.log(file, fileList);
        },
        handleSuccess(response, file, fileList) { // 文件上传成功
          // 成功提示
          this.$message.success(response.message)
          // 刷新
          this.findAllSubject()
        }

2.3.2 前端:完整版

<template>
  <div>
    <el-table
      v-loading="listLoading"
      :data="subjectList"
      border
      fit
      highlight-current-row
      style="width: 100%;"
      row-key="title"
      :tree-props="{children: 'children'}"
    >
      <el-table-column label="科目名称" prop="title" align="left" width="200">
      </el-table-column>
      <el-table-column label="排序" prop="sort" width="80px" min-width="50px">
      </el-table-column>
      <el-table-column label="添加时间" width="200px" align="center">
        <template slot-scope="{row}">
          <span>{{ row.gmtCreate | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="更新时间" width="200px" align="center">
        <template slot-scope="{row}">
          <span>{{ row.gmtModified | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="{row}">
          <el-button type="primary" size="mini">
            修改
          </el-button>
          <el-button v-if="row.status!='deleted'" size="mini" type="danger" >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
​
    <!-- 文件上传 -->
    <el-upload
      class="upload-demo"
      :action="updateUrl"
      :limit="1"
      :on-exceed="handleExceed"
      :before-upload="beforeUpload"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :file-list="fileList">
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">只能上传xls或xlsx文件,且不超过500kb</div>
    </el-upload>
  </div>
</template>
​
<script>
import { findAllSub } from '@/api/edu/course'
​
export default {
  data() {
    return {
      subjectList: [] ,
      listLoading: false,
      fileList: [],     //上传文件列表
      updateUrl: process.env.VUE_APP_BASE_API + '/course-service/subject/upload',   //上传路径
    }
  },
  methods: {
    async findAllSubject() {  // 查询所有
      this.listLoading = true
      let { data } = await findAllSub()
      this.subjectList = data
      this.listLoading = false
    },
    handleExceed(files, fileList) {   // 超出个数限制
      this.$message.warning(`当前选择1个文件`);
    },
    beforeUpload(file) {      // 上传文件之前
      // 是否是 xlsx 文件(2003)
      const isXlsx = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      // 是否是 xls 文件(2010)
      const isXls = file.type === 'application/vnd.ms-excel'
      const isLt2M = file.size / 1024 / 1024 < 2;
​
      if (!isXlsx && !isXls) {
        this.$message.error('上传文件不是excel文件!');
      }
      if (!isLt2M) {
        this.$message.error('上传文件大小不能超过 2MB!');
      }
      return (isXlsx || isXls) && isLt2M;
    },
    handleRemove(file, fileList) {  // 文件列表移除文件
      console.log(file, fileList);
    },
    handleSuccess(response, file, fileList) { // 文件上传成功
      // 成功提示
      this.$message.success(response.message)
      // 刷新
      this.findAllSubject()
    }
  },
  mounted() {
    this.findAllSubject()
  },
}
</script>
​
<style>
​
</style>
​

2.3.4 后端

1) 完善JavaBean

package com.czxy.zx.domain;
​
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
​
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
​
/**
 * 课程科目(EduSubject)表实体类
 *
 * @author 桐叔
 */
@Data
@TableName("edu_subject")
public class EduSubject{
    @TableId(type = IdType.ASSIGN_UUID)
    //课程科目ID
    private String id;
    //科目名称
    private String title;
    //父ID
    private String parentId;
    //排序字段
    private Integer sort;
    //创建时间
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    @TableField(fill = FieldFill.INSERT)
    private Date gmtCreate;
    //更新时间
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    @TableField(fill = FieldFill.INSERT)
    private Date gmtModified;
​
    @TableField(exist = false)
    private List<EduSubject> children = new ArrayList<>();
​
}

2)填充数据处理类

 

package com.czxy.zx.course.handler;
​
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
​
import java.util.Date;
​
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Component
public class SubjectMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        // 创建时间
        this.setFieldValByName("gmtCreate",new Date(), metaObject);
        // 修改时间
        this.setFieldValByName("gmtModified",new Date() , metaObject);
    }
​
    @Override
    public void updateFill(MetaObject metaObject) {
        // 修改时,填充的内容
        this.setFieldValByName("gmtModified",new Date() , metaObject);
    }
}
​

3)service:通过title查询

 

  • 接口

    package com.czxy.zx.course.service;
    ​
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.czxy.zx.domain.EduSubject;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     */
    public interface EduSubjectService extends IService<EduSubject> {
        /**
         * 通过title查询
         * @param title
         * @return
         */
        EduSubject findByTitle(String title);
    }
    ​

  • 实现类

    package com.czxy.zx.course.service.impl;
    ​
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.czxy.zx.course.mapper.EduSubjectMapper;
    import com.czxy.zx.course.service.EduSubjectService;
    import com.czxy.zx.domain.EduSubject;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    ​
    /**
     * @author 桐叔
     * @email liangtong@itcast.cn
     */
    @Service
    @Transactional
    public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {
        @Override
        public EduSubject findByTitle(String title) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("title", title);
    ​
            EduSubject eduSubject = baseMapper.selectOne(queryWrapper);
            return eduSubject;
        }
    }
    ​

4)controller:上传

 /**
     * 文件上传
     * @param file
     * @return
     */
    @PostMapping("/upload")
    public BaseResult upload(MultipartFile file) {
        try {
            // 解析excel
            EasyExcel.read(file.getInputStream(), UploadSubjectVo.class, eduSubjectListener).sheet(0).doRead();
​
            return BaseResult.ok("上传成功");
        } catch (IOException e) {
            return BaseResult.error("上传失败");
        }
    }

5)excel内容封装类

package com.czxy.zx.course.upload;
​
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
​
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Data
public class UploadSubjectVo {
​
    @ExcelProperty("一级分类")
    private String oneLevel;
​
    @ExcelProperty("二级分类")
    private String twoLevel;
​
​
}
​

6)上传内容处理类

 

 

package com.czxy.zx.course.upload;
​
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.czxy.zx.course.service.EduSubjectService;
import com.czxy.zx.domain.EduSubject;
import org.springframework.stereotype.Component;
​
import javax.annotation.Resource;
​
/**
 * @author 桐叔
 * @email liangtong@itcast.cn
 */
@Component
public class EduSubjectListener extends AnalysisEventListener<UploadSubjectVo> {
​
    @Resource
    private EduSubjectService eduSubjectService;
​
    @Override
    public void invoke(UploadSubjectVo uploadSubjectVo, AnalysisContext analysisContext) {
        // 1. 处理一级
        // 1.1 查询一级
        EduSubject oneSubject = eduSubjectService.findByTitle(uploadSubjectVo.getOneLevel());
        // 1.2 保存一级
        if(oneSubject == null) {
            oneSubject = new EduSubject();
            oneSubject.setTitle(uploadSubjectVo.getOneLevel());
            oneSubject.setSort(0);
            oneSubject.setParentId("0");        // 一级默认0
            eduSubjectService.save(oneSubject);
        }
​
        // 2. 处理二级
        // 2.1 查询二级
        EduSubject twoSubject = eduSubjectService.findByTitle(uploadSubjectVo.getTwoLevel());
        // 2.2 保存二级
        if(twoSubject == null) {
            twoSubject = new EduSubject();
            twoSubject.setTitle(uploadSubjectVo.getTwoLevel());
            twoSubject.setSort(0);
            twoSubject.setParentId(oneSubject.getId()); //二级的父ID为一级的ID
            eduSubjectService.save(twoSubject);
        }
​
    }
​
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
​
    }
}
​
posted @ 2022-11-09 08:11  陶然同学  阅读(2)  评论(0编辑  收藏  举报