Files
learning-system-portal/src/components/Course/courseForm.vue
2025-11-14 10:32:42 +08:00

2095 lines
76 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div>
<el-dialog title="选择课程类型" :visible.sync="courseChooseShow" :close-on-click-modal="false" width="700px" custom-class="g-dialog" >
<div style="padding: 10px 20px;">
<el-form label-width="120px" label-position="left" >
<el-form-item label="课程名称" required><el-input maxlength="90" v-model="courseInfo.name" show-word-limit placeholder="课程名称(限90字以内)"></el-input></el-form-item>
<el-form-item label="是否设置目录" required>
<div>
<el-radio v-model="courseInfo.type" :label="20"></el-radio>
<el-radio v-model="courseInfo.type" :label="10"></el-radio>
</div>
</el-form-item>
<!-- <div style="margin-top:40px">适合您<span style="color:#e83d3a;font-size: 16px;">快速</span>分享<span style="color:#e83d3a;font-size: 16px;">单一</span>的视频音频或者文档制作说明</div> -->
<!-- <div v-show="courseExample == 1">适合您<span class="tip">快速</span>分享<span class="tip">单一</span>的视频音频或者文档制作说明</div>
<div v-show="courseExample == 2">适合您分享<span class="tip">体系化</span>、<span class="tip">结构化</span>的课程内容制作说明</div>
-->
</el-form>
</div>
<!-- <div style="height:100px"></div> -->
<div style="text-align: center;height: 80px;padding-top:30px">
<span slot="footer" class="dialog-footer">
<el-button @click="courseChooseShow = false"> </el-button>
<el-button @click="toInputCourse()" type="primary">确定</el-button>
</span>
<!-- style="height: 200px;" -->
<!-- 微课示意图 -->
<!-- <div v-if="courseExample == 1">
<div class="example"><el-image style="width: 100%; height: 100% ; vertical-align: top; " fit="contain" :src="`${webBaseUrl}/images/weiSketch.svg`"></el-image></div>
</div> -->
<!-- 录播课示意图 -->
<!-- <div v-if="courseExample == 2">
<div class="example">
<el-image style="width: 100%; height: 100%" fit="contain" :src="`${webBaseUrl}/images/luSketch.svg`"></el-image>
</div>
</div> -->
</div>
<!-- <span slot="footer" class="dialog-footer">
<el-button @click="courseChooseShow = false"> </el-button>
<el-button @click="toInputCourse()" type="primary">确定</el-button>
</span> -->
</el-dialog>
<!-- 蒙层引导组件 -->
<div v-if="showGuidance" class="guidance-overlay" @click="closeGuidance">
<div class="guidance-content">
<div class="guidance-title"></div> <!--新功能引导-->
<div class="guidance-steps">
<div class="guidance-step" :class="{ active: currentStep === 1 }">
<div class="step-number"></div>
<div class="step-content">
<div class="step-title">用标签为课程精准定位吸引更多学员可从以下维度构思</div>
<div class="step-desc" style="padding-left: 20px;"> 讲领域品质管理</div>
<div class="step-desc" style="padding-left: 20px;"> 教技能沟通技巧</div>
<div class="step-desc" style="padding-left: 20px;"> 涉内容5W1H分析法</div>
</div>
</div>
<!-- <div class="guidance-step" :class="{ active: currentStep === 2 }">
<div class="step-number">2</div>
<div class="step-content">
<div class="step-title">添加课程标签</div>
<div class="step-desc">为课程添加相关标签,最多5个便于搜索和分类,可回车创建新标签</div>
</div>
</div>-->
</div>
<!-- <div class="guidance-actions">
<el-button @click="previousStep1" v-if="currentStep > 1">上一步</el-button>
<el-button type="primary" @click="nextStep">
{{ currentStep === 2 ? '完成' : '下一步' }}
</el-button>
<el-button @click="closeGuidance">跳过引导</el-button>
</div>-->
</div>
</div>
<!-- 高亮指引元素 -->
<!-- <div v-if="showGuidance" class="highlight-element" :style="highlightStyle"></div>-->
<!--微课-->
<el-dialog v-if="weike.dlgShow" width="980px" :title="curCourseId == '' ? '新建课程' : '编辑课程'" :visible.sync="weike.dlgShow" :close-on-click-modal="false" custom-class="g-dialog" top="8vh">
<el-form label-width="100px" size="small" class="wei-from" style="min-height: 600px;">
<el-row :gutter="10">
<el-col :span="10">
<div style="height: 30px; border-bottom: 1px solid #f3f3f3;margin-bottom: 10px;">
<span>基本信息</span>
<span style="padding-left: 50px;"><el-checkbox v-model="weike.onlyRequired">只显示必填项</el-checkbox></span>
<span style="float: right;"><el-button size="small" :loading="btnLoading" type="primary" @click="saveAndNext(1)">保存基本信息</el-button></span>
</div>
<el-form-item label="名称" required><el-input maxlength="90" v-model="courseInfo.name" show-word-limit placeholder="课程名称(限90字以内)"></el-input></el-form-item>
<el-form-item label="封面图片" v-show="!weike.onlyRequired">
<!-- 上传封面图-->
<div style="display:flex">
<div @click.stop="chooseFile">
<!-- <image :src="courseCoverurl" style="width:160px;height:90px" width="160px" height="90px"></image> -->
<imageUpload :disabled="true" :value="courseCoverurl" width="160px" height="90px" @success="uploadCoverImgSuccess" @remove="removeCoverImgSuccess"></imageUpload>
</div>
<span style="margin-left:10px;font-size: 12px;">
高宽比为16:9 (:800 * 450)的png或jpg图片不要大于2M
</span>
</div>
</el-form-item>
<el-form-item label="内容分类" required >
<el-cascader
placeholder="选择内容分类"
style="width: 100%;"
clearable
v-model="sysTypeList"
:props="{ value: 'id', label: 'name' }"
:options="sysTypeListMap"
@focus="onContentTypeFocus"
@change="onContentTypeChange">
</el-cascader>
</el-form-item>
<el-form-item label="标签" required class="guidance-highlight" data-step="1" style="display: flex" >
<courseTag ref="courseTag" :courseId="curCourseId" :sysTypeList="sysTypeList"
:initialTags="courseTags" @change="handleTagsChange"
@focus="onTagFocus" style="width: 95%;">
</courseTag>
<el-tooltip content="点击查看标签新功能引导" placement="top">
<i class="el-icon-question" style="color: #409EFF; cursor: pointer;" @click="handleTagHelp"></i>
</el-tooltip>
</el-form-item>
<el-form-item label="资源归属" required>
<el-input placeholder="请选择" v-model="orgName" >
<el-button v-if="identity==3 || identity==5" @click="showChooseOrg()" slot="append" icon="el-icon-search">选择</el-button>
</el-input>
</el-form-item>
<el-form-item label="场景" v-show="!weike.onlyRequired">
<el-col :span="18">
<el-select v-model="courseInfo.forScene" style="width: 100%;" clearable>
<el-option v-for="item in sceneList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
<el-col :span="6"><el-checkbox v-model="courseInfo.openCourse" :true-label="1" :false-label="0">公开课</el-checkbox></el-col>
</el-form-item>
<el-form-item label="授课教师" required>
<!--授课老师默认是当前操作人-->
<!-- <el-select
style="width: 100%;"
v-model="teacherValues"
multiple
filterable
remote
value-key="teacherId"
ref="elSelect"
reserve-keyword
placeholder="请输入授课教师姓名"
@change="changeTeachers"
:remote-method="remoteFindTeacher"
:loading="loading">
<el-option v-for="item in teacherDownList" :key="item.teacherId" :label="item.teacherName + item.teacherCode" :value="item"></el-option>
</el-select> -->
<choice :teacherValue="teacherValues" @getTeacherList="getTeacherList"></choice>
</el-form-item>
<el-form-item label="目标人群" required>
<el-input maxlength="50" v-model="courseInfo.forUsers" show-word-limit placeholder="目标人群(限50字以内)"></el-input>
</el-form-item>
<el-form-item v-if="visibleShow" label="学员可见">
<el-checkbox v-model="courseInfo.visible"></el-checkbox>
</el-form-item>
<el-form-item label="受众" v-if="!weike.onlyRequired">
<el-select value-key="id" style="width: 100%;" v-model="courseCrowds" filterable multiple :clearable="false" @remove-tag="removeCrowd" placeholder="请选择">
<el-option v-for="item in userGroupList" :key="item.id" :disabled="item.disabled" :label="item.name" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item label="课程价值" v-if="!weike.onlyRequired">
<el-input maxlength="200" v-model="courseInfo.value" show-word-limit placeholder="课程价值(限200字以内)"></el-input>
</el-form-item>
<!-- <el-form-item label="系统标签" v-if="!weike.onlyRequired">
<el-select style="width: 100%;" :allow-create="true"
v-model="showTags"
multiple
filterable
remote
reserve-keyword
placeholder="请输入关键词"
:remote-method="remoteTagMethod"
:loading="loading">
<el-option v-for="item in tagList" :key="item.id" :label="item.name" :value="item.name"> </el-option>
</el-select>
</el-form-item> -->
<el-form-item v-if="!weike.onlyRequired" label="关键字">
<!-- <el-input v-model="courseInfo.keywords" maxlength="100" show-word-limit placeholder="请输入关键字(限100字以内)"></el-input> -->
<el-input v-model.trim="keywords" maxlength="100" @keyup.enter.native="changeKeywords" placeholder="请输入关键字"></el-input>
<el-tag v-for="(tag,index) in tips" size="small" :key="index" closable type="info" @close="closeKeywordsTag(tag,index)">{{ tag }}</el-tag>
</el-form-item>
<el-form-item v-if="!weike.onlyRequired" label="观看设置">
<el-radio style="margin-right: 10px;" v-model="courseInfo.device" :label="1">PC端可见</el-radio>
<el-radio style="margin-right: 10px;" v-model="courseInfo.device" :label="2">移动端可见</el-radio>
<el-radio style="margin-right: 10px;" v-model="courseInfo.device" :label="3">多端可见</el-radio>
</el-form-item>
<el-form-item v-if="!weike.onlyRequired" label="课程来源">
<el-radio-group v-model="courseInfo.source">
<el-radio :label="1">内部</el-radio>
<el-radio :label="2">外部</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="!weike.onlyRequired" label="课程简介">
<el-input type="textarea"
maxlength="255"
show-word-limit
:rows="3"
v-model="courseInfo.summary"
placeholder="请尽量填写课程简介,用于列表中显示,可以让用户更容易了解课程信息">
</el-input>
</el-form-item>
</el-col>
<el-col :span="14">
<div @click="checkCourse"><weikeContent ref="weikeContent" :reset="weikeReset" :contents="contentInfo.list" :course="courseInfo" min-height="644px"></weikeContent></div>
</el-col>
<!-- <el-form-item label="完成规则" v-if="!weike.onlyRequired"><el-input maxlength="50" v-model="courseInfo.passFormula" placeholder="可基于组织树或受众选择"></el-input></el-form-item> -->
<!-- <el-form-item label="开放权限" v-if="!weike.onlyRequired"><el-input maxlength="50" v-model="courseInfo.openObject" placeholder="可基于组织树或受众选择"></el-input></el-form-item> -->
<!-- <el-col :span="24">
<el-form-item v-if="!weike.onlyRequired" label="课程简介">
<el-input
type="textarea"
maxlength="150"
show-word-limit
:rows="2"
v-model="courseInfo.summary"
placeholder="请尽量填写课程简介(限255字以内),用于列表中显示,可以让用户更容易了解课程信息"
></el-input>
</el-form-item>
</el-col> -->
<!-- <el-col :span="24">
<el-form-item v-if="!weike.onlyRequired" label="课程描述">
<WxEditor v-model="courseInfo.overview" :minHeight="50"></WxEditor>
</el-form-item>
</el-col> -->
</el-row>
</el-form>
<div style="padding-right: 30px;"><div></div></div>
<span slot="footer" class="dialog-footer">
<span class="red-tip">有分项内容保存的请先保存分项内容再提交</span>
<el-checkbox style="margin-right:10px" v-if="curCourseId != ''" v-model="checked"></el-checkbox><span v-if="curCourseId != ''" style="font-size:14px;color:#787878;">我已阅读并遵守<span style="color:#588afc;margin-right:10px;cursor: pointer;" @click="courseInfoFormCheckedShow = true">平台内容发布要求</span></span>
<!-- <el-button v-if="curCourseId!='' && contentInfo.list.length>0">预览</el-button> -->
<el-button :loading="btnLoading" v-if="curCourseId != ''" :disabled="!checked" @click="submitCourse()" type="primary">提交审核</el-button>
<el-button @click="closeForm()">关闭</el-button>
</span>
</el-dialog>
<!--录播课-->
<el-dialog v-if="biaoke.dlgShow" width="980px" :title="curCourseId == '' ? '新建课程' : '编辑课程'" :visible.sync="biaoke.dlgShow" :close-on-click-modal="false" custom-class="g-dialog" top="8vh">
<el-tabs v-model="biaoke.tabIndex" @tab-click="changeBiaokeTab" style="min-height: 600px;">
<el-tab-pane label="课程信息" name="base" style="width: 90%;">
<!-- :rules="rulesTwo" -->
<el-form label-width="80px" size="mini">
<el-form-item label="名称" required>
<el-col :span="18">
<el-input maxlength="90" v-model="courseInfo.name" show-word-limit placeholder="课程名称(限90字以内)"></el-input>
</el-col>
<el-col :span="6" style="padding-left: 30px;"><el-checkbox v-model="courseInfo.openCourse" :true-label="1" :false-label="0">公开课</el-checkbox></el-col>
</el-form-item>
<el-form-item label="封面图片">
<el-col :span="12">
<div style="display:flex">
<!-- 上传图片 -->
<!-- {{courseCoverurl}} -->
<div @click.stop="chooseFile">
<imageUpload :disabled="true" :value="courseCoverurl" width="160px" height="90px" @subimage="acceptimage" @success="uploadCoverImgSuccess" @remove="removeCoverImgSuccess"></imageUpload>
</div>
<span style="margin-left:20px">
高宽比为16:9 (:800*450)<br/>png或jpg图片<br/>不要大于2M
</span>
</div>
</el-col>
<el-col :span="12">
<el-form-item label="内容分类" required >
<el-cascader
placeholder="选择内容分类"
style="width: 100%;"
clearable
v-model="sysTypeList"
:props="{ value: 'id', label: 'name' }"
:options="sysTypeListMap"
@focus="onContentTypeFocus"
@change="onContentTypeChange">
</el-cascader>
</el-form-item>
<el-form-item label="场景">
<el-select v-model="courseInfo.forScene" style="width: 100%;" clearable>
<el-option v-for="item in sceneList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="授课教师" required>
<!--授课老师默认是当前操作人-->
<!-- <el-select
style="width: 100%;"
v-model="teacherValues"
multiple
filterable
remote
value-key="teacherId"
ref="elSelect"
reserve-keyword
placeholder="请输入授课教师姓名"
@change="changeTeachers"
:remote-method="remoteFindTeacher"
:loading="loading">
<el-option v-for="item in teacherDownList" :key="item.teacherId" :label="item.teacherName + item.teacherCode" :value="item"></el-option>
</el-select> -->
<choice :teacherValue="teacherValues" @getTeacherList="getTeacherList"></choice>
</el-form-item>
<el-form-item label="标签" required class="tag-from-item" data-step="1" >
<courseTag ref="courseTag" :courseId="curCourseId" :sysTypeList="sysTypeList"
:initialTags="courseTags" @change="handleTagsChange"
@focus="onTagFocus" >
</courseTag>
<el-tooltip content="点击查看标签新功能引导" placement="top">
<i class="el-icon-question" style="color: #409EFF; cursor: pointer;" @click="handleTagHelp"></i>
</el-tooltip>
</el-form-item>
<el-form-item label="关键字">
<el-input v-model.trim="keywords" maxlength="100" @keyup.enter.native="changeKeywords" placeholder="请输入关键字"></el-input>
<el-tag v-for="(tag,index) in tips" size="small" :key="index" closable type="info" @close="closeKeywordsTag(tag,index)">
{{ tag }}
</el-tag>
</el-form-item>
</el-col>
</el-form-item>
<el-form-item label="资源归属" required>
<el-input placeholder="请选择" v-model="orgName" >
<el-button v-if="identity==3 || identity==5" @click="showChooseOrg()" slot="append" icon="el-icon-search">选择</el-button>
</el-input>
</el-form-item>
<el-form-item label="目标人群" required>
<el-col :span="14">
<el-input maxlength="50" v-model="courseInfo.forUsers" show-word-limit placeholder="目标人群(限50字以内)"></el-input>
</el-col>
<el-col :span="10">
<el-form-item v-if="visibleShow" label="学员可见">
<el-checkbox v-model="courseInfo.visible"></el-checkbox>
</el-form-item>
</el-col>
</el-form-item>
<el-form-item label="受众"><!--:disabled="item.disabled"-->
<el-select value-key="id" style="width: 100%;" v-model="courseCrowds" filterable multiple :clearable="false" @remove-tag="removeCrowd" placeholder="请选择">
<el-option v-for="item in userGroupList" :key="item.id" :label="item.name" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item label="课程价值"><el-input maxlength="200" v-model="courseInfo.value" show-word-limit placeholder="课程价值(限200字以内)"></el-input></el-form-item>
<!-- <el-form-item label="系统标签" >
<el-col :span="14">
<el-select style="width: 100%;" :allow-create="true"
v-model="showTags"
multiple
filterable
remote
reserve-keyword
placeholder="请输入关键词"
:remote-method="remoteTagMethod"
:loading="loading">
<el-option v-for="item in tagList" :key="item.id" :label="item.name" :value="item.name"> </el-option>
</el-select>
</el-col>
<el-col :span="10">
<el-form-item label="关键字"><el-input v-model="courseInfo.keywords" maxlength="50" placeholder="关键字"></el-input></el-form-item>
</el-col>
</el-form-item> -->
<el-form-item label="观看设置">
<el-col :span="14">
<el-radio v-model="courseInfo.device" :label="1">PC端可见</el-radio>
<el-radio v-model="courseInfo.device" :label="2">移动端可见</el-radio>
<el-radio v-model="courseInfo.device" :label="3">多端可见</el-radio>
</el-col>
<el-col :span="10">
<el-form-item label="课程来源">
<el-radio-group v-model="courseInfo.source">
<el-radio :label="1">内部</el-radio>
<el-radio :label="2">外部</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-form-item>
<!-- <el-form-item label="完成规则" ><el-input maxlength="50" v-model="courseInfo.passFormula" placeholder="可基于组织树或受众选择"></el-input></el-form-item> -->
<!-- <el-form-item label="开放权限" ><el-input maxlength="50" v-model="courseInfo.openObject" placeholder="可基于组织树或受众选择"></el-input></el-form-item> -->
<el-form-item label="课程简介">
<el-input
type="textarea"
show-word-limit
maxlength="255"
:rows="5"
v-model="courseInfo.summary"
placeholder="请尽量填写课程简介,用于列表中显示,可以让用户更容易了解课程信息">
</el-input>
</el-form-item>
<!-- v-if="!weike.onlyRequired" -->
<!-- <el-form-item label="课程描述">
<WxEditor v-model="courseInfo.overview" :minHeight="50"></WxEditor>
</el-form-item> -->
</el-form>
</el-tab-pane>
<el-tab-pane label="课程内容" name="content" :disabled="curCourseId == ''">
<el-container style="min-height: 550px; border: 1px solid #FFFFFF">
<el-aside width="300px">
<div style="padding-left: 6px;height:30px">
<el-checkbox v-model="courseInfo.orderStudy">按顺序学习</el-checkbox>
<!-- <span class="cctree-title" style="margin-left:10px">课程内容</span> -->
<el-button type="text" icon="el-icon-setting" @click="catalogSortDialogOpen" style="float:right;margin-right:10px;height: 30px;">章节排序</el-button>
</div>
<div class="cctree" style="max-height: 470px;overflow: auto;">
<div v-for="(cc, ccidx) in catalogTree" :key="ccidx" class="cctree-chapter">
<div class="cctree-chapter-name">
<span style="width:80%" >{{ cc.section.name }}</span>
<span style=" flex:1; text-align: right;cursor: pointer; ">
<i class="el-icon-edit-outline" @click="editSection(cc.section)"></i>
<i @click="delSection(cc.section, ccidx)" class="el-icon-delete" style="margin-left: 5px;"></i>
</span>
</div>
<ul class="cctree-chapter-cells">
<li class="cctree-chapter-cell" v-for="(child, childIdx) in cc.contents" :key="childIdx">
{{ getContentTypeName(child.contentType) }}
<a @click="setCurContent(child)"> {{ child.contentName }}</a>
</li>
<li style="padding-left: 20px;padding-top: 5px;">
<span @click="addNewContent(cc.section)" style="border: 1px dotted #ababab;padding: 3px 10px;cursor: pointer;">
<i class="el-icon-plus"></i>
<span class="add-text">添加内容</span>
</span>
</li>
</ul>
</div>
</div>
<div style="padding-top: 15px;">
<div><el-button @click="addNewSection()" type="primary" icon="el-icon-plus">添加章</el-button></div>
</div>
</el-aside>
<el-main style="padding: 0px;">
<catalog-courseware ref="courseware" :reset="onlineReset" :content="curContent" :addOrder="addOrder" :course="courseInfo" @save="saveCurContent" @remove="delCurContent"></catalog-courseware>
</el-main>
</el-container>
</el-tab-pane>
</el-tabs>
<span slot="footer" class="dialog-footer">
<span class="red-tip">有分项内容保存的请先保存分项内容再提交</span>
<el-checkbox v-if="curCourseId != ''" style="margin-right:10px" v-model="checked"></el-checkbox><span v-if="curCourseId != ''" style="font-size:14px;color:#787878">我已阅读并遵守<span style="color:#588afc;margin-right:10px;cursor: pointer;" @click="courseInfoFormCheckedShow = true">平台内容发布要求</span></span>
<el-button :loading="btnLoading" v-if="biaoke.tabIndex == 'base'" type="primary" @click="saveAndNext(2)">保存并下一步</el-button>
<el-button :loading="btnLoading" v-if="biaoke.tabIndex == 'content'" type="primary" @click="previousStep()">上一步</el-button>
<el-button :loading="btnLoading" type="primary" :disabled="!checked" @click="submitCourse()" v-if="curCourseId != ''">提交审核</el-button>
<el-button type="info" @click="closeForm()">关闭</el-button>
</span>
</el-dialog>
<el-dialog title="章节排序" :visible.sync="catalogSortDialogShow" :close-on-click-modal="false" width="800px" custom-class="g-dialog">
<div><catalogSort ref="catalogSort" v-if="catalogSortDialogShow" :treeData="catalogTree" :courseId="curCourseId"></catalogSort></div>
<span slot="footer" class="dialog-footer">
<el-button @click="catalogSortDialogShow = false"> </el-button>
<el-button @click="saveCatalogSort" type="primary">确定</el-button>
</span>
</el-dialog>
<el-dialog class="checked-show" :visible.sync="courseInfoFormCheckedShow" top="14vh" width="800px" :show-close="false" :modal="false">
<agreement></agreement>
<span slot="footer" class="dialog-footer">
<el-button style="margin-right:10px" type="primary" @click="courseInfoFormCheckedShow = false"> </el-button>
</span>
</el-dialog>
<!--选择图片-->
<filecloud :show="dlgFileChoose.show" @choose="changeCourseImage" @close="choseChoose"></filecloud>
<chooseOrg ref="refChooseOrg" @confirm="confirmChooseOrg"></chooseOrg>
</div>
</template>
<script>
import courseTag from "@/components/Course/courseTag.vue";
import choice from '@/components/Course/choice.vue';
import agreement from '@/components/Portal/agreement.vue';
import weikeContent from '@/components/Course/weikeContent.vue';
import catalogCourseware from '@/components/Course/catalogCourseware.vue';
import imageUpload from '@/components/ImageUpload/index.vue';
import apiType from '../../api/modules/type.js';
import scene from '../../api/modules/scene.js';
import apiUserGroup from '../../api/modules/usergroup.js';
import apiTeacher from '../../api/modules/teacher.js';
import apiTag from '../../api/modules/tag.js';
import apiHRBP from '../../api/boe/HRBP.js';
import apiUserBasic from '../../api/boe/userbasic.js';
import apiCourse from '../../api/modules/course.js';
import apiCourseAudit from '../../api/modules/courseAudit.js';
import apiOrg from '../../api/system/organiza.js';
import apiUser from '../../api/system/user.js';
import apiCourseTag from '../../api/modules/courseTag.js';
import WxEditor from '@/components/Editor/index.vue';
import catalogSort from '@/components/Course/catalogSort.vue';
import { courseType, getType } from '../../utils/tools.js';
import { mapGetters, mapActions } from 'vuex';
import filecloud from '@/components/FileCloud/index.vue';
import chooseOrg from '@/components/System/chooseOrg.vue';
export default {
props: {},
components: { courseTag, weikeContent, catalogCourseware, imageUpload, WxEditor, catalogSort,agreement,filecloud,choice,chooseOrg},
data() {
return {
keywords:'',//关键字的定义
tips:[],
addOrder:1,
checked:false,
courseInfoFormCheckedShow:false,
orgChooseShow:false,
weikeReset: '',
onlineReset: '',
sysTypeListMap: [],
resOwnerListMap: [],
userGroupList:[],
sysTypeList: [],
getContentTypeName: getType,
courseChooseShow: false, //是否选择课程类型选择
courseChooseId: 0, //选择的课程类型id
dlgFileChoose:{
show:false
},
courseTypes: [
// 10微课21在线课(直播)20:在线课( 录播)30:面授课40:混合式,
{ id: 1, img: this.webBaseUrl + '/images/ctype1.png', name: '微课', info: '一种单一课件的课程', type: 10 },
{ id: 2, img: this.webBaseUrl + '/images/ctype20.png', name: '在线课', info: '在线-录播课', type: 20 }
// { id:3, img: '/temp/record.png', name: '在线课', info: '在线-直播课' ,type: 21},
// { id:4, img: '/images/ctype4.png', name: '面授课', info: 'XXXX',type: 30 }
],
curCourseId: '', //当前课程的id
curStepIndex: 1, //当前位于哪一步
biaokeTab: 'base',
fileUrl: process.env.VUE_APP_FILE_BASE_URL, //文章的url路径
courseExample: '',
isModifyEdit: true, //此变量需要删除
courseCoverurl: '', //显示的图片
btnLoading: false,
requireSaveCourse: false,
orgName:'',
orgNamePath:'',
orgKid:'',
courseTags:[],
courseInfo: {
id: '',
name: '',
orderStudy: false,
type: 10,
orgId:'',
coverImg: '',
source: 1,
forUsers: '',
forScene: '',
value: '',
tags: '',
keywords: '',
device: 3,
status: 1,
summary: '',
overview: '',
visible:true,
refId:'',
refType:''
},
visibleShow:false,
extendRefId:'',
extendRefType:'',
courseTeachers: [], //课程的老师
courseCrowds:[],//课程的用户受众
curContent: { id: '', contentType: 0, csectionId: '', contentName: '', contentRefId: '' }, //当前编辑的内容
contentInfo: {
curIndex: -1, //当前编辑的索引值
list: []
},
sectionInfo: {
list: []
},
showTags: [], //用于显示标签
courseTypeMap: courseType,
informationDetails: { course: { id: '' } },
resOwnerArray: [],
loading: false,
isModify: true, // true,
edit: false,
tagList: [], // 标签
sceneList: [], // 场景
teacherDownList: [], //远程查询的教师列表
teacherValues: [], //用于绑定el-select的数组
weike: {
onlyRequired: true,
dlgShow: false,
fileType: '',
info: {
shebei: ''
}
},
biaoke: {
dlgShow: false,
tabIndex: 'base'
},
mixture: {
dlgShow: false
},
rightTypeId: {},
catalogSortDialogShow: false,
// 蒙层引导相关数据
showGuidance: false,
currentStep: 1,
highlightStyle: {},
guidanceElements: [],
isFirstCreate: false, // 标记是否为首次创建
};
},
created() {
this.getSceneData();
},
computed: {
...mapGetters(['resOwnerMap', 'sysTypeMap','userInfo','identity']),
catalogTree() {
let treeList = [];
let $this = this;
this.sectionInfo.list.forEach(sec => {
let treeNode = { section: sec, contents: [] };
$this.contentInfo.list.forEach(c => {
if (c.csectionId == sec.id) {
treeNode.contents.push(c);
}
});
treeList.push(treeNode);
});
return treeList;
}
},
watch: {
courseInfo: {
handler(newVal) {
//需要保存
this.requireSaveCourse = true;
},
deep: true
}
},
mounted() {
let extendFlag=this.$route.query.f; //是否是管理端过来的
this.extendRefId=this.$route.query.refId;
this.extendRefType=this.$route.query.refType;
if(extendFlag && extendFlag=='choose'){
this.visibleShow=true;
}
//console.log("url参数",extendFlag,this.extendRefId,this.extendRefType)
this.curStepIndex = 1; //回到第一步
this.btnLoading = false;
this.getResOwnerTree().then(rs => {
this.resOwnerListMap = rs;
});
this.getSysTypeTree().then(rs => {
this.sysTypeListMap = rs;
});
//已经加载tree的情况下不需要再单独的加载一次
this.loadResOwners();
this.loadSysTypes();
this.loadUserGroup();
},
methods: {
handleTagHelp(){
this.checkAndShowGuidance();
},
// 关键字的更改
changeKeywords(option){
if(option.target.value){
this.tips.push(option.target.value)
}
this.keywords = ''
},
//关闭关键字
closeKeywordsTag(item,index){
this.tips.splice(index, 1);
},
// 处理标签变化事件
handleTagsChange(tags) {
console.log("父组件:",tags)
// 限制最多5个标签
if (tags.length > 5) {
this.$message.warning('最多只能选择5个标签')
// 强制限制为5个
tags = tags.slice(0, 5);
return
}
let ids = "";
tags.forEach(tag=>{
console.log("父组件name : ",tag.tagName)
ids += tag.id + ',';
})
this.courseInfo.tags = ids;
this.$emit('change', tags.slice(0, 5)); // 确保传出数据也不超过5个
},
showChooseOrg(){
this.$refs.refChooseOrg.dlgShow = true;
},
removeCrowd(e){
//console.log(e);
if(e.disabled){
this.$message.error("您不能移除创建人加的受众");
this.courseCrowds.push(e);
return false;
}
},
confirmChooseOrg(orgInfo,parentInfo){
//console.log(orgInfo,'orgInfo');
// let hrbpData=orgInfo;
// if(!orgInfo.hrbpId){
// hrbpData=parentInfo;
// //没有,就直接找此机构的上级,如果没有上线就提示,如果有就不提示
// }
// if(hrbpData && (!hrbpData.hrbpId || hrbpData.hrbpId=='-1')){
// this.$message.error("此机构及上级都无HRBP审核人信息请重新选择");
// return;
// }
this.orgName=orgInfo.name;
this.orgKid=orgInfo.kid; //kid已不存在
this.courseInfo.orgId=orgInfo.id;
this.courseInfo.orgName=orgInfo.name;
this.$refs.refChooseOrg.dlgShow = false;
},
getTeacherList(res) {
this.teacherValues = res;
},
chooseFile(){
this.dlgFileChoose.show=true;
},
choseChoose(){
this.dlgFileChoose.show=false;
},
changeCourseImage(img){
if(!img.path){
return;
}
this.dlgFileChoose.show=false;
this.courseInfo.coverImg = img.path;
this.courseCoverurl = this.fileUrl+img.path;
},
acceptimage(value){
this.courseInfo.coverImg = value.path;
this.courseCoverurl = value.path;
},
...mapActions({
getResOwnerTree: 'resOwner/getResOwnerTree',
loadResOwners: 'resOwner/loadResOwners',
getSysTypeTree: 'sysType/getSysTypeTree',
loadSysTypes: 'sysType/loadSysTypes'
}),
loadUserGroup(){
let $this=this;
let params = {
keyword:'',
page:1,
pageSize:500
}
// apiUserGroup.findByName('').then(rs=>{
// if(rs.status==200){
// let crowdList=[];
// rs.result.forEach(item=>{
// crowdList.push({
// id:item.key,
// name:item.value,
// disabled:false
// })
// })
// this.userGroupList=crowdList;
// }
// });
apiUserBasic.getUserAudiences(params).then(rs=>{
if(rs.status==200){
let crowdList=[];
rs.result.list.forEach(item=>{
crowdList.push({
id:item.id,
name:item.audienceName,
disabled:false
})
});
this.userGroupList=crowdList;
}
})
},
resOwnerName(code) {
if (code == '') {
return '';
}
return this.resOwnerMap.get(code);
},
sysTypeName(code) {
if (code == '') {
return '';
}
return this.sysTypeMap.get(code);
},
checkCourse() {
if (this.courseInfo.id == '') {
if (this.courseInfo.name == '') {
this.$message.error('请先填写课程的名称');
return;
}
this.saveAndNext(0);
}
},
// 场景过滤
sceneFilter(forScene) {
// sceneList
// this.courseInfo.forScene
let name = '';
this.sceneList.forEach(item => {
if (item.id === forScene) {
name = item.name;
}
});
return name;
},
closeForm() {
this.weike.dlgShow = false;
this.biaoke.dlgShow = false;
// this.courseInfo.checked = false;
this.$emit('close');
},
initShow(editData) {
console.log('初始化显示内容============', editData)
//console.log(this.$refs.weikePanel,'this.$refs.weikePanel');
//this.$refs.weikePanel.init();
//this.$refs.onlineCourse.resetData();
//刷新用户受众
//初始化显示内容
this.btnLoading = false;
this.curStepIndex = 1; //打开都是第一步
this.courseCoverurl = '';
this.resetCurCourseContent();
this.curCourseId = '';
this.courseChooseId = 0;
this.courseInfo = {
id: '',
name: '',
type: 0,
coverImg: '',
source: 1,
forUsers: '',
forScene: '',
value: '',
tags: '',
keywords: '',
device: 3,
status: 1,
summary: '',
overview: '',
visible:true,
refId:this.extendRefId,
refType:this.extendRefType
};
if(this.extendRefId){
this.courseInfo.visible=false;
}
this.contentInfo.list = [];
this.sectionInfo.list = [];
this.courseTeachers = [];
this.resOwnerArray = [];
this.sysTypeList = [];
this.showTags = [];
this.teacherValues = [];
this.courseCrowds=[];
this.courseCoverurl = '';
// 关键字的清空
this.tips=[];
if (!editData) {
this.tips=[];
this.courseTags=[],
//console.log("新建课程?");
//以下为了保证初始化处理
this.weikeReset = Math.round(Math.random()) + '';
this.onlineReset = Math.round(Math.random()) + '';
this.courseChooseShow = true;
this.biaoke.tabIndex = 'base';
this.courseInfo.orgId=this.userInfo.departId;
if(!this.courseInfo.orgId){
this.courseInfo.orgId=this.userInfo.departId;
}
this.orgKid='';
if(this.courseInfo.orgId){
// apiOrg.getSimple(this.courseInfo.orgId).then(rrs=>{
// if(rrs.status==200){
// this.orgName=rrs.result.name;
// this.orgKid=rrs.result.kid;
// this.orgNamePath=rrs.result.namePath;
// }
// });
apiUserBasic.getOrgInfo(this.courseInfo.orgId).then(rs=>{
if(rs.status==200){
this.orgName=rs.result.name;
this.courseInfo.orgName=rs.result.name;
//this.orgKid=rs.result.kid;
this.orgNamePath=rs.result.namePath;
}
});
}
} else {
//console.log(editData,'editData');
this.weikeReset = editData.id;
this.onlineReset = editData.id;
//console.log("编辑课程?");
this.courseInfo.orgId=editData.orgId;
this.curCourseId = editData.id; //设置
this.courseInfo.type = editData.type; //设置课程类型,因为这里的课程对象可能不全,所以只能设置值,不能整个对象附值
this.getDetail(editData.id); //获取课程的详细信息
//设置,显示哪个
if (editData.type === 10) {
this.weike.dlgShow = true;
} else if (editData.type === 20 || editData.type === 21) {
this.biaoke.dlgShow = true;
}
}
},
resetCurCourseContent() {
this.curContent = { id: '', contentType: 0, contentName: '', content: '', csectionId: '', contentRefId: '', courseId: this.courseInfo.id };
},
// chooseCourseType(item, idx, open) {
// this.courseChooseId = item.id;
// this.curDialogId = item.id;
// this.courseInfo.type = item.type;
// if (open) {
// this.toInputCourse();
// }
// },
showExample(ct) {
this.courseExample = ct.id;
},
// hideExample() {
// this.courseExample = this.courseChooseId;
// },
toInputCourse() {
if (this.courseInfo.name == '') {
this.$message.error('请填写课程名称');
return;
}
if(this.courseInfo.type == 0) {
this.$message.error('是否设置目录');
return;
}
if(this.courseInfo.type == 10) {
this.courseChooseId = 1;
} else if(this.courseInfo.type == 20){
this.courseChooseId = 2;
}
// if (this.courseChooseId == 1) {
// //点击确定的处理,打开微课的需要做哪些初始化
// this.courseInfo.type = 10;
// //this.$refs.weikePanel.init();
// } else if (this.courseChooseId == 2) {
// //要开标课(录播课)需要哪些处理
// this.courseInfo.type = 20;
// //this.$refs.onlineCourse.resetData();
// } else {
// this.$message.error('未指定课程类型');
// return;
// }
apiCourse.saveOnlyCourse(this.courseInfo).then(rs => {
if (rs.status == 200) {
this.courseChooseShow = false;
this.courseInfo = rs.result;
this.curCourseId = this.courseInfo.id
console.log('保存课程成功',this.curCourseId)
console.log('isTip ',this.courseInfo.isTip)
// if(this.courseInfo.isTip){
// // 检查是否为首次创建,显示引导
// this.checkAndShowGuidance();
// }
if (this.courseChooseId == 1) {
this.weike.dlgShow = true;
} else {
this.biaoke.dlgShow = true;
}
// this.$nextTick(() => {
// this.initTagComponent();
// // 如果显示引导,初始化高亮元素
// if (this.showGuidance) {
// this.$nextTick(() => {
// this.initGuidanceElements();
// this.highlightCurrentStep();
// });
// }
// });
} else {
this.$message.error(rs.message);
}
});
},
// 检查并显示引导
checkAndShowGuidance() {
// 检查本地存储,判断是否为首次创建
// const hasShownGuidance = localStorage.getItem('course_creation_guidance_shown');
// if (!hasShownGuidance) {
this.showGuidance = true;
this.currentStep = 1;
this.isFirstCreate = true;
// 标记引导已显示
localStorage.setItem('course_creation_guidance_shown', 'true');
// apiCourse.saveTip();
// }
},
// 初始化引导元素
initGuidanceElements() {
this.guidanceElements = Array.from(document.querySelectorAll('.guidance-highlight'));
},
// 高亮当前步骤对应的元素
highlightCurrentStep() {
if (this.guidanceElements.length === 0) return;
const currentElement = this.guidanceElements[this.currentStep - 1];
if (currentElement) {
currentElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
},
// 下一步
nextStep() {
if (this.currentStep < 2) {
this.currentStep++;
this.highlightCurrentStep();
} else {
this.closeGuidance();
}
},
// 上一步
previousStep1() {
if (this.currentStep > 1) {
this.currentStep--;
this.highlightCurrentStep();
}
},
// 关闭引导
closeGuidance() {
this.showGuidance = false;
this.currentStep = 1;
this.highlightStyle = {};
},
// 内容分类获得焦点时的处理
onContentTypeFocus() {
if (this.showGuidance && this.currentStep === 1) {
this.currentStep = 2;
this.highlightCurrentStep();
}
},
// 内容分类改变时的处理
onContentTypeChange() {
if (this.showGuidance && this.currentStep === 1) {
this.currentStep = 2;
this.highlightCurrentStep();
}
},
// 标签获得焦点时的处理
onTagFocus() {
if (this.showGuidance && this.currentStep === 2) {
this.closeGuidance();
}
},
// 新增初始化标签方法
initTagComponent() {
if (this.$refs.courseTag) {
// 确保组件已渲染后再调用搜索
setTimeout(() => {
this.$refs.courseTag.debouncedSearch('');
}, 100);
}
},
//上传课程图片处理
uploadCoverImgSuccess(res) {
//console.log(res,'res');
this.courseInfo.coverImg = res.result.filePath;
this.courseCoverurl = res.result.httpPath;
},
removeCoverImgSuccess() {
this.courseCoverurl = '';
this.courseInfo.coverImg = '';
},
//获取课程信息
async getDetail(id) {
this.curCourseId = id;
this.orgName='';
let $this = this;
try {
const { result, status } = await apiCourse.detail(id);
if (status === 200) {
this.courseTags = result.tagList;
console.log('获取课程信息成功', this.courseTags);
//把数据附给三个对象
if(result.course.visible==''){
result.course.visible=false;
}
// 给关键字赋值
if(result.course.keywords){
this.tips = result.course.keywords.split(',') || []
}
this.courseInfo = result.course;
this.checked = false;
this.contentInfo.list = result.contents;
this.sectionInfo.list = result.sections;
this.courseTeachers = result.teachers; //课程的老师信息
if(!this.courseInfo.orgId){
//根据课程创建者获取机构id
apiUser.getOrgSimpleByUserId(result.course.sysCreateAid).then(ors=>{
if(ors.status==200){
$this.courseInfo.orgId=ors.result.id;
// apiOrg.getSimple(ors.result.id).then(rrs=>{
// if(rrs.status==200){
// $this.orgName=rrs.result.name;
// $this.orgKid=rrs.result.kid;
// $this.orgNamePath=rrs.result.namePath;
// }
// })
apiUserBasic.getOrgInfo(ors.result.id).then(rrs=>{
if(rrs.status==200){
$this.orgName=rrs.result.name;
this.courseInfo.orgName=rrs.result.name;
//$this.orgKid=rrs.result.kid;
$this.orgNamePath=rrs.result.namePath;
}else{
this.courseInfo.orgId='';
//this.$message.error('资源归属已变更,请重新选择');
}
})
}else{
//this.$message.error('无机构关联,不需要提示');
}
})
}else{
// apiOrg.getSimple(this.courseInfo.orgId).then(rrs=>{
// if(rrs.status==200){
// $this.orgName=rrs.result.name;
// $this.orgKid=rrs.result.kid;
// $this.orgNamePath=rrs.result.namePath;
// }else{
// $this.courseInfo.orgId='';
// $this.$message.error('资源归属已变更,请重新选择');
// }
// });
apiUserBasic.getOrgInfo(this.courseInfo.orgId).then(rs=>{
if(rs.status==200){
$this.orgName=rs.result.name;
$this.courseInfo.orgName=rs.result.name;
//$this.orgKid=rs.result.kid;
$this.orgNamePath=rs.result.namePath;
}else{
$this.courseInfo.orgId='';
$this.$message.error('资源归属已变更,请重新选择');
}
});
}
this.resOwnerArray=[];
if (result.course.resOwner1 == '') {
this.resOwnerArray.push(result.course.resOwner1);
}
if(result.course.resOwner2 == ''){
this.resOwnerArray.push(result.course.resOwner2);
}
if(result.course.resOwner3 == ''){
this.resOwnerArray.push(result.course.resOwner3);
}
this.sysTypeList=[];
if(result.course.sysType1!='' && result.course.sysType1!='0'){
this.sysTypeList.push(result.course.sysType1);
}
if(result.course.sysType2!='' && result.course.sysType2!='0'){
this.sysTypeList.push(result.course.sysType2);
}
if(result.course.sysType3!='' && result.course.sysType3!='0'){
this.sysTypeList.push(result.course.sysType3);
}
//console.log(this.sysTypeList,'this.sysTypeList');
//受众处理crowds
let crowdList=[];
if(result.crowds && result.crowds.length>0){
result.crowds.forEach(crowd=>{
let newCrowd={
id:crowd.groupId,
name:crowd.groupName,
disabled:false
}
crowdList.push(newCrowd);
let hasUG=$this.userGroupList.some(ug=>{
return ug.id==crowd.groupId;
});
if(!hasUG){
newCrowd.disabled=true;
$this.userGroupList.push(newCrowd);
}
});
}
this.courseCrowds=crowdList;
//反向看userGroupList是否有
//课程图片
if (this.courseInfo.coverImg != '') {
this.courseCoverurl = this.fileUrl+this.courseInfo.coverImg;
}
//处理显示的教师信息
let tnames = [],
tlist = [];
this.courseTeachers.forEach(item => {
tnames.push(item.teacherName);
tlist.push({
teacherId: item.teacherId,
teacherName: item.teacherName,
teacherCode: ''
});
});
this.teacherValues = tlist;
this.teacherDownList = tlist;
if (this.courseInfo.tags != '') {
this.showTags = this.courseInfo.tags.split(',');
}
this.$nextTick(function() {
$this.requireSaveCourse = false;
});
//this.requireSaveCourse=false;//不需要保存
}
} catch (error) {
console.log(error);
}
},
changeTeachers(t) {
//用于监听教师列表的选择变化
this.requireSaveCourse = true;
this.$refs.elSelect.query = '';
},
formartTeacher() {},
addNewSection() {
//以后需要加inputPatterninputErrorMessage 验证
let $this = this;
this.$prompt('请输入新章的名称', '添加章', {
confirmButtonText: '确定',
cancelButtonText: '取消',
customClass:'cusprompt',
inputPattern:/^(a-z|A-Z|0-9)*[^$%^&*;:,<>?()\""\']{1,20}$/,
inputErrorMessage:'不要超过20个字'
})
.then(({ value }) => {
let section = {
courseId: $this.curCourseId,
name: value,
parentId: -1,
orderIndex: 1
};
this.saveSection(section);
})
.catch(() => {});
},
editSection(sec) {
let $this = this;
this.$prompt('', '修改章的名称', {
inputValue: sec.name,
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern:/^(a-z|A-Z|0-9)*[^$%^&*;:,<>?()\""\']{1,20}$/,
inputErrorMessage:'不要超过20个字'
})
.then(({ value }) => {
sec.name = value;
this.saveSection(sec);
})
.catch(() => {});
},
delSection(sec, idx) {
//检查是否有内容,对于有内容的不能删除
let has = this.contentInfo.list.some(con => {
return con.csectionId == sec.id;
});
if (has) {
this.$message.error('有资源内容的章不能删除');
return;
}
apiCourse.delSection(sec.id).then(res => {
if (res.status == 200) {
this.sectionInfo.list.splice(idx, 1);
} else {
this.$message.error(res.message);
}
});
},
saveSection(section) {
let addNew = section.id ? false : true;
if (addNew) {
//设置显示顺序
let maxOrder = 1;
this.sectionInfo.list.forEach(sec => {
if (sec.orderIndex > maxOrder) {
maxOrder = sec.orderIndex;
}
});
section.orderIndex = maxOrder + 1;
}
apiCourse.saveSection(section).then(res => {
if (res.status == 200) {
if (addNew) {
this.sectionInfo.list.push(res.result);
}
} else {
this.$message.error(res.message);
}
});
//设置状态
},
addNewContent(sec) {
//console.log(sec,'sec');
this.resetCurCourseContent();
this.curContent.csectionId = sec.id;
this.orderValue(sec.id);
},
// 计算新增节的顺序
orderValue(id) {
let cha = this.catalogTree.find(item=>{return item.section.id == id});
let order = [];
if(cha.contents.length > 0) {
cha.contents.forEach(con=>{
order.push(con.sortIndex);
})
let addOrder = order.sort(function(a,b) {return b-a;})
this.addOrder = addOrder[0] + 1;
} else {
this.addOrder = 1;
}
},
// 控制 过滤
deviceFilter(num) {
let name = '';
switch (num) {
case 1:
name = '移动端可见';
break;
case 2:
name = 'PC端可见';
break;
case 3:
name = '全部可见';
break;
default:
name = '';
break;
}
return name;
},
// 标签远程查询
async remoteTagMethod(query) {
if (query) {
try {
const { result, status } = await apiTag.findByName(1, query);
if (status === 200) {
this.tagList = result;
}
} catch (error) {
console.log(error);
}
} else {
this.tagList = [];
}
},
// 上一步
previousStep() {
//this.curStepIndex=1;
this.biaoke.tabIndex = 'base';
//以下几项都是要删除的
// this.isModify = !this.isModify;
// this.isModifyEdit = !this.isModifyEdit;
},
//保存课程信息并进入下一步
saveAndNext(btnType) {
console.log("courseForm 保存课程信息 btnType = " + btnType);
//if(this.courseInfo.type)
//console.log(this.courseCrowds,'courseCrowds');
//标签,多个,转化为逗号分隔的
console.log("courseForm 保存课程信息 this.showTags = " + this.showTags);
console.log("courseForm 保存课程信息 this.courseInfo.tags = " + this.courseInfo.tags);
// if (this.showTags.length > 0) {
// this.courseInfo.tags = this.courseInfo.tags.join();
// }
// console.log("courseForm 保存课程信息 this.courseInfo.tags = " + this.courseInfo.tags);
this.courseInfo.keywords = this.tips.join(',') || ''
//检查输入是否合法
//if(!this.requireSaveCourse){
// this.curStepIndex=2;//转到第二步处理
// this.biaoke.tabIndex='content';//对于录博课转到内容的tab, 以后是不是可以去掉Tab. 因为有无tab都一样
//this.$message.success('保存成功,未修改课程基本信息不需要多次保存');
// return;
// }
//设置保存状态
this.btnLoading = true;
//处理资源归属
//下面是初始化的数据
let ownerCode=this.resOwnerListMap[0].code;
this.resOwnerArray=[];
this.resOwnerArray.push(ownerCode);
this.courseInfo.resOwner1 = '';
this.courseInfo.resOwner2 = '';
this.courseInfo.resOwner3 = '';
if (this.resOwnerArray.length > 0) {
this.courseInfo.resOwner1 = this.resOwnerArray[0]; //资源归属一级的id
}
if (this.resOwnerArray.length > 1) {
this.courseInfo.resOwner2 = this.resOwnerArray[1]; //资源归属二级的id
}
if (this.resOwnerArray.length > 2) {
this.courseInfo.resOwner3 = this.resOwnerArray[2]; //资源归属三级的id
}
// 分类
this.courseInfo.sysType1 = '';
this.courseInfo.sysType2 = '';
this.courseInfo.sysType3 = '';
if (this.sysTypeList.length > 0) {
this.courseInfo.sysType1 = this.sysTypeList[0]; //一级的id
}
if (this.sysTypeList.length > 1) {
this.courseInfo.sysType2 = this.sysTypeList[1]; //二级的id
}
if (this.sysTypeList.length > 2) {
this.courseInfo.sysType3 = this.sysTypeList[2]; //三级的id
}
//受众的处理
let crowds=[];
this.courseCrowds.forEach(item=>{
crowds.push({
groupId:item.id,
groupName:item.name
})
});
//以下是老师内容的处理
let saveTeachers = [];
this.teacherValues.forEach(item => {
saveTeachers.push(item);
});
let postData = {
course: this.courseInfo,
teachers: saveTeachers,
crowds:crowds
};
console.log(postData);
//this.btnLoading=false;
apiCourse
.saveBase(postData)
.then(res => {
this.btnLoading = false;
if (res.status === 200) {
// let checked = this.courseInfo.checked;
let result = res.result;
this.courseInfo = result.course;
// if(checked) {
// this.courseInfo.checked = true;
// }
this.curCourseId = result.course.id; //设置当前课程的id
this.courseTeachers = result.teachers;
//this.curStepIndex=2;//转到第二步处理
this.requireSaveCourse = false; //不需要再保存,点下一步时不保存
this.biaoke.tabIndex = 'content';
//注意下次不修改之前不需要保存
this.$nextTick(function() {
this.requireSaveCourse = false;
});
if (btnType == 1) {
//this.weike.dlgShow=false;
}
if (btnType > 0) {
this.$message.success('保存成功');
}
} else {
this.btnLoading = false;
this.$message.error(res.message);
}
})
.catch(err => {
this.btnLoading = false;
});
},
// 判断是否有未保存的内容
unsavedContent() {
const courseware = this.$refs.courseware;
//console.log(courseware,'courseware');
let pass = true;
if(this.curContent.id == '') {// 新增
if(this.curContent.contentType == 60) { // 判断作业是否保存
if(courseware.homework.content || courseware.homework.name || courseware.homework.deadTime){
pass = false;
}
} else if(this.curContent.contentType == 61) { //考试
// if(courseware.exam.paperContent != '') {
// pass = false;
// }
// if(courseware.examPaper.items.length >0) {
// pass = false;
// }
}else if(this.curContent.contentType == 41) { //图文
if(courseware.htmlContent.length > 7){
pass = false;
}
}else if(this.curContent.contentType == 52) { //外部链接
if(courseware.linkInfo.url != '') {
pass = false;
}
}
} else {// 编辑
if(this.curContent.contentType == 60) { // 判断作业是否保存
if(JSON.stringify(courseware.homeworkChange) !== JSON.stringify(courseware.homework)) {
pass = false;
}
} else if(this.curContent.contentType == 61) { //考试
// console.log(courseware.exam,'courseware.exam');
// if(courseware.exam.paperContent !== courseware.examChange.paperContent || JSON.stringify(courseware.examPaper) != JSON.stringify(courseware.examPaperChange)) {
// pass = false;
// }
} else if(this.curContent.contentType == 41) { //图文
if(this.curContent.content !== courseware.htmlContent) {
pass = false;
}
} else if(this.curContent.contentType == 52) { //外部链接
if(this.curContent.content !== JSON.stringify(courseware.linkInfo)) {
pass = false;
}
} else if(this.curContent.contentType == 10 || this.curContent.contentType == 20) {// 视频
if(this.curContent.content !== JSON.stringify(courseware.curriculumData)) {
pass = false;
}
}
}
return pass;
},
unsavedWeiContent() {
// console.log(this.contentInfo.list,'contentInfo.list');
// console.log(this.courseInfo,'courseInfo');
//console.log(this.$refs.weikeContent,'weikeContent');
const courseware = this.$refs.weikeContent;
//console.log(this.catalogTree,'this.catalogTree');
if(courseware.cware.content.id==''){
this.$message.error('无课件内容,请先添加课件内容保存后再提交');
return false;
}
if(courseware.homework.show == 2) { // 作业
this.$message.error('请先保存作业再提交');
return false;
}
let pass = true;
if(courseware.homework.show == 2) { // 作业
this.$message.error('请先保存作业再提交');
return false;
}
if(courseware.assess.show == 2) { // 评估
//this.$message.error('请先保存评估再提交');
//return false;
}
if(courseware.exam.show == 3) { // 评估
this.$message.error('请先保存考试再提交');
return false;
}
return true;
},
submitCourse() {
console.log("courseForm 课程提交审核 this.showTags = " + this.showTags);
console.log("courseForm 课程提交审核 this.courseInfo.tags = " + this.courseInfo.tags);
if(this.biaoke.dlgShow && !this.unsavedContent()){
this.$message.error('您有未保存的内容,请先保存');
return;
}
if(this.weike.dlgShow && !this.unsavedWeiContent()){
return;
}
//console.log(this.courseInfo.orgId,'this.courseInfo.orgId');
//console.log(this.orgKid,'this.orgKid');
if(!this.courseInfo.orgId){
this.$message.error('请选择资源归属');
return;
}
// if(!this.orgKid){
// this.$message.error('资源归属无关联HRBP信息');
// return;
// }
//console.log(this.resOwnerListMap[0],'this.resOwnerListMap[0]');
//return;
let ownerCode=this.resOwnerListMap[0].code;
this.resOwnerArray=[];
this.resOwnerArray.push(ownerCode);
//console.log(ownerCode,'ownerCode');
//提交课程,需要验证,这个是单独的处理,
this.courseInfo.status = 2; //提交状态
//if(this.resOwnerArray.length==0){
//}
//console.log(this.resOwnerArray,'this.resOwnerArray');
//return;
if(this.resOwnerArray.length < 1) {
this.$message.error('请选择资源归属');
return;
}
if (this.showTags.length > 0) {
// this.courseInfo.tags = this.showTags.join();
}
if (this.sysTypeList.length < 1) {
this.$message.error('请选择内容分类');
return;
}
if (this.teacherValues.length == 0) {
this.$message.error('请选择课程教师');
return;
}
//在子组件中无法检查的到,所这里在后台进行检查 了
// if(this.contentInfo.list.length==0){
// this.$message.error("还没有课程内容,请先完善课程内容");
// return;
// }
if (this.courseInfo.type == 10) {
//if(this.cware.)
} else if (this.courseInfo.type == 20) {
if (this.sectionInfo.list.length == 0) {
this.$message.error('还没有课程内容,请先完善课程内容');
return;
}
let pass = true;
this.catalogTree.some(sec => {
if (sec.contents.length == 0) {
pass = false;
return true;
}
return false;
});
if (!pass) {
this.$message.error('不能有空的章节');
return;
}
}
//以下是填充内容,交提交,与前面的保存同相同的代码
this.courseInfo.resOwner1 = '';
this.courseInfo.resOwner2 = '';
this.courseInfo.resOwner3 = '';
if (this.resOwnerArray.length > 0) {
this.courseInfo.resOwner1 = this.resOwnerArray[0]; //资源归属一级的id
}
if (this.resOwnerArray.length > 1) {
this.courseInfo.resOwner2 = this.resOwnerArray[1]; //资源归属二级的id
}
if (this.resOwnerArray.length > 2) {
this.courseInfo.resOwner3 = this.resOwnerArray[2]; //资源归属三级的id
}
// 分类
this.courseInfo.sysType1 = '';
this.courseInfo.sysType2 = '';
this.courseInfo.sysType3 = '';
if (this.sysTypeList.length > 0) {
this.courseInfo.sysType1 = this.sysTypeList[0]; //一级的id
}
if (this.sysTypeList.length > 1) {
this.courseInfo.sysType2 = this.sysTypeList[1]; //二级的id
}
if (this.sysTypeList.length > 2) {
this.courseInfo.sysType3 = this.sysTypeList[2]; //三级的id
}
//受众的处理
let crowds=[];
this.courseCrowds.forEach(item=>{
crowds.push({
groupId:item.id,
groupName:item.name
})
});
let saveTeachers = [];
this.teacherValues.forEach(item => {
saveTeachers.push(item);
});
let postData = {
course: this.courseInfo,
teachers: saveTeachers,
crowds:crowds
};
this.btnLoading = true;
let $this = this;
//2023-1-5 对于默认管理员不需要提交hrbp。直接提交并发布
let adminType=this.userInfo.adminType;
if(adminType==1){ //默认管理员,直接审核通过
apiCourseAudit.submitAndPublish(postData).then(res=>{
setTimeout(function() {
$this.btnLoading = false;
}, 1000);
if (res.status === 200) {
//提交成功,直接关闭当前窗口
this.$message.success('提交成功!!!');
} else {
this.$message.error(res.message);
}
this.biaoke.dlgShow = false;
this.weike.dlgShow = false;
this.$emit('submitSuccess');
});
}else{
//先获取HRBP审核 人员信息,姓名,机构路径,工号,用于邮件中的信息
apiUserBasic.getOrgHrbpInfo(this.courseInfo.orgId).then(rs=>{
if(rs.status==200 && rs.result){
postData.auditUser={
email:rs.result.email,
code:rs.result.userNo,
name:rs.result.name,
aid:rs.result.id,
orgId:rs.result.orgId
}
//下面的机构名称,路径不对,应该取课程的资源归属(机构)的路径
postData.course.orgName=rs.result.orgNamePath+'/'+rs.result.orgName;
apiCourse.submitCourse(postData).then(res => {
//this.btnLoading=false;
setTimeout(function() {
$this.btnLoading = false;
}, 1000);
if (res.status === 200) {
//提交成功,直接关闭当前窗口
this.$message.success('提交成功!!!');
this.biaoke.dlgShow = false;
this.weike.dlgShow = false;
//提交成功回调处理
this.$emit('submitSuccess');
} else {
this.$message.error(res.message);
this.biaoke.dlgShow = false;
this.weike.dlgShow = false;
this.$emit('submitSuccess');
}
});
}else{
$this.btnLoading = false;
this.$message.error('获取审核HRBP失败:'+rs.message);
}
}).catch(err=>{
//this.$message.error('获取审核HRBP失败:'+err);
this.$message.error('获取审核HRBP失败请检查资源归属下是否有HRBP审核人员');
$this.btnLoading = false;
})
}
},
// 教师列标,远程查询
async remoteFindTeacher(query) {
if (query) {
this.loading = true;
try {
const { result, message, status } = await apiTeacher.findByName(query);
this.loading = false;
if (status === 200) {
let list = [];
result.forEach(item => {
list.push({
teacherId: item.id,
teacherName: item.name,
teacherCode: item.code
});
});
this.teacherDownList = list;
} else {
this.$message.error('查询教师信息失败:' + message);
}
} catch (err) {
this.loading = false;
}
} else {
this.teacherDownList = [];
}
},
//获取场景,保留
async getSceneData() {
try {
const { result, status } = await scene.list(1);
if (status === 200) {
this.sceneList = result;
}
} catch (error) {
console.log(error);
}
},
setCurContent(item) {
//此方法应该是设置内容curContent, 设置了它,右边就会自动变化
this.curContent = item;
},
changeBiaokeTab(tab) {
//检查保存的情况
if (this.curCourseId == '') {
return;
}
if (tab.name == 'base') {
this.curStepIndex = 1;
} else {
this.curStepIndex = 2;
}
},
saveCurContent(cc) {
this.curContent = cc;
//检查 是否存在
let index = -1;
this.contentInfo.list.some((con, conIdx) => {
if (con.id == cc.id) {
index = conIdx;
return true;
} else {
return false;
}
});
if (index == -1) {
this.contentInfo.list.push(cc);
} else {
// this.contentInfo.list[index] = cc;
this.contentInfo.list.splice(index,1,cc);
}
//计算顺序值
},
delCurContent() {
//从列表中移除
let $this = this;
let id = this.curContent.id;
let secId = this.curContent.csectionId;
this.contentInfo.list.some((con, idx) => {
if (con.id == id) {
$this.contentInfo.list.splice(idx, 1);
$this.resetCurCourseContent();
$this.curContent.csectionId = secId;
return true;
} else {
return false;
}
});
//this.curContent.id='';
},
catalogSortDialogOpen() {
this.catalogSortDialogShow = true;
},
// 保存章节排序
saveCatalogSort() {
let that = this;
this.$refs.catalogSort.save(this.sectionInfo.list, this.contentInfo.list, function() {
that.catalogSortDialogShow = false;
});
}
}
};
</script>
<style lang="scss" scoped>
.red-tip{
margin-top: 8px;
color: red;
font-size: 14px;
float: left;
font-weight: 600;
}
::v-deep .wei-from{
.el-form-item{
margin-bottom: 10px;
}
.el-textarea__inner{
padding-right: 40px;
}
}
::v-deep .checked-show{
.el-dialog__header{
padding:0;
}
}
.el-dialog__body {
padding: 10px 10px;
// overflow-y: auto;
max-height: calc(70vh - 140px);
}
.example {
height: 100%;
border: 1px solid #9d9d9d;
text-align: center;
// padding-top: 50px;
}
.el-container .el-aside {
padding: 5px 0px;
}
.course-types {
display: flex;
// padding: 15px;
.course-type {
margin: 0 10px;
text-align: center;
padding: 0 5px;
cursor: pointer;
img {
width: 110px;
height: 110px;
}
.info {
padding-top: 10px;
}
}
.choose {
border: 2px solid #008000;
}
.static {
pointer-events: none;
}
}
.el-aside {
padding: 5px 10px;
margin-bottom: 0px;
}
.cctree-title {
font-weight: 600;
color: #444444;
font-size: 16px;
cursor: pointer;
}
.add-text {
font-weight: 500;
color: #444444;
font-size: 12px;
margin-left: 5px;
}
.tip{
font-size: 16px;
color:#ffb30f;
}
.cctree {
.cctree-chapter {
.cctree-chapter-name {
// text-align: right;
border-bottom: 1px solid #dddddd;
padding: 0px 6px;
display: flex;
}
.cctree-chapter-cells {
margin: 0px;
padding: 0px 6px;
.cctree-chapter-cell {
cursor: pointer;
line-height: 30px;
list-style-type: circle;
padding-left: 20px;
}
}
}
}
</style>
<style lang="scss">
.cusprompt{
padding: 20px 30px;
.el-message-box__content{
margin-top: 30px;
.el-message-box__input{
}
}
}
/* 蒙层样式 */
.guidance-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
z-index: 9999;
display: flex;
justify-content: center;
align-items: center;
}
.guidance-content {
position: fixed;
background: white;
border-radius: 8px;
padding: 24px;
max-width: 500px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
z-index: 10000;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.guidance-title {
font-size: 18px;
font-weight: bold;
margin-bottom: 20px;
text-align: center;
}
.guidance-steps {
margin-bottom: 20px;
}
.guidance-step {
display: flex;
align-items: flex-start;
margin-bottom: 16px;
opacity: 0.5;
transition: opacity 0.3s;
}
.guidance-step.active {
opacity: 1;
}
.step-number {
//width: 24px;
height: 24px;
//background: #409EFF;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
font-size: 14px;
}
.step-content {
flex: 1;
}
.step-title {
font-weight: bold;
margin-bottom: 4px;
}
.step-desc {
color: #666;
font-size: 14px;
}
.guidance-actions {
display: flex;
justify-content: center;
gap: 12px;
}
/* 高亮元素样式 */
.highlight-element {
position: fixed;
border: 2px solid #409EFF;
border-radius: 4px;
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.4), 0 0 15px rgba(64, 158, 255, 0.5);
z-index: 9998;
pointer-events: none;
transition: all 0.3s ease;
}
/* 被高亮元素的样式 */
.guidance-highlight {
position: relative;
z-index: 10001;
}
//.el-form-item__content {
// display: flex;
// width: 80%;
// .tag-container {
// width: 95%;
// }
//}
.tag-from-item .el-form-item__content {
margin-left: 0 !important;
display: flex;
//align-items: center;
.tag-container {
width: 95%;
}
}
.guidance-highlight .el-form-item__content {
margin-left: 0 !important;
display: flex;
width: 75%;
}
</style>