123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- <template>
- <div
- class="insert-position-tip"
- @dragenter="onDragEnter"
- @dragover="onDragOver"
- @dragleave="onDragLeave"
- @drop="onDrop"
- :style="{
- marginLeft: marginLeft,
- }"
- >
- {{positionDebug}}
- </div>
- </template>
- <script>
- import { mapGetters } from "vuex";
- import { deepClone } from "@/utils/other.js";
- export default {
- props: {
- index: {
- type: Number,
- required: true,
- },
- positionDebug: {
- type: String,
- default: '',
- },
- indentLevel: {
- type: Number,
- default: 1,
- },
- topologyLevel: {
- type: Number,
- default: 1,
- },
- parentNode: {
- type: Object,
- default: null,
- },
- },
- computed: {
- ...mapGetters({
- info: 'info',
- dragInfo: 'editorNavDragInfo',
- }),
- marginLeft() {
- return (this.indentLevel - 1) * 12 + 'px'
- },
- },
- methods: {
- canDrop() {
- switch (this.dragInfo.type) {
- case 'scene': // 被拖拽的是场景
- if (this.topologyLevel === 1) {
- // console.log('情况1:被拖拽的是场景,拖拽到一级分组列表');
- return false
- } else if (this.topologyLevel === 2) {
- // console.log('情况2:被拖拽的是场景,拖拽到一级分组中');
- if (this.parentNode.children.length === 0) { // 如果目标一级分组内容显示是空的,即其下只有一个(内容肯定是空的)默认二级分组
- return true
- } else { // 如果目标一级分组之下显示了内容,则肯定是显示了二级分组。
- return false
- }
- } else if (this.topologyLevel === 3) {
- // console.log('情况3:被拖拽的是场景,拖拽到二级分组中');
- return true
- } else {
- console.error('情况4:不该出现');
- return false
- }
- case 'topologyGroupLevel2': // 被拖拽的是拓扑结构中二级分组
- if (this.topologyLevel === 1) {
- // console.log('情况5:被拖拽的是拓扑结构中二级分组,拖拽到一级分组列表');
- return true
- } else if (this.topologyLevel === 2) {
- // console.log('情况6:被拖拽的是拓扑结构中二级分组,拖拽到一级分组中');
- return true
- } else if (this.topologyLevel === 3) {
- if (this.indentLevel === 2) {
- // console.log('情况7:被拖拽的是拓扑结构中二级分组,拖拽到隐藏的默认二级分组中');
- return true
- } else {
- // console.log('情况8:被拖拽的是拓扑结构中二级分组,拖拽到普通的二级分组中');
- return false
- }
- } else {
- console.error('情况9:不该出现');
- return false
- }
- case 'topologyGroupLevel1': // 被拖拽的是拓扑结构中一级分组
- if (this.topologyLevel === 1) {
- // console.log('情况10:被拖拽的是拓扑结构中一级分组,拖拽到一级分组列表');
- return true
- } else if (this.topologyLevel === 2) { // 拖拽到一级分组中
- if (this.dragInfo.node.children.length === 1 && this.dragInfo.node.children[0].name === '默认二级分组') {
- // console.log('情况11:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到一级分组中');
- return true
- } else {
- // console.log('情况12:被拖拽的一级分组并非只有一个隐藏的默认二级分组,拖拽到一级分组中');
- return false
- }
- } else if (this.topologyLevel === 3) { // 拖拽到二级分组中
- if (this.indentLevel === 2) { // 拖拽到隐藏的默认二级分组中
- if (this.dragInfo.node.children.length === 1 && this.dragInfo.node.children[0].name === '默认二级分组') {
- if (this.dragInfo.node.children[0].id === this.parentNode.id) {
- // console.log('情况13:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到自身的默认二级分组中');
- return false
- } else {
- // console.log('情况14:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到另一个一级分组中隐藏的默认二级分组中');
- return true
- }
- } else {
- // console.log('情况15:被拖拽的一级分组并非只有一个隐藏的默认二级分组,拖拽到隐藏的默认二级分组中');
- return false
- }
- } else {
- // console.log('情况16:被拖拽的是拓扑结构中一级分组,拖拽到普通二级分组中')
- return false
- }
- } else {
- console.error('情况17:不该出现');
- return false
- }
- default:
- console.error('情况18:不该出现');
- return false
- }
- },
- onDragEnter(e) {
- if (!this.canDrop()) {
- return
- } else {
- e.preventDefault()
- e.target.style.backgroundColor = '#0076f6'
- e.dataTransfer.dropEffect = 'move'
- }
- },
- onDragOver(e) {
- if (!this.canDrop()) {
- return
- } else {
- e.preventDefault()
- e.dataTransfer.dropEffect = 'move'
- }
- },
- onDragLeave(e) {
- // e.preventDefault()
- e.target.style.backgroundColor = ''
- },
- onDrop(e) {
- // e.preventDefault()
- e.target.style.backgroundColor = ''
- switch (this.dragInfo.type) {
- case 'scene': // 被拖拽的是场景
- {
- if (this.topologyLevel === 2) {
- // console.log('情况2:被拖拽的是场景,拖拽到一级分组中。只有一种可能:目标一级分组内容显示是空的,即其下只有一个(内容肯定是空的)默认二级分组。')
-
- /**
- * 找到被拖拽的场景
- */
- const draggedNode = this.info.scenes.find((item) => {
- return item.id === this.dragInfo.node.id
- })
- /**
- * 找到目标一级分组
- */
- const targetGroupLevel1 = this.info.catalogRoot.find((item) => {
- return item.id === this.parentNode.id
- })
- console.log(targetGroupLevel1);
- /**
- * 找到目标一级分组下辖的默认二级分组
- */
- const targetGroupLevel2 = this.info.catalogs.find((item) => {
- console.log(item.id);
- return item.id === targetGroupLevel1.children[0]
- })
- /**
- * 被拖拽的场景的所属二级分组记录修改
- */
- draggedNode.category = targetGroupLevel2.id
- } else if (this.topologyLevel === 3) {
- // console.log('情况3:被拖拽的是场景,插入到二级分组中')
- /**
- * 确定要插入的分组中各场景应有的weight(从1开始递增,小的先显示)
- */
- const belongGroupCopy = deepClone(this.parentNode.children)
- const draggedNodeCopy = deepClone(this.dragInfo.node)
- draggedNodeCopy.isCopy = true
- belongGroupCopy.splice(this.index, 0, draggedNodeCopy)
- const toDeleteIndex = belongGroupCopy.findIndex((item) => {
- return (item.id === this.dragInfo.node.id && !item.isCopy)
- })
- if (toDeleteIndex >= 0) {
- belongGroupCopy.splice(toDeleteIndex, 1)
- }
- for (let [index, elem] of belongGroupCopy.entries()) {
- elem.weight = index + 1
- }
- /**
- * 真正修改场景原始数据的weight和所属分组
- */
- for (const eachSceneCopy of belongGroupCopy) {
- for (const eachScene of this.info.scenes) {
- if (eachSceneCopy.id === eachScene.id) {
- this.$set( eachScene, 'weight', eachSceneCopy.weight )
- }
- if (this.dragInfo.node.id === eachScene.id) {
- eachScene.category = this.parentNode.id // 注意category拼写!
- }
- }
- }
- }
- }
- break;
- case 'topologyGroupLevel2': // 被拖拽的是拓扑结构中二级分组
- if (this.topologyLevel === 1) {
- // console.log('情况5:被拖拽的是拓扑结构中二级分组,拖拽到一级分组列表');
- /**
- * 在拖拽到的位置新增一个一级分组,name是原二级分组的name;唯一child的id赋值为被拖拽的二级分组的id
- */
- const newGroupLevel1 = {
- id: 'r_' + this.$randomWord(true, 8, 8),
- name: this.dragInfo.node.name,
- children: [this.dragInfo.node.id],
- }
- this.info.catalogRoot.splice(this.index, 0, newGroupLevel1)
- // 被拖拽的二级分组名称改为“默认二级分组”;
- const draggedGroup = this.info.catalogs.find((item) => {
- return item.id === this.dragInfo.node.id
- })
-
- draggedGroup.name = '默认二级分组'
- /**
- * 被拖拽的二级分组原属的一级分组的children中,删除【被拖拽的二级分组对应的元素】
- */
- const parentGroup = this.info.catalogRoot.find((item) => {
- return item.id === this.dragInfo.node.parentId
- })
- const idxToDelete = parentGroup.children.findIndex((id) => {
- return id === this.dragInfo.node.id
- })
- parentGroup.children.splice(idxToDelete, 1)
-
- // 如果被拖拽的二级分组原属的一级分组中没有任何二级分组了,则新增一个默认二级分组
- if (parentGroup.children.length === 0) {
- let newGroupLevel2Id = 'c_' + this.$randomWord(true, 8, 8)
- parentGroup.children.push(newGroupLevel2Id)
- this.info.catalogs.push({
- id: newGroupLevel2Id,
- name: '默认二级分组',
- })
- }
- break;
- } else if (this.topologyLevel === 2) {
- // console.log('情况6:被拖拽的是拓扑结构中二级分组,拖拽到一级分组中');
- // 找到原属一级分组
- const originalParentGroup = this.info.catalogRoot.find((item) => {
- return item.id === this.dragInfo.node.parentId
- })
-
- // 找到原属一级分组children中那个二级分组条目,并做上待删除记号
- const originalGroupIndex = originalParentGroup.children.findIndex((eachLevel2Id) => {
- return eachLevel2Id === this.dragInfo.node.id
- })
- originalParentGroup.children[originalGroupIndex] += '__need__delete__'
-
- // 找到要插入的一级分组
- const targetGroup = this.info.catalogRoot.find((item) => {
- return item.id === this.parentNode.id
- })
-
- // 把被拖拽的二级分组的id插进去
- targetGroup.children.splice(this.index, 0, this.dragInfo.node.id)
- // 把原来那个二级分组条目删除
- this.$nextTick(() => {
- const toDeleteIndex = originalParentGroup.children.findIndex((eachLevel2Id) => {
- return eachLevel2Id.toString().endsWith('__need__delete__')
- })
- originalParentGroup.children.splice(toDeleteIndex, 1)
- })
- // 如果被拖拽的二级分组原属的一级分组中没有任何二级分组了,则新增一个默认二级分组
- if (originalParentGroup.children.length === 0) {
- let newGroupLevel2Id = 'c_' + this.$randomWord(true, 8, 8)
- originalParentGroup.children.push(newGroupLevel2Id)
- this.info.catalogs.push({
- id: newGroupLevel2Id,
- name: '默认二级分组',
- })
- }
- } else if (this.topologyLevel === 3) {
- // console.log('情况7:被拖拽的是拓扑结构中二级分组,拖拽到隐藏的默认二级分组中');
- // 找到拖拽到的二级分组所属的一级分组
- const targetGroupLevel1 = this.info.catalogRoot.find((item) => {
- return item.id === this.parentNode.parentId
- })
- // 新增一个child条目,对应被拖拽的二级分组
- targetGroupLevel1.children.push(this.dragInfo.node.id)
-
- // 找到被拖拽的二级分组原属的一级分组
- const originalGroupLevel1 = this.info.catalogRoot.find((item) => {
- return item.id === this.dragInfo.node.parentId
- })
-
- // 删除这个二级分组条目
- const idxToDelete = originalGroupLevel1.children.findIndex((id) => {
- return id === this.dragInfo.node.id
- })
- originalGroupLevel1.children.splice(idxToDelete, 1)
- // 如果被拖拽的二级分组原属的一级分组中没有任何二级分组了,则新增一个默认二级分组
- if (originalGroupLevel1.children.length === 0) {
- let newGroupLevel2Id = 'c_' + this.$randomWord(true, 8, 8)
- originalGroupLevel1.children.push(newGroupLevel2Id)
- this.info.catalogs.push({
- id: newGroupLevel2Id,
- name: '默认二级分组',
- })
- }
- }
- break;
- case 'topologyGroupLevel1': // 被拖拽的是拓扑结构中一级分组
- if (this.topologyLevel === 1) {
- // console.log('情况10:被拖拽的是拓扑结构中一级分组,拖拽到一级分组列表');
- // 在一级分组列表中找到这个一级分组条目
- let originalGroupIndex = this.info.catalogRoot.findIndex((item) => {
- return item.id === this.dragInfo.node.id
- })
-
- // 复制这个一级分组条目
- const groupCopy = deepClone(this.info.catalogRoot[originalGroupIndex])
- // 旧的一级分组条目加上待删除标记
- this.info.catalogRoot[originalGroupIndex].__need__delete__ = true
- // 插入新的一级分组条目
- this.info.catalogRoot.splice(this.index, 0 , groupCopy)
- // 在一级分组列表中再次找到要删除的一级分组条目
- originalGroupIndex = this.info.catalogRoot.findIndex((item) => {
- return item.__need__delete__
- })
- // 删除旧的一级分组条目
- this.info.catalogRoot.splice(originalGroupIndex, 1)
- } else if (this.topologyLevel === 2) {
- // console.log('情况11:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到一级分组中');
- // 默认二级分组改名成原一级分组的名字
- const groupLevel2 = this.info.catalogs.find((item) => {
- return item.id === this.dragInfo.node.children[0].id
- })
- groupLevel2.name = this.dragInfo.node.name
- // 拖拽到的一级分组中新增一个child,对应那个二级分组
- const targetGroupLevel1 = this.info.catalogRoot.find((item) => {
- return item.id === this.parentNode.id
- })
- targetGroupLevel1.children.splice(this.index, 0, this.dragInfo.node.children[0].id)
-
- // 删除原一级分组
- const originalGroupLevel1Idx = this.info.catalogRoot.findIndex((item) => {
- return item.id === this.dragInfo.node.id
- })
- this.info.catalogRoot.splice(originalGroupLevel1Idx, 1)
- } else if (this.topologyLevel === 3) {
- // console.log('情况14:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到另一个一级分组中隐藏的默认二级分组中');
- // 找到被拖拽的一级分组索引
- const originalGroupLevel1Idx = this.info.catalogRoot.findIndex((item) => {
- return item.id === this.dragInfo.node.id
- })
- // 找到被拖拽的一级分组下辖的默认二级分组的完整数据条目
- const groupLevel2 = this.info.catalogs.find((item) => {
- return item.id === this.info.catalogRoot[originalGroupLevel1Idx].children[0]
- })
- // 被拖拽的一级分组下辖默认二级分组的名称改为与父亲同名
- groupLevel2.name = this.info.catalogRoot[originalGroupLevel1Idx].name
- // 找到拖拽到的二级分组所属的一级分组
- const targetGroupLevel1 = this.info.catalogRoot.find((item) => {
- return item.id === this.parentNode.parentId
- })
- // 新增一个child条目,对应被拖拽的一级分组下辖的默认二级分组
- targetGroupLevel1.children.push(groupLevel2.id)
-
- // 删除被拖拽的一级分组
- this.info.catalogRoot.splice(originalGroupLevel1Idx, 1)
- }
- break;
- default:
- break;
- }
- }
- }
- }
- </script>
- <style lang="less" scoped>
- .insert-position-tip {
- height: 1px;
- box-sizing: content-box;
- padding-top: 8px;
- padding-bottom: 8px;
- margin-top: -5px;
- margin-bottom: -5px;
- position: relative;
- z-index: 1;
- background-clip: content-box;
- color: transparent;
- // background-color: red;
- }
- </style>
|