|
@@ -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>
|