App.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <script setup lang="ts">
  2. import { onMounted, ref, h, computed, unref, watchEffect } from "vue";
  3. import { createApp } from "/@/hooks/userApp";
  4. import tagView from "/@/components/custom/tagView.vue";
  5. import LoadingLogo from "/@/components/basic/loading.vue";
  6. import MiniMap from "/@/components/basic/miniMap.vue";
  7. import FloorplanView from "/@/components/basic/floorplan.vue";
  8. import { useSceneStore } from "/@/store/modules/scene";
  9. import type { FloorsType } from "/@/store/modules/scene";
  10. import { useAppStore } from "./store/modules/app";
  11. import Guideline from "/@/components/basic/guide.vue";
  12. import ChatRoom from "/@/components/chatRoom/index.vue";
  13. import Title from "/@/components/basic/title.vue";
  14. import FloorSwitch from "/@/components/basic/FloorSwitch.vue";
  15. import GuidePanel from "/@/components/custom/panel.vue";
  16. import browser from "/@/utils/browser";
  17. import { useRtcStore } from "./store/modules/rtc";
  18. const sceneStore = useSceneStore();
  19. const appStore = useAppStore();
  20. const rtcStore = useRtcStore();
  21. const dataLoaded = ref(false);
  22. const scene$ = ref<Nullable<HTMLElement>>(null);
  23. const refMiniMap = ref<Nullable<string>>(null);
  24. const flying = computed(() => appStore.flying);
  25. const player = computed(() => appStore.player);
  26. const metadata = computed(() => sceneStore.metadata);
  27. const mode = computed(() => appStore.mode);
  28. const isJoined = computed(() => rtcStore.isJoined);
  29. const isLoaded = computed(() => appStore.isLoaded);
  30. const controls = computed(() => {
  31. return metadata.value.controls;
  32. });
  33. const floorplanViewShow = computed(() => {
  34. return (
  35. Boolean(controls.value.showDollhouse) &&
  36. Boolean(controls.value.showFloorplan) &&
  37. mode.value !== "panorama"
  38. );
  39. });
  40. const show = ref(false);
  41. const isTourMode = computed(() => appStore.isTourMode);
  42. watchEffect(() => {
  43. console.warn("mode", mode);
  44. });
  45. onMounted(async () => {
  46. const app = await createApp({
  47. dom: scene$.value as HTMLElement,
  48. num: browser.getURLParam("m") || "KK-t-gpAaKxXhE9",
  49. mobile: true,
  50. });
  51. // SDK初始化
  52. app.use("MinMap", { theme: { camera_fillStyle: "#ED5D18" } });
  53. app.use("Tag");
  54. app.use("TourPlayer");
  55. app.use("TagView", {
  56. render(data) {
  57. if (data.media["image"] && data.media["image"].length) {
  58. return h(tagView, {
  59. sid: data.sid,
  60. url: app.resource.getUserResourceURL(data.media["image"][0].src),
  61. content: data.content,
  62. title: data.title,
  63. });
  64. }
  65. return `<span class="tag-icon animate" style="display:none"></span>`;
  66. },
  67. });
  68. app.use("TourPlayer");
  69. app.render();
  70. // SDK初始化结束
  71. // SDK global Event start
  72. app.Scene.on("ready", () => {
  73. show.value = true;
  74. });
  75. app.Scene.on("loaded", (pano) => {
  76. refMiniMap.value = "[xui_min_map]";
  77. appStore.setFloorId(pano.floorIndex);
  78. // store.commit("setFloorId", pano.floorIndex);
  79. // store.commit("rtc/setShowdaogou", true);
  80. // if (browser.getURLParam("roomId") && browser.getURLParam("vruserId") && browser.getURLParam("name")) {
  81. // store.commit("showShoppingguide", true);
  82. // }
  83. });
  84. app.store.on("metadata", (metadata: KankanMetaDataType) => {
  85. sceneStore.load(metadata);
  86. if (!metadata.controls.showMap) {
  87. app.MinMap.hide(true);
  88. }
  89. dataLoaded.value = true;
  90. appStore.isLoad();
  91. });
  92. app.store.on("floorcad", ({ floors }: { floors: FloorsType[] }) => {
  93. if (floors?.length) {
  94. sceneStore.loadFloorData(floors);
  95. }
  96. });
  97. app.Camera.on("mode.beforeChange", ({ toMode, floorIndex, fromMode }) => {
  98. appStore.setMode(toMode);
  99. if (toMode != "dollhouse") {
  100. appStore.setFloorId(floorIndex);
  101. }
  102. if (fromMode) {
  103. appStore.setFlying(true);
  104. }
  105. });
  106. app.Camera.on("mode.afterChange", () => {
  107. appStore.setFlying(false);
  108. });
  109. app.Camera.on("flying.started", () => {
  110. appStore.setFlying(true);
  111. });
  112. app.Camera.on("flying.ended", ({ targetPano }) => {
  113. appStore.setFlying(false);
  114. appStore.setFloorId(targetPano.id);
  115. });
  116. });
  117. // SDK global Event end
  118. // method
  119. const changeMode = (name: string) => {
  120. if (!flying.value) {
  121. appStore.setMode(name);
  122. } else {
  123. appStore.setMode(name);
  124. }
  125. };
  126. </script>
  127. <template>
  128. <LoadingLogo :thumb="true" />
  129. <!-- 引导页 -->
  130. <Title v-if="!isJoined && isLoaded" />
  131. <Guideline />
  132. <div class="ui-view-layout" :class="{ show: show }">
  133. <div class="scene" ref="scene$"></div>
  134. <template v-if="dataLoaded">
  135. <!-- 小地图 start -->
  136. <MiniMap
  137. :show="!!unref(refMiniMap) && player.showWidgets"
  138. :show-dollhouse="Boolean(controls.showDollhouse)"
  139. :to="refMiniMap"
  140. @change-mode="changeMode"
  141. />
  142. <!-- 小地图 end -->
  143. <!-- 平面图 start -->
  144. <FloorplanView
  145. :show="floorplanViewShow"
  146. :mode="mode"
  147. @change-mode="changeMode"
  148. />
  149. <!-- 平面图 end -->
  150. <!-- 聊天 start-->
  151. <ChatRoom v-if="!isTourMode" />
  152. <!-- 聊天 end -->
  153. <!-- 多楼层 start-->
  154. <FloorSwitch />
  155. <!-- 多楼层 end -->
  156. <!-- panel start-->
  157. <GuidePanel v-if="isTourMode" />
  158. <!-- panel end -->
  159. </template>
  160. </div>
  161. </template>
  162. <style lang="scss">
  163. @import "./app.scss";
  164. </style>