index.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. <template>
  2. <div>
  3. <!-- <div v-if="isRenaming">
  4. <input ref="rename" type="text" @blur="onInputNewNameComplete" v-model="inputData.name" />
  5. </div> -->
  6. <!-- <button @click="addNode(null)">Add Node</button> -->
  7. <el-tree
  8. :highlight-current="true"
  9. ref="sceneTree"
  10. :data="this.info.navigationTrees"
  11. :expand-on-click-node="false"
  12. node-key="id"
  13. class="custom-tree"
  14. :default-expand-all="false"
  15. @node-drag-start="handleDragStart"
  16. @node-drag-enter="handleDragEnter"
  17. @node-drag-leave="handleDragLeave"
  18. @node-drag-over="handleDragOver"
  19. @node-drag-end="handleDragEnd"
  20. @node-drop="handleDrop"
  21. @node-click="handlerGroup"
  22. @node-expand="handleNodeExpand"
  23. @node-collapse="handleNodeCollapse"
  24. draggable
  25. :allow-drop="allowDrop"
  26. :allow-drag="allowDrag"
  27. >
  28. <template slot-scope="{ node, data }">
  29. <div class="tree-msg" :class="data.type == 'group' ? 'group-item' : 'image-item'">
  30. <!-- <div class="line"></div> -->
  31. <div class="tree-info">
  32. <div v-if="data.type == 'group'" class="group-info">
  33. <i v-if="data.type == 'group' && !expandedNodes.includes(data.id)" class="iconfont icon-editor_folder_off folder_collapsed"></i>
  34. <!-- 拖拽图标 -->
  35. <i ref="drag-group" class="drag-icon iconfont icon-editor_folder_off folder_collapsed"></i>
  36. <i v-if="data.type == 'group' && expandedNodes.includes(data.id)" class="iconfont icon-editor_folder_on folder_expanded"></i>
  37. <span v-if="reNameId != data.id"> {{ data.name }}</span>
  38. <input
  39. ref="reNameInput"
  40. v-model.trim="data.name"
  41. @blur="onInputNewNameComplete(data)"
  42. v-if="reNameId == data.id"
  43. maxlength="50"
  44. :placeholder="$i18n.t('navigation.enter_name')"
  45. class="group-title-input"
  46. />
  47. <div v-if="reNameId != data.id && deleteId == null" class="controls-btn">
  48. <i v-if="data.type == 'group' && data.level == 0" class="iconfont icon-editor_list_add icon-add" @click.stop="addNode(data)" v-tooltip="$i18n.t('navigation.add_two_group')"> </i>
  49. <i
  50. v-if="(data.type == 'group' && data.children.length && data.children[0].type != 'group') || (data.type == 'group' && !data.children.length)"
  51. class="iconfont icon-editor_list_image icon-image"
  52. @click.stop="onRequestForAddScene(data)"
  53. v-tooltip="$i18n.t('navigation.add_pano_or_scene')"
  54. >
  55. </i>
  56. <i @click="onClickForRename(data)" class="iconfont icon-editor_list_edit icon-edit" v-tooltip="$i18n.t('navigation.rename')"> </i>
  57. <i class="iconfont icon-editor_list_delete icon-delete" v-tooltip="$i18n.t('navigation.delete')" @click.stop="onDel(node, data)"> </i>
  58. </div>
  59. </div>
  60. <div class="image-info" v-else>
  61. <div class="cover-image">
  62. <img ref="drag-image" :src="data.icon + ossImagePreviewUrlSuffix()" alt="" />
  63. </div>
  64. <div class="image-name">
  65. <div class="name-top">
  66. <span v-if="reNameId != data.id">{{ data.name }}</span>
  67. <input
  68. ref="reNameInput"
  69. v-if="reNameId == data.id"
  70. v-model.trim="inputData.name"
  71. @blur="onInputNewNameComplete(data)"
  72. maxlength="50"
  73. :placeholder="$i18n.t('navigation.enter_name')"
  74. class="group-title-input"
  75. />
  76. </div>
  77. <span class="name-bottom">
  78. {{ data.type === "pano" ? $i18n.t("navigation.pano") : $i18n.t("navigation.scene") }}
  79. </span>
  80. </div>
  81. <div v-if="reNameId != data.id && deleteId == null" class="controls-btn">
  82. <i @click="onClickForRename(data)" class="iconfont icon-editor_list_edit icon-edit" v-tooltip="$i18n.t('navigation.rename')"> </i>
  83. <i class="iconfont icon-editor_list_delete icon-delete" v-tooltip="$i18n.t('navigation.delete')" @click.stop="onDel(node, data)"> </i>
  84. </div>
  85. </div>
  86. </div>
  87. <div class="deletion-confirm-wrap">
  88. <div class="deletion-confirm" :class="deleteId == data.id ? 'show' : 'hide'" v-clickoutside="onRequestForCancelDelete" @click.stop="onConfirmDelete(node, data)">
  89. {{ $i18n.t("navigation.delete") }}
  90. </div>
  91. </div>
  92. <!-- <div class="controls-btn">
  93. <i v-if="data.type == 'group' && data.level == 0" class="iconfont icon-editor_list_add icon-add" @click.stop="addNode(data)" v-tooltip="$i18n.t('navigation.add_two_group')"> </i>
  94. <i
  95. v-if="(data.type == 'group' && data.children.length && data.children[0].type != 'group') || (data.type == 'group' && !data.children.length)"
  96. class="iconfont icon-editor_list_image icon-image"
  97. @click.stop="onRequestForAddScene(data)"
  98. v-tooltip="$i18n.t('navigation.add_pano_or_scene')"
  99. >
  100. </i>
  101. <i @click="onClickForRename(data)" class="iconfont icon-editor_list_edit icon-edit" v-tooltip="$i18n.t('navigation.rename')"> </i>
  102. <i class="iconfont icon-editor_list_delete icon-delete" v-tooltip="$i18n.t('navigation.delete')" @click.stop="() => remove(node, data)"> </i>
  103. </div> -->
  104. </div>
  105. </template>
  106. </el-tree>
  107. <!-- 选择全景图 or 场景 组件 -->
  108. <div class="dialog" style="z-index: 2000" v-if="isShowSelectionWindow">
  109. <MaterialSelector
  110. :title="$i18n.t('gather.select_material')"
  111. @cancel="isShowSelectionWindow = false"
  112. @submit="onSubmitFromMaterialSelector"
  113. :selectableType="['pano', '3D']"
  114. :initialMaterialType="'pano'"
  115. :isMultiSelection="true"
  116. />
  117. </div>
  118. </div>
  119. </template>
  120. <script>
  121. // import { VueTreeList, Tree, TreeNode } from "vue-tree-list";
  122. import { mapGetters, mapMutations } from "vuex";
  123. import SceneInGroup from "@/components/sceneInGroupInEditor.vue";
  124. import MaterialSelector from "@/components/materialSelector.vue";
  125. import { isUpgradeAdapter } from "@/utils/fixVersion";
  126. import { ossImagePreviewUrlSuffix, getRandomSid } from "@/utils/other.js";
  127. export default {
  128. components: {
  129. // VueTreeList,
  130. MaterialSelector,
  131. },
  132. computed: {
  133. ...mapGetters({
  134. info: "base/baseInfo",
  135. sceneList: "base/sceneList",
  136. currentScene: "scene/currentScene",
  137. currentSecondId: "navigation/currentSecondId",
  138. currentRootId: "navigation/currentRootId",
  139. }),
  140. },
  141. watch: {
  142. "info.navigationTrees": {
  143. // immediate: true,
  144. handler: function (newVal, oldVal) {
  145. if (newVal) {
  146. //赋值新数据后保存展开状态
  147. this.$nextTick(() => {
  148. this.newNodesMap = [];
  149. for (let key in this.$refs.sceneTree.store.nodesMap) {
  150. this.newNodesMap.push(this.$refs.sceneTree.store.nodesMap[key]);
  151. }
  152. this.nodesMap.forEach((item, index) => {
  153. this.newNodesMap.forEach((new_item, new_index) => {
  154. if (index == new_index) {
  155. new_item.expanded = item.expanded;
  156. }
  157. });
  158. });
  159. this.nodesMap = this.newNodesMap;
  160. });
  161. }
  162. },
  163. deep: true,
  164. },
  165. sceneList: {
  166. // immediate: true,
  167. handler: function (newVal, oldVal) {
  168. if (newVal) {
  169. if (this.info.firstScene) {
  170. if (!newVal.some((item) => item.id == this.info.firstScene.id) && (this.currentScene.id == this.info.firstScene.id )) {
  171. this.$store.commit("base/setData", { firstScene: null });
  172. }
  173. // console.error("设置空");
  174. // if (!newVal.some((item) => item.id == this.currentScene.id || item.id == this.currentScene.sid)) {
  175. // console.error("设置空");
  176. // this.$store.commit("scene/setCurrentScene", null);
  177. // }
  178. }
  179. }
  180. },
  181. deep: true,
  182. },
  183. "info.firstScene": {
  184. // immediate: true,
  185. handler: function (newVal, oldVal) {
  186. if (!newVal&&oldVal ) {
  187. console.error("设置空");
  188. this.$store.commit("scene/setCurrentScene", null);
  189. }
  190. },
  191. deep: true,
  192. },
  193. },
  194. data() {
  195. return {
  196. inputData: null,
  197. insertTag: null,
  198. isShowSelectionWindow: false,
  199. expandedNodes: [], // 用于存储已展开节点的数组
  200. nodesMap: [],
  201. newNodesMap: [],
  202. reNameId: null,
  203. backUpName: "",
  204. deleteId: null,
  205. timer: null,
  206. };
  207. },
  208. methods: {
  209. ossImagePreviewUrlSuffix,
  210. handleNodeExpand(data, node, instance) {
  211. console.log("节点展开", data);
  212. // 当节点展开时,将其id添加到数组中
  213. this.expandedNodes.push(data.id);
  214. console.error(this.expandedNodes);
  215. },
  216. handleNodeCollapse(data, node, instance) {
  217. console.log("节点折叠", data);
  218. // 当节点折叠时,从数组中移除其id
  219. const index = this.expandedNodes.indexOf(data.id);
  220. if (index !== -1) {
  221. this.expandedNodes.splice(index, 1);
  222. }
  223. console.error(this.expandedNodes);
  224. },
  225. handleDragStart(node, ev) {
  226. console.log("drag start", node);
  227. if (node.data.type == "group") {
  228. ev.dataTransfer.setDragImage(this.$refs["drag-group"], -10, -18);
  229. } else {
  230. ev.dataTransfer.setDragImage(this.$refs["drag-image"], -10, -18);
  231. }
  232. },
  233. handleDragEnter(draggingNode, dropNode, ev) {
  234. console.log("tree drag enter: ", dropNode);
  235. if (!this.timer) {
  236. if (dropNode.data.type == "group" && dropNode.data.children.length && !dropNode.expanded) {
  237. this.timer = setTimeout(() => {
  238. console.error("可以展开");
  239. dropNode.expanded = true;
  240. this.clearTimer();
  241. }, 1000);
  242. }
  243. }
  244. },
  245. clearTimer() {
  246. clearTimeout(this.timer);
  247. this.timer = null;
  248. },
  249. handleDragLeave(draggingNode, dropNode, ev) {
  250. this.clearTimer();
  251. // if (dropNode.expanded) {
  252. // dropNode.expanded = false;
  253. // }
  254. // console.log("tree drag leave: ", dropNode.data.type);
  255. },
  256. handleDragOver(draggingNode, dropNode, ev) {
  257. // console.log("tree drag over: ", dropNode.data.type);
  258. },
  259. handleDragEnd(draggingNode, dropNode, dropType, ev) {
  260. // console.log("tree drag end: ", dropNode && dropNode.data.type, dropType);
  261. this.clearTimer();
  262. this.processTreeData("drag");
  263. },
  264. handleDrop(draggingNode, dropNode, dropType, ev) {
  265. // console.log("tree drop: ", dropNode.data.type, dropType);
  266. return false;
  267. },
  268. allowDrop(draggingNode, dropNode, type) {
  269. if (draggingNode.data.type != "group") {
  270. //拖拽场景
  271. if (dropNode.level == 1) {
  272. //不允许拖拽到第一层级
  273. if (!dropNode.data.children.length || (dropNode.data.children.length && dropNode.data.children[0].type != "group")) {
  274. return type == "inner";
  275. } else {
  276. return false;
  277. }
  278. } else if (dropNode.level == 2) {
  279. //不允许拖拽到和目录同级
  280. if (dropNode.data.type == "group") {
  281. return type == "inner";
  282. }
  283. }
  284. return type == "prev" || type == "next";
  285. } else {
  286. //拖拽组
  287. if (draggingNode.level == 2 || draggingNode.level == 1) {
  288. //当拖拽的是第一第二级目录的时候,只能拖拽到第二级目录的前后,不能拖拽到2级目录的里面
  289. if (dropNode.level == 3) {
  290. return false;
  291. }
  292. if (dropNode.level == 2) {
  293. if (dropNode.data.type != "group") {
  294. if (dropNode.parent.data.children.length && dropNode.parent.data.children[0].type != "group") {
  295. return type == "prev" || type == "next";
  296. } else {
  297. return false;
  298. }
  299. } else {
  300. return type == "prev" || type == "next";
  301. }
  302. } else if (dropNode.level == 1) {
  303. return type == "prev" || type == "next" || type == "inner";
  304. }
  305. }
  306. }
  307. },
  308. allowDrag(draggingNode) {
  309. // console.error(draggingNode.data.name)
  310. // return draggingNode.data.name.indexOf("三级 3-2-2") === -1;
  311. return true;
  312. },
  313. handlerGroup(data, note, e) {
  314. if (data.type == "group") {
  315. // if (data.children.length) {
  316. this.$refs.sceneTree.store.nodesMap[data.id].expanded = this.insertTag ? true : !this.$refs.sceneTree.store.nodesMap[data.id].expanded;
  317. if (this.$refs.sceneTree.store.nodesMap[data.id].expanded) {
  318. this.handleNodeExpand(data);
  319. } else {
  320. this.handleNodeCollapse(data);
  321. }
  322. this.insertTag = null;
  323. // }
  324. }
  325. },
  326. onRequestForAddScene(item) {
  327. this.insertTag = item;
  328. this.isShowSelectionWindow = true;
  329. },
  330. onSubmitFromMaterialSelector(selected) {
  331. console.error(this.insertTag);
  332. let changeListLength = this.insertTag.children.length || 0;
  333. let newScenes = [];
  334. let roundId = new Date().getTime();
  335. for (const item of selected) {
  336. roundId += 1;
  337. if (item.materialType === "pano") {
  338. newScenes.push({
  339. children: [],
  340. fodderId: item.id,
  341. icon: item.icon,
  342. sceneCode: item.sceneCode,
  343. name: item.name,
  344. // category: this.level === 1 ? this.groupNode.children[0].id : this.groupNode.id,
  345. type: "pano",
  346. sort: changeListLength,
  347. parentId: null,
  348. level: this.insertTag.level + 1,
  349. id: "add_" + roundId,
  350. sid: "sid_" + getRandomSid(), //用于修改导航之后的标识
  351. // id: "s_" + this.$randomWord(true, 8, 8),
  352. });
  353. } else if (item.materialType === "3D") {
  354. console.log("item.num", item.num);
  355. newScenes.push({
  356. children: [],
  357. icon: item.thumb,
  358. sceneCode: item.num,
  359. name: item.sceneName,
  360. sort: changeListLength,
  361. // category: this.level === 1 ? this.groupNode.children[0].id : this.groupNode.id,
  362. type: "4dkk",
  363. level: this.insertTag.level + 1,
  364. version: isUpgradeAdapter(item.isUpgrade), // 'V3' OR 'V4'. 全景看看v1.3新增
  365. id: "add_" + roundId,
  366. sid: "sid_" + getRandomSid(), //用于修改导航之后的标识
  367. // id: "s_" + this.$randomWord(true, 8, 8),
  368. // fodderId: item.id,
  369. });
  370. }
  371. changeListLength++;
  372. }
  373. console.error(newScenes);
  374. console.error(this.sceneList);
  375. let allSuccess = true;
  376. newScenes.forEach((item, i) => {
  377. // let temp = this.info.scenes.find((eachScene) => {
  378. let temp = this.sceneList.find((eachScene) => {
  379. return eachScene.sceneCode === item.sceneCode;
  380. });
  381. if (temp) {
  382. setTimeout(() => {
  383. this.$msg.message(
  384. `${item.type == "4dkk" ? this.$i18n.t("navigation.scene_name") : this.$i18n.t("navigation.pano")}${this.$i18n.t("navigation.already_exists", {
  385. msg: item.sceneTitle,
  386. })}`
  387. );
  388. }, i * 100);
  389. allSuccess = false;
  390. return;
  391. }
  392. // this.info.scenes.push(item);
  393. this.insertTag.children.push(item);
  394. });
  395. this.isShowSelectionWindow = false;
  396. if (allSuccess) {
  397. this.handlerGroup(this.insertTag);
  398. this.$msg.success(this.$i18n.t("gather.success"));
  399. }
  400. },
  401. onClickForRename(data) {
  402. // this.isRenaming = true;
  403. this.inputData = data;
  404. this.backUpName = data.name;
  405. this.reNameId = data.id;
  406. if (this.inputData.name == "默认二级分组") {
  407. this.inputData.name = this.$i18n.t("navigation.default_group_two");
  408. } else if (this.inputData.name == "一级分组") {
  409. this.inputData.name = this.$i18n.t("navigation.group_one");
  410. } else {
  411. // this.inputData .name = data.name;
  412. }
  413. this.$nextTick(() => {
  414. this.$refs.reNameInput.focus();
  415. });
  416. // this.$nextTick(() => {
  417. // // this.$refs['input-for-rename'].focus()
  418. // this.$refs["input-for-rename"].select();
  419. // this.$refs["input-for-rename"].scrollIntoView({
  420. // behavior: "smooth",
  421. // });
  422. // });
  423. },
  424. onInputNewNameComplete(data) {
  425. console.error(data.name);
  426. if (this.inputData.name.trim() == "") {
  427. // data.name = this.backUpName;
  428. // data.name = data.name;
  429. this.reNameId = null;
  430. return;
  431. }
  432. data.name = this.inputData.name;
  433. this.reNameId = null;
  434. // this.isRenaming = false;
  435. // if (!this.inputData.name.trim()) {
  436. // return;
  437. // }
  438. // if (this.inputData.name !== this.groupNode.name) {
  439. // // this.$emit("renameGroup", this.groupNode.id, this.level, this.newName);
  440. // }
  441. // this.inputData = null;
  442. },
  443. onDel(node, data) {
  444. this.deleteId = data.id;
  445. },
  446. onRequestForCancelDelete() {
  447. this.deleteId = null;
  448. },
  449. onConfirmDelete(node, data) {
  450. // this.$emit("delete", this.sceneInfo.id);
  451. // this.isConfirmingDeletion = false;
  452. this.onRequestForCancelDelete();
  453. if (this.sceneList.length == 1 && data.type != "group") {
  454. this.$alert({
  455. title: this.$i18n.t("navigation.delete_init_scene"),
  456. content: this.$i18n.t("navigation.keep_one_scene"),
  457. });
  458. return;
  459. }
  460. console.error(node, data);
  461. if (this.info.navigationTrees.length == 1 && node.level == 1) {
  462. this.$alert({
  463. content: this.$i18n.t("navigation.keep_one_group"),
  464. });
  465. return;
  466. }
  467. if ((node.level == 1 || node.level == 2) && data.type == "group") {
  468. let delScenes = [];
  469. this.info.navigationTrees.forEach((item) => {
  470. item.children.forEach((s_item) => {
  471. if (s_item.type != "group" && (item.id == node.data.id || s_item.id == node.data.id)) {
  472. delScenes.push(s_item);
  473. }
  474. s_item.children.forEach((t_item) => {
  475. if (t_item.type != "group" && (item.id == node.data.id || s_item.id == node.data.id)) {
  476. delScenes.push(t_item);
  477. }
  478. });
  479. });
  480. });
  481. if (delScenes.length >= this.sceneList.length) {
  482. //如果要删除的场景大于等于 当前场景数量,则弹出提示 至少保留一个
  483. this.$alert({
  484. title: this.$i18n.t("navigation.delete_init_scene"),
  485. content: this.$i18n.t("navigation.keep_one_scene"),
  486. });
  487. return;
  488. }
  489. }
  490. const parent = node.parent;
  491. const children = parent.data.children || parent.data;
  492. const index = children.findIndex((d) => d.id === data.id);
  493. children.splice(index, 1);
  494. this.processTreeData("del");
  495. // if (parent.data.children.length == 1 && parent.data.children[0].type == "group") {
  496. // let newChild = children[0].children;
  497. // parent.data.children = newChild;
  498. // }
  499. // console.error(this.info.navigationTrees);
  500. },
  501. addNode(data) {
  502. let roundId = new Date().getTime();
  503. let group = {
  504. id: "add_" + roundId,
  505. sid: "sid_" + getRandomSid(), //用于修改导航之后的标识
  506. name: data ? this.$i18n.t("navigation.group_two") : this.$i18n.t("navigation.group_one"),
  507. type: "group",
  508. level: data ? 1 : 0,
  509. children: [],
  510. };
  511. console.error(group);
  512. if (data) {
  513. // if (data.children.length && data.children[0].type != "group") {
  514. // //新增子目录的时候,如果目录里面没有子目录,新增一个默认目录包含旧数据
  515. // let list = JSON.parse(JSON.stringify(data.children));
  516. // data.children = [];
  517. // let defaultDir = {
  518. // id: "add_" + (roundId + 1),
  519. // sort: 0,
  520. // name: this.$i18n.t("navigation.default_group_two"),
  521. // type: "group",
  522. // children: list,
  523. // };
  524. // data.children.push(defaultDir);
  525. // }
  526. data.children.push(group);
  527. this.$refs.sceneTree.store.nodesMap[data.id].expanded = true;
  528. } else {
  529. this.info.navigationTrees.push(group);
  530. }
  531. this.processTreeData("add");
  532. this.$nextTick(() => {
  533. this.onClickForRename(group);
  534. });
  535. },
  536. getRoundId() {
  537. return new Date().getTime();
  538. },
  539. processTreeData(type) {
  540. this.info.navigationTrees.forEach((item) => {
  541. //一级目录
  542. let panoList = item.children.filter((pano) => pano.type != "group");
  543. let groupList = item.children.filter((pano) => pano.type == "group");
  544. switch (type) {
  545. case "add":
  546. if (panoList.length && groupList.length) {
  547. //新增目录到二级目录。且二级目录只有场景的时候
  548. console.error("add");
  549. let list = [];
  550. let defaultDir = {
  551. id: "add_" + (this.getRoundId() + 1),
  552. sid: "sid_" + getRandomSid(), //用于修改导航之后的标识
  553. sort: 0,
  554. name: this.$i18n.t("navigation.default_group_two"),
  555. type: "group",
  556. children: panoList,
  557. };
  558. list.push(defaultDir);
  559. list = list.concat(groupList);
  560. item.children = list;
  561. }
  562. if (item.children.length == 1 && item.type == "group" && !item.children[0].children.length) {
  563. //新增二级目录的时候,如果新增完只有一个二级目录,且二级目录为空,创建多一个目录,且第一个为默认二级目录
  564. let list = [];
  565. let defaultDir = {
  566. id: "add_" + (this.getRoundId() + 1),
  567. sid: "sid_" + getRandomSid(), //用于修改导航之后的标识
  568. sort: 0,
  569. name: this.$i18n.t("navigation.default_group_two"),
  570. type: "group",
  571. children: [],
  572. };
  573. list.push(defaultDir);
  574. list = list.concat(groupList);
  575. item.children = list;
  576. }
  577. break;
  578. case "del":
  579. if (groupList.length == 1 && !panoList.length && groupList[0].children.length) {
  580. //当只有一个二级目录,二级目录有场景
  581. item.children = groupList[0].children;
  582. }
  583. if (groupList.length == 1 && !groupList[0].children.length) {
  584. //当只有一个二级目录,二级目录没有场景
  585. item.children = [];
  586. }
  587. break;
  588. case "drag":
  589. if (panoList.length && groupList.length) {
  590. //新增目录到二级目录。且二级目录只有场景的时候
  591. console.error("drag");
  592. let list = [];
  593. let defaultDir = {
  594. id: "add_" + (this.getRoundId() + 1),
  595. sid: "sid_" + getRandomSid(), //用于修改导航之后的标识
  596. sort: 0,
  597. name: this.$i18n.t("navigation.default_group_two"),
  598. type: "group",
  599. children: panoList,
  600. };
  601. list.push(defaultDir);
  602. list = list.concat(groupList);
  603. item.children = list;
  604. console.error(item.children);
  605. break;
  606. }
  607. }
  608. // if (item.id == this.currentRootId) {
  609. // console.error(groupList);
  610. // if (groupList.length) {
  611. // let index = groupList.findIndex((pano) => pano.children.length);
  612. // this.$store.commit("navigation/setData", { currentSecondId: groupList[index].id });
  613. // } else {
  614. // this.$store.commit("navigation/setData", { currentSecondId: null });
  615. // }
  616. // // let currentSecondId = item.children.find((group) => group.id == this.currentSecondId);
  617. // // console.error("currentSecondId", currentSecondId);
  618. // }
  619. });
  620. },
  621. },
  622. created() {},
  623. };
  624. </script>
  625. <style lang="less" rel="stylesheet/less" scoped>
  626. .vtl {
  627. // .vtl-drag-disabled {
  628. // background-color: #d0cfcf;
  629. // &:hover {
  630. // background-color: #d0cfcf;
  631. // }
  632. // }
  633. // .vtl-disabled {
  634. // background-color: #d0cfcf;
  635. // }
  636. }
  637. </style>
  638. <style lang="less" rel="stylesheet/less" scoped>
  639. .icon {
  640. &:hover {
  641. cursor: pointer;
  642. }
  643. }
  644. .el-tree {
  645. background: none !important;
  646. color: hsla(0, 0%, 100%, 0.6);
  647. // .folder_expanded {
  648. // display: none;
  649. // }
  650. // .is-expanded {
  651. // .folder_collapsed {
  652. // display: none;
  653. // }
  654. // .folder_expanded {
  655. // display: inline-block;
  656. // }
  657. // }
  658. .tree-msg {
  659. width: calc(100% - 24px);
  660. // min-height: 40px;
  661. color: hsla(0, 0%, 100%, 0.6);
  662. // display: flex;
  663. // align-items: center;
  664. // justify-content: space-between;
  665. padding-right: 10px;
  666. .tree-info {
  667. // display: flex;
  668. // align-items: center;
  669. // justify-content: flex-start;
  670. height: 100%;
  671. // height: 40px;
  672. // flex: 1;
  673. .group-info {
  674. display: flex;
  675. align-items: center;
  676. justify-content: flex-start;
  677. flex: 1;
  678. height: 100%;
  679. position: relative;
  680. .drag-icon {
  681. position: absolute;
  682. width: 40px;
  683. height: 40px;
  684. background: #313131;
  685. box-shadow: 0 0 4px 0 rgb(0 0 0 / 50%);
  686. border-radius: 4px;
  687. display: flex;
  688. justify-content: center;
  689. align-items: center;
  690. z-index: -1;
  691. }
  692. span {
  693. margin-left: 6px;
  694. display: inline-block;
  695. text-overflow: ellipsis;
  696. overflow: hidden;
  697. white-space: nowrap;
  698. flex: 1 1 auto;
  699. }
  700. }
  701. }
  702. .image-info {
  703. display: flex;
  704. align-items: center;
  705. // padding: 10px 0;
  706. height: 64px;
  707. // flex: 1;
  708. width: 100%;
  709. .cover-image {
  710. flex: 0 0 auto;
  711. width: 64px;
  712. height: 64px;
  713. background: #b0b0b0;
  714. border-radius: 2px;
  715. background-size: cover;
  716. img {
  717. width: 100%;
  718. height: 100%;
  719. pointer-events: none;
  720. object-fit: cover;
  721. }
  722. }
  723. .image-name {
  724. margin-left: 10px;
  725. width: calc(100% - 74px);
  726. flex: 1 1 auto;
  727. display: flex;
  728. flex-direction: column;
  729. justify-content: space-between;
  730. height: 100%;
  731. flex: 1;
  732. .name-top {
  733. width: 100%;
  734. span {
  735. width: 100%;
  736. word-break: break-all;
  737. display: -webkit-box;
  738. -webkit-box-orient: vertical;
  739. -webkit-line-clamp: 2;
  740. overflow: hidden;
  741. font-size: 14px;
  742. color: hsla(0, 0%, 100%, 0.6);
  743. white-space: normal;
  744. }
  745. }
  746. .name-bottom {
  747. color: #0076f6;
  748. }
  749. }
  750. .group-title-input {
  751. width: 100%;
  752. margin-left: 0;
  753. }
  754. }
  755. .group-title-input {
  756. margin-left: 6px;
  757. flex: 1 1 auto;
  758. width: 1px;
  759. height: 30px;
  760. background: #1a1b1d;
  761. border-radius: 2px;
  762. border: 1px solid #404040;
  763. color: #fff;
  764. font-size: 14px;
  765. padding: 0 10px 0 16px;
  766. &:focus {
  767. border-color: #0076f6;
  768. }
  769. }
  770. .deletion-confirm-wrap {
  771. position: absolute;
  772. top: 0;
  773. bottom: 0;
  774. right: 0;
  775. width: 44px;
  776. overflow: hidden;
  777. pointer-events: none;
  778. border-top-right-radius: 4px;
  779. border-bottom-right-radius: 4px;
  780. > .deletion-confirm {
  781. position: absolute;
  782. top: 0;
  783. bottom: 0;
  784. width: 100%;
  785. background: #fa5555;
  786. transition: right 0.3s;
  787. cursor: pointer;
  788. text-align: center;
  789. font-size: 12px;
  790. color: #fff;
  791. pointer-events: auto;
  792. &::after {
  793. content: "";
  794. height: 100%;
  795. vertical-align: middle;
  796. display: inline-block;
  797. }
  798. &.show {
  799. right: 0;
  800. }
  801. &.hide {
  802. right: -44px;
  803. }
  804. }
  805. }
  806. .controls-btn {
  807. display: none;
  808. > i {
  809. margin-left: 12px;
  810. &.iconfont {
  811. &:hover {
  812. color: #0076f6;
  813. }
  814. }
  815. }
  816. }
  817. &.image-item {
  818. .controls-btn {
  819. position: absolute;
  820. right: 10px;
  821. bottom: 8px;
  822. }
  823. .tree-info {
  824. display: flex;
  825. align-items: center;
  826. justify-content: flex-start;
  827. width: 100%;
  828. }
  829. }
  830. }
  831. }
  832. </style>
  833. <style lang="less">
  834. .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
  835. background: none !important;
  836. }
  837. .el-tree-node:focus > .el-tree-node__content {
  838. background: none !important;
  839. }
  840. .el-tree-node:focus > .el-tree-node__content:hover {
  841. background: #313131 !important;
  842. }
  843. .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content:hover {
  844. background: #313131 !important;
  845. }
  846. .el-tree-node__content:hover,
  847. .el-upload-list__item:hover {
  848. background: #313131;
  849. }
  850. .el-tree-node > .el-tree-node__children {
  851. overflow: inherit;
  852. }
  853. .el-tree-node__content {
  854. // height: 60px;
  855. height: auto;
  856. // padding: 10px 0;
  857. border-radius: 4px;
  858. }
  859. .el-tree-node__content {
  860. // padding-left: 30px !important;
  861. position: relative;
  862. &::before {
  863. content: "";
  864. width: 24px;
  865. height: 24px;
  866. display: inline-block;
  867. }
  868. &:hover {
  869. .controls-btn {
  870. display: block !important;
  871. }
  872. }
  873. }
  874. .custom-tree .el-tree__drop-indicator {
  875. // display: none
  876. // margin-top: -25px; /* 修改间距为10px */
  877. // margin-bottom: 10px; /* 修改间距为10px */
  878. }
  879. .el-tree-node__expand-icon {
  880. // height: 44px;
  881. display: flex;
  882. align-items: center;
  883. margin-right: 5px;
  884. }
  885. // .el-tree-node__expand-icon:hover {
  886. // background: red;
  887. // }
  888. // .el-tree-node__content{
  889. // background: red;
  890. // }
  891. .el-tree-node__content .el-tree-node__expand-icon {
  892. position: absolute;
  893. height: 100%;
  894. // left: 6px;
  895. }
  896. .el-tree-node__content .el-tree-node__expand-icon:first-child + .group-item {
  897. height: 44px;
  898. }
  899. .el-tree-node__content .el-tree-node__expand-icon:first-child + .image-item {
  900. height: 80px;
  901. }
  902. </style>