dev_202412
yujialong 2 months ago
parent 78a7ecd845
commit ebc36e7376
  1. 2
      src/components/editor.js
  2. 4
      src/layouts/header/index.vue
  3. 3
      src/pages/lesson/content/source.vue
  4. 458
      src/pages/lesson/detail/index.vue
  5. 29
      src/pages/lesson/list/index.vue
  6. 5
      src/styles/common.scss

@ -625,6 +625,8 @@ export default {
ed.target.editorCommands.execCommand("fontName", false, "Microsoft Yahei")
ed.target.editorCommands.execCommand("fontSize", false, "14px")
ed.target.editorCommands.execCommand("lineHeight", false, "1.5")
const el = top.document.querySelector('#focus-el')
el && el.focus() // 第一个字段聚焦
})
},
}

@ -17,8 +17,8 @@
<span class="m-l-10">{{ customerName || userName }}</span>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-if="!customerName" command="person">个人中心</el-dropdown-item>
<el-dropdown-item v-else command="resetPw">修改密码</el-dropdown-item>
<el-dropdown-item command="person">个人中心</el-dropdown-item>
<!-- <el-dropdown-item v-else command="resetPw">修改密码</el-dropdown-item> -->
</el-dropdown-menu>
</el-dropdown>
<el-divider direction="vertical"></el-divider>

@ -62,7 +62,7 @@
<el-input placeholder="请输入资源名称" prefix-icon="el-icon-search" v-model="checkedKeyword" clearable></el-input>
<div :class="['lines']">
<div class="lines">
<template v-for="(item, i) in checked">
<div v-if="item.name.includes(checkedKeyword)" :key="i" class="line">
<div class="check-left">
@ -81,7 +81,6 @@
<img class="icon" src="@/assets/img/empty.svg" alt="">
<p>暂无数据</p>
</div>
</div>
</div>

@ -216,36 +216,41 @@
</div>
<!-- 配置弹窗 -->
<el-dialog :visible.sync="configVisible" width="1200px" center custom-class="config-dia">
<el-drawer title="添加系统资源" :visible.sync="configVisible" size="1200px" :close-on-click-modal="false"
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>
<h6 class="p-title" style="margin-bottom: 0;">课程系统列表</h6>
<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 class="line">
<el-checkbox v-model="item.check" @change="val => courseChange(val, item)"></el-checkbox>
<div :class="['name', { active: curSystem == item.id }]" @click="getProject(item)">
<span>{{ item.label }}</span>
<i class="el-icon-arrow-right"></i>
</div>
</div>
<div class="children">
<div v-for="(system, j) in item.children" :key="j" :title="system.label" class="line">
<el-checkbox v-model="system.check" @change="val => systemChange(val, system, item)"></el-checkbox>
<div :class="['name', { active: curSystem == item.id }]" @click="getProject(system)">
<span>{{ system.label }}</span>
<i class="el-icon-arrow-right"></i>
</div>
</div>
</div>
</li>
</ul>
</div>
<div class="item project">
<div class="title-wrap flex-center">
<p class="addhr_tag"></p>
<span>项目列表</span>
</div>
<h6 class="p-title">项目列表</h6>
<el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="projectKeyword"
clearable></el-input>
<ul class="systems">
<ul class="projects">
<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">
@ -257,33 +262,33 @@
</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 v-if="checkeds.length">
<div class="flex-between m-b-10">
<p class="total">已选项目{{ checkeds.length }}</p>
<el-button type="text" @click="batchDelChecked">批量移除</el-button>
</div>
<el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model="checkedKeyword" clearable></el-input>
<div class="lines">
<template v-for="(item, i) in checkeds">
<div v-if="item.projectName.includes(checkedKeyword)" :key="i" class="line">
<div class="check-left">
<el-checkbox v-model="item.check"></el-checkbox>
<span class="serial">{{ i + 1 }}</span>
<el-tooltip effect="dark" :content="item.projectName" placement="top-start">
<p class="checked-name ellipsis">{{ item.projectName }}</p>
</el-tooltip>
</div>
<i class="el-icon-delete action-icon" @click="delProject(item)"></i>
</div>
</template>
</el-table-column>
</el-table>
</div>
</template>
<div v-else class="none">
<img class="icon" src="@/assets/img/empty.svg" alt="">
<p>暂无数据</p>
</div>
</div>
</div>
@ -291,7 +296,7 @@
<el-button @click="configVisible = false"> </el-button>
<el-button type="primary" @click="handleConfirm"> </el-button>
</span>
</el-dialog>
</el-drawer>
</div>
</template>
@ -301,6 +306,7 @@ import Util from '@/libs/util'
import Editor from '@tinymce/tinymce-vue'
import editorConfig from '@/components/editor'
import Oss from '@/components/upload/upload.js'
import _ from 'lodash'
export default {
components: {
Editor,
@ -308,11 +314,8 @@ export default {
data () {
return {
cid: this.$route.query.cid,
headers: {
token: sessionStorage.getItem("token")
},
editorConfig,
step: 1,
step: 2,
form: {
curriculumName: "",
curriculumType: '',
@ -325,7 +328,6 @@ export default {
teachingObjectives: "",
systemIdByAssessment: [],
systemIdByPractice: [],
supplier: [],
coverUrl: 'https://izhixinyun.com/images/course-cover.png',
curriculumDisciplines: [
{
@ -350,9 +352,6 @@ export default {
professionalId: [
{ required: true, message: "请选择专业", trigger: "change" }
],
supplier: [
{ required: true, message: "请选择供应厂商", trigger: "change" }
],
expectedCourse: [
{ required: true, message: "请选择预计课时", trigger: "change" }
],
@ -364,17 +363,14 @@ export default {
],
},
subjectList: [],
ProfessionalClassList: [],
ProfessionalList: [],
pageNo: 1,
pageSize: 10,
multipleSelection: [],
systemKeyword: "",
searchTimer: null,
configVisible: false,//
permissions: "", // 01
permissions: '', // 01
practiceData: [],
practiceTotal: 0,
multiplePractice: [],
@ -387,7 +383,6 @@ export default {
updateTime: 0,
systemAll: [],
systems: [],
systemsAll: [],
systemChecked: [],
curSystem: '',
projects: [],
@ -397,17 +392,6 @@ export default {
checkedAll: [],
checkAll: false,
status: [
{
id: 0,
name: '正常'
}
],
practiceData: [],
practiceTotal: 0,
multiplePractice: [],
assessmentData: [],
assessmentTotal: 0,
multipleAssessment: [],
@ -421,54 +405,28 @@ export default {
},
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);
this.getProject()
}, 500)
},
checkedKeyword: function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.filterChecked();
}, 500);
}
},
created () {
},
mounted () {
this.getSubject()
this.getConfig()
this.getSystem()
this.getCourseSystem()
this.cid && this.getInfoData()
},
methods: {
getInfoData () {
this.$post(`${this.api.curriculumDetail}?cid=${this.cid}`).then(({ data }) => {
if (data.supplier) data.supplier = data.supplier.split(',').map(e => +e)
this.form = data
this.practiceData = data.practiceConfig
this.assessmentData = data.assessmentConfig
this.$nextTick(() => {
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
this.form.curriculumDisciplines.forEach(e => {
this.$set(e, 'professionalClassList', [])
this.$set(e, 'professionalList', [])
@ -478,26 +436,31 @@ export default {
if (!e.professionalCategoryId) this.$set(e, 'professionalCategoryId', '')
if (!e.professionalId) this.$set(e, 'professionalId', '')
})
});
}).catch(err => {
});
},
//
getSystem () {
const checked = this[!this.permissions ?
'practiceData' :
this.permissions == 1 ?
'assessmentData' :
'matches']
this.$post(this.api.queryServiceConfig, {
systemName: '',
pageNum: 1,
pageSize: 1000,
supplierId: ''
}).then(({ serviceList }) => {
this.systemsAll = serviceList.records
})
}).catch(err => { })
},
//
async getCourseSystem () {
const res = await this.$get(this.api.getSystemIdBySchool)
const systems = res.data
const { data } = await this.$get(this.api.getSchoolEffectiveCourse)
if (systems.length && data.length) {
this.cid = [data[0].mallId]
data.map(e => {
e.id = e.mallId
e.label = e.curriculumName
e.check = false
const children = _.cloneDeep(systems.filter(n => e.systemId.split(',').includes(n.id + ''))) //
children.map(n => {
n.check = false
})
e.children = children
})
this.systems = data
// this.getProject(result[0])
}
},
//
addSubject () {
@ -582,56 +545,12 @@ export default {
this.form.coverUrl = ''
},
//
getConfig () {
const checked = this[!this.permissions ?
'practiceData' :
this.permissions == 1 ?
'assessmentData' :
'matches']
this.$post(this.api.queryServiceConfig, {
systemName: this.systemKeyword,
pageNum: 1,
pageSize: 1000,
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
//
courseChange (val, item) {
item.children.map(e => e.check = val)
},
//
systemChange (val, item) {
async systemChange (val, system, course) {
//
const { projects, checkeds } = this
if (projects.length && projects[0].systemId == item.systemId) {
@ -640,27 +559,55 @@ export default {
})
}
this.projectKeyword = ''
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}&keyword=${this.projectKeyword}`).then(res => {
const { data } = await this.$post(this.api.queryProjectManage, {
projectName: this.projectKeyword,
platformId: 1,
founder: 2,
permissions: this.permissions,
cid: course.cid,
mallId: course.mallId,
systemId: system.id,
pageNum: 1,
pageSize: 1000,
})
const list = data.records
list.forEach(e => {
e.check = val
const i = checkeds.findIndex(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))
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)
})
i === -1 && checkeds.push(e)
} else if (i !== -1) {
checkeds.splice(i, 1)
}
this.checkedAll = JSON.parse(JSON.stringify(checkeds)) //
this.getProject(item, 1)
}).catch(err => { })
})
this.checkedAll = _.cloneDeep(checkeds) //
},
//
async getProject (item, fromSystemChange) {
const checked = this.checkeds
if (item) this.curSystem = item.systemId
const { data } = await this.$post(this.api.queryProjectManage, {
projectName: this.projectKeyword,
platformId: 1,
founder: 2,
permissions: this.permissions,
cid: item.cid,
mallId: item.mallId,
systemId: item.children.map(e => e.id).join(),
pageNum: 1,
pageSize: 1000,
})
// 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
},
//
checkAllChange (val, systemId) {
@ -675,7 +622,7 @@ export default {
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)
i === -1 && this.checkeds.push(item)
} else if (i !== -1) {
this.checkeds.splice(i, 1)
}
@ -686,11 +633,6 @@ export default {
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
@ -730,9 +672,6 @@ export default {
} 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;
}
}
},
@ -745,13 +684,11 @@ export default {
//
handleConfig (type) {
this.systemKeyword = ''
this.projectKeyword = ''
this.checkedKeyword = ''
this.permissions = type;
this.configVisible = true;
this.pageNo = 1;
this.getConfig();
this.pageNo = 1
this.checkeds = JSON.parse(JSON.stringify(type == 1 ? this.assessmentData : type == 2 ? this.matches : this.practiceData))
this.checkedAll = JSON.parse(JSON.stringify(this.checkeds))
},
@ -828,7 +765,6 @@ export default {
if (valid) {
if (this.submiting) return false
const form = JSON.parse(JSON.stringify(this.form))
form.supplier = form.supplier.join()
form.platformId = Setting.platformId
this.submiting = true
this.loadIns = this.$loading({
@ -1082,27 +1018,65 @@ export default {
}
/deep/.config-dia {
.config-wrap {
.el-drawer__header {
padding-bottom: 20px;
margin-bottom: 0;
border-bottom: 1px solid #eee;
}
.none {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
font-size: 14px;
text-align: center;
color: #a3a3a3;
}
.title-wrap {
.p-title {
margin-bottom: 15px;
}
.config-wrap {
display: flex;
padding: 15px;
}
.item {
width: 250px;
max-height: 600px;
width: 350px;
height: calc(100vh - 93px);
padding: 10px;
margin-right: 20px;
overflow: hidden;
&.project {
border-right: 1px solid #eee;
}
}
.system {
width: 350px;
background-color: #f9f9f9;
}
.systems {
max-height: calc(100vh - 133px);
margin-top: 10px;
overflow: auto;
.line {
&>.name {
span {
max-width: 280px;
}
}
}
}
.projects {
margin-top: 10px;
max-height: 520px;
overflow: auto;
@ -1112,25 +1086,35 @@ export default {
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;
}
.name {
display: inline-flex;
flex: 1;
justify-content: space-between;
align-items: center;
margin-left: 5px;
cursor: pointer;
span {
max-width: 200px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
&.active,
&:hover {
color: #062c87;
}
.children {
padding-left: 20px;
.name {
span {
max-width: 200px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
max-width: 265px !important;
}
}
}
@ -1138,24 +1122,42 @@ export default {
.checked {
flex: 1;
width: auto;
}
.el-table .cell {
font-size: 12px;
}
.lines {
height: calc(100vh - 228px);
padding-right: 10px;
margin-top: 10px;
overflow: auto;
}
.rm {
font-size: 14px;
cursor: pointer;
.line {
display: flex;
align-items: center;
padding: 5px 0;
color: #333;
}
&.disabled {
color: #ccc;
cursor: not-allowed;
}
.serial {
width: 32px;
margin: 0 12px;
text-align: center;
white-space: nowrap;
}
&:hover {
color: #17161f;
}
.check-left {
display: inline-flex;
align-items: center;
}
.checked-name {
width: 360px;
margin-right: 20px;
}
.action-icon {
font-size: 14px;
cursor: pointer;
}
}
</style>

@ -44,8 +44,8 @@
</el-col>
<el-col :span="6">
<el-form-item>
<el-input placeholder="请输入课程名称" prefix-icon="el-icon-search" v-model="form.curriculumName" clearable
@keyup.enter.native="onSearch"></el-input>
<el-input placeholder="请输入课程名称" prefix-icon="el-icon-search" v-model="form.curriculumName"
clearable></el-input>
</el-form-item>
</el-col>
</el-form>
@ -65,7 +65,7 @@
</div>
</div>
<el-table v-loading="loading" :data="courseData" class="table" ref="table" header-align="center"
@selection-change="handleSelectionChange" :row-key="getRowKeys">
@selection-change="handleSelectionChange" row-key="cid">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="70" label="序号" align="center"></el-table-column>
<el-table-column prop="curriculumName" label="课程名称" align="center"></el-table-column>
@ -146,9 +146,6 @@ export default {
this.getData();
},
methods: {
getRowKeys (row) {
return row.cid;
},
//
getData () {
this.$post(this.api.curriculumList, {
@ -274,27 +271,21 @@ export default {
}
}).catch(err => { })
} else {
this.$message.warning("请先选择课程 !");
this.$message.warning("请先选择课程 !")
}
},
//
handleCurrentChange (val) {
this.page = val;
this.$router.push(`/curriculum?page=${val}`)
this.getData();
},
//
onSearch () {
this.page = 1;
this.getData();
this.page = val
this.$router.push(`list?page=${val}`)
this.getData()
},
//
changeSwitch (value, row) {
this.$post(`${this.api.isShelves}?cid=${row.cid}&isShelves=${value}`).then((res) => {
this.getData();
this.$message.success("修改上下架状态成功!");
}).catch((res) => {
});
this.getData()
this.$message.success("修改上下架状态成功!")
}).catch((res) => { })
}
}
};

@ -389,4 +389,9 @@
position: fixed;
top: 0;
left: 0;
}
.el-drawer__header > :first-child {
font-size: 16px;
font-weight: 600;
color: #333;
}
Loading…
Cancel
Save