insertPositionTipInEditor.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  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. info: "base/baseInfo",
  45. sceneList: "base/sceneList",
  46. dragInfo: "editorNavDragInfo",
  47. }),
  48. marginLeft() {
  49. return (this.indentLevel - 1) * 12 + "px";
  50. },
  51. },
  52. methods: {
  53. canDrop() {
  54. console.error(this.dragInfo.type, this.topologyLevel, this.parentNode);
  55. switch (this.dragInfo.type) {
  56. case "scene": // 被拖拽的是场景
  57. if (this.topologyLevel === 1) {
  58. // console.log('情况1:被拖拽的是场景,拖拽到一级分组列表');
  59. return false;
  60. } else if (this.topologyLevel === 2) {
  61. // console.log('情况2:被拖拽的是场景,拖拽到一级分组中');
  62. if (this.parentNode.children.length === 0) {
  63. // 如果目标一级分组内容显示是空的,即其下只有一个(内容肯定是空的)默认二级分组
  64. return true;
  65. } else {
  66. // 如果目标一级分组之下显示了内容,则肯定是显示了二级分组。
  67. // return false
  68. return true;
  69. }
  70. } else if (this.topologyLevel === 3) {
  71. // console.log('情况3:被拖拽的是场景,拖拽到二级分组中');
  72. return true;
  73. } else {
  74. console.error("情况4:不该出现");
  75. return false;
  76. }
  77. case "topologyGroupLevel2": // 被拖拽的是拓扑结构中二级分组
  78. if (this.topologyLevel === 1) {
  79. // console.log('情况5:被拖拽的是拓扑结构中二级分组,拖拽到一级分组列表');
  80. return true;
  81. } else if (this.topologyLevel === 2) {
  82. // console.log('情况6:被拖拽的是拓扑结构中二级分组,拖拽到一级分组中');
  83. return true;
  84. } else if (this.topologyLevel === 3) {
  85. if (this.indentLevel === 2) {
  86. // console.log('情况7:被拖拽的是拓扑结构中二级分组,拖拽到隐藏的默认二级分组中');
  87. return true;
  88. } else {
  89. // console.log('情况8:被拖拽的是拓扑结构中二级分组,拖拽到普通的二级分组中');
  90. return false;
  91. }
  92. } else {
  93. console.error("情况9:不该出现");
  94. return false;
  95. }
  96. case "topologyGroupLevel1": // 被拖拽的是拓扑结构中一级分组
  97. if (this.topologyLevel === 1) {
  98. // console.log('情况10:被拖拽的是拓扑结构中一级分组,拖拽到一级分组列表');
  99. return true;
  100. } else if (this.topologyLevel === 2) {
  101. // 拖拽到一级分组中
  102. if (this.dragInfo.node.children.length === 1 && this.dragInfo.node.children[0].name === "默认二级分组") {
  103. // console.log('情况11:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到一级分组中');
  104. return true;
  105. } else {
  106. // console.log('情况12:被拖拽的一级分组并非只有一个隐藏的默认二级分组,拖拽到一级分组中');
  107. return false;
  108. }
  109. } else if (this.topologyLevel === 3) {
  110. // 拖拽到二级分组中
  111. if (this.indentLevel === 2) {
  112. // 拖拽到隐藏的默认二级分组中
  113. if (this.dragInfo.node.children.length === 1 && this.dragInfo.node.children[0].name === "默认二级分组") {
  114. if (this.dragInfo.node.children[0].id === this.parentNode.id) {
  115. // console.log('情况13:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到自身的默认二级分组中');
  116. return false;
  117. } else {
  118. // console.log('情况14:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到另一个一级分组中隐藏的默认二级分组中');
  119. return true;
  120. }
  121. } else {
  122. // console.log('情况15:被拖拽的一级分组并非只有一个隐藏的默认二级分组,拖拽到隐藏的默认二级分组中');
  123. return false;
  124. }
  125. } else {
  126. // console.log('情况16:被拖拽的是拓扑结构中一级分组,拖拽到普通二级分组中')
  127. return false;
  128. }
  129. } else {
  130. console.error("情况17:不该出现");
  131. return false;
  132. }
  133. default:
  134. console.error("情况18:不该出现");
  135. return false;
  136. }
  137. },
  138. onDragEnter(e) {
  139. if (!this.canDrop()) {
  140. return;
  141. } else {
  142. e.preventDefault();
  143. e.target.style.backgroundColor = "#0076f6";
  144. e.dataTransfer.dropEffect = "move";
  145. }
  146. },
  147. onDragOver(e) {
  148. if (!this.canDrop()) {
  149. return;
  150. } else {
  151. e.preventDefault();
  152. e.dataTransfer.dropEffect = "move";
  153. }
  154. },
  155. onDragLeave(e) {
  156. // e.preventDefault()
  157. e.target.style.backgroundColor = "";
  158. },
  159. onDrop(e) {
  160. // e.preventDefault()
  161. e.target.style.backgroundColor = "";
  162. switch (this.dragInfo.type) {
  163. case "scene": // 被拖拽的是场景
  164. {
  165. if (this.topologyLevel === 2) {
  166. // console.log('情况2:被拖拽的是场景,拖拽到一级分组中。只有一种可能:目标一级分组内容显示是空的,即其下只有一个(内容肯定是空的)默认二级分组。')
  167. /**
  168. * 找到被拖拽的场景
  169. */
  170. // const draggedNode = this.info.scenes.find((item) => {
  171. const draggedNode = this.sceneList.find((item) => {
  172. // return item.id === this.dragInfo.node.id
  173. return item.sceneCode === this.dragInfo.node.sceneCode;
  174. });
  175. console.log( this.parentNode);
  176. /**
  177. * 找到目标一级分组
  178. */
  179. const targetGroupLevel1 = this.info.catalogRoot.find((item) => {
  180. return item.id === this.parentNode.id;
  181. });
  182. console.log(targetGroupLevel1);
  183. /**
  184. * 找到目标一级分组下辖的默认二级分组
  185. */
  186. const targetGroupLevel2 = this.info.catalogs.find((item) => {
  187. console.log(item.id);
  188. return item.id === targetGroupLevel1.children[0];
  189. });
  190. /**
  191. * 被拖拽的场景的所属二级分组记录修改
  192. */
  193. draggedNode.category = targetGroupLevel2.id;
  194. } else if (this.topologyLevel === 3) {
  195. // console.log('情况3:被拖拽的是场景,插入到二级分组中')
  196. /**
  197. * 确定要插入的分组中各场景应有的weight(从1开始递增,小的先显示)
  198. */
  199. const belongGroupCopy = deepClone(this.parentNode.children);
  200. const draggedNodeCopy = deepClone(this.dragInfo.node);
  201. draggedNodeCopy.isCopy = true;
  202. belongGroupCopy.splice(this.index, 0, draggedNodeCopy);
  203. const toDeleteIndex = belongGroupCopy.findIndex((item) => {
  204. return item.id === this.dragInfo.node.id && !item.isCopy;
  205. });
  206. if (toDeleteIndex >= 0) {
  207. belongGroupCopy.splice(toDeleteIndex, 1);
  208. }
  209. for (let [index, elem] of belongGroupCopy.entries()) {
  210. elem.weight = index + 1;
  211. }
  212. /**
  213. * 真正修改场景原始数据的weight和所属分组
  214. */
  215. for (const eachSceneCopy of belongGroupCopy) {
  216. for (const eachScene of this.info.scenes) {
  217. if (eachSceneCopy.id === eachScene.id) {
  218. this.$set(eachScene, "weight", eachSceneCopy.weight);
  219. }
  220. if (this.dragInfo.node.id === eachScene.id) {
  221. eachScene.category = this.parentNode.id; // 注意category拼写!
  222. }
  223. }
  224. }
  225. }
  226. }
  227. break;
  228. case "topologyGroupLevel2": // 被拖拽的是拓扑结构中二级分组
  229. if (this.topologyLevel === 1) {
  230. // console.log('情况5:被拖拽的是拓扑结构中二级分组,拖拽到一级分组列表');
  231. /**
  232. * 在拖拽到的位置新增一个一级分组,name是原二级分组的name;唯一child的id赋值为被拖拽的二级分组的id
  233. */
  234. const newGroupLevel1 = {
  235. id: "r_" + this.$randomWord(true, 8, 8),
  236. name: this.dragInfo.node.name,
  237. children: [this.dragInfo.node.id],
  238. };
  239. this.info.catalogRoot.splice(this.index, 0, newGroupLevel1);
  240. // 被拖拽的二级分组名称改为“默认二级分组”;
  241. const draggedGroup = this.info.catalogs.find((item) => {
  242. return item.id === this.dragInfo.node.id;
  243. });
  244. draggedGroup.name = "默认二级分组";
  245. /**
  246. * 被拖拽的二级分组原属的一级分组的children中,删除【被拖拽的二级分组对应的元素】
  247. */
  248. const parentGroup = this.info.catalogRoot.find((item) => {
  249. return item.id === this.dragInfo.node.parentId;
  250. });
  251. const idxToDelete = parentGroup.children.findIndex((id) => {
  252. return id === this.dragInfo.node.id;
  253. });
  254. parentGroup.children.splice(idxToDelete, 1);
  255. // 如果被拖拽的二级分组原属的一级分组中没有任何二级分组了,则新增一个默认二级分组
  256. if (parentGroup.children.length === 0) {
  257. let newGroupLevel2Id = "c_" + this.$randomWord(true, 8, 8);
  258. parentGroup.children.push(newGroupLevel2Id);
  259. this.info.catalogs.push({
  260. id: newGroupLevel2Id,
  261. name: "默认二级分组",
  262. });
  263. }
  264. break;
  265. } else if (this.topologyLevel === 2) {
  266. // console.log('情况6:被拖拽的是拓扑结构中二级分组,拖拽到一级分组中');
  267. // 找到原属一级分组
  268. const originalParentGroup = this.info.catalogRoot.find((item) => {
  269. return item.id === this.dragInfo.node.parentId;
  270. });
  271. // 找到原属一级分组children中那个二级分组条目,并做上待删除记号
  272. const originalGroupIndex = originalParentGroup.children.findIndex((eachLevel2Id) => {
  273. return eachLevel2Id === this.dragInfo.node.id;
  274. });
  275. originalParentGroup.children[originalGroupIndex] += "__need__delete__";
  276. // 找到要插入的一级分组
  277. const targetGroup = this.info.catalogRoot.find((item) => {
  278. return item.id === this.parentNode.id;
  279. });
  280. // 把被拖拽的二级分组的id插进去
  281. targetGroup.children.splice(this.index, 0, this.dragInfo.node.id);
  282. // 把原来那个二级分组条目删除
  283. this.$nextTick(() => {
  284. const toDeleteIndex = originalParentGroup.children.findIndex((eachLevel2Id) => {
  285. return eachLevel2Id.toString().endsWith("__need__delete__");
  286. });
  287. originalParentGroup.children.splice(toDeleteIndex, 1);
  288. });
  289. // 如果被拖拽的二级分组原属的一级分组中没有任何二级分组了,则新增一个默认二级分组
  290. if (originalParentGroup.children.length === 0) {
  291. let newGroupLevel2Id = "c_" + this.$randomWord(true, 8, 8);
  292. originalParentGroup.children.push(newGroupLevel2Id);
  293. this.info.catalogs.push({
  294. id: newGroupLevel2Id,
  295. name: "默认二级分组",
  296. });
  297. }
  298. } else if (this.topologyLevel === 3) {
  299. // console.log('情况7:被拖拽的是拓扑结构中二级分组,拖拽到隐藏的默认二级分组中');
  300. // 找到拖拽到的二级分组所属的一级分组
  301. const targetGroupLevel1 = this.info.catalogRoot.find((item) => {
  302. return item.id === this.parentNode.parentId;
  303. });
  304. // 新增一个child条目,对应被拖拽的二级分组
  305. targetGroupLevel1.children.push(this.dragInfo.node.id);
  306. // 找到被拖拽的二级分组原属的一级分组
  307. const originalGroupLevel1 = this.info.catalogRoot.find((item) => {
  308. return item.id === this.dragInfo.node.parentId;
  309. });
  310. // 删除这个二级分组条目
  311. const idxToDelete = originalGroupLevel1.children.findIndex((id) => {
  312. return id === this.dragInfo.node.id;
  313. });
  314. originalGroupLevel1.children.splice(idxToDelete, 1);
  315. // 如果被拖拽的二级分组原属的一级分组中没有任何二级分组了,则新增一个默认二级分组
  316. if (originalGroupLevel1.children.length === 0) {
  317. let newGroupLevel2Id = "c_" + this.$randomWord(true, 8, 8);
  318. originalGroupLevel1.children.push(newGroupLevel2Id);
  319. this.info.catalogs.push({
  320. id: newGroupLevel2Id,
  321. name: "默认二级分组",
  322. });
  323. }
  324. }
  325. break;
  326. case "topologyGroupLevel1": // 被拖拽的是拓扑结构中一级分组
  327. if (this.topologyLevel === 1) {
  328. // console.log('情况10:被拖拽的是拓扑结构中一级分组,拖拽到一级分组列表');
  329. // 在一级分组列表中找到这个一级分组条目
  330. let originalGroupIndex = this.info.catalogRoot.findIndex((item) => {
  331. return item.id === this.dragInfo.node.id;
  332. });
  333. // 复制这个一级分组条目
  334. const groupCopy = deepClone(this.info.catalogRoot[originalGroupIndex]);
  335. // 旧的一级分组条目加上待删除标记
  336. this.info.catalogRoot[originalGroupIndex].__need__delete__ = true;
  337. // 插入新的一级分组条目
  338. this.info.catalogRoot.splice(this.index, 0, groupCopy);
  339. // 在一级分组列表中再次找到要删除的一级分组条目
  340. originalGroupIndex = this.info.catalogRoot.findIndex((item) => {
  341. return item.__need__delete__;
  342. });
  343. // 删除旧的一级分组条目
  344. this.info.catalogRoot.splice(originalGroupIndex, 1);
  345. } else if (this.topologyLevel === 2) {
  346. // console.log('情况11:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到一级分组中');
  347. // 默认二级分组改名成原一级分组的名字
  348. const groupLevel2 = this.info.catalogs.find((item) => {
  349. return item.id === this.dragInfo.node.children[0].id;
  350. });
  351. groupLevel2.name = this.dragInfo.node.name;
  352. // 拖拽到的一级分组中新增一个child,对应那个二级分组
  353. const targetGroupLevel1 = this.info.catalogRoot.find((item) => {
  354. return item.id === this.parentNode.id;
  355. });
  356. targetGroupLevel1.children.splice(this.index, 0, this.dragInfo.node.children[0].id);
  357. // 删除原一级分组
  358. const originalGroupLevel1Idx = this.info.catalogRoot.findIndex((item) => {
  359. return item.id === this.dragInfo.node.id;
  360. });
  361. this.info.catalogRoot.splice(originalGroupLevel1Idx, 1);
  362. } else if (this.topologyLevel === 3) {
  363. // console.log('情况14:被拖拽的一级分组只有一个隐藏的默认二级分组,拖拽到另一个一级分组中隐藏的默认二级分组中');
  364. // 找到被拖拽的一级分组索引
  365. const originalGroupLevel1Idx = this.info.catalogRoot.findIndex((item) => {
  366. return item.id === this.dragInfo.node.id;
  367. });
  368. // 找到被拖拽的一级分组下辖的默认二级分组的完整数据条目
  369. const groupLevel2 = this.info.catalogs.find((item) => {
  370. return item.id === this.info.catalogRoot[originalGroupLevel1Idx].children[0];
  371. });
  372. // 被拖拽的一级分组下辖默认二级分组的名称改为与父亲同名
  373. groupLevel2.name = this.info.catalogRoot[originalGroupLevel1Idx].name;
  374. // 找到拖拽到的二级分组所属的一级分组
  375. const targetGroupLevel1 = this.info.catalogRoot.find((item) => {
  376. return item.id === this.parentNode.parentId;
  377. });
  378. // 新增一个child条目,对应被拖拽的一级分组下辖的默认二级分组
  379. targetGroupLevel1.children.push(groupLevel2.id);
  380. // 删除被拖拽的一级分组
  381. this.info.catalogRoot.splice(originalGroupLevel1Idx, 1);
  382. }
  383. break;
  384. default:
  385. break;
  386. }
  387. },
  388. },
  389. };
  390. </script>
  391. <style lang="less" scoped>
  392. .insert-position-tip {
  393. height: 1px;
  394. box-sizing: content-box;
  395. padding-top: 8px;
  396. padding-bottom: 8px;
  397. margin-top: -5px;
  398. margin-bottom: -5px;
  399. position: relative;
  400. z-index: 1;
  401. background-clip: content-box;
  402. color: transparent;
  403. // background-color: red;
  404. }
  405. </style>