浏览代码

add:课程结构

Tang 3 年之前
父节点
当前提交
a2c985a703

+ 2 - 0
src/api/api.js

@@ -101,6 +101,7 @@ import studyAccountStatus from '../newApi/studyAccountStatus'//学习账号标
 import mock from '../newApi/mock'//模考管理
 import mockSub from '../newApi/mockSub'//预约模考管理
 import systemExam from '../newApi/systemExam'//模考活动列表
+import newCourseApi from '../newApi/newCourseApi'//(新)课程列表
 
 
 
@@ -182,6 +183,7 @@ export default {
     ...mock,
     ...mockSub,
     ...systemExam,
+    ...newCourseApi,
 
     // ...login,
     // ...profession,

+ 81 - 0
src/newApi/newCourseApi.js

@@ -0,0 +1,81 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增目录
+    appNodeDir(data) {
+        return request({
+            url: '/node/dir',
+            method: 'post',
+            data
+        })
+    },
+    //删除目录
+    delNodeDir(data) {
+        return request({
+            url: '/node/dir/del/' + data,
+            method: 'post',
+        })
+    },
+    //修改目录
+    editNodeDir(data) {
+        return request({
+            url: '/node/dir/edit',
+            method: 'post',
+            data
+        })
+    },
+    //查询目录列表
+    inquireNodeDir(data) {
+        return request({
+            url: '/node/dir/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //获取目录详细信息
+    obtainNodeDirId(data) {
+        return request({
+            url: `/node/dir/` + data,
+            method: 'get',
+        })
+    },
+    // ----------------------------------------------------------------
+    //新增课程目录节点
+    appSystemDir(data) {
+        return request({
+            url: '/system/node',
+            method: 'post',
+            data
+        })
+    },
+    //删除课程目录节点
+    delSystemDir(data) {
+        return request({
+            url: '/system/node/del/' + data,
+            method: 'post',
+        })
+    },
+    //修改课程目录节点
+    editSystemDir(data) {
+        return request({
+            url: '/system/node/edit',
+            method: 'post',
+            data
+        })
+    },
+    //查询课程目录节点列表
+    inquireSystemDir(data) {
+        return request({
+            url: '/system/node/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //获取课程目录节点详细信息
+    obtainSystemDirId(data) {
+        return request({
+            url: `/system/node/` + data,
+            method: 'get',
+        })
+    },
+
+}

+ 8 - 0
src/store/getters.js

@@ -261,5 +261,13 @@ const getters = {
     }
     return state.dict.beforeLists
   },
+  teachList(state) {
+    if (!state.dict.teachList) {
+      api.inquiresystemteacherlist({ status: 1 }).then(res => {
+        state.dict.teachList = res.rows
+      })
+    }
+    return state.dict.teachList
+  }
 }
 export default getters

+ 7 - 0
src/store/modules/dict.js

@@ -31,6 +31,7 @@ const state = {
   beforeList: null,//前培安排过滤
   beforeLists: null,//前培安排
   indexnum: null,//模拟
+  teachList: null,//教师列表
 }
 const mutations = {
   //更新角色列表
@@ -204,6 +205,12 @@ const mutations = {
       state.paperexam = res.rows
     })
   },
+  //更新教师列表
+  TEACHLIST(state) {
+    api.inquiresystemteacherlist({ status: 1 }).then(res => {
+      state.teachList = res.rows
+    })
+  }
 }
 
 const actions = {

+ 2 - 0
src/views/education/teacher/teacherList/index.vue

@@ -352,6 +352,7 @@ export default {
           this.$message.success("新增成功");
           this.dialog = false;
           this.search();
+          this.$store.commit("TEACHLIST");
         });
       }
       if (this.int === 2) {
@@ -359,6 +360,7 @@ export default {
           this.$message.success("修改成功");
           this.dialog = false;
           this.search();
+          this.$store.commit("TEACHLIST");
         });
       }
     },

+ 590 - 0
src/views/resource/videoManagement/course/addBaseInfo/index.vue

@@ -0,0 +1,590 @@
+<template>
+  <div id="AddBaseInfo">
+    <div class="boxWidth">
+      <el-form
+        label-position="right"
+        label-width="120px"
+        :model="listData"
+        :rules="rules"
+        ref="listData"
+      >
+        <el-form-item label="教育类型" prop="educationTypeId">
+          <el-select
+            v-model="listData.educationTypeId"
+            placeholder="请选择教育类型"
+            @change="changeEducationTypeId"
+          >
+            <el-option
+              v-for="(item, index) in eduTypeOptions"
+              :key="index"
+              :label="item.educationName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="业务层次" prop="businessId">
+          <el-select
+            v-model="listData.businessId"
+            placeholder="请选择业务层次"
+            @change="changeBusinessId"
+          >
+            <el-option
+              v-for="(item, index) in newCourTypeOptions"
+              :key="index"
+              :label="item.projectName + '-' + item.businessName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          label="院校"
+          prop="schoolId"
+          v-if="listData.businessId && avtives()"
+        >
+          <el-select v-model="listData.schoolId" placeholder="请选择院校">
+            <el-option
+              v-for="(item, index) in newSchoolOption"
+              :key="index"
+              :label="item.schoolName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <!-- <el-form-item
+          label="专业"
+          prop="majorId"
+          v-if="listData.businessId && avtivesMajor()"
+        >
+          <el-select v-model="listData.majorId" placeholder="请选择专业">
+            <el-option
+              v-for="(item, index) in newMajorOption"
+              :key="index"
+              :label="item.categoryName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item> -->
+        <el-form-item
+          label="科目"
+          prop="subjectId"
+          v-if="listData.businessId"
+        >
+          <el-select v-model="listData.subjectId" placeholder="请选择科目">
+            <el-option
+              v-for="(item, index) in newSujectOption"
+              :key="index"
+              :label="item.subjectName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="名称前缀" prop="prefixName">
+          <el-input v-model="listData.prefixName"></el-input>
+          <div style="color: #999">注:便于检索、归类,以及区分一样的标题</div>
+        </el-form-item>
+        <el-form-item label="课程名称" prop="courseName">
+          <el-input v-model="listData.courseName"></el-input>
+          <div style="color: #999">
+            注:请尽量规范易懂,方便在课程目录表呈现给学员
+          </div>
+        </el-form-item>
+        <el-form-item label="课程封面">
+          <el-row :gutter="10" style="margin-bottom: 10px">
+            <el-col :span="12">
+              <div
+                style="
+                  width: 100%;
+                  height: 150px;
+                  border: 2px dashed #999;
+                  border-radius: 28px;
+                  line-height: 150px;
+                  text-align: center;
+                "
+                v-if="!listData.coverUrl"
+              >
+                <label for="uplose">
+                  <i class="el-icon-circle-plus-outline iconStsz"></i
+                ></label>
+                <input
+                  ref="file"
+                  type="file"
+                  style="display: none"
+                  id="uplose"
+                  @change="getImgFile"
+                />
+              </div>
+              <el-image
+                v-else
+                style="width: 100%"
+                :src="$methodsTools.splitImgHost(listData.coverUrl)"
+                :preview-src-list="[
+                  $methodsTools.splitImgHost(listData.coverUrl),
+                ]"
+              >
+              </el-image>
+            </el-col>
+            <el-col :span="11">
+              <span style="color: #999; font-size: 14px"
+                >注:请上传小于300kb,尺寸为750*440的图片,支持gif、jpg、jpeg、png等类型</span
+              >
+            </el-col>
+          </el-row>
+          <el-button
+            v-if="listData.coverUrl"
+            type="danger"
+            size="mini"
+            class="margin-top: 20px;"
+            @click="clearImgs"
+            >删除</el-button
+          >
+        </el-form-item>
+        <el-form-item label="是否发布" prop="publishStatus">
+          <el-radio-group v-model="listData.publishStatus">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="课程简介">
+          <el-input type="textarea" v-model="listData.introduction"></el-input>
+        </el-form-item>
+        <el-form-item label="适合对象">
+          <el-input
+            type="textarea"
+            v-model="listData.suitableObject"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <div class="courseStyle">
+        课程详情<span style="color: #999; margin-left: 6px">支持图文</span>
+      </div>
+      <div style="text-align: center; margin-bottom: 10px">
+        <el-button
+          size="mini"
+          :type="active === 1 ? 'success' : ''"
+          @click="active = 1"
+          >PC端</el-button
+        >
+        <el-button
+          size="mini"
+          :type="active === 2 ? 'success' : ''"
+          @click="active = 2"
+          >手机端</el-button
+        >
+      </div>
+      <editor
+        v-show="active === 1"
+        v-model="listData.pcDetailHtml"
+        :min-height="300"
+        :max-height="500"
+        :uploadStatus="uploadStatus"
+      />
+      <editor
+        v-show="active === 2"
+        v-model="listData.mobileDetailHtml"
+        :min-height="300"
+        :max-height="500"
+        :uploadStatus="uploadStatus"
+      />
+      <div style="text-align: center; margin-top: 20px">
+        <el-button @click="backPage" size="mini">取消</el-button>
+        <el-button
+          type="primary"
+          @click="submit('listData')"
+          size="mini"
+          :loading="disabledBtn"
+          >确定</el-button
+        >
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Editor from "@/components/Editor";
+
+export default {
+  name: "AddBaseInfo",
+  components: { Editor },
+  data() {
+    return {
+      disabledBtn: false,
+      uploadStatus: 2, //富文本组件传值
+      active: 1,
+      //   弹窗数据
+      bfImg: "oss/images/avatar/20211013/1634097664410_1397766697",
+      listData: {
+        publishStatus: 1,
+        coverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
+        educationTypeId: "",
+        businessId: "",
+        schoolId: "",
+        majorId: "",
+        subjectId: "",
+      },
+
+      eduTypeOptions: [], //教育类型数据
+      courTypeOptions: [], //业务层次数据
+      sujectOption: [], //科目数据
+      schoolOption: [], //院校数据
+      majorOption: [], //专业数据
+
+      newCourTypeOptions: [], //当前业务层次数据
+      newSujectOption: [], //当前科目数据数据
+      newSchoolOption: [], //当前院校数据
+      newMajorOption: [], //当前专业数据
+      //表单验证
+      rules: {
+        educationTypeId: [
+          {
+            required: true,
+            message: "请选择教育类型",
+            trigger: ["blur", "change"],
+          },
+        ],
+        businessId: [
+          {
+            required: true,
+            message: "请选择业务层次",
+            trigger: ["blur", "change"],
+          },
+        ],
+        // schoolId: [
+        //   {
+        //     required: true,
+        //     message: "请选择院校",
+        //     trigger: ["blur", "change"],
+        //   },
+        // ],
+        // majorId: [
+        //   {
+        //     required: true,
+        //     message: "请选择专业",
+        //     trigger: ["blur", "change"],
+        //   },
+        // ],
+        subjectId: [
+          {
+            required: true,
+            message: "请选择科目",
+            trigger: ["blur", "change"],
+          },
+        ],
+        prefixName: [
+          { required: false, message: "请输入名称前缀", trigger: "blur" },
+        ],
+        courseName: [
+          { required: true, message: "请输入课程名称", trigger: "blur" },
+        ],
+        publishStatus: [
+          { required: true, message: "请选择是否发布", trigger: "change" },
+        ],
+      },
+    };
+  },
+  mounted() {
+    this.getDict();
+  },
+  methods: {
+    avtives() {
+      if (this.listData.educationTypeId) {
+        for (let i = 0; i < this.eduTypeOptions.length; i++) {
+          if (this.eduTypeOptions[i].id === this.listData.educationTypeId) {
+            return this.eduTypeOptions[i].tireStatus.indexOf("3") != -1;
+          }
+        }
+      }
+    },
+    avtivesMajor() {
+      if (this.listData.educationTypeId) {
+        for (let i = 0; i < this.eduTypeOptions.length; i++) {
+          if (this.eduTypeOptions[i].id === this.listData.educationTypeId) {
+            return this.eduTypeOptions[i].tireStatus.indexOf("4") != -1;
+          }
+        }
+      }
+    },
+    getDict() {
+      this.$api.inquireCourseEducationType({ status: 1 }).then((res) => {
+        this.eduTypeOptions = res.rows;
+      });
+      this.$api.inquireCourseProjectType({ status: 1 }).then((res) => {
+        this.projectTypeOptions = res.rows;
+      });
+      this.$api.inquirebusinessList({ status: 1 }).then((res) => {
+        this.courTypeOptions = res.rows;
+        this.newCourTypeOptions = res.rows;
+      });
+      this.$api.inquireCourseSubject({ status: 1 }).then((res) => {
+        res.rows.map((item, index) => {
+          var array = [];
+          item.courseProjectTypes.map((items, indexs) => {
+            array.push(items.id);
+          });
+          item.courseArrays = array;
+        });
+        this.sujectOption = res.rows;
+      });
+      this.$api.inquireUserSchool({ status: 1 }).then((res) => {
+        res.rows.map((item, index) => {
+          var array = [];
+          item.courseProjectTypes.map((items, indexs) => {
+            array.push(items.id);
+          });
+          item.courseArrays = array;
+        });
+        this.schoolOption = res.rows;
+      });
+      this.$api.inquireCourseMajor({ status: 1 }).then((res) => {
+        res.rows.map((item, index) => {
+          var array = [];
+          item.courseProjectTypeVo.map((items, indexs) => {
+            array.push(items.id);
+          });
+          item.courseArrays = array;
+        });
+        this.majorOption = res.rows;
+      });
+    },
+    //改变教育类型
+    changeEducationTypeId() {
+      var arrays = [];
+      this.courTypeOptions.map((item) => {
+        if (item.educationId === this.listData.educationTypeId) {
+          arrays.push(item);
+        }
+      });
+      this.newCourTypeOptions = arrays;
+      this.listData.businessId = "";
+    },
+    //改变业务层次触发
+    changeBusinessId() {
+      this.listData.schoolId = "";
+      this.listData.majorId = "";
+      this.listData.subjectId = "";
+      this.courTypeOptions.map((item) => {
+        if (item.id === this.listData.businessId) {
+          this.listData.educationTypeId = item.educationId;
+          var newSchoolOption = [];
+          var newMajorOption = [];
+          var newSujectOption = [];
+          // this.$api
+          //   .inquireCourseSubjectlistAll({status:1, projectId: item.projectId })
+          //   .then((res) => {
+          //     this.newSujectOption = res.rows
+          //   });
+          for (let i = 0; i < this.schoolOption.length; i++) {
+            if (
+              this.schoolOption[i].courseArrays.indexOf(item.projectId) !== -1
+            ) {
+              newSchoolOption.push(this.schoolOption[i]);
+            }
+          }
+          if (!newSchoolOption.length) {
+            this.newSchoolOption = this.schoolOption;
+          } else {
+            this.newSchoolOption = newSchoolOption;
+          }
+          for (let i = 0; i < this.majorOption.length; i++) {
+            if (
+              this.majorOption[i].courseArrays.indexOf(item.projectId) !== -1
+            ) {
+              newMajorOption.push(this.majorOption[i]);
+            }
+          }
+          // if (!newMajorOption.length) {
+          //   this.newMajorOption = this.majorOption;
+          // } else {
+            this.newMajorOption = newMajorOption;
+          // }
+          for (let i = 0; i < this.sujectOption.length; i++) {
+            if (
+              this.sujectOption[i].courseArrays.indexOf(item.projectId) !== -1
+            ) {
+              newSujectOption.push(this.sujectOption[i]);
+            }
+          }
+          if (!newSujectOption.length) {
+            this.newSujectOption = [];
+          } else {
+            this.newSujectOption = newSujectOption;
+          }
+          // this.schoolOption.map((items) => {
+          //   if (items.courseArrays.indexOf(item.projectId) !== -1) {
+          //     newSchoolOption.push(items);
+          //   }
+          // });
+          // this.newSchoolOption = newSchoolOption;
+          // this.majorOption.map((items) => {
+          //   if (items.courseArrays.indexOf(item.projectId) !== -1) {
+          //     newMajorOption.push(items);
+          //   }
+          // });
+          // this.newMajorOption = newMajorOption;
+        }
+      });
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          if (
+            this.listData.coverUrl === "" ||
+            this.listData.coverUrl === null ||
+            this.listData.coverUrl === undefined
+          ) {
+            this.$message.error("请上传节封面");
+            return false;
+          }
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    async rulesTableSumbit() {
+      this.disabledBtn = true;
+      this.courTypeOptions.map((item) => {
+        if (item.id === this.listData.businessId) {
+          this.listData.projectId = item.projectId;
+        }
+      });
+      this.listData.status = 1;
+      this.$api
+        .addCourse(this.listData)
+        .then((res) => {
+          this.$message.success("新增成功");
+          setTimeout(() => {
+            this.$store
+              .dispatch("tagsView/exitView", this.$route)
+              .then((rest) => {
+                this.$router
+                  .replace({
+                    path: "tableContents",
+                    query: {
+                      id: res.data
+                    },
+                  })
+                  .catch((err) => {});
+              });
+          }, 300);
+        })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
+    },
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        this.$router.push({
+          path: "course",
+        });
+      });
+    },
+    getImgFile() {
+      var self = this;
+      var file = self.$refs.file.files[0];
+      if (file === undefined) {
+        self.$set(self.listData, "coverUrl", "");
+        return;
+      }
+      if (file.size > 0.3 * 1024 * 1024) {
+        self.$message.error("图片不得大于300kb");
+        return;
+      }
+      var type = self.$refs.file.value.toLowerCase().split(".").splice(-1);
+      if (
+        type[0] != "jpg" &&
+        type[0] != "png" &&
+        type[0] != "jpeg" &&
+        type[0] != "gif"
+      ) {
+        self.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
+        self.$refs.file.value = "";
+        return;
+      }
+      this.$upload.upload(file, 0).then((res) => {
+        self.listData.coverUrl = res;
+      });
+    },
+    clearImgs() {
+      this.listData.coverUrl = "";
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.courseStyle {
+  margin: 20px;
+  margin-bottom: 10px;
+  font-size: 14px;
+  border-bottom: 2px solid skyblue;
+}
+.boxWidth {
+  min-width: 800px;
+}
+.numInputs {
+  width: 150px;
+}
+.checkboxSty {
+  max-height: 210px;
+  overflow: auto;
+  display: flex;
+  flex-direction: column;
+}
+.listBoxStys {
+  flex-shrink: 0;
+  padding: 0px 10px;
+  border-radius: 8px;
+  border: 1px solid #eee;
+  margin-right: 10px;
+  margin-bottom: 6px;
+}
+.closeIcons {
+  color: red;
+  cursor: pointer;
+  margin-left: 6px;
+}
+.ach {
+  display: flex;
+  align-items: center;
+  overflow: hidden;
+}
+.clh {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+}
+.imgBoxins {
+  display: flex;
+  text-align: center;
+  .uploadImgBox {
+    width: 375px;
+    height: 220px;
+    .img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
+.iconStsz {
+  font-size: 40px;
+  color: #67c23a;
+  cursor: pointer;
+}
+.dis_plays {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
+.comInputsty {
+  width: 50px;
+  height: 24px;
+  text-align: center;
+  border: none;
+}
+</style>

+ 406 - 0
src/views/resource/videoManagement/course/index.vue

@@ -0,0 +1,406 @@
+<template>
+  <div id="course">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      @addClick="addClick"
+      :loading="loading"
+      @editInfo="editInfo"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="edit(props.scope.row)">修改</el-button>
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "course",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "课程管理",
+        index: 0,
+        ch: "条",
+        num: true,
+        border: true,
+        choice: true,
+        addHide: false,
+        changeWidth: "140px",
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop: "educationTypeId",
+          placeholder: "教育类型",
+          scope: "educationType",
+        },
+        {
+          prop: "businessId",
+          placeholder: "业务层次",
+          scope: "businessLevel",
+          edu: "educationTypeId",
+        },
+        {
+          prop: "schoolId",
+          placeholder: "院校",
+          scope: "schoolList",
+          edu: "educationTypeId",
+        },
+        {
+          prop: "majorId",
+          placeholder: "专业",
+          scope: "Professional",
+          edu: "educationTypeId",
+        },
+        {
+          prop: "subjectId",
+          placeholder: "科目",
+          scope: "sujectType",
+          edu: "educationTypeId",
+        },
+        {
+          prop: "prefixName",
+          placeholder: "请输入标题前缀",
+        },
+        {
+          prop: "publishStatus",
+          placeholder: "发布状态",
+          scope: "select",
+          options: [
+            {
+              label: "发布",
+              value: 1,
+            },
+            {
+              label: "未发布",
+              value: 0,
+            },
+          ],
+        },
+        {
+          prop: "courseName",
+          placeholder: "请输入课程名称",
+          scope: false,
+        },
+      ],
+      formData: {
+        status: "0,1",
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "课程编码",
+          prop: "code",
+          hidden: false,
+        },
+        {
+          label: "名称前缀",
+          prop: "prefixName",
+          hidden: false,
+        },
+        {
+          label: "课程名称",
+          prop: "courseName",
+          hidden: true,
+          scope: "editInfo",
+        },
+        {
+          label: "科目",
+          prop: "subjectName",
+          hidden: true,
+        },
+        {
+          label: "专业",
+          prop: "categoryName",
+          hidden: false,
+        },
+        {
+          label: "院校",
+          prop: "schoolName",
+          hidden: false,
+        },
+        {
+          label: "业务层次",
+          prop1: "projectName",
+          prop2: "businessName",
+          hidden: true,
+          scope: "InfoMore",
+        },
+        {
+          label: "教育类型",
+          prop: "educationName",
+          hidden: true,
+        },
+        {
+          label: "发布状态",
+          prop: "publishStatus",
+          hidden: true,
+          scope: "fabStatus",
+        },
+        {
+          label: "最后编辑时间",
+          prop: "updateTime",
+          scope: "aTimeList",
+          hidden: true,
+        },
+        {
+          label: "创建时间",
+          prop: "createTime",
+          scope: "aTimeList",
+          hidden: true,
+        },
+        // {
+        //   label: "课程章节",
+        //   prop: "courseId",
+        //   hidden: true,
+        //   scope: "aboutTrees",
+        // },
+        {
+          label: "关联商品",
+          hidden: true,
+          prop: "goodsList",
+          prop1: "goodsName",
+          scope: "aboutChapter",
+          int: 4,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      pageSize: 10, //每页多少条数据
+      currentPage: 1, //当前页码
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  activated() {
+    this.search();
+  },
+  methods: {
+    edit(v) {
+      const jump = () => {
+        this.$router.push({
+          path: "tableContents",
+          query: {
+            id: v.courseId
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "TableContents";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "TableContents",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
+    editInfo(v) {
+      this.edit(v);
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          status: "0,1",
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      this.$api
+        .inquireCourseListS(this.formData)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    del(v) {
+      this.$api.gradecheckGoodsChange({ courseId: v.courseId }).then((res) => {
+        if (res.data > 0) {
+          this.$message.error("已有学员正在学习该课程,无法删除");
+          return;
+        } else {
+          this.$alert(
+            "确定删除此内容?<br />内容删除后将无法恢复,请慎重考虑",
+            "提示",
+            {
+              dangerouslyUseHTMLString: true,
+            }
+          )
+            .then(() => {
+              var data = {
+                courseId: v.courseId,
+                status: -1,
+              };
+              this.$api.editCourse(data).then((res) => {
+                this.$message.success("删除成功");
+                this.search();
+              });
+            })
+            .catch(() => {
+              this.$message({
+                type: "info",
+                message: "已取消删除",
+              });
+            });
+        }
+      });
+    },
+    addClick(v, int) {
+      if (v === undefined) {
+        this.$router.push({
+          path: "addBaseInfo",
+        });
+      }
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 744 - 0
src/views/resource/videoManagement/course/tableContents/basePage.vue

@@ -0,0 +1,744 @@
+<template>
+  <div id="basePage">
+    <div class="boxWidth">
+      <el-form
+        label-position="right"
+        label-width="120px"
+        :model="listData"
+        :rules="rules"
+        ref="listData"
+      >
+        <el-form-item label="教育类型" prop="educationTypeId">
+          <el-select
+            disabled
+            v-model="listData.educationTypeId"
+            placeholder="请选择教育类型"
+            @change="changeEducationTypeId"
+          >
+            <el-option
+              v-for="(item, index) in eduTypeOptions"
+              :key="index"
+              :label="item.educationName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="业务层次" prop="businessId">
+          <el-select
+            disabled
+            v-model="listData.businessId"
+            placeholder="请选择业务层次"
+            @change="changeBusinessId"
+          >
+            <el-option
+              v-for="(item, index) in newCourTypeOptions"
+              :key="index"
+              :label="item.projectName + '-' + item.businessName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          label="院校"
+          prop="schoolId"
+          v-if="listData.businessId && avtives()"
+        >
+          <el-select v-model="listData.schoolId" placeholder="请选择院校">
+            <el-option
+              v-for="(item, index) in newSchoolOption"
+              :key="index"
+              :label="item.schoolName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <!-- <el-form-item
+          label="专业"
+          prop="majorId"
+          v-if="listData.businessId && avtivesMajor()"
+        >
+          <el-select v-model="listData.majorId" placeholder="请选择专业">
+            <el-option
+              v-for="(item, index) in newMajorOption"
+              :key="index"
+              :label="item.categoryName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item> -->
+        <el-form-item label="科目" prop="subjectId" v-if="listData.businessId">
+          <el-select
+            v-model="listData.subjectId"
+            placeholder="请选择科目"
+            disabled
+          >
+            <el-option
+              v-for="(item, index) in newSujectOption"
+              :key="index"
+              :label="item.subjectName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="名称前缀" prop="prefixName">
+          <el-input v-model="listData.prefixName"></el-input>
+          <div style="color: #999">注:便于检索、归类,以及区分一样的标题</div>
+        </el-form-item>
+        <el-form-item label="课程名称" prop="courseName">
+          <el-input v-model="listData.courseName"></el-input>
+          <div style="color: #999">
+            注:请尽量规范易懂,方便在课程目录表呈现给学员
+          </div>
+        </el-form-item>
+
+        <el-form-item label="课程封面" prop="coverUrl">
+          <el-row :gutter="10" style="margin-bottom: 10px">
+            <el-col :span="12">
+              <div
+                style="
+                  width: 100%;
+                  height: 150px;
+                  border: 2px dashed #999;
+                  border-radius: 28px;
+                  line-height: 150px;
+                  text-align: center;
+                "
+                v-if="!listData.coverUrl"
+              >
+                <label for="uplose">
+                  <i class="el-icon-circle-plus-outline iconStsz"></i
+                ></label>
+                <input
+                  ref="file"
+                  type="file"
+                  style="display: none"
+                  id="uplose"
+                  @change="getImgFile"
+                />
+              </div>
+              <el-image
+                v-else
+                style="width: 100%"
+                :src="$methodsTools.splitImgHost(listData.coverUrl)"
+                :preview-src-list="[
+                  $methodsTools.splitImgHost(listData.coverUrl),
+                ]"
+              >
+              </el-image>
+            </el-col>
+            <el-col :span="11">
+              <span style="color: #999; font-size: 14px"
+                >注:请上传小于300kb,尺寸为750*440的图片,支持gif、jpg、jpeg、png等类型</span
+              >
+            </el-col>
+          </el-row>
+          <el-button
+            v-if="listData.coverUrl"
+            type="danger"
+            size="mini"
+            class="margin-top: 20px;"
+            @click="clearImgs"
+            >删除</el-button
+          >
+        </el-form-item>
+        <el-form-item label="审核学时" prop="auditingDirId">
+          <el-select
+            v-model="listData.auditingDirId"
+            placeholder="请选择审核学时目录"
+          >
+            <el-option
+              v-for="(item, index) in copyEditableTabs"
+              :key="index"
+              :label="item.dirName"
+              :value="item.dirId"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="是否发布" prop="publishStatus">
+          <el-radio-group v-model="listData.publishStatus">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="课程简介">
+          <el-input type="textarea" v-model="listData.introduction"></el-input>
+        </el-form-item>
+        <el-form-item label="适合对象">
+          <el-input
+            type="textarea"
+            v-model="listData.suitableObject"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <div class="courseStyle">
+        课程详情<span style="color: #999; margin-left: 6px">支持图文</span>
+      </div>
+      <div style="text-align: center; margin-bottom: 10px">
+        <el-button
+          size="mini"
+          :type="active === 1 ? 'success' : ''"
+          @click="active = 1"
+          >PC端</el-button
+        >
+        <el-button
+          size="mini"
+          :type="active === 2 ? 'success' : ''"
+          @click="active = 2"
+          >手机端</el-button
+        >
+      </div>
+      <editor
+        v-show="active === 1"
+        v-model="listData.pcDetailHtml"
+        :min-height="300"
+        :max-height="500"
+        :uploadStatus="uploadStatus"
+      />
+      <editor
+        v-show="active === 2"
+        v-model="listData.mobileDetailHtml"
+        :min-height="300"
+        :max-height="500"
+        :uploadStatus="uploadStatus"
+      />
+      <div style="text-align: center; margin-top: 20px">
+        <el-button @click="backPage" size="mini">取消</el-button>
+        <el-button
+          type="primary"
+          @click="submit('listData')"
+          size="mini"
+          :loading="disabledBtn"
+          :disabled="!noStudent"
+          >确定</el-button
+        >
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Editor from "@/components/Editor";
+
+export default {
+  components: { Editor },
+  props: ["copyEditableTabs"],
+  data() {
+    var validatorCheckUrl = (rule, value, callback) => {
+      if (!value) {
+        return callback(new Error("请上传封面"));
+      } else {
+        callback();
+      }
+    };
+    return {
+      disabledBtn: false,
+      uploadStatus: 2, //富文本组件传值
+      active: 1,
+      //   弹窗数据
+      bfImg: "oss/images/avatar/20211013/1634097664410_1397766697",
+      listData: {
+        coverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
+        educationTypeId: "",
+        businessId: "",
+        schoolId: "",
+        majorId: "",
+        subjectId: "",
+      },
+
+      eduTypeOptions: [], //教育类型数据
+      courTypeOptions: [], //业务层次数据
+      sujectOption: [], //科目数据
+      schoolOption: [], //院校数据
+      majorOption: [], //专业数据
+
+      newCourTypeOptions: [], //当前业务层次数据
+      newSujectOption: [], //当前科目数据数据
+      newSchoolOption: [], //当前院校数据
+      newMajorOption: [], //当前专业数据
+      noStudent: true,
+      //表单验证
+      rules: {
+        educationTypeId: [
+          {
+            required: true,
+            message: "请选择教育类型",
+            trigger: ["blur", "change"],
+          },
+        ],
+        businessId: [
+          {
+            required: true,
+            message: "请选择业务层次",
+            trigger: ["blur", "change"],
+          },
+        ],
+        // schoolId: [
+        //   {
+        //     required: true,
+        //     message: "请选择院校",
+        //     trigger: ["blur", "change"],
+        //   },
+        // ],
+        // majorId: [
+        //   {
+        //     required: true,
+        //     message: "请选择专业",
+        //     trigger: ["blur", "change"],
+        //   },
+        // ],
+        subjectId: [
+          {
+            required: true,
+            message: "请选择科目",
+            trigger: ["blur", "change"],
+          },
+        ],
+        prefixName: [
+          { required: false, message: "请输入名称前缀", trigger: "blur" },
+        ],
+        courseName: [
+          { required: true, message: "请输入课程名称", trigger: "blur" },
+        ],
+        publishStatus: [
+          { required: true, message: "请选择是否发布", trigger: "change" },
+        ],
+        coverUrl: [{ required: true, validator: validatorCheckUrl }],
+      },
+    };
+  },
+  mounted() {
+    this.$modal.loading("正在导入数据,请稍后...");
+    // this.$api
+    //   .gradecheckGoodsChange({ courseId: this.$route.query.id })
+    //   .then((res) => {
+    //     if (res.data > 0) {
+    //       // this.noStudent = false;
+    //     }
+    //   });
+    this.getDict();
+  },
+  methods: {
+    avtives() {
+      if (this.listData.educationTypeId) {
+        for (let i = 0; i < this.eduTypeOptions.length; i++) {
+          if (this.eduTypeOptions[i].id === this.listData.educationTypeId) {
+            return this.eduTypeOptions[i].tireStatus.indexOf("3") != -1;
+          }
+        }
+      }
+    },
+    avtivesMajor() {
+      if (this.listData.educationTypeId) {
+        for (let i = 0; i < this.eduTypeOptions.length; i++) {
+          if (this.eduTypeOptions[i].id === this.listData.educationTypeId) {
+            return this.eduTypeOptions[i].tireStatus.indexOf("4") != -1;
+          }
+        }
+      }
+    },
+    search() {
+      this.$api
+        .obtainCourseS(this.$route.query.id)
+        .then((res) => {
+          this.listData = res.data;
+          this.changeBusiness();
+        })
+        .finally(() => {
+          this.$modal.closeLoading();
+        });
+    },
+    changeBusiness() {
+      var arrays = [];
+      this.courTypeOptions.map((item) => {
+        if (item.educationId === this.listData.educationTypeId) {
+          arrays.push(item);
+        }
+      });
+      this.newCourTypeOptions = arrays;
+      this.courTypeOptions.map((item) => {
+        if (item.id === this.listData.businessId) {
+          var newSujectOption = [];
+          var newSchoolOption = [];
+          var newMajorOption = [];
+          for (let i = 0; i < this.schoolOption.length; i++) {
+            if (
+              this.schoolOption[i].courseArrays.indexOf(item.projectId) !== -1
+            ) {
+              newSchoolOption.push(this.schoolOption[i]);
+            }
+          }
+          if (!newSchoolOption.length) {
+            this.newSchoolOption = this.schoolOption;
+          } else {
+            this.newSchoolOption = newSchoolOption;
+          }
+
+          for (let i = 0; i < this.majorOption.length; i++) {
+            if (
+              this.majorOption[i].courseArrays.indexOf(item.projectId) !== -1
+            ) {
+              newMajorOption.push(this.majorOption[i]);
+            }
+          }
+          if (!newMajorOption.length) {
+            this.newMajorOption = this.majorOption;
+          } else {
+            this.newMajorOption = newMajorOption;
+          }
+
+          for (let i = 0; i < this.sujectOption.length; i++) {
+            if (
+              this.sujectOption[i].courseArrays.indexOf(item.projectId) !== -1
+            ) {
+              newSujectOption.push(this.sujectOption[i]);
+            }
+          }
+          if (!newSujectOption.length) {
+            this.newSujectOption = this.sujectOption;
+          } else {
+            this.newSujectOption = newSujectOption;
+          }
+          // this.$api
+          //   .inquireCourseSubjectlistAll({ projectId: item.projectId })
+          //   .then((res) => {
+          //     this.newSujectOption = res.rows
+          //   });
+          // this.sujectOption.map((items) => {
+          //   if (items.courseArrays.indexOf(item.projectId) !== -1) {
+          //     newSujectOption.push(items);
+          //   }
+          // });
+          // this.schoolOption.map((items) => {
+          //   if (items.courseArrays.indexOf(item.projectId) !== -1) {
+          //     newSchoolOption.push(items);
+          //   }
+          // });
+          // this.majorOption.map((items) => {
+          //   if (items.courseArrays.indexOf(item.projectId) !== -1) {
+          //     newMajorOption.push(items);
+          //   }
+          // });
+          // this.newSujectOption = newSujectOption;
+          // this.newSchoolOption = newSchoolOption;
+          // this.newMajorOption = newMajorOption;
+        }
+      });
+    },
+    async getDict() {
+      await this.EducationType();
+      await this.ProjectType();
+      await this.businessList();
+      await this.CourseSubject();
+      await this.UserSchool();
+      await this.CourseMajor();
+      this.search();
+    },
+    //改变教育类型
+    changeEducationTypeId() {
+      var arrays = [];
+      this.courTypeOptions.map((item) => {
+        if (item.educationId === this.listData.educationTypeId) {
+          arrays.push(item);
+        }
+      });
+      this.newCourTypeOptions = arrays;
+      this.listData.businessId = "";
+    },
+    //改变业务层次触发
+    changeBusinessId() {
+      this.listData.schoolId = "";
+      this.listData.majorId = "";
+      this.listData.subjectId = "";
+      this.courTypeOptions.map((item) => {
+        if (item.id === this.listData.businessId) {
+          this.listData.educationTypeId = item.educationId;
+          var newSujectOption = [];
+          var newSchoolOption = [];
+          var newMajorOption = [];
+          // this.sujectOption.map((items) => {
+          //   if (items.courseArrays.indexOf(item.projectId) !== -1) {
+          //     newSujectOption.push(items);
+          //   }
+          // });
+          // this.schoolOption.map((items) => {
+          //   if (items.courseArrays.indexOf(item.projectId) !== -1) {
+          //     newSchoolOption.push(items);
+          //   }
+          // });
+          // this.majorOption.map((items) => {
+          //   if (items.courseArrays.indexOf(item.projectId) !== -1) {
+          //     newMajorOption.push(items);
+          //   }
+          // });
+          // this.newSujectOption = newSujectOption;
+          // this.newSchoolOption = newSchoolOption;
+          // this.newMajorOption = newMajorOption;
+          for (let i = 0; i < this.schoolOption.length; i++) {
+            if (
+              this.schoolOption[i].courseArrays.indexOf(item.projectId) !== -1
+            ) {
+              newSchoolOption.push(this.schoolOption[i]);
+            }
+          }
+          if (!newSchoolOption.length) {
+            this.newSchoolOption = this.schoolOption;
+          } else {
+            this.newSchoolOption = newSchoolOption;
+          }
+
+          for (let i = 0; i < this.majorOption.length; i++) {
+            if (
+              this.majorOption[i].courseArrays.indexOf(item.projectId) !== -1
+            ) {
+              newMajorOption.push(this.majorOption[i]);
+            }
+          }
+          // if (!newMajorOption.length) {
+          //   this.newMajorOption = this.majorOption;
+          // } else {
+          this.newMajorOption = newMajorOption;
+          // }
+
+          for (let i = 0; i < this.sujectOption.length; i++) {
+            if (
+              this.sujectOption[i].courseArrays.indexOf(item.projectId) !== -1
+            ) {
+              newSujectOption.push(this.sujectOption[i]);
+            }
+          }
+          if (!newSujectOption.length) {
+            this.newSujectOption = [];
+          } else {
+            this.newSujectOption = newSujectOption;
+          }
+        }
+      });
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          // if (
+          //   this.listData.coverUrl === "" ||
+          //   this.listData.coverUrl === null ||
+          //   this.listData.coverUrl === undefined
+          // ) {
+          //   this.$message.error("请上传节封面");
+          //   return false;
+          // }
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    async rulesTableSumbit() {
+      this.disabledBtn = true;
+      this.courTypeOptions.map((item) => {
+        if (item.id === this.listData.businessId) {
+          this.listData.projectId = item.projectId;
+        }
+      });
+      this.listData.status = 1;
+      this.$api
+        .editCourse(this.listData)
+        .then((res) => {
+          this.$message.success("修改成功");
+          setTimeout(() => {
+            this.$store
+              .dispatch("tagsView/exitView", this.$route)
+              .then((res) => {
+                this.$router.push({
+                  path: "course",
+                });
+              });
+          }, 300);
+        })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
+    },
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        this.$router.push({
+          path: "course",
+        });
+      });
+    },
+    getImgFile() {
+      var self = this;
+      var file = self.$refs.file.files[0];
+      if (file === undefined) {
+        self.$set(self.listData, "coverUrl", "");
+        return;
+      }
+      if (file.size > 0.3 * 1024 * 1024) {
+        self.$message.error("图片不得大于300kb");
+        return;
+      }
+      var type = self.$refs.file.value.toLowerCase().split(".").splice(-1);
+      if (
+        type[0] != "jpg" &&
+        type[0] != "png" &&
+        type[0] != "jpeg" &&
+        type[0] != "gif"
+      ) {
+        self.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
+        self.$refs.file.value = "";
+        return;
+      }
+      this.$upload.upload(file, 0).then((res) => {
+        self.listData.coverUrl = res;
+      });
+    },
+    clearImgs() {
+      this.listData.coverUrl = "";
+      this.$refs.listData.validateField("coverUrl");
+    },
+    EducationType() {
+      return new Promise((resolve, reject) => {
+        this.$api.inquireCourseEducationType({ status: 1 }).then((res) => {
+          this.eduTypeOptions = res.rows;
+          resolve();
+        });
+      });
+    },
+    ProjectType() {
+      return new Promise((resolve, reject) => {
+        this.$api.inquireCourseProjectType({ status: 1 }).then((res) => {
+          this.projectTypeOptions = res.rows;
+          resolve();
+        });
+      });
+    },
+    businessList() {
+      return new Promise((resolve, reject) => {
+        this.$api.inquirebusinessList({ status: 1 }).then((res) => {
+          this.courTypeOptions = res.rows;
+          this.newCourTypeOptions = res.rows;
+          resolve();
+        });
+      });
+    },
+    CourseSubject() {
+      return new Promise((resolve, reject) => {
+        this.$api.inquireCourseSubject({ status: 1 }).then((res) => {
+          res.rows.map((item, index) => {
+            var array = [];
+            item.courseProjectTypes.map((items, indexs) => {
+              array.push(items.id);
+            });
+            item.courseArrays = array;
+          });
+          this.sujectOption = res.rows;
+          resolve();
+        });
+      });
+    },
+    UserSchool() {
+      return new Promise((resolve, reject) => {
+        this.$api.inquireUserSchool({ status: 1 }).then((res) => {
+          res.rows.map((item, index) => {
+            var array = [];
+            item.courseProjectTypes.map((items, indexs) => {
+              array.push(items.id);
+            });
+            item.courseArrays = array;
+          });
+          this.schoolOption = res.rows;
+          resolve();
+        });
+      });
+    },
+    CourseMajor() {
+      return new Promise((resolve, reject) => {
+        this.$api.inquireCourseMajor({ status: 1 }).then((res) => {
+          res.rows.map((item, index) => {
+            var array = [];
+            item.courseProjectTypeVo.map((items, indexs) => {
+              array.push(items.id);
+            });
+            item.courseArrays = array;
+          });
+          this.majorOption = res.rows;
+          resolve();
+        });
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.courseStyle {
+  margin: 20px;
+  margin-bottom: 10px;
+  font-size: 14px;
+  border-bottom: 2px solid skyblue;
+}
+.boxWidth {
+  min-width: 800px;
+}
+.numInputs {
+  width: 150px;
+}
+.checkboxSty {
+  max-height: 210px;
+  overflow: auto;
+  display: flex;
+  flex-direction: column;
+}
+.listBoxStys {
+  flex-shrink: 0;
+  padding: 0px 10px;
+  border-radius: 8px;
+  border: 1px solid #eee;
+  margin-right: 10px;
+  margin-bottom: 6px;
+}
+.closeIcons {
+  color: red;
+  cursor: pointer;
+  margin-left: 6px;
+}
+.ach {
+  display: flex;
+  align-items: center;
+  overflow: hidden;
+}
+.clh {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+}
+.imgBoxins {
+  width: 375px;
+  height: 220px;
+  text-align: center;
+  img {
+    height: 100%;
+  }
+}
+.iconStsz {
+  font-size: 40px;
+  color: #67c23a;
+  cursor: pointer;
+}
+.dis_plays {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
+.comInputsty {
+  width: 50px;
+  height: 24px;
+  text-align: center;
+  border: none;
+}
+</style>

+ 879 - 0
src/views/resource/videoManagement/course/tableContents/courseLi.vue

@@ -0,0 +1,879 @@
+<template>
+  <div>
+    <ul class="fatherSty">
+      <li class="floatLefts" v-for="(item, index) in headerData" :key="index">
+        {{ item.label }}:
+        <span v-if="item.scope === 'more'">{{
+          pageInfo[item.prop1] + "-" + pageInfo[item.prop2]
+        }}</span>
+        <el-select
+          @change="changeFunc"
+          v-else-if="item.scope === 'selectTeacher'"
+          v-model="items.teacherId"
+          size="mini"
+          style="width: 140px"
+        >
+          <el-option
+            v-for="item in teachList"
+            :key="item.teacherId"
+            :label="item.teacherName"
+            :value="item.teacherId"
+          >
+          </el-option>
+        </el-select>
+        <span v-else>{{ pageInfo[item.prop] }}</span>
+      </li>
+    </ul>
+    <!-- 目录start -->
+    <div>
+      <el-button :size="size" type="success" @click="openAddTable"
+        >添加 目录/课程</el-button
+      >
+      <el-button :size="size" type="primary">Excel批量新增</el-button>
+      <el-button :size="size" type="primary" style="float: right"
+        >排序</el-button
+      >
+    </div>
+    <div class="treeBox">
+      <el-tree
+        :props="props"
+        :load="loadNode"
+        lazy
+        node-key="id"
+        ref="asyncTree"
+      >
+        <span class="custom-tree-node" slot-scope="{ node, data }">
+          <span
+            ><span
+              v-if="data.nodeType === 1 || data.nodeType === 2"
+              :style="
+                data.nodeType === 1
+                  ? 'color:#409EFF;'
+                  : data.nodeType === 2
+                  ? 'color:#67C23A'
+                  : ''
+              "
+              >{{
+                data.nodeType === 1
+                  ? "[目录]"
+                  : data.nodeType === 2
+                  ? data.sectionType === 1
+                    ? "[录播]"
+                    : data.sectionType === 2
+                    ? "[直播]"
+                    : data.sectionType === 3
+                    ? "[回放]"
+                    : "[未知]"
+                  : ""
+              }}</span
+            >
+            {{ node.label }}</span
+          >
+          <span>
+            <el-button v-if="false" type="text" size="mini" @click.stop="append(data, node)">
+              关联试卷
+            </el-button>
+            <el-button
+              type="text"
+              size="mini"
+              @click.stop="addDir(data)"
+              v-if="node.level < 3 && data.nodeType === 1"
+            >
+              添加子目录
+            </el-button>
+            <el-button
+              v-if="data.nodeType === 1"
+              type="text"
+              size="mini"
+              @click.stop="addCourse(data)"
+            >
+              添加课程
+            </el-button>
+            <el-button
+              v-if="data.nodeType === 2"
+              type="text"
+              size="mini"
+              @click.stop="append(data)"
+            >
+              预览
+            </el-button>
+            <el-button
+              type="text"
+              size="mini"
+              @click.stop="editTreeChild(data)"
+            >
+              编辑
+            </el-button>
+            <el-button type="text" size="mini" @click.stop="delTreeChild(data)">
+              删除
+            </el-button>
+          </span>
+        </span>
+      </el-tree>
+    </div>
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisible"
+      width="760px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">添加课程</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogVisible = false"
+          />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="110px"
+          :model="listData"
+          ref="listData"
+          :rules="rules"
+        >
+          <el-form-item label="选择类型" prop="nodeType"
+            ><el-radio-group
+              v-model="listData.nodeType"
+              :size="size"
+              @change="clearValid"
+              :disabled="listData.nodeDis"
+            >
+              <el-radio :label="1">目录</el-radio>
+              <el-radio :label="2">课程</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <template v-if="listData.nodeType === 1">
+            <el-form-item label="目录名称" prop="nodeName">
+              <el-input
+                v-model="listData.nodeName"
+                :size="size"
+                placeholder="请输入目录名称"
+              ></el-input>
+            </el-form-item>
+            <el-form-item label="排序" prop="sort">
+              <el-input-number
+                :precision="0"
+                :controls="false"
+                v-model="listData.sort"
+                :min="0"
+                label="排序"
+                :size="size"
+              ></el-input-number>
+            </el-form-item>
+          </template>
+          <template v-if="listData.nodeType === 2">
+            <el-form-item label="课程类型" prop="sectionType">
+              <el-select
+                v-model="listData.sectionType"
+                placeholder="请选择课程类型"
+                @change="clearValid"
+              >
+                <el-option label="录播" :value="1"> </el-option
+                ><el-option label="直播" :value="2"> </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="标题前缀" prop="prefixName">
+              <el-input v-model="listData.prefixName"></el-input>
+            </el-form-item>
+            <el-form-item label="课程名称" prop="name">
+              <el-input v-model="listData.name"></el-input>
+            </el-form-item>
+            <!-- 录播区别start -->
+            <template v-if="listData.sectionType === 1">
+              <el-form-item label="地址URL" prop="recordingUrl">
+                <el-input v-model="listData.recordingUrl"></el-input>
+              </el-form-item>
+              <el-form-item label="视频时长" prop="durationTime">
+                <el-time-picker
+                  value-format="HH:mm:ss"
+                  range-separator=":"
+                  v-model="listData.durationTime"
+                >
+                </el-time-picker>
+              </el-form-item>
+            </template>
+            <!-- 录播区别end -->
+            <!-- 直播区别start -->
+            <template v-if="listData.sectionType === 2">
+              <el-form-item label="频道号" prop="liveUrl">
+                <el-input v-model="listData.liveUrl"></el-input>
+              </el-form-item>
+              <el-form-item label="直播开始时间" prop="liveStartTime"
+                ><el-date-picker
+                  v-model="listData.liveStartTime"
+                  type="datetime"
+                  placeholder="请选择直播开始时间"
+                  value-format="timestamp"
+                  @change="checkTime"
+                >
+                </el-date-picker>
+              </el-form-item>
+              <el-form-item label="直播结束时间" prop="liveEndTime"
+                ><el-date-picker
+                  v-model="listData.liveEndTime"
+                  type="datetime"
+                  placeholder="请选择直播结束时间"
+                  value-format="timestamp"
+                  @change="checkTime"
+                >
+                </el-date-picker>
+              </el-form-item>
+            </template>
+            <!-- 直播区别end -->
+            <el-form-item label="讲师" prop="teacherId">
+              <el-select v-model="listData.teacherId" placeholder="请选择讲师">
+                <el-option
+                  v-for="(item, index) in teachList"
+                  :key="index"
+                  :label="item.teacherName"
+                  :value="item.teacherId"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="排序" prop="sort">
+              <el-input-number
+                :precision="0"
+                :controls="false"
+                v-model="listData.sort"
+                :min="0"
+                label="排序"
+                :size="size"
+              ></el-input-number>
+            </el-form-item>
+            <el-form-item label="封面" prop="coverUrl">
+              <el-row :gutter="10" style="margin-bottom: 10px">
+                <el-col :span="12">
+                  <div
+                    style="
+                      width: 100%;
+                      height: 150px;
+                      border: 2px dashed #999;
+                      border-radius: 28px;
+                      line-height: 150px;
+                      text-align: center;
+                    "
+                    v-if="!listData.coverUrl"
+                  >
+                    <label for="uplose">
+                      <i class="el-icon-circle-plus-outline iconStsz"></i
+                    ></label>
+                    <input
+                      ref="file"
+                      type="file"
+                      style="display: none"
+                      id="uplose"
+                      @change="getImgFile"
+                    />
+                  </div>
+                  <el-image
+                    v-else
+                    style="width: 100%"
+                    :src="$methodsTools.splitImgHost(listData.coverUrl)"
+                    :preview-src-list="[
+                      $methodsTools.splitImgHost(listData.coverUrl),
+                    ]"
+                  >
+                  </el-image>
+                </el-col>
+                <el-col :span="11">
+                  <span style="color: #999; font-size: 14px"
+                    >注:请上传小于300kb,尺寸为750*440的图片,支持gif、jpg、jpeg、png等类型</span
+                  >
+                  <el-button
+                    v-if="listData.coverUrl"
+                    type="danger"
+                    size="mini"
+                    class="margin-top: 20px;"
+                    @click="clearImgs"
+                    >删除</el-button
+                  >
+                </el-col>
+              </el-row>
+            </el-form-item>
+            <el-form-item label="是否发布" prop="publishStatus">
+              <el-radio-group v-model="listData.publishStatus">
+                <el-radio :label="1">是</el-radio>
+                <el-radio :label="0">否</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </template>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button
+          type="primary"
+          :loading="disabledBtn"
+          @click="submit('listData')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+export default {
+  props: ["items"],
+  data() {
+    var validatorCheckUrl = (rule, value, callback) => {
+      if (!value) {
+        return callback(new Error("请上传封面"));
+      } else {
+        callback();
+      }
+    };
+    var validatorCheckStartTime = (rule, value, callback) => {
+      if (!value) {
+        return callback(new Error("请选择直播开始时间"));
+      } else if (value > this.listData.liveEndTime) {
+        return callback(new Error("直播开始时间不能大于直播结束时间"));
+      } else {
+        callback();
+      }
+    };
+    var validatorCheckEndTime = (rule, value, callback) => {
+      if (!value) {
+        return callback(new Error("请选择直播结束时间"));
+      } else if (value < this.listData.liveStartTime) {
+        return callback(new Error("直播结束时间不能小于直播开始时间"));
+      } else {
+        callback();
+      }
+    };
+    return {
+      size: "small",
+      pageInfo: {}, //课程基础参数
+      props: {
+        label: "nodeName",
+        children: "children",
+      },
+      headerData: [
+        {
+          label: "课程名称",
+          prop: "courseName",
+        },
+        {
+          label: "业务层次",
+          prop1: "projectName",
+          prop2: "businessName",
+          scope: "more",
+        },
+        {
+          label: "所属院校",
+          prop: "schoolName",
+        },
+        {
+          label: "所属专业",
+          prop: "categoryName",
+        },
+        {
+          label: "科目",
+          prop: "subjectName",
+        },
+        {
+          label: "授课老师",
+          prop: "teacherId",
+          scope: "selectTeacher",
+        },
+      ],
+      dialogVisible: false,
+      disabledBtn: false,
+      listitem: [
+        {
+          label: "选择类型",
+          scope: "radio",
+          prop: "nodeType",
+          options: [
+            {
+              label: "目录",
+              value: 1,
+            },
+            {
+              label: "课程",
+              value: 2,
+            },
+          ],
+        },
+      ],
+      listData: {
+        coverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
+        publishStatus: 1,
+        sort: 0,
+      },
+      //表单验证
+      rules: {
+        nodeType: [
+          { required: true, message: "请选择类型", trigger: "change" },
+        ],
+        nodeName: [
+          { required: true, message: "请输入目录名称", trigger: "blur" },
+        ],
+        sort: [{ required: true, message: "请输入排序", trigger: "blur" }],
+        sectionType: [
+          { required: true, message: "请选择课程类型", trigger: "change" },
+        ],
+        prefixName: [
+          { required: false, message: "请输入标题前缀", trigger: "blur" },
+        ],
+        name: [{ required: true, message: "请输入课程标题", trigger: "blur" }],
+        recordingUrl: [
+          {
+            required: true,
+            message: "请输入URL地址",
+            trigger: ["blur", "change"],
+          },
+        ],
+        durationTime: [
+          {
+            required: true,
+            message: "请选择视频时长",
+            trigger: "change",
+          },
+        ],
+        liveUrl: [
+          {
+            required: true,
+            message: "请输入频道号",
+            trigger: ["blur", "change"],
+          },
+        ],
+        liveStartTime: [
+          {
+            required: true,
+            validator: validatorCheckStartTime,
+          },
+        ],
+        liveEndTime: [
+          {
+            required: true,
+            validator: validatorCheckEndTime,
+          },
+        ],
+        teacherId: [
+          { required: false, message: "请选择讲师", trigger: "change" },
+        ],
+        coverUrl: [{ required: true, validator: validatorCheckUrl }],
+        publishStatus: [
+          { required: true, message: "请选择是否发布", trigger: "change" },
+        ],
+      },
+      node_had: null, //node实例
+    };
+  },
+  computed: { ...mapGetters(["teachList"]) },
+  mounted() {
+    this.$api.obtainCourseS(this.items.courseId).then((res) => {
+      this.pageInfo = res.data;
+    });
+  },
+  methods: {
+    //添加子目录
+    addDir(data) {
+      this.listData = {
+        nodeType: 1,
+        pid: data.id,
+        nodeDis: true,
+        coverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
+        publishStatus: 1,
+        sort: 0,
+      };
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.listData.clearValidate();
+      });
+    },
+    //添加课程
+    addCourse(data) {
+      this.listData = {
+        nodeType: 2,
+        pid: data.id,
+        nodeDis: true,
+        coverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
+        publishStatus: 1,
+        sort: 0,
+      };
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.listData.clearValidate();
+      });
+    },
+    /* 局部重新加载 */
+    reloadFn(id) {
+      if (id) {
+        const node = this.$refs.asyncTree.getNode(id);
+        if (node) {
+          node.loaded = false;
+          node.expand();
+        }
+      } else {
+        this.node_had.loaded = false;
+        this.node_had.expand();
+      }
+    },
+    //懒加载树形
+    loadNode(node, resolve) {
+      if (node.data && node.data.id) {
+        this.getData(node.data.id, resolve);
+      } else if (node.level === 0) {
+        this.node_had = node;
+        this.getData(0, resolve);
+      }
+    },
+    getData(id, resolve) {
+      this.$api
+        .inquireSystemDir({ dirId: this.items.dirId, pid: id })
+        .then((res) => {
+          return resolve(res.data);
+        });
+    },
+    append(data, node) {
+      console.log(data, node);
+    },
+    editTreeChild(data) {
+      if (data.nodeType === 1) {
+        this.listData = JSON.parse(JSON.stringify(data));
+        this.listData.nodeDis = true;
+      }
+      if (data.nodeType === 2) {
+        this.$api.obtainCourseSection(data.sectionId).then((res) => {
+          if (res.data.sectionType === 1 || res.data.sectionType === 3) {
+            if (res.data.durationTime) {
+              res.data.durationTime = this.$methodsTools.secondToDate(
+                res.data.durationTime,
+                false
+              );
+            }
+          }
+          if (res.data.sectionType === 2) {
+            if (res.data.liveStartTime) {
+              res.data.liveStartTime = res.data.liveStartTime * 1000;
+            }
+            if (res.data.liveEndTime) {
+              res.data.liveEndTime = res.data.liveEndTime * 1000;
+            }
+          }
+          delete res.data.sort;
+          var ary = Object.assign(data, res.data);
+          ary.nodeDis = true;
+          for (let k in ary) {
+            this.$set(this.listData, k, ary[k]);
+          }
+        });
+      }
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.listData.clearValidate();
+      });
+    },
+    //删除tree节点
+    delTreeChild(data) {
+      this.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          let ary = JSON.parse(JSON.stringify(data));
+          ary.status = -1;
+          this.$api.editSystemDir(ary).then((res) => {
+            this.reloadFn(data.pid);
+            this.$message({
+              type: "success",
+              message: "删除成功!",
+            });
+          });
+        })
+        .catch(() => {});
+    },
+    //审核学习
+    changeFunc() {
+      this.$api.editNodeDir(this.items).then((res) => {
+        this.$message.success("修改成功");
+      });
+    },
+    //打开添加目录/课程窗口
+    openAddTable() {
+      this.listData = {
+        coverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
+        publishStatus: 1,
+        sort: 0,
+      };
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.listData.clearValidate();
+      });
+    },
+    //窗口关闭逻辑
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    //切换类型逻辑
+    clearValid() {
+      this.$refs.listData.clearValidate();
+    },
+    //提交校验
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.submitForm();
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    //提交逻辑
+    submitForm() {
+      this.disabledBtn = true;
+      let data = JSON.parse(JSON.stringify(this.listData));
+      if (data.nodeType === 1) {
+        //目录结构
+        this.dirDataFunc(data);
+      } else if (data.nodeType === 2) {
+        //节结构
+        this.sectionDataFunc(data);
+      } else {
+        this.disabledBtn = false;
+      }
+    },
+    //目录结构生成
+    dirDataFunc(data) {
+      let info = {
+        dirId: this.items.dirId,
+        nodeName: data.nodeName,
+        nodeType: 1,
+        pid: data.pid || 0,
+        status: 1,
+        sort: data.sort,
+      };
+      if (data.id) {
+        info.id = data.id;
+        this.$api
+          .editSystemDir(info)
+          .then((res) => {
+            this.dialogVisible = false;
+            this.$message.success("修改目录成功");
+            this.reloadFn(info.pid);
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      } else {
+        this.$api
+          .appSystemDir(info)
+          .then((res) => {
+            this.dialogVisible = false;
+            this.$message.success("添加目录成功");
+            this.reloadFn(info.pid);
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      }
+    },
+    //节目录结构生成
+    async sectionDataFunc(data) {
+      //共有信息
+      let info = {
+        businessList: [
+          {
+            educationTypeId: this.pageInfo.educationTypeId,
+            educationName: this.pageInfo.educationName,
+            projectId: this.pageInfo.projectId,
+            projectName: this.pageInfo.projectName,
+            businessId: this.pageInfo.businessId,
+            businessName: this.pageInfo.businessName,
+            subjectId: this.pageInfo.subjectId,
+            subjectName: this.pageInfo.subjectName,
+          },
+        ],
+        sectionType: data.sectionType,
+        prefixName: data.prefixName,
+        name: data.name,
+        teacherId: data.teacherId,
+        coverUrl: data.coverUrl,
+        publishStatus: data.publishStatus,
+        status: 1,
+      };
+      //录播信息
+      if (data.sectionType === 1) {
+        info.recordingUrl = data.recordingUrl;
+        info.durationTime = this.$methodsTools.secondFormDate(
+          data.durationTime
+        );
+      }
+      //直播信息
+      if (data.sectionType === 2) {
+        info.liveUrl = data.liveUrl;
+        info.liveStartTime = parseInt(data.liveStartTime / 1000);
+        info.liveEndTime = parseInt(data.liveEndTime / 1000);
+      }
+      if (data.sectionId) {
+        info.sectionId = data.sectionId;
+        /**
+         * 修改节 - 返回节Id
+         */
+        await this.editSection(info);
+        let sectionData = {
+          dirId: data.dirId,
+          id: data.id,
+          nodeType: 2,
+          pid: data.pid,
+          sectionId: data.sectionId,
+          status: 1,
+          sort: data.sort,
+        };
+        this.$api
+          .editSystemDir(sectionData)
+          .then((res) => {
+            this.dialogVisible = false;
+            this.$message.success("修改成功");
+            this.reloadFn(data.pid);
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      } else {
+        /**
+         * 新增节 - 返回节Id
+         */
+        const sectionId = await this.addSection(info);
+        let sectionData = {
+          dirId: this.items.dirId,
+          nodeType: 2,
+          pid: data.pid,
+          sectionId: sectionId,
+          status: 1,
+          sort: data.sort,
+        };
+        this.$api
+          .appSystemDir(sectionData)
+          .then((res) => {
+            this.dialogVisible = false;
+            this.$message.success("添加成功");
+            this.reloadFn(data.pid);
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      }
+    },
+    //新增节
+    addSection(data) {
+      return new Promise((resolve, reject) => {
+        this.$api
+          .appCourseSection(data)
+          .then((res) => {
+            resolve(res.data);
+          })
+          .catch((err) => {
+            this.disabledBtn = false;
+            reject();
+          });
+      });
+    },
+    //修改节
+    editSection(data) {
+      return new Promise((resolve, reject) => {
+        this.$api
+          .editCourseSection(data)
+          .then((res) => {
+            resolve();
+          })
+          .catch((err) => {
+            this.disabledBtn = false;
+            reject();
+          });
+      });
+    },
+    //切换时间校验
+    checkTime() {
+      if (this.listData.liveStartTime) {
+        this.$refs.listData.validateField("liveStartTime");
+      }
+      if (this.listData.liveEndTime) {
+        this.$refs.listData.validateField("liveEndTime");
+      }
+    },
+    //删除照片逻辑
+    clearImgs() {
+      this.listData.coverUrl = "";
+      this.$refs.listData.validateField("coverUrl");
+    },
+    //上传封面逻辑
+    getImgFile() {
+      var self = this;
+      var file = self.$refs.file.files[0];
+      if (file === undefined) {
+        self.$set(self.listData, "coverUrl", "");
+        return;
+      }
+      if (file.size > 0.3 * 1024 * 1024) {
+        self.$message.error("图片不得大于300kb");
+        return;
+      }
+      var type = self.$refs.file.value.toLowerCase().split(".").splice(-1);
+      if (
+        type[0] != "jpg" &&
+        type[0] != "png" &&
+        type[0] != "jpeg" &&
+        type[0] != "gif"
+      ) {
+        self.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
+        self.$refs.file.value = "";
+        return;
+      }
+      this.$upload.upload(file, 0).then((res) => {
+        self.listData.coverUrl = res;
+        self.$refs.listData.validateField("coverUrl");
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.treeBox {
+  border: 1px solid #d6d6d6;
+  // border-bottom: none;
+  margin-top: 14px;
+}
+/deep/.el-tree-node__content {
+  height: 40px;
+  border-bottom: 1px solid #d6d6d6;
+}
+.fatherSty {
+  display: flex;
+  align-items: center;
+  background-color: #eee;
+  padding: 10px;
+  margin-bottom: 15px;
+}
+.floatLefts {
+  height: 28px;
+  line-height: 28px;
+  font-size: 14px;
+  flex-wrap: wrap;
+  margin-right: 30px;
+}
+.iconStsz {
+  font-size: 40px;
+  color: #67c23a;
+  cursor: pointer;
+}
+.custom-tree-node {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 14px;
+  padding-right: 8px;
+}
+</style>

+ 281 - 0
src/views/resource/videoManagement/course/tableContents/index.vue

@@ -0,0 +1,281 @@
+<template>
+  <div id="tableContents">
+    <el-tabs v-model="editableTabsValue" type="card" editable @edit="editTabs">
+      <el-tab-pane
+        v-for="(item, index) in editableTabs"
+        :key="index"
+        :label="item.dirName"
+        :name="item.dirId"
+        lazy
+      >
+        <base-page v-if="item.basePage" :copyEditableTabs="copyEditableTabs" />
+        <course-li v-else :items="item" />
+      </el-tab-pane>
+    </el-tabs>
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisible"
+      width="560px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">添加课程</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogVisible = false"
+          />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="110px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item
+            v-for="(items, indexs) in listitem"
+            :key="indexs"
+            :label="items.label"
+            :prop="items.prop"
+          >
+            <el-input
+              :placeholder="items.placeholder"
+              v-model="listData[items.prop]"
+            ></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button
+          type="primary"
+          :loading="disabledBtn"
+          @click="submit('listData')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import basePage from "./basePage.vue";
+import courseLi from "./courseLi.vue";
+export default {
+  name:"TableContents",
+  components: { basePage, courseLi },
+  data() {
+    return {
+      editableTabsValue: "-1",
+      editableTabs: [],
+      copyEditableTabs: [],
+      id: null,
+      dialogVisible: false,
+      disabledBtn: false, //节流
+      listitem: [
+        {
+          label: "课程名称:",
+          placeholder: "请输入课程名称",
+          prop: "dirName",
+        },
+      ],
+      listData: {
+        dirName: "",
+      },
+      rules: {
+        dirName: [
+          { required: true, message: "请输入课程名称", trigger: "blur" },
+        ],
+      },
+    };
+  },
+  created() {
+    this.id = this.$route.query.id;
+    this.getCourseLi();
+  },
+  methods: {
+    //获取初始tabs
+    getCourseLi() {
+      this.$api
+        .inquireNodeDir({
+          courseId: this.id,
+        })
+        .then((res) => {
+          var ay = {
+            dirId: "-1",
+            courseId: this.id,
+            dirName: "课程基本信息",
+            basePage: true,
+          };
+          this.copyEditableTabs = JSON.parse(JSON.stringify(res.rows));
+          res.rows.unshift(ay);
+          res.rows.forEach((item) => {
+            item.dirId = item.dirId + "";
+          });
+          this.editableTabs = res.rows;
+        });
+    },
+    //操作课程新增or删除
+    editTabs(id, action) {
+      if (action === "add") {
+        this.dialogVisible = true;
+      }
+      if (action === "remove") {
+        if (id === "-1") {
+          this.$message.error("不允许删除基本信息");
+          return;
+        }
+        this.$confirm("此操作将永久删除该课程, 是否继续?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        })
+          .then(() => {
+            this.$api
+              .editNodeDir({ dirId: id, status: -1 })
+              .then((res) => {
+                let tabs = this.editableTabs;
+                let activeName = this.editableTabsValue;
+                if (activeName === id) {
+                  tabs.forEach((tab, index) => {
+                    if (tab.dirId === id) {
+                      let nextTab = tabs[index + 1] || tabs[index - 1];
+                      if (nextTab) {
+                        activeName = nextTab.dirId;
+                      }
+                    }
+                  });
+                }
+                this.editableTabsValue = activeName;
+                this.editableTabs = tabs.filter((tab) => tab.dirId !== id);
+                this.$message.success("删除成功");
+              })
+          })
+          .catch(() => {});
+      }
+    },
+    //新增课程
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.$api
+            .appNodeDir({ courseId: this.id, dirName: this.listData.dirName })
+            .then((res) => {
+              res.data.dirId = res.data.dirId + "";
+              this.editableTabs.push(res.data);
+              this.editableTabsValue = res.data.dirId;
+              this.dialogVisible = false;
+            });
+        } else {
+          return false;
+        }
+      });
+    },
+    loadingClose() {
+      this.$refs["listData"].resetFields();
+      this.disabledBtn = false;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__body {
+    max-height: 75vh;
+    overflow: auto;
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>