|
@@ -1,18 +1,21 @@
|
|
|
<template>
|
|
|
<div class="syllabus-tree-main">
|
|
|
<vuescroll>
|
|
|
- <el-tree :data="treeDatas" :props="defaultProps" class="tree" node-key="id" default-expand-all highlight-current
|
|
|
- @node-drop="handleDrop" @node-click="onNodeClick" :draggable="editable" :expand-on-click-node="false">
|
|
|
+ <el-tree :data="treeDatas" :props="defaultProps" :allow-drop="allowDrop" class="tree" node-key="id"
|
|
|
+ default-expand-all highlight-current @node-drop="handleDrop" @node-click="onNodeClick"
|
|
|
+ :draggable="editable" :expand-on-click-node="false" ref="tree">
|
|
|
<span class="custom-tree-node" slot-scope="{ node, data }">
|
|
|
<span class="tree-node-lable">
|
|
|
{{data.title}}
|
|
|
- <Icon type="md-cube" title="有关联资源" v-if="data.rnodes && data.rnodes.length"/>
|
|
|
+ <!-- {{data.id}} -->
|
|
|
+ <Icon type="md-cube" :title="$t('syllabus.tree.hasResource')" v-if="data.rnodes && data.rnodes.length" />
|
|
|
</span>
|
|
|
<span class="custom-tree-tools" v-if="editable">
|
|
|
- <Icon type="md-create" size="16" title="编辑" @click="onEditItem(node,data,$event)" />
|
|
|
- <Icon type="md-add" size="16" title="添加" @click="onAddNode(data,$event)" />
|
|
|
- <Icon type="md-remove" size="16" title="删除" @click="remove(node,data)" />
|
|
|
- <Icon type="md-share" v-if="isFirstLevel(data.pid)" @click="doShare(data)"/>
|
|
|
+ <Icon type="md-create" size="16" :title="$t('syllabus.tree.edit')" @click="onEditItem(node,data,$event)" />
|
|
|
+ <Icon type="md-add" size="16" :title="$t('syllabus.tree.add')" @click="onAddNode(node,data,$event)" />
|
|
|
+ <Icon type="md-remove" size="16" :title="$t('syllabus.tree.remove')" @click="remove(node,data)" />
|
|
|
+ <Icon type="md-share" v-if="isFirstLevel(data)" :title="isSchool ? $t('syllabus.tree.coEdit') : $t('syllabus.tree.share')"
|
|
|
+ @click="doShare(data)" />
|
|
|
</span>
|
|
|
</span>
|
|
|
</el-tree>
|
|
@@ -20,14 +23,15 @@
|
|
|
|
|
|
<!-- 新增或者编辑弹窗 -->
|
|
|
<Modal v-model="isEditOrAdd" width="500" footer-hide class="tree-modal">
|
|
|
- <div class="modal-header" slot="header">{{ isEditItem ? '编辑节点':'新增节点'}}</div>
|
|
|
+ <div class="modal-header" slot="header">{{ isEditItem ? $t('syllabus.tree.editTitle'):$t('syllabus.tree.addTitle')}}</div>
|
|
|
<div class="modal-content">
|
|
|
- <p class="node-title">父节点</p>
|
|
|
+ <p class="node-title">{{ $t('syllabus.tree.parent') }}</p>
|
|
|
<Input v-model="nodeInfo.parent" style="width: 100%" disabled />
|
|
|
- <p class="node-title">节点名称</p>
|
|
|
- <Input v-model="nodeInfo.title" placeholder="请输入节点名称..." style="width: 100%" />
|
|
|
+ <p class="node-title">{{ $t('syllabus.tree.nodeName') }}</p>
|
|
|
+ <Input v-model="nodeInfo.title" :placeholder="$t('syllabus.tree.place1')" style="width: 100%" />
|
|
|
</div>
|
|
|
- <Button @click="onSubmitNode" class="modal-btn" style="width: 88%;margin-left: 6%;margin-bottom: 20px;">确认</Button>
|
|
|
+ <Button @click="onSubmitNode" class="modal-btn"
|
|
|
+ style="width: 88%;margin-left: 6%;margin-bottom: 20px;">{{ $t('syllabus.tree.confirm') }}</Button>
|
|
|
</Modal>
|
|
|
</div>
|
|
|
</template>
|
|
@@ -65,7 +69,8 @@
|
|
|
currentParentData: null,
|
|
|
currentResources: [],
|
|
|
currentItems: [],
|
|
|
- curNode:null,
|
|
|
+ curNode: null,
|
|
|
+ curData:null,
|
|
|
nodeInfo: {
|
|
|
id: null,
|
|
|
title: '',
|
|
@@ -79,22 +84,50 @@
|
|
|
pid: '',
|
|
|
code: '',
|
|
|
status: 1,
|
|
|
- parent: ''
|
|
|
- }
|
|
|
+ parent: '',
|
|
|
+ rnodes:[]
|
|
|
+ },
|
|
|
+ isSchool: false,
|
|
|
+ flatArr:[]
|
|
|
}
|
|
|
},
|
|
|
+ created() {
|
|
|
+ this.isSchool = this.$route.name === 'syllabus'
|
|
|
+ },
|
|
|
methods: {
|
|
|
onNodeClick(data, node) {
|
|
|
- console.log(data, node)
|
|
|
- this.curNode = data
|
|
|
- this.$emit('onNodeClick',data)
|
|
|
+ this.curNode = node
|
|
|
+ this.curData = data
|
|
|
+ this.$emit('onNodeClick', {
|
|
|
+ data:data,
|
|
|
+ node:node
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ doShare(data) {
|
|
|
+ this.$emit('doShare', data)
|
|
|
},
|
|
|
|
|
|
- doShare(data){
|
|
|
- this.$emit('doShare',data)
|
|
|
+ /* 禁止一级节点往下级进行拖拽 */
|
|
|
+ allowDrop(draggingNode, dropNode, dropType) {
|
|
|
+ if (draggingNode.level === dropNode.level) {
|
|
|
+ if(draggingNode.level === 1){
|
|
|
+ return dropType === 'prev' || dropType === 'after'
|
|
|
+ }else{
|
|
|
+ return dropType === 'prev' || dropType === 'after' || dropType === 'inner'
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果是二三级拖到其他级别 则正常拖拽 但是不能拖到第一级
|
|
|
+ if(draggingNode.level !== 1 && dropNode.level !== 1){
|
|
|
+ return dropType === 'prev' || dropType === 'after' || dropType === 'inner'
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
},
|
|
|
// 拖拽完成回调
|
|
|
handleDrop(draggingNode, dropNode, dropType) {
|
|
|
+ this.$emit('addModifyId',this.getChapterIdById(draggingNode.data.id))
|
|
|
+ this.$emit('addModifyId',this.getChapterIdById(dropNode.data.id))
|
|
|
switch (dropType) {
|
|
|
case 'before':
|
|
|
draggingNode.data.pid = dropNode.data.pid
|
|
@@ -109,35 +142,58 @@
|
|
|
break
|
|
|
}
|
|
|
this.$parent.hasModify = true
|
|
|
+
|
|
|
},
|
|
|
|
|
|
// 删除节点操作
|
|
|
remove(node, data) {
|
|
|
+ let isFirstLevel = this.isFirstLevel(data)
|
|
|
this.$Modal.confirm({
|
|
|
- title: '删除节点',
|
|
|
- content: '<p>确认删除该节点?</p>',
|
|
|
- okText: '确认',
|
|
|
- cancelText: '取消',
|
|
|
+ title: this.$t('syllabus.tree.removeTitle'),
|
|
|
+ content: this.$t('syllabus.tree.removeConfirm'),
|
|
|
onOk: () => {
|
|
|
const parent = node.parent
|
|
|
const children = parent.data.children || parent.data
|
|
|
const index = children.findIndex(d => d.id === data.id)
|
|
|
- children.splice(index, 1)
|
|
|
- this.$Message.success('删除成功')
|
|
|
- this.$parent.hasModify = true
|
|
|
+ // 如果是删除的第一层的节点 则直接访问API进行删除 如果不是 则记录子节点的PID
|
|
|
+ if(isFirstLevel){
|
|
|
+ this.$api.syllabus.DeleteTree({
|
|
|
+ id:data.id,
|
|
|
+ code:this.volume.id,
|
|
|
+ scope:this.volume.scope
|
|
|
+ }).then(res => {
|
|
|
+ if (!res.error) {
|
|
|
+ if(res.code === 404){
|
|
|
+ this.$parent.modifyIdArr = this.$parent.modifyIdArr.filter(i => i !== data.id)
|
|
|
+ }
|
|
|
+ children.splice(index, 1)
|
|
|
+ this.$Message.success(this.$t('syllabus.tree.removeSucTip'))
|
|
|
+ } else {
|
|
|
+ this.$Message.warning(res.error);
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ this.$Message.error(err);
|
|
|
+ })
|
|
|
+ }else{
|
|
|
+ children.splice(index, 1)
|
|
|
+ this.$Message.success(this.$t('syllabus.tree.removeSucTip'))
|
|
|
+ this.$parent.hasModify = true
|
|
|
+ this.$emit('addModifyId',this.getChapterIdById(data.id))
|
|
|
+ }
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
|
|
|
// 点击添加展开弹窗
|
|
|
- onAddNode(data, e) {
|
|
|
+ onAddNode(node,data, e) {
|
|
|
e.stopPropagation() // 防止点击事件穿透到父层
|
|
|
this.isEditItem = false
|
|
|
this.isEditOrAdd = true
|
|
|
-
|
|
|
this.currentParentData = data // 当前点击节点即为父节点
|
|
|
this.nodeInfo.parent = data.title
|
|
|
+ this.nodeInfo.id = data.id
|
|
|
this.nodeInfo.title = ''
|
|
|
+ this.curNode = node
|
|
|
},
|
|
|
|
|
|
// 编辑节点操作
|
|
@@ -145,73 +201,27 @@
|
|
|
e.stopPropagation() // 防止点击事件穿透到父层
|
|
|
this.isEditOrAdd = true
|
|
|
this.isEditItem = true
|
|
|
-
|
|
|
this.currentEditData = data
|
|
|
this.nodeInfo.parent = node.parent.data.title || this.volume.name
|
|
|
this.nodeInfo.title = node.data.title
|
|
|
+ this.nodeInfo.id = node.data.id
|
|
|
+ this.curNode = node
|
|
|
},
|
|
|
-
|
|
|
-
|
|
|
- onRelatedContent(node, data, e) {
|
|
|
- e.stopPropagation() // 防止点击事件穿透到父层
|
|
|
- this.isRelatedContent = true
|
|
|
- this.currentEditData = data
|
|
|
- },
|
|
|
-
|
|
|
- onShowContent(val, data) {
|
|
|
- console.log(data)
|
|
|
- this.contentIndex = val
|
|
|
- this.currentItems = []
|
|
|
- this.currentResources = []
|
|
|
- // data.items.length && this.findQuestionById(data.items)
|
|
|
- data.resources.length && this.findResourceById(data.resources)
|
|
|
- this.isShowContent = true
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 通过id查询内容信息
|
|
|
- * */
|
|
|
- findResourceById(ids) {
|
|
|
-
|
|
|
- this.$api.learnActivity.FindSyllabusResourceById(ids).then(
|
|
|
- res => {
|
|
|
- if (!res.error) {
|
|
|
- this.currentResources = res.result.data
|
|
|
- } else {
|
|
|
- this.$Message.error("API ERROR")
|
|
|
- }
|
|
|
- },
|
|
|
- err => {
|
|
|
- this.$Message.error("API ERROR")
|
|
|
-
|
|
|
- }
|
|
|
- )
|
|
|
-
|
|
|
- },
|
|
|
- /**
|
|
|
- * 通过id查询题目信息
|
|
|
- * */
|
|
|
- findQuestionById(ids) {
|
|
|
- this.$api.learnActivity.FindQuestionById(ids).then(
|
|
|
- res => {
|
|
|
- if (!res.error) {
|
|
|
- this.currentItems = res.result.data
|
|
|
- } else {
|
|
|
- this.$Message.error("API ERROR")
|
|
|
- }
|
|
|
- },
|
|
|
- err => {
|
|
|
- this.$Message.error("API ERROR")
|
|
|
-
|
|
|
- }
|
|
|
- )
|
|
|
+
|
|
|
+ /* 根据节点获取它所在的章节信息 */
|
|
|
+ getChapterByNode(node){
|
|
|
+ console.log(node)
|
|
|
+ if(node.level === 1){
|
|
|
+ return node
|
|
|
+ }else{
|
|
|
+ return this.getChapterByNode(node.parent)
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
-
|
|
|
// 提交编辑或者新增
|
|
|
onSubmitNode() {
|
|
|
if (!this.nodeInfo.title) {
|
|
|
- this.$Message.warning('节点名称不能为空')
|
|
|
+ this.$Message.warning(this.$t('syllabus.tree.nodeNameTip'))
|
|
|
return
|
|
|
}
|
|
|
if (this.isEditItem) {
|
|
@@ -231,55 +241,54 @@
|
|
|
}
|
|
|
this.currentParentData.children.push(newChild)
|
|
|
}
|
|
|
-
|
|
|
this.isEditOrAdd = false
|
|
|
this.$parent.hasModify = true
|
|
|
- this.$Message.success(this.isEditItem ? '编辑成功' : '添加成功')
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 选择关联题目
|
|
|
- * @param val 当前已选题目
|
|
|
- */
|
|
|
- onSelectQuestion(val) {
|
|
|
- this.questionList = val.questions
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 选择关联内容
|
|
|
- * @param val 当前已选内容
|
|
|
- */
|
|
|
- onSelectFile(val) {
|
|
|
- this.fileList = val.files
|
|
|
- console.log(val)
|
|
|
+ this.$emit('addModifyId',this.getChapterIdById(this.curData.id))
|
|
|
+ this.$Message.success(this.isEditItem ? this.$t('syllabus.tree.editSucTip') : this.$t('syllabus.tree.addSucTip'))
|
|
|
},
|
|
|
-
|
|
|
- /** 保存内容与题目关联 */
|
|
|
- onSaveNode() {
|
|
|
- this.isLoading = true
|
|
|
- this.currentEditData.items = this.currentEditData.items ? [...new Set(this.currentEditData.items.concat(
|
|
|
- this.questionList.map(item => item.id)))] : [...new Set(this.questionList.map(item => item.id))]
|
|
|
- this.currentEditData.resources = this.currentEditData.resources ? [...new Set(this.currentEditData
|
|
|
- .resources.concat(this.fileList.map(item => item.url)))] : [...new Set(this.fileList.map(item =>
|
|
|
- item.url))]
|
|
|
- this.$api.syllabus.SaveOrUpdateAsNodes([this.currentEditData]).then(res => {
|
|
|
- if (!res.error && res) {
|
|
|
- this.isRelatedContent = false
|
|
|
- this.$emit('onTreeUpdate')
|
|
|
- this.isLoading = false
|
|
|
- this.$parent.hasModify = true
|
|
|
- } else {
|
|
|
- this.$Message.warning('获取数据失败')
|
|
|
- }
|
|
|
+
|
|
|
+ /* 获取整个树的章节与子节点归属 */
|
|
|
+ getAllChild(arr){
|
|
|
+ let result = []
|
|
|
+ arr.forEach(item => {
|
|
|
+ result.push({
|
|
|
+ chapterId:item.id,
|
|
|
+ children:this.flatChildren(item.children)
|
|
|
+ })
|
|
|
})
|
|
|
+ this.flatArr = result
|
|
|
},
|
|
|
+
|
|
|
+ /* 递归拉平所有children */
|
|
|
+ flatChildren(children){
|
|
|
+ let result = []
|
|
|
+ const fn = (source)=>{
|
|
|
+ source.forEach(i => {
|
|
|
+ result.push(i.id)
|
|
|
+ if(i.children.length){
|
|
|
+ fn(i.children)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ fn(children)
|
|
|
+ return result
|
|
|
+ },
|
|
|
+
|
|
|
+ /* 根据某个节点ID换取它对应的章节ID */
|
|
|
+ getChapterIdById(id){
|
|
|
+ if(this.flatArr.map(i => i.chapterId).includes(id)){
|
|
|
+ return id
|
|
|
+ }else{
|
|
|
+ let targetChapter = this.flatArr.find(i => i.children.includes(id))
|
|
|
+ return targetChapter.chapterId
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
},
|
|
|
- computed:{
|
|
|
- isFirstLevel(){
|
|
|
- return pid => {
|
|
|
- return pid === this.volume.id
|
|
|
+ computed: {
|
|
|
+ isFirstLevel() {
|
|
|
+ return data => {
|
|
|
+ return data.pid === this.volume.id
|
|
|
}
|
|
|
},
|
|
|
},
|
|
@@ -288,21 +297,12 @@
|
|
|
treeData: {
|
|
|
handler: function(n, o) {
|
|
|
// 以下为拼接树形数据以及册别数据
|
|
|
- // let defaultTree = []
|
|
|
- // let volumeParent = {
|
|
|
- // title: this.volume.name,
|
|
|
- // id: this.volume.id,
|
|
|
- // code: this.volume.code,
|
|
|
- // pid: 'Root',
|
|
|
- // children: []
|
|
|
- // }
|
|
|
- // volumeParent.children = n
|
|
|
- // defaultTree.push(volumeParent)
|
|
|
- this.treeDatas = n
|
|
|
- this.$nextTick().then(() =>{
|
|
|
+ this.treeDatas = n.map(i => i.trees[0])
|
|
|
+ this.getAllChild(this.treeDatas)
|
|
|
+ this.$nextTick().then(() => {
|
|
|
const firstNode = document.querySelector('.el-tree-node')
|
|
|
firstNode.click();
|
|
|
- })
|
|
|
+ })
|
|
|
},
|
|
|
immediate: true
|
|
|
},
|
|
@@ -358,7 +358,7 @@
|
|
|
}
|
|
|
|
|
|
.tree /deep/ .el-tree-node:before {
|
|
|
- border-left: 1px dashed #343434;
|
|
|
+ border-left: 1px dashed #626262;
|
|
|
bottom: 0px;
|
|
|
height: 100%;
|
|
|
top: -20px;
|
|
@@ -366,7 +366,7 @@
|
|
|
}
|
|
|
|
|
|
.tree /deep/ .el-tree-node:after {
|
|
|
- border-top: 1px dashed #343434;
|
|
|
+ border-top: 1px dashed #626262;
|
|
|
height: 20px;
|
|
|
top: 20px;
|
|
|
width: 12px;
|