insertPositionTipInEditor.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. <template>
  2. <div
  3. class="insert-position-tip"
  4. @dragenter="onDragEnter"
  5. @dragover="onDragOver"
  6. @dragleave="onDragLeave"
  7. @drop="onDrop"
  8. :style="{
  9. marginLeft: marginLeft,
  10. }"
  11. >
  12. {{positionDebug}}
  13. </div>
  14. </template>
  15. <script>
  16. import { mapGetters } from "vuex";
  17. import { deepClone } from "@/utils/other.js";
  18. export default {
  19. props: {
  20. index: {
  21. type: Number,
  22. required: true,
  23. },
  24. positionDebug: {
  25. type: String,
  26. default: '',
  27. },
  28. indentLevel: {
  29. type: Number,
  30. default: 1,
  31. },
  32. topologyLevel: {
  33. type: Number,
  34. default: 1,
  35. },
  36. parentNode: {
  37. type: Object,
  38. default: null,
  39. },
  40. },
  41. computed: {
  42. ...mapGetters({
  43. info: 'info',
  44. dragInfo: 'editorNavDragInfo',
  45. }),
  46. marginLeft() {
  47. return (this.indentLevel - 1) * 12 + 'px'
  48. },
  49. },
  50. methods: {
  51. canDrop() {
  52. switch (this.dragInfo.type) {
  53. case 'scene': // 被拖拽的是场景
  54. if (this.topologyLevel === 1) {
  55. // console.log('情况1:被拖拽的是场景,拖拽到一级分组列表');
  56. return false
  57. } else if (this.topologyLevel === 2) {
  58. // console.log('情况2:被拖拽的是场景,拖拽到一级分组中');
  59. return false
  60. } else if (this.topologyLevel === 3) {
  61. // console.log('情况3:被拖拽的是场景,拖拽到二级分组中');
  62. return true
  63. } else {
  64. console.error('情况4:不该出现');
  65. return false
  66. }
  67. case 'topologyGroupLevel2': // 被拖拽的是拓扑结构中二级分组
  68. if (this.topologyLevel === 1) {
  69. // console.log('情况5:被拖拽的是拓扑结构中二级分组,拖拽到一级分组列表');
  70. return true
  71. } else if (this.topologyLevel === 2) {
  72. // console.log('情况6:被拖拽的是拓扑结构中二级分组,拖拽到一级分组中');
  73. return true
  74. } else if (this.topologyLevel === 3) {
  75. if (this.indentLevel === 2) {
  76. // console.log('情况7:被拖拽的是拓扑结构中二级分组,拖拽到隐藏的默认二级分组中');
  77. return true
  78. } else {
  79. // console.log('情况8:被拖拽的是拓扑结构中二级分组,拖拽到普通的二级分组中');
  80. return false
  81. }
  82. } else {
  83. console.error('情况9:不该出现');
  84. return false
  85. }
  86. case 'topologyGroupLevel1': // 被拖拽的是拓扑结构中一级分组
  87. if (this.topologyLevel === 1) {
  88. // console.log('情况10:被拖拽的是拓扑结构中一级分组,拖拽到一级分组列表');
  89. return true
  90. } else if (this.topologyLevel === 2) { // 拖拽到一级分组中
  91. if (this.dragInfo.node.children.length === 1 && this.dragInfo.node.children[0].name === '默认二级分组') {
  92. // console.log('情况11:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到一级分组中');
  93. return true
  94. } else {
  95. // console.log('情况12:被拖拽的一级分组并非只有一个隐藏的默认二级分组,拖拽到一级分组中');
  96. return false
  97. }
  98. } else if (this.topologyLevel === 3) { // 拖拽到二级分组中
  99. if (this.indentLevel === 2) { // 拖拽到隐藏的默认二级分组中
  100. if (this.dragInfo.node.children.length === 1 && this.dragInfo.node.children[0].name === '默认二级分组') {
  101. if (this.dragInfo.node.children[0].id === this.parentNode?.id) {
  102. // console.log('情况13:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到自身的默认二级分组中');
  103. return false
  104. } else {
  105. // console.log('情况14:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到另一个一级分组中隐藏的默认二级分组中');
  106. return true
  107. }
  108. } else {
  109. // console.log('情况15:被拖拽的一级分组并非只有一个隐藏的默认二级分组,拖拽到隐藏的默认二级分组中');
  110. return false
  111. }
  112. } else {
  113. // console.log('情况16:被拖拽的是拓扑结构中一级分组,拖拽到普通二级分组中')
  114. return false
  115. }
  116. } else {
  117. console.error('情况17:不该出现');
  118. return false
  119. }
  120. default:
  121. console.error('情况18:不该出现');
  122. return false
  123. }
  124. },
  125. onDragEnter(e) {
  126. if (!this.canDrop()) {
  127. return
  128. } else {
  129. e.preventDefault()
  130. e.target.style.backgroundColor = '#0076f6'
  131. e.dataTransfer.dropEffect = 'move'
  132. }
  133. },
  134. onDragOver(e) {
  135. if (!this.canDrop()) {
  136. return
  137. } else {
  138. e.preventDefault()
  139. e.dataTransfer.dropEffect = 'move'
  140. }
  141. },
  142. onDragLeave(e) {
  143. // e.preventDefault()
  144. e.target.style.backgroundColor = ''
  145. },
  146. onDrop(e) {
  147. // e.preventDefault()
  148. e.target.style.backgroundColor = ''
  149. switch (this.dragInfo.type) {
  150. case 'scene': // 被拖拽的是场景
  151. // console.log('情况3:被拖拽的是场景,插入到二级分组中');
  152. /**
  153. * 确定要插入的分组中各场景应有的weight(从1开始递增,小的先显示)
  154. */
  155. // eslint-disable-next-line no-case-declarations
  156. const belongGroupCopy = deepClone(this.parentNode.children)
  157. // eslint-disable-next-line no-case-declarations
  158. const draggedNodeCopy = deepClone(this.dragInfo.node)
  159. draggedNodeCopy.isCopy = true
  160. belongGroupCopy.splice(this.index, 0, draggedNodeCopy)
  161. // eslint-disable-next-line no-case-declarations
  162. const toDeleteIndex = belongGroupCopy.findIndex((item) => {
  163. return (item.id === this.dragInfo.node.id && !item.isCopy)
  164. })
  165. if (toDeleteIndex >= 0) {
  166. belongGroupCopy.splice(toDeleteIndex, 1)
  167. }
  168. for (let [index, elem] of belongGroupCopy.entries()) {
  169. elem.weight = index + 1
  170. }
  171. /**
  172. * 真正修改场景原始数据的weight和所属分组
  173. */
  174. for (const eachSceneCopy of belongGroupCopy) {
  175. for (const eachScene of this.info.scenes) {
  176. if (eachSceneCopy.id === eachScene.id) {
  177. this.$set( eachScene, 'weight', eachSceneCopy.weight )
  178. }
  179. if (this.dragInfo.node.id === eachScene.id) {
  180. eachScene.category = this.parentNode.id // 注意category拼写!
  181. }
  182. }
  183. }
  184. break;
  185. case 'topologyGroupLevel2': // 被拖拽的是拓扑结构中二级分组
  186. if (this.topologyLevel === 1) {
  187. // console.log('情况5:被拖拽的是拓扑结构中二级分组,拖拽到一级分组列表');
  188. /**
  189. * 在拖拽到的位置新增一个一级分组,name是原二级分组的name;唯一child的id赋值为被拖拽的二级分组的id
  190. */
  191. const newGroupLevel1 = {
  192. id: 'r_' + this.$randomWord(true, 8, 8),
  193. name: this.dragInfo.node.name,
  194. children: [this.dragInfo.node.id],
  195. }
  196. this.info.catalogRoot.splice(this.index, 0, newGroupLevel1)
  197. /**
  198. * 被拖拽的二级分组名称改为“默认二级分组”;
  199. */
  200. const draggedGroup = this.info.catalogs.find((item) => {
  201. return item.id === this.dragInfo.node.id
  202. })
  203. draggedGroup.name = '默认二级分组'
  204. /**
  205. *
  206. */
  207. // 被拖拽的二级分组原属的一级分组的children中,删除【被拖拽的二级分组对应的元素】
  208. const parentGroup = this.info.catalogRoot.find((item) => {
  209. return item.id === this.dragInfo.node.parentId
  210. })
  211. const idxToDelete = parentGroup.children.findIndex((id) => {
  212. return id === this.dragInfo.node.id
  213. })
  214. parentGroup.children.splice(idxToDelete, 1)
  215. break;
  216. } else if (this.topologyLevel === 2) {
  217. // console.log('情况6:被拖拽的是拓扑结构中二级分组,拖拽到一级分组中');
  218. // 找到原属一级分组
  219. const originalParentGroup = this.info.catalogRoot.find((item) => {
  220. return item.id === this.dragInfo.node.parentId
  221. })
  222. // 找到原属一级分组children中那个二级分组条目,并做上待删除记号
  223. const originalGroupIndex = originalParentGroup.children.findIndex((eachLevel2Id) => {
  224. return eachLevel2Id === this.dragInfo.node.id
  225. })
  226. originalParentGroup.children[originalGroupIndex] += '__need__delete__'
  227. // 找到要插入的一级分组
  228. const targetGroup = this.info.catalogRoot.find((item) => {
  229. return item.id === this.parentNode.id
  230. })
  231. // 把被拖拽的二级分组的id插进去
  232. targetGroup.children.splice(this.index, 0, this.dragInfo.node.id)
  233. // 把原来那个二级分组条目删除
  234. this.$nextTick(() => {
  235. const toDeleteIndex = originalParentGroup.children.findIndex((eachLevel2Id) => {
  236. return eachLevel2Id.endsWith('__need__delete__')
  237. })
  238. originalParentGroup.children.splice(toDeleteIndex, 1)
  239. })
  240. } else if (this.topologyLevel === 3) {
  241. // console.log('情况7:被拖拽的是拓扑结构中二级分组,拖拽到隐藏的默认二级分组中');
  242. }
  243. break;
  244. case 'topologyGroupLevel1': // 被拖拽的是拓扑结构中一级分组
  245. if (this.topologyLevel === 1) {
  246. // console.log('情况10:被拖拽的是拓扑结构中一级分组,拖拽到一级分组列表');
  247. // 在一级分组列表中找到这个一级分组条目
  248. let originalGroupIndex = this.info.catalogRoot.findIndex((item) => {
  249. return item.id === this.dragInfo.node.id
  250. })
  251. // 复制这个一级分组条目
  252. const groupCopy = deepClone(this.info.catalogRoot[originalGroupIndex])
  253. // 旧的一级分组条目加上待删除标记
  254. this.info.catalogRoot[originalGroupIndex].__need__delete__ = true
  255. // 插入新的一级分组条目
  256. this.info.catalogRoot.splice(this.index, 0 , groupCopy)
  257. // 在一级分组列表中再次找到要删除的一级分组条目
  258. originalGroupIndex = this.info.catalogRoot.findIndex((item) => {
  259. return item.__need__delete__
  260. })
  261. // 删除旧的一级分组条目
  262. this.info.catalogRoot.splice(originalGroupIndex, 1)
  263. } else if (this.topologyLevel === 2) {
  264. // console.log('情况11:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到一级分组中');
  265. // 默认二级分组改名成原一级分组的名字
  266. const groupLevel2 = this.info.catalogs.find((item) => {
  267. return item.id === this.dragInfo.node.children[0].id
  268. })
  269. groupLevel2.name = this.dragInfo.node.name
  270. // 拖拽到的一级分组中新增一个child,对应那个二级分组
  271. const targetGroupLevel1 = this.info.catalogRoot.find((item) => {
  272. return item.id === this.parentNode.id
  273. })
  274. targetGroupLevel1.children.splice(this.index, 0, this.dragInfo.node.children[0].id)
  275. // 删除原一级分组
  276. const originalGroupLevel1Idx = this.info.catalogRoot.findIndex((item) => {
  277. return item.id === this.dragInfo.node.id
  278. })
  279. this.info.catalogRoot.splice(originalGroupLevel1Idx, 1)
  280. } else if (this.topologyLevel === 3) {
  281. console.log('情况14:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到另一个一级分组中隐藏的默认二级分组中');
  282. }
  283. break;
  284. }
  285. }
  286. }
  287. }
  288. </script>
  289. <style lang="less" scoped>
  290. .insert-position-tip {
  291. height: 1px;
  292. box-sizing: content-box;
  293. padding-top: 3px;
  294. padding-bottom: 3px;
  295. background-clip: content-box;
  296. color: transparent;
  297. // background-color: red;
  298. }
  299. </style>