1130 lines
38 KiB
1130 lines
38 KiB
4 months ago
|
<template>
|
||
|
<div class="wrap">
|
||
|
<el-card v-if="!id" shadow="hover" class="m-b-20">
|
||
|
<div class="flex-between">
|
||
|
<el-page-header @back="back" :content="'新建课程'"></el-page-header>
|
||
|
</div>
|
||
|
</el-card>
|
||
|
<div class="page">
|
||
|
<div class="overflow">
|
||
|
<ul :class="['steps', { pointer: !editing && id && publishStatus }]">
|
||
|
<li :class="{ active: step === 1, done: step > 1 }" @click="toStep(1)">
|
||
|
<span class="circle">1</span>
|
||
|
<p class="text">填写课程信息</p>
|
||
|
</li>
|
||
|
<li :class="{ active: step === 2, done: step > 2 }" @click="toStep(2)">
|
||
|
<span class="circle circle2">2</span>
|
||
|
<p class="text">设置练习项目</p>
|
||
|
</li>
|
||
|
<li :class="{ active: step === 3, done: step > 3 }" @click="toStep(3)">
|
||
|
<span class="circle circle3">3</span>
|
||
|
<p class="text">设置考核项目</p>
|
||
|
</li>
|
||
|
<li :class="{ done: step > 3 }">
|
||
|
<span class="circle circle4">4</span>
|
||
|
<p class="text">完成</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
<div class="page-content">
|
||
4 months ago
|
<!-- 第一步 -->
|
||
4 months ago
|
<el-form v-show="step === 1" class="form" :model="form" :rules="rules" ref="form" label-width="100px">
|
||
|
<el-form-item label="课程名称" prop="curriculumName">
|
||
|
<el-input class="w-input" id="focus-el" placeholder="请输入课程名称"
|
||
|
v-model.trim="form.curriculumName"></el-input>
|
||
|
</el-form-item>
|
||
|
<el-form-item label="课程类别" prop="curriculumType">
|
||
|
<el-select class="w-input" v-model="form.curriculumType" clearable placeholder="请选择课程类型">
|
||
|
<el-option label="实训课程" :value="1"></el-option>
|
||
|
<el-option label="理论课程" :value="0"></el-option>
|
||
|
<el-option label="理实课程" :value="2"></el-option>
|
||
|
</el-select>
|
||
|
</el-form-item>
|
||
|
|
||
|
<el-form-item class="req" label="适用专业" required>
|
||
|
<div class="subject">
|
||
|
<div v-for="(item, i) in form.mallDisciplines" :key="i" class="line">
|
||
|
<el-form-item label="学科类别">
|
||
|
<el-select v-model="item.categoryId" @change="getProfessionalClass(item)">
|
||
|
<el-option v-for="(item, index) in subjectList" :key="index" :label="item.disciplineName"
|
||
|
:value="item.disciplineId"></el-option>
|
||
|
</el-select>
|
||
|
</el-form-item>
|
||
|
<el-form-item label="专业类">
|
||
|
<el-select v-model="item.professionalCategoryId" :disabled="item.categoryId ? false : true"
|
||
|
@change="getProfessional(item)">
|
||
|
<el-option v-for="(item, index) in item.professionalClassList" :key="index"
|
||
|
:label="item.professionalClassName" :value="item.professionalClassId"></el-option>
|
||
|
</el-select>
|
||
|
</el-form-item>
|
||
|
<el-form-item label="专业">
|
||
|
<el-select v-model="item.professionalId" :disabled="item.professionalCategoryId ? false : true">
|
||
|
<el-option v-for="(item, index) in item.professionalList" :key="index"
|
||
|
:label="item.professionalName" :value="item.professionalId"></el-option>
|
||
|
</el-select>
|
||
|
</el-form-item>
|
||
|
<i v-if="i && !isDetail" class="del el-icon-delete" @click="form.mallDisciplines.splice(i, 1)"></i>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div v-if="!isDetail" class="subject-plus" @click="addSubject">
|
||
|
<i class="el-icon-circle-plus-outline"></i>
|
||
|
</div>
|
||
|
</el-form-item>
|
||
|
|
||
|
<el-form-item label="预计课时" prop="expectedCourse">
|
||
|
<el-select class="w-input" v-model="form.expectedCourse" clearable placeholder="请选择预计课时">
|
||
|
<el-option label="32课时" value="32课时"></el-option>
|
||
|
<el-option label="64课时" value="64课时"></el-option>
|
||
|
</el-select>
|
||
|
</el-form-item>
|
||
|
<el-form-item label="供应厂商" prop="supplier">
|
||
|
<el-select class="w-input" v-model="form.supplier" clearable placeholder="请选择供应厂商" multiple>
|
||
|
<el-option v-for="(item, i) in suppliers" :key="i" :label="item.supplierName"
|
||
|
:value="item.supplierId"></el-option>
|
||
|
</el-select>
|
||
|
</el-form-item>
|
||
|
<el-form-item label="课程封面">
|
||
|
<el-card shadow="hover">
|
||
|
<div class="cover-wrap">
|
||
|
<el-upload name="file" accept=".jpg,.png,.jpeg,.gif" ref="upload" drag :on-remove="handleRemove"
|
||
|
:on-error="uploadError" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed" action=""
|
||
|
:http-request="handleRequest">
|
||
|
<i class="el-icon-upload"></i>
|
||
|
<div class="el-upload__text">
|
||
|
<p>将图片拖到此处,或<em>点击上传</em></p>
|
||
|
<p style="font-size: 12px;color: #9f9f9f;line-height: 1.4;">建议上传484*278像素图片</p>
|
||
|
</div>
|
||
|
</el-upload>
|
||
|
<div class="preview">
|
||
|
<p class="preview-title">默认图片预览</p>
|
||
|
<img class="preview-pic" :src="form.coverUrl" alt="">
|
||
|
</div>
|
||
|
</div>
|
||
|
</el-card>
|
||
|
</el-form-item>
|
||
|
|
||
|
<el-form-item label="课程简介" prop="briefIntroduction">
|
||
|
<Editor api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda' v-model="form.briefIntroduction"
|
||
|
:init="editorConfig" :disabled="isDetail" />
|
||
|
</el-form-item>
|
||
|
<el-form-item label="详情介绍" prop="teachingObjectives">
|
||
|
<Editor api-key='rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda' v-model="form.teachingObjectives"
|
||
|
:init="editorConfig" :disabled="isDetail" />
|
||
|
</el-form-item>
|
||
|
</el-form>
|
||
|
|
||
4 months ago
|
<!-- 第二步 -->
|
||
4 months ago
|
<template v-if="step === 2">
|
||
|
<div class="tool">
|
||
|
<ul class="filter">
|
||
4 months ago
|
<!-- <li>
|
||
4 months ago
|
<label>搜索:</label>
|
||
|
<el-input placeholder="请输入实训项目名称、理论试卷名称" suffix-icon="el-icon-search" v-model="form.keyWord" clearable
|
||
|
size="small" style="width: 300px"></el-input>
|
||
4 months ago
|
</li> -->
|
||
4 months ago
|
</ul>
|
||
|
<div>
|
||
|
<el-button @click="handleBatchDelete(0)">批量移除</el-button>
|
||
|
<el-button @click="handleConfig(0)" icon="el-icon-plus" circle></el-button>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div>
|
||
|
<el-table :data="practiceData" class="table" header-align="center" max-height="400"
|
||
|
@selection-change="handleSelectionPractice">
|
||
|
<el-table-column type="selection" width="55" align="center"></el-table-column>
|
||
|
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
|
||
|
<el-table-column prop="projectName" label="项目名称" align="center">
|
||
|
<template slot-scope="scope">
|
||
|
{{ scope.row.projectName || scope.row.paperName }}
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
|
||
|
<el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
|
||
|
<el-table-column label="排序" align="center" width="100">
|
||
|
<template slot-scope="scope">
|
||
|
<el-input v-model.trim="scope.row.sort"
|
||
|
@input="practiceSortChange(scope.row, scope.$index)"></el-input>
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
<el-table-column label="展示控制" align="center" width="100">
|
||
|
<template slot-scope="scope">
|
||
|
<el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
|
||
|
:disabled="scope.row.disabled">
|
||
|
</el-switch>
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
<el-table-column label="操作" align="center" width="100">
|
||
|
<template slot-scope="scope">
|
||
|
<el-button :disabled="scope.row.disabled"
|
||
|
@click.native.prevent="handleDelete(scope.$index, practiceData)">移除
|
||
|
</el-button>
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
</el-table>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
4 months ago
|
<!-- 第三步 -->
|
||
4 months ago
|
<template v-else-if="step === 3">
|
||
4 months ago
|
<div class="mgb20" style="text-align: right;">
|
||
|
<el-button @click="handleBatchDelete(1)">批量移除</el-button>
|
||
|
<el-button @click="handleConfig(1)" icon="el-icon-plus" circle></el-button>
|
||
|
</div>
|
||
|
<div>
|
||
|
<el-table :data="assessmentData" class="table" header-align="center" max-height="400"
|
||
|
@selection-change="handleSelectionAssessment">
|
||
|
<el-table-column type="selection" width="55" align="center"></el-table-column>
|
||
|
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
|
||
|
<el-table-column prop="projectName" label="项目名称" align="center">
|
||
|
<template slot-scope="scope">
|
||
|
{{ scope.row.projectName || scope.row.paperName }}
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
|
||
|
<el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
|
||
|
<el-table-column label="排序" align="center" width="100">
|
||
|
<template slot-scope="scope">
|
||
|
<el-input v-model.trim="scope.row.sort"
|
||
|
@input="assessmentSortChange(scope.row, scope.$index)"></el-input>
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
<el-table-column label="展示控制" align="center" width="100">
|
||
|
<template slot-scope="scope">
|
||
|
<el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
|
||
|
:disabled="scope.row.disabled">
|
||
|
</el-switch>
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
<el-table-column label="操作" align="center" width="100">
|
||
|
<template slot-scope="scope">
|
||
|
<el-button :disabled="scope.row.disabled"
|
||
|
@click.native.prevent="handleDelete(scope.$index, assessmentData)">移除</el-button>
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
</el-table>
|
||
|
</div>
|
||
4 months ago
|
</template>
|
||
4 months ago
|
|
||
|
<div v-else-if="step === 4" class="modal">
|
||
|
<h1>课程已保存!</h1>
|
||
|
<div class="btns">
|
||
|
<el-button type="primary" @click="back">确定</el-button>
|
||
|
</div>
|
||
|
</div>
|
||
4 months ago
|
</div>
|
||
|
</div>
|
||
4 months ago
|
<div v-if="step !== 4" class="btns">
|
||
4 months ago
|
<el-button v-if="step === 2 || step === 3" type="primary" @click="prev">上一步</el-button>
|
||
|
<el-button v-else type="primary" @click="save(0, 2)">下一步</el-button>
|
||
|
<el-button type="primary" @click="save(1)">保存</el-button>
|
||
|
<el-button @click="cancel">{{ editing ? '取消' : '返回' }}</el-button>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<!-- 配置弹窗 -->
|
||
|
<el-dialog :visible.sync="configVisible" width="1200px" center custom-class="config-dia">
|
||
|
<div class="config-wrap">
|
||
|
<div class="item system">
|
||
|
<div class="title-wrap flex-center">
|
||
|
<p class="addhr_tag"></p>
|
||
|
<span>系统列表</span>
|
||
|
</div>
|
||
|
<el-input placeholder="请输入系统名称" prefix-icon="el-icon-search" v-model.trim="systemKeyword"
|
||
|
clearable></el-input>
|
||
|
|
||
|
<ul class="systems">
|
||
|
<li v-for="(item, i) in systems" :key="i" :title="item.systemName">
|
||
|
<el-checkbox v-model="item.check" @change="val => systemChange(val, item)"></el-checkbox>
|
||
|
<div :class="['name', { active: curSystem == item.systemId }]" @click="getProject(item)">
|
||
|
<span>{{ item.systemName }}</span>
|
||
|
<i class="el-icon-arrow-right"></i>
|
||
|
</div>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="item project">
|
||
|
<div class="title-wrap flex-center">
|
||
|
<p class="addhr_tag"></p>
|
||
|
<span>项目列表</span>
|
||
|
</div>
|
||
|
<el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="projectKeyword"
|
||
|
clearable></el-input>
|
||
|
|
||
|
<ul class="systems">
|
||
|
<el-checkbox v-if="projects.length" v-model="checkAll" label="全选"
|
||
|
@change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox>
|
||
|
<li v-for="(item, i) in projects" :key="i" :title="item.projectName">
|
||
|
<el-checkbox v-model="item.check"
|
||
|
:label="item.remark ? item.remark + '(' + item.projectName + ')' : (item.projectName || item.paperName)"
|
||
|
@change="val => projectChange(val, item)"></el-checkbox>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="item checked">
|
||
|
<div class="title-wrap flex-center">
|
||
|
<p class="addhr_tag"></p>
|
||
|
<span>已选择项目({{ checkeds.length }}个)</span>
|
||
|
</div>
|
||
|
<el-input style="width: 200px;margin-bottom: 20px;" placeholder="请输入项目名称" prefix-icon="el-icon-search"
|
||
|
v-model.trim="checkedKeyword" clearable></el-input>
|
||
|
<el-table :data="checkeds" class="table" header-align="center" max-height="470">
|
||
|
<el-table-column type="index" width="55" label="序号" align="center"></el-table-column>
|
||
|
<el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
|
||
|
<el-table-column prop="projectName" width="80" label="系统类型" align="center">
|
||
|
<template slot-scope="scope">
|
||
|
{{ scope.row.type === 1 ? '流程类' : scope.row.type === 3 ? '理论' : '编程类' }}
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
|
||
|
<el-table-column prop="projectName" label="项目名称" align="center">
|
||
|
<template slot-scope="scope">
|
||
|
{{ scope.row.projectName || scope.row.paperName }}
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
<el-table-column label="操作" align="center" width="55">
|
||
|
<template slot-scope="scope">
|
||
|
<i :class="['el-icon-delete rm', { disabled: scope.row.disabled }]"
|
||
|
@click="delProject(scope.$index, scope.row)"></i>
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
</el-table>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<span slot="footer" class="dialog-footer">
|
||
|
<el-button @click="configVisible = false">取 消</el-button>
|
||
|
<el-button type="primary" @click="handleConfirm">确 定</el-button>
|
||
|
</span>
|
||
|
</el-dialog>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
import Util from '@/libs/util'
|
||
|
import Editor from '@tinymce/tinymce-vue'
|
||
|
import editorConfig from '@/utils/editor'
|
||
|
import Oss from '@/components/upload/upload.js'
|
||
|
export default {
|
||
|
components: {
|
||
|
Editor,
|
||
|
},
|
||
|
data () {
|
||
|
return {
|
||
|
headers: {
|
||
|
token: sessionStorage.getItem("token")
|
||
|
},
|
||
|
editorConfig,
|
||
|
isDetail: Boolean(this.$route.query.isDetail),
|
||
4 months ago
|
step: 1,
|
||
4 months ago
|
form: {
|
||
|
cid: this.$route.query.cid,
|
||
|
curriculumName: "",
|
||
|
curriculumType: '',
|
||
|
courseType: "",
|
||
|
categoryId: 1,
|
||
|
professionalCategoryId: 1,
|
||
|
professionalId: 1,
|
||
|
expectedCourse: "",
|
||
|
briefIntroduction: "",
|
||
|
teachingObjectives: "",
|
||
|
systemIdByAssessment: [],
|
||
|
systemIdByPractice: [],
|
||
|
supplier: [],
|
||
|
coverUrl: 'https://izhixinyun.com/images/course-cover.png',
|
||
|
mallDisciplines: [
|
||
|
{
|
||
|
professionalClassList: [],
|
||
|
professionalList: [],
|
||
|
categoryId: 1,
|
||
|
professionalCategoryId: 1,
|
||
|
professionalId: 1,
|
||
|
}
|
||
|
],
|
||
|
},
|
||
|
rules: {
|
||
|
curriculumName: [
|
||
|
{ required: true, message: "请输入课程名称", trigger: "blur" }
|
||
|
],
|
||
|
categoryId: [
|
||
|
{ required: true, message: "请选择学科类别", trigger: "change" }
|
||
|
],
|
||
|
professionalId: [
|
||
|
{ required: true, message: "请选择专业", trigger: "change" }
|
||
|
],
|
||
|
supplier: [
|
||
|
{ required: true, message: "请选择供应厂商", trigger: "change" }
|
||
|
],
|
||
|
expectedCourse: [
|
||
|
{ required: true, message: "请选择预计课时", trigger: "change" }
|
||
|
],
|
||
|
professionalCategoryId: [
|
||
|
{ required: true, message: "请选择专业类", trigger: "change" }
|
||
|
],
|
||
|
courseType: [
|
||
|
{ required: true, message: "请选择课程类别", trigger: "change" }
|
||
|
],
|
||
|
},
|
||
|
subjectList: [],
|
||
|
ProfessionalClassList: [],
|
||
|
ProfessionalList: [],
|
||
|
|
||
|
pageNo: 1,
|
||
|
pageSize: 10,
|
||
|
multipleSelection: [],
|
||
|
systemKeyword: "",
|
||
|
searchTimer: null,
|
||
|
configVisible: false,// 配置弹框
|
||
|
|
||
|
permissions: "", // 练习:0;考核:1
|
||
|
practiceData: [],
|
||
|
practiceTotal: 0,
|
||
|
multiplePractice: [],
|
||
|
|
||
|
matches: [],
|
||
|
matcheTotal: 0,
|
||
|
multipleMatch: [],
|
||
|
submiting: false, // 新增编辑防抖标识
|
||
|
loadIns: null,
|
||
|
updateTime: 0,
|
||
|
systemAll: [],
|
||
|
systems: [],
|
||
|
systemsAll: [],
|
||
|
systemChecked: [],
|
||
|
curSystem: '',
|
||
|
projects: [],
|
||
|
projectKeyword: '',
|
||
|
checkedKeyword: '',
|
||
|
checkeds: [],
|
||
|
checkedAll: [],
|
||
|
checkAll: false,
|
||
|
suppliers: [],
|
||
|
mulSystem: this.$store.state.btns.includes('/curriculum:支持多系统组课'), // 是否支持多系统组课
|
||
|
|
||
|
|
||
|
status: [
|
||
|
{
|
||
|
id: 0,
|
||
|
name: '正常'
|
||
|
}
|
||
|
],
|
||
|
practiceData: [],
|
||
|
practiceTotal: 0,
|
||
|
multiplePractice: [],
|
||
|
|
||
|
assessmentData: [],
|
||
|
assessmentTotal: 0,
|
||
|
multipleAssessment: [],
|
||
|
};
|
||
|
},
|
||
|
watch: {
|
||
|
// 监听信息是否有更改,有的话页面离开的时候要询问是否要保存
|
||
|
form: {
|
||
|
handler () {
|
||
|
this.updateTime++
|
||
|
},
|
||
|
deep: true
|
||
|
},
|
||
|
systemKeyword: function (val) {
|
||
|
clearTimeout(this.searchTimer);
|
||
|
this.searchTimer = setTimeout(() => {
|
||
|
this.getConfig();
|
||
|
}, 500);
|
||
|
},
|
||
|
projectKeyword: function (val) {
|
||
|
clearTimeout(this.searchTimer);
|
||
|
this.searchTimer = setTimeout(() => {
|
||
|
this.getProject();
|
||
|
}, 500);
|
||
|
},
|
||
|
checkedKeyword: function (val) {
|
||
|
clearTimeout(this.searchTimer);
|
||
|
this.searchTimer = setTimeout(() => {
|
||
|
this.filterChecked();
|
||
|
}, 500);
|
||
|
}
|
||
|
},
|
||
|
created () {
|
||
|
|
||
|
},
|
||
|
mounted () {
|
||
|
this.getSubject()
|
||
|
this.getConfig()
|
||
|
this.getSystem()
|
||
|
this.getSupplier()
|
||
|
this.form.cid && this.getInfoData()
|
||
|
},
|
||
|
methods: {
|
||
|
getInfoData () {
|
||
|
this.$post(`${this.api.curriculumDetail}?cid=${this.form.cid}`).then(({ data }) => {
|
||
|
if (data.supplier) data.supplier = data.supplier.split(',').map(e => +e)
|
||
|
if (data.categoryId) {
|
||
|
this.$get(this.api.courseProfessionalClass, { disciplineId: data.categoryId }).then(res => {
|
||
|
this.ProfessionalClassList = res.list;
|
||
|
}).catch(res => { });
|
||
|
}
|
||
|
if (data.professionalCategoryId) {
|
||
|
this.$get(this.api.courseProfessional, { professionalClassId: data.professionalCategoryId }).then(res => {
|
||
|
this.ProfessionalList = res.list;
|
||
|
}).catch(res => { });
|
||
|
}
|
||
|
this.$nextTick(() => {
|
||
|
this.form = data;
|
||
|
const pList = data.practiceConfig
|
||
|
const { systemsAll } = this
|
||
|
pList.map(e => {
|
||
|
if (!systemsAll.find(n => n.systemId == e.systemId)) e.disabled = true
|
||
|
})
|
||
|
this.practiceData = pList
|
||
|
|
||
|
const aList = data.assessmentConfig
|
||
|
aList.map(e => {
|
||
|
if (!systemsAll.find(n => n.systemId == e.systemId)) e.disabled = true
|
||
|
})
|
||
|
this.assessmentData = aList
|
||
|
|
||
|
const cList = data.competitionConfig
|
||
|
cList.map(e => {
|
||
|
if (!systemsAll.find(n => n.systemId == e.systemId)) e.disabled = true
|
||
|
})
|
||
|
this.matches = cList
|
||
|
});
|
||
|
}).catch(err => {
|
||
|
});
|
||
|
},
|
||
|
// 获取供应厂商
|
||
|
getSupplier () {
|
||
|
const sid = this.$store.state.dataPer.find(e => e.permissionName === '课程管理')
|
||
|
this.$get(this.api.getSupplierListByRole, {
|
||
|
permissionId: sid.permissionId
|
||
|
}).then(res => {
|
||
|
this.suppliers = res.supplierList
|
||
|
}).catch(res => { })
|
||
|
},
|
||
|
// 获取系统
|
||
|
getSystem () {
|
||
|
const checked = this[!this.permissions ?
|
||
|
'practiceData' :
|
||
|
this.permissions == 1 ?
|
||
|
'assessmentData' :
|
||
|
'matches']
|
||
|
const sid = this.$store.state.dataPer.find(e => e.permissionName === '课程管理')
|
||
|
this.$post(this.api.queryServiceConfig, {
|
||
|
systemName: '',
|
||
|
pageNum: 1,
|
||
|
pageSize: 1000,
|
||
|
supplierId: sid ? sid.supplierId : ''
|
||
|
}).then(({ serviceList }) => {
|
||
|
this.systemsAll = serviceList.records
|
||
|
}).catch(err => { })
|
||
|
},
|
||
|
|
||
|
// 添加学科
|
||
|
addSubject () {
|
||
|
const e = {
|
||
|
professionalClassList: [],
|
||
|
professionalList: [],
|
||
|
categoryId: 1,
|
||
|
professionalCategoryId: 1,
|
||
|
professionalId: 1,
|
||
|
}
|
||
|
this.form.mallDisciplines.push(e)
|
||
|
this.getProfessionalClassData(e)
|
||
|
},
|
||
|
// 获取学科类别
|
||
|
getSubject () {
|
||
|
this.$get(this.api.courseDiscipline).then(res => {
|
||
|
this.subjectList = res.list
|
||
|
this.form.mallDisciplines.forEach(e => {
|
||
|
e.categoryId === 1 && this.getProfessionalClass(e)
|
||
|
})
|
||
|
}).catch(err => { })
|
||
|
},
|
||
|
// 清除学科类别
|
||
|
clearClass (item) {
|
||
|
item.professionalCategoryId = item.categoryId === 1 ? 1 : ''
|
||
|
item.professionalId = item.categoryId === 1 ? 1 : ''
|
||
|
},
|
||
|
// 获取专业类
|
||
|
getProfessionalClass (item) {
|
||
|
this.clearClass(item);
|
||
|
this.getProfessionalClassData(item);
|
||
|
},
|
||
|
getProfessionalClassData (item) {
|
||
|
this.$get(this.api.courseProfessionalClass, {
|
||
|
disciplineId: item.categoryId
|
||
|
}).then(res => {
|
||
|
item.professionalClassList = res.list
|
||
|
this.form.mallDisciplines.forEach(e => {
|
||
|
e.professionalCategoryId === 1 && this.getProfessional(e)
|
||
|
})
|
||
|
}).catch(err => { })
|
||
|
},
|
||
|
// 清除专业类
|
||
|
clearProfess (item) {
|
||
|
item.professionalId = item.professionalCategoryId === 1 ? 1 : ''
|
||
|
},
|
||
|
// 获取专业
|
||
|
getProfessional (item) {
|
||
|
this.clearProfess(item);
|
||
|
this.getProfessionalData(item);
|
||
|
},
|
||
|
getProfessionalData (item) {
|
||
|
this.$get(this.api.courseProfessional, {
|
||
|
professionalClassId: item.professionalCategoryId
|
||
|
}).then(res => {
|
||
|
item.professionalList = res.list
|
||
|
}).catch(err => { })
|
||
|
},
|
||
|
|
||
|
|
||
|
handleExceed (files, fileList) {
|
||
|
Util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`);
|
||
|
},
|
||
|
// 封面自定义上传
|
||
|
async handleRequest ({ file }) {
|
||
|
Oss.upload(file).then(res => {
|
||
|
this.form.coverUrl = res.url
|
||
|
})
|
||
|
},
|
||
|
uploadError (err, file, fileList) {
|
||
|
this.$message({
|
||
|
message: "上传出错,请重试!",
|
||
|
type: "error",
|
||
|
center: true
|
||
|
})
|
||
|
},
|
||
|
beforeRemove (file, fileList) {
|
||
|
return this.$confirm(`确定移除 ${file.name}?`);
|
||
|
},
|
||
|
handleRemove () {
|
||
|
Oss.del(this.form.coverUrl)
|
||
|
this.form.coverUrl = ''
|
||
|
},
|
||
|
|
||
|
// 获取系统
|
||
|
getConfig () {
|
||
|
const checked = this[!this.permissions ?
|
||
|
'practiceData' :
|
||
|
this.permissions == 1 ?
|
||
|
'assessmentData' :
|
||
|
'matches']
|
||
|
const sid = this.$store.state.dataPer.find(e => e.permissionName === '课程管理')
|
||
|
this.$post(this.api.queryServiceConfig, {
|
||
|
systemName: this.systemKeyword,
|
||
|
pageNum: 1,
|
||
|
pageSize: 1000,
|
||
|
supplierId: sid ? sid.supplierId : ''
|
||
|
}).then(res => {
|
||
|
const list = res.serviceList.records
|
||
|
this.systemAll = JSON.parse(JSON.stringify(list)) // 全部系统,另外保存
|
||
|
const result = []
|
||
|
list.map(e => {
|
||
|
// 如果选中的项目里有该系统的项目,则隐藏
|
||
|
// if (!checked.find(n => n.systemId == e.systemId)) {
|
||
|
// e.check = !!checked.find(n => n.systemId == e.systemId)
|
||
|
e.check = false
|
||
|
result.push(e)
|
||
|
// }
|
||
|
})
|
||
|
this.systems = result
|
||
|
this.checkAll = !!checked.find(n => n.systemId == result[0].systemId) // 因为默认显示第一个系统的项目,所以如果系统默认选中,则全选也勾选上
|
||
|
result.length && this.getProject(result[0])
|
||
|
}).catch(err => { })
|
||
|
},
|
||
|
// 获取项目列表
|
||
|
async getProject (item, fromSystemChange) {
|
||
|
const checked = this.checkeds
|
||
|
if (item) this.curSystem = item.systemId
|
||
|
let res
|
||
|
if (!fromSystemChange) {
|
||
|
res = await this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${this.curSystem}&keyword=${this.projectKeyword}`)
|
||
|
}
|
||
|
const result = []
|
||
|
const projects = fromSystemChange ? this.projects : res
|
||
|
projects.map(e => {
|
||
|
// 如果选择了该项目,则禁用并选中
|
||
|
const include = checked.some(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && n.paperId == e.paperId))
|
||
|
e.check = include
|
||
|
result.push(e)
|
||
|
})
|
||
|
this.checkAll = !result.filter(e => !e.check).length
|
||
|
this.projects = result
|
||
|
},
|
||
|
// 系统选择回调
|
||
|
systemChange (val, item) {
|
||
|
// 项目列表选中状态同步
|
||
|
const { projects, checkeds } = this
|
||
|
if (projects.length && projects[0].systemId == item.systemId) {
|
||
|
projects.map(e => {
|
||
|
e.check = val
|
||
|
})
|
||
|
}
|
||
|
this.projectKeyword = ''
|
||
|
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}&keyword=${this.projectKeyword}`).then(res => {
|
||
|
if (val) {
|
||
|
// 如果不支持多选系统,选中后全部取消选中再选中当前系统
|
||
|
if (!this.mulSystem) {
|
||
|
this.systems.map(e => e.check = false)
|
||
|
item.check = true
|
||
|
}
|
||
|
res.map(e => {
|
||
|
if (!checkeds.find(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))) {
|
||
|
checkeds.push(e)
|
||
|
}
|
||
|
})
|
||
|
} else {
|
||
|
res.map(e => {
|
||
|
const i = checkeds.findIndex(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))
|
||
|
i === -1 || checkeds.splice(i, 1)
|
||
|
})
|
||
|
}
|
||
|
this.checkedAll = JSON.parse(JSON.stringify(checkeds)) // 全部已选项目,另外保存
|
||
|
this.getProject(item, 1)
|
||
|
}).catch(err => { })
|
||
|
},
|
||
|
// 项目全选回调
|
||
|
checkAllChange (val, systemId) {
|
||
|
this.systemChange(val, { systemId })
|
||
|
this.systems.map(e => {
|
||
|
if (e.systemId == systemId) e.check = val
|
||
|
})
|
||
|
},
|
||
|
// 项目选择回调
|
||
|
projectChange (val, item) {
|
||
|
const { systemId, paperId } = item
|
||
|
const i = this.checkeds.findIndex(e => (item.projectId && e.projectId == item.projectId && e.systemId == systemId) || (paperId && paperId == e.paperId))
|
||
|
// 选中,则push,否则移除
|
||
|
if (val) {
|
||
|
this.checkeds.push(item)
|
||
|
} else if (i !== -1) {
|
||
|
this.checkeds.splice(i, 1)
|
||
|
}
|
||
|
// 同步系统
|
||
|
this.systems.map(e => {
|
||
|
if (e.systemId == systemId) e.check = !this.projects.filter(n => !n.check).length
|
||
|
})
|
||
|
this.checkAll = !this.projects.find(e => !e.check) // 同步全选框
|
||
|
this.checkedAll = JSON.parse(JSON.stringify(this.checkeds)) // 全部已选项目,另外保存
|
||
|
},
|
||
|
// 已选择项目模糊查询
|
||
|
filterChecked () {
|
||
|
const val = this.checkedKeyword
|
||
|
this.checkeds = this.checkedAll.filter(e => (e.projectName && e.projectName.includes(val)) || (e.paperName && e.paperName.includes(val)))
|
||
|
},
|
||
|
// 删除已选项目
|
||
|
delProject (i, e) {
|
||
|
if (e.disabled) return
|
||
|
this.$confirm("确定要删除吗?", "提示", {
|
||
|
type: "warning"
|
||
|
}).then(() => {
|
||
|
this.checkeds.splice(i, 1)
|
||
|
// 如果当前展示的项目列表跟删掉的项目是同个系统,则找到项目列表里删掉的该项目,重置check和disabled
|
||
|
if (e.systemId == this.curSystem) {
|
||
|
const { projectId, paperId } = e
|
||
|
this.projects.map(n => {
|
||
|
if ((projectId && n.projectId == projectId) || (paperId && n.paperId == paperId)) {
|
||
|
n.check = false
|
||
|
}
|
||
|
})
|
||
|
this.checkAll = !this.projects.find(e => !e.check)
|
||
|
}
|
||
|
this.systems.map(n => {
|
||
|
if (n.systemId == e.systemId) n.check = false
|
||
|
})
|
||
|
}).catch(() => { })
|
||
|
},
|
||
|
// 确认系统
|
||
|
handleConfirm () {
|
||
|
const list = this.checkeds
|
||
|
if (!list.length) {
|
||
|
this.$message.warning("请选择系统!");
|
||
|
} else {
|
||
|
this.configVisible = false
|
||
|
list.map((e, i) => {
|
||
|
e.isShow = 0; // isShow是否展示(默认0:展示 1:不展示)
|
||
|
e.sort = i + 1; // 排序
|
||
|
});
|
||
|
if (!this.permissions) {
|
||
|
this.practiceData = JSON.parse(JSON.stringify(list))
|
||
|
this.practiceTotal = this.practiceData.length;
|
||
|
} else if (this.permissions == 1) {
|
||
|
this.assessmentData = JSON.parse(JSON.stringify(list))
|
||
|
this.assessmentTotal = this.assessmentData.length;
|
||
|
} else if (this.permissions == 2) {
|
||
|
this.matches = JSON.parse(JSON.stringify(list))
|
||
|
this.matchTotal = this.matches.length;
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
handleSelectionPractice (val) { // 多选练习项目
|
||
|
this.multiplePractice = val;
|
||
|
},
|
||
|
handleSelectionMatch (val) { // 多选竞赛项目
|
||
|
this.multipleMatch = val;
|
||
|
},
|
||
|
|
||
|
// 练习考核弹框
|
||
|
handleConfig (type) {
|
||
|
this.systemKeyword = ''
|
||
|
this.projectKeyword = ''
|
||
|
this.checkedKeyword = ''
|
||
|
this.permissions = type;
|
||
|
this.configVisible = true;
|
||
|
this.pageNo = 1;
|
||
|
this.getConfig();
|
||
|
this.checkeds = JSON.parse(JSON.stringify(type == 1 ? this.assessmentData : type == 2 ? this.matches : this.practiceData))
|
||
|
this.checkedAll = JSON.parse(JSON.stringify(this.checkeds))
|
||
|
},
|
||
|
handleBatchDelete (type) { // 批量移除
|
||
|
if (type == 1 && !this.multipleAssessment.length) {
|
||
|
this.$message.warning("请勾选考核项目!");
|
||
|
return;
|
||
|
} else if (!type && !this.multiplePractice.length) {
|
||
|
this.$message.warning("请勾选练习项目!");
|
||
|
return;
|
||
|
} else if (type == 2 && !this.multipleMatch.length) {
|
||
|
this.$message.warning("请勾选竞赛项目!");
|
||
|
return;
|
||
|
}
|
||
|
this.$confirm("此操作将批量移除项目, 是否继续?", "提示", {
|
||
|
type: "warning"
|
||
|
}).then(() => {
|
||
|
if (type == 1) {
|
||
|
let ids = this.multipleAssessment.map(i => i.projectId);
|
||
|
let tempArr = [];
|
||
|
for (let i = 0; i < this.assessmentData.length; i++) {
|
||
|
if (!ids.includes(this.assessmentData[i].projectId)) {
|
||
|
tempArr.push(this.assessmentData[i]);
|
||
|
}
|
||
|
}
|
||
|
this.assessmentData = tempArr;
|
||
|
} else if (!type) {
|
||
|
let ids = this.multiplePractice.map(i => i.projectId);
|
||
|
let tempArr = [];
|
||
|
for (let i = 0; i < this.practiceData.length; i++) {
|
||
|
if (!ids.includes(this.practiceData[i].projectId)) {
|
||
|
tempArr.push(this.practiceData[i]);
|
||
|
}
|
||
|
}
|
||
|
this.practiceData = tempArr;
|
||
|
} else {
|
||
|
let ids = this.multipleMatch.map(i => i.projectId);
|
||
|
let tempArr = [];
|
||
|
for (let i = 0; i < this.matches.length; i++) {
|
||
|
if (!ids.includes(this.matches[i].projectId)) {
|
||
|
tempArr.push(this.matches[i]);
|
||
|
}
|
||
|
}
|
||
|
this.matches = tempArr;
|
||
|
}
|
||
|
this.$message.success("批量移除成功");
|
||
|
}).catch(() => {
|
||
|
this.$message.info("已取消批量移除");
|
||
|
});
|
||
|
},
|
||
|
handleDelete (index, data) { // 移除
|
||
|
this.$confirm("此操作将移除该项目, 是否继续?", "提示", {
|
||
|
type: "warning"
|
||
|
}).then(() => {
|
||
|
data.splice(index, 1);
|
||
|
this.$message.success("移除成功");
|
||
|
}).catch(() => {
|
||
|
this.$message.info("已取消移除");
|
||
|
});
|
||
|
},
|
||
|
practiceSortChange (row, index) { // 处理排序
|
||
|
this.practiceData.splice(index, 1, row);
|
||
|
},
|
||
|
|
||
|
save () {
|
||
|
this.$refs.form.validate((valid) => {
|
||
|
if (valid) {
|
||
|
if (this.submiting) return false
|
||
|
const form = JSON.parse(JSON.stringify(this.form))
|
||
|
form.supplier = form.supplier.join()
|
||
|
|
||
|
this.submiting = true
|
||
|
this.loadIns = this.$loading({
|
||
|
lock: true,
|
||
|
text: 'Loading',
|
||
|
spinner: 'el-icon-loading',
|
||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||
|
})
|
||
|
debugger
|
||
|
if (form.cid) {
|
||
|
this.$post(this.api.modifyCourse, form).then((res) => {
|
||
|
this.$message.success("编辑成功");
|
||
|
}).catch((res) => {
|
||
|
this.submiting = false
|
||
|
this.loadIns.close()
|
||
|
});
|
||
|
} else {
|
||
|
this.$post(this.api.createCurriculum, form).then((res) => {
|
||
|
this.loadIns.close()
|
||
|
this.$router.push('/curriculum')
|
||
|
}).catch((res) => {
|
||
|
this.submiting = false
|
||
|
this.loadIns.close()
|
||
|
});
|
||
|
}
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
},
|
||
4 months ago
|
// 返回上一页
|
||
|
back () {
|
||
|
this.loadIns && this.loadIns.close()
|
||
|
this.$router.push(this.$store.state.referrer || '/curriculum')
|
||
|
}
|
||
4 months ago
|
}
|
||
|
};
|
||
|
</script>
|
||
|
|
||
|
<style lang="scss" scoped>
|
||
|
.wrap {
|
||
|
.steps {
|
||
|
display: flex;
|
||
|
justify-content: center;
|
||
|
margin-bottom: 20px;
|
||
|
|
||
|
&.pointer {
|
||
|
li {
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
li {
|
||
|
position: relative;
|
||
|
margin-right: 100px;
|
||
|
text-align: center;
|
||
|
}
|
||
|
|
||
|
.circle {
|
||
|
display: inline-flex;
|
||
|
justify-content: center;
|
||
|
align-items: center;
|
||
|
width: 35px;
|
||
|
margin: 0 auto 10px;
|
||
|
line-height: 35px;
|
||
|
font-size: 18px;
|
||
|
color: #333;
|
||
|
background: #f9f9f9;
|
||
|
border: 5px solid #e1e1e1;
|
||
|
border-radius: 50%;
|
||
|
|
||
|
&:after {
|
||
|
content: '';
|
||
|
position: absolute;
|
||
|
left: 64px;
|
||
|
width: 146px;
|
||
|
height: 3px;
|
||
|
background: #e1e1e1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.active {
|
||
|
.circle {
|
||
|
color: #fff;
|
||
|
border-color: #26499f;
|
||
|
background: #062c87;
|
||
|
}
|
||
|
|
||
|
.text {
|
||
|
color: #062c87;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.done {
|
||
|
.circle {
|
||
|
color: #fff;
|
||
|
background: #062c87;
|
||
|
border-color: #26499f;
|
||
|
|
||
|
&:after {
|
||
|
background: #062c87;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.text {
|
||
|
color: #062c87;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.circle2:after {
|
||
|
left: 71px;
|
||
|
width: 147px;
|
||
|
}
|
||
|
|
||
|
.circle4:after {
|
||
|
display: none;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.overflow {
|
||
|
height: calc(100vh - 342px);
|
||
|
margin-bottom: 20px;
|
||
|
overflow: auto;
|
||
|
}
|
||
|
|
||
|
.btns {
|
||
|
text-align: center;
|
||
|
}
|
||
|
|
||
|
.form {
|
||
|
width: 1000px;
|
||
|
margin: 0 auto;
|
||
|
}
|
||
|
|
||
|
/deep/.w-input {
|
||
|
width: 400px;
|
||
|
}
|
||
|
|
||
|
.cover-wrap {
|
||
|
display: flex;
|
||
|
justify-content: space-around;
|
||
|
|
||
|
.preview-title {
|
||
|
margin-bottom: 10px;
|
||
|
font-size: 16px;
|
||
|
color: #000;
|
||
|
text-align: center;
|
||
|
}
|
||
|
|
||
|
.preview-pic {
|
||
|
width: 220px;
|
||
|
max-height: 140px;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.subject {
|
||
|
padding: 10px;
|
||
|
border: 1px dashed #ccc;
|
||
|
|
||
|
.line {
|
||
|
position: relative;
|
||
|
display: flex;
|
||
|
padding-right: 50px;
|
||
|
margin-bottom: 10px;
|
||
|
|
||
|
&:last-child {
|
||
|
margin-bottom: 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.el-form-item {
|
||
|
margin-bottom: 0;
|
||
|
}
|
||
|
|
||
|
.del {
|
||
|
position: absolute;
|
||
|
top: 11px;
|
||
|
right: 20px;
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.subject-plus {
|
||
|
margin-top: 5px;
|
||
|
text-align: center;
|
||
|
font-size: 18px;
|
||
|
color: #062c87;
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
}
|
||
|
|
||
4 months ago
|
.modal {
|
||
|
width: 500px;
|
||
|
padding-top: 150px;
|
||
|
margin: 0 auto;
|
||
|
|
||
|
h1 {
|
||
|
margin: 20px;
|
||
|
text-align: center;
|
||
|
}
|
||
|
|
||
|
.btns {
|
||
|
text-align: center;
|
||
|
}
|
||
|
}
|
||
|
|
||
4 months ago
|
/deep/.config-dia {
|
||
|
.config-wrap {
|
||
|
display: flex;
|
||
|
}
|
||
|
|
||
|
.title-wrap {
|
||
|
margin-bottom: 15px;
|
||
|
}
|
||
|
|
||
|
.item {
|
||
|
width: 250px;
|
||
|
max-height: 600px;
|
||
|
padding: 10px;
|
||
|
margin-right: 20px;
|
||
|
overflow: hidden;
|
||
|
}
|
||
|
|
||
|
.system {
|
||
|
background-color: #f9f9f9;
|
||
|
}
|
||
|
|
||
|
.systems {
|
||
|
margin-top: 10px;
|
||
|
max-height: 520px;
|
||
|
overflow: auto;
|
||
|
|
||
|
li {
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
margin: 10px 0;
|
||
|
}
|
||
|
|
||
|
.name {
|
||
|
display: inline-flex;
|
||
|
flex: 1;
|
||
|
justify-content: space-between;
|
||
|
align-items: center;
|
||
|
margin-left: 5px;
|
||
|
cursor: pointer;
|
||
|
|
||
|
&.active,
|
||
|
&:hover {
|
||
|
color: #062c87;
|
||
|
}
|
||
|
|
||
|
span {
|
||
|
max-width: 200px;
|
||
|
text-overflow: ellipsis;
|
||
|
white-space: nowrap;
|
||
|
overflow: hidden;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.checked {
|
||
|
flex: 1;
|
||
|
width: auto;
|
||
|
|
||
|
.el-table .cell {
|
||
|
font-size: 12px;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.rm {
|
||
|
font-size: 14px;
|
||
|
cursor: pointer;
|
||
|
|
||
|
&.disabled {
|
||
|
color: #ccc;
|
||
|
cursor: not-allowed;
|
||
|
}
|
||
|
|
||
|
&:hover {
|
||
|
color: #17161f;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</style>
|