gemercheung 2 年之前
父節點
當前提交
7c5b69c717

+ 32 - 5
packages/qjkankan-editor/src/components/pulldownMenuInEditor.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="pull-down-menu-in-editor" v-clickoutside="onClickOutside">
     <button class="menu-cover" @click="isExpand = !isExpand">
-      {{ placeholder ? placeholder : $i18n.t(`zh_key.${value}`) }}
+      {{ placeholder ? placeholder : current.label }}
       <i
         class="iconfont icon-material_preview_upload_collect"
         :class="{ flip: isExpand }"
@@ -13,7 +13,8 @@
         :key="index"
         @click="onSelect(item)"
       >
-        {{ $i18n.t(`zh_key.${item}`) }}
+        <!-- {{ $i18n.t(`zh_key.${item}`) }} -->
+        {{ item.label }}
       </button>
     </div>
   </div>
@@ -25,7 +26,7 @@ export default {
     valueList: {
       type: Array,
       default: function () {
-        return ["111", "222"];
+        return [];
       },
     },
     placeholder: {
@@ -40,8 +41,34 @@ export default {
   data() {
     return {
       isExpand: false,
+      current: {
+        id: "",
+        label: "",
+      },
     };
   },
+  watch: {
+    valueList: {
+      handler(val) {
+        if (val && val.length > 0) {
+          if (!this.current.id) {
+            this.current = this.valueList[0];
+          }
+        }
+      },
+      immediate: true,
+    },
+    value: {
+      handler(val) {
+        const changeValue = this.valueList.find((i) => i.id === val);
+        if (changeValue) {
+          this.current = changeValue;
+        }
+      },
+      immediate: true,
+    },
+  },
+
   methods: {
     onClickOutside() {
       if (this.isExpand) {
@@ -51,7 +78,7 @@ export default {
     onSelect(item) {
       console.log(item, "ads");
       this.isExpand = false;
-      this.$emit("input", item);
+      this.$emit("input", item.id);
     },
   },
 };
@@ -92,7 +119,7 @@ button {
       border-top: none;
       cursor: pointer;
       text-align: left;
-      padding:0 16px;
+      padding: 0 16px;
     }
   }
 }

+ 64 - 69
packages/qjkankan-editor/src/lang/_en.json

@@ -551,19 +551,19 @@
       "delete_work": "Delete project",
       "comfirm_delete": "Confirm to delete the project?"
     },
-    "components":{
-      "prev":"Previous",
-      "next":"Next",
-      "zoom_in":"Zoom in",
-      "zoom_out":"Zoom out",
-      "delete":"Delete",
-      "fullscreen":"Full screen",
-      "cancel_fullscreen":"Exit full screen",
-      "pano_setting":"Thumbnail Settings",
-      "drag_to_cut":"Drag the screen to have a screenshot",
-      "cutting":"Screenshot",
-      "preview_cover":"View",
-      "rename_material":"Rename the material"
+    "components": {
+      "prev": "Previous",
+      "next": "Next",
+      "zoom_in": "Zoom in",
+      "zoom_out": "Zoom out",
+      "delete": "Delete",
+      "fullscreen": "Full screen",
+      "cancel_fullscreen": "Exit full screen",
+      "pano_setting": "Thumbnail Settings",
+      "drag_to_cut": "Drag the screen to have a screenshot",
+      "cutting": "Screenshot",
+      "preview_cover": "View",
+      "rename_material": "Rename the material"
     }
   },
   "gather": {
@@ -617,7 +617,6 @@
     "delete_success": "Deletion succeeded",
     "delete_fail": "Delete failed",
     "loading": "Loading",
-
     "too_long_word": "Title is too long; please upload an image with a 50-word or shorter title.",
     "too_long_word_audio": "Title is too long; please upload an audio with a 50-word or shorter title",
     "too_long_word_video": "Title is too long; please upload a video with a 50-word or shorter title",
@@ -625,23 +624,18 @@
     "cutting": "Cropping",
     "material_upload_fail": "Failed to upload material",
     "material_cutting_fail": "Failed to crop image",
-
     "fill_complete": "Please fill in the complete information.",
     "fill_phone": "Please fill in the phone number correctly",
     "edit_success": "Modification succeeded",
     "setting_success": "Setting succeeded",
     "scene_link_copy_tips": "Copied",
     "scene_link_copy_failed": "Copy failed",
-    
     "delete_material": "Delete material",
     "comfirm_delete_material": "Confirm to delete the material?",
-
     "can_not_delete_folder_when_uploading": "Please do not delete the folder while the material is being uploaded.",
     "delete_folder": "Delete folder",
     "comfirm_delete_folder": "Are you sure you wish to delete the folder and its contents?",
-
     "save_done": "Save successfully",
-
     "nothing_edit": "You haven't created any content yet",
     "at_least_one_scene": "At least one scene can be previewed. Please go to \"Scene Navigation\" to add",
     "exitVr": "Exit VR",
@@ -667,35 +661,35 @@
     "save": "Save"
   },
   "edit_settings": {
-    "coverBase_button":"Opening Cover",
-    "coverBase_button_tips":"The opening content of the entire project may be presented as an image or video.",
+    "coverBase_button": "Opening Cover",
+    "coverBase_button_tips": "The opening content of the entire project may be presented as an image or video.",
     "cover_show": "Show opening cover",
-    "cover_pull_tit":"Cover Type",
-    "coverSelecVideoAndImg":"Image + Video",
-    "coverSelecImg":"Image",
-    "coverSelecVideo":"Video",
-    "coverImgTit":"Image Settings",
-    "coverUpTit1":"1920*1080 pixels, within 2M, jpg/gif/png format is recommended",
-    "coverUpTit2":"750*1624 pixels ,within 1M, jpg/gif/png format is recommended",
-    "coverUpTit3":"300*300 pixels, within 100kb, jpg format is recommended",
-    "coverUpTit4":"1920*1080 pixels, within 5M, MP4 format is recommended",
-    "coverUpTit5":"750*1624 pixels, within 5M, MP4 format is recommended",
-    "coverImgLoc1":"Center",
-    "coverImgLoc2":"Full",
-    "coverImgBacTit":"Background Settings",
-    "coverImgBacSelec1":"Fill Color",
-    "coverImgBacSelec2":"Background-repeat",
-    "coverVideoTit":"Video Settings",
-    "select_video":"Select Video",
-    "coverImageInWay":"Entry Method",
-    "coverImageInWayTit":"Automatic entry after 3 seconds countdown",
-    "coverVideoInWay":"Entry Method",
-    "coverVideoInWayTit":"Auto-entry after video playback",
-    "coverVideoControl":"Video Control",
-    "coverVideoControlTit":"Display the video control or not",
-    "coverImageOrder":"Displaying Order",
-    "coverImageOrderTit1":"Images will appear before the video begins to play",
-    "coverImageOrderTit2":"Images will appear after the video begins to play",
+    "cover_pull_tit": "Cover Type",
+    "coverSelecVideoAndImg": "Image + Video",
+    "coverSelecImg": "Image",
+    "coverSelecVideo": "Video",
+    "coverImgTit": "Image Settings",
+    "coverUpTit1": "1920*1080 pixels, within 2M, jpg/gif/png format is recommended",
+    "coverUpTit2": "750*1624 pixels ,within 1M, jpg/gif/png format is recommended",
+    "coverUpTit3": "300*300 pixels, within 100kb, jpg format is recommended",
+    "coverUpTit4": "1920*1080 pixels, within 5M, MP4 format is recommended",
+    "coverUpTit5": "750*1624 pixels, within 5M, MP4 format is recommended",
+    "coverImgLoc1": "Center",
+    "coverImgLoc2": "Full",
+    "coverImgBacTit": "Background Settings",
+    "coverImgBacSelec1": "Fill Color",
+    "coverImgBacSelec2": "Background-repeat",
+    "coverVideoTit": "Video Settings",
+    "select_video": "Select Video",
+    "coverImageInWay": "Entry Method",
+    "coverImageInWayTit": "Automatic entry after 3 seconds countdown",
+    "coverVideoInWay": "Entry Method",
+    "coverVideoInWayTit": "Auto-entry after video playback",
+    "coverVideoControl": "Video Control",
+    "coverVideoControlTit": "Display the video control or not",
+    "coverImageOrder": "Displaying Order",
+    "coverImageOrderTit1": "Images will appear before the video begins to play",
+    "coverImageOrderTit2": "Images will appear after the video begins to play",
     "auto_pano": "Rotation",
     "enter_auto": "Enter the rotation mode (takes 3 mins to complete per rotation)",
     "set_bgm": "Set the BGM",
@@ -707,7 +701,7 @@
     "hide": "Hide",
     "show": "Display",
     "button_name": "Button name",
-    "button_type":"Button type",
+    "button_type": "Button type",
     "button_open_method": "Open methods",
     "button_placeholder": "Please enter the button name",
     "please_input": "Please enter",
@@ -765,21 +759,24 @@
     "自定义遮罩": "Custom Mask",
     "自定义按钮": "Custom Button",
     "开场封面": "Opening Cover",
-
-
     "素材": "Material",
     "名称": "Title",
     "大小": "Size",
     "分辨率": "Resolution",
     "创建时间": "Created",
     "修改时间": "Modified",
-
     "封面": "Cover",
     "场景标题": "Scene Title",
     "拍摄时间": "Shooting Time",
-    "一级分组":"1st Grouping",
-    "二级分组":"2nd Grouping",
-    "默认二级分组":"Default as 2nd grouping"
+    "一级分组": "1st Grouping",
+    "二级分组": "2nd Grouping",
+    "默认二级分组": "Default as 2nd grouping"
+  },
+  "customButton": {
+    "phone": "Tel",
+    "link": "Link",
+    "self": "Pop-up Notification",
+    "target": "New Tab"
   },
   "navigation": {
     "scene_edit_tips": "Please direct to the 4Dage Personal Center scene editing platform",
@@ -812,11 +809,10 @@
     "screen_tips": "The start screen is the initial screen that appears when entering a scene; please drag the panorama to select the appropriate screen setting.",
     "setting_screen": "Set the current view to the start screen",
     "goto_4dkk_edit_tips": "4Dage Personal Center~"
-
   },
   "hotspot": {
     "hotspot_type": "Hotspots Style",
-    "img_size":"Upload up to 20 images",
+    "img_size": "Upload up to 20 images",
     "hotspot_tips": "Add icon hotspots to the panorama and configure their effect",
     "add_hotspot": "Add hotspot",
     "current_hotspots": "Current Pano Hotspots",
@@ -915,9 +911,8 @@
     "change_pdf": "Change the PDF",
     "pdf_invalid_tip": "Please upload PDF files within 50M",
     "add_article": "Add Paragraph",
-    "edit_article":"Edit paragraph",
+    "edit_article": "Edit paragraph",
     "cancel_add_hotspot": "The edited content will not be saved, confirm to close it"
-    
   },
   "explanation": {
     "explanation_settings": "Voice Guide",
@@ -932,7 +927,7 @@
     "menu_width": "88px",
     "play_width": "31"
   },
-  "tips_code":{
+  "tips_code": {
     "FAILURE_2020": "appId is absent",
     "FAILURE_2021": "The appId was wrongly parsed",
     "FAILURE_5001": "token is empty",
@@ -952,16 +947,16 @@
     "FAILURE_3201": "Failed to request the interface",
     "FAILURE_3104": "The folder with the same name has already existed, please move the material directly",
     "FAILURE_error": "Network exception, please try again later",
-    "tips":"Tips",
-    "relogin":"Invalid login status; please log in again",
-    "goto_login":"Go to login",
-    "login_success":"Login completed, please continue",
-    "need_one":"Please keep at least one scene",
-    "not_less_than":"File title may not exceed 50 characters in length",
-    "work_had_delete":"The project has been deleted and cannot be edited",
-    "material_can_not_delete":"The material cannot be removed because it has been cited.",
-    "illegality_image":"This image is not supported",
-    "password_error":"Password error",
+    "tips": "Tips",
+    "relogin": "Invalid login status; please log in again",
+    "goto_login": "Go to login",
+    "login_success": "Login completed, please continue",
+    "need_one": "Please keep at least one scene",
+    "not_less_than": "File title may not exceed 50 characters in length",
+    "work_had_delete": "The project has been deleted and cannot be edited",
+    "material_can_not_delete": "The material cannot be removed because it has been cited.",
+    "illegality_image": "This image is not supported",
+    "password_error": "Password error",
     "FAILURE_3024": "Storage is at capacity",
     "loading_fail": "Failed to load"
   }

+ 6 - 0
packages/qjkankan-editor/src/lang/_zh.json

@@ -773,6 +773,12 @@
     "二级分组": "二级分组",
     "默认二级分组": "默认二级分组"
   },
+  "customButton": {
+    "phone": "电话",
+    "link": "链接",
+    "self": "弹出层打开",
+    "target": "新窗口打开"
+  },
   "navigation": {
     "scene_edit_tips": "请前往四维时代个人中心编辑场景",
     "go_scene_editor": "立即前往",

+ 92 - 53
packages/qjkankan-editor/src/views/base/customButtonSettings.vue

@@ -28,25 +28,25 @@
         <div class="left">
           <i class="iconfont icon-edit_input_arrow icon-expand"></i>
           <img
-            v-if="item.type === '电话' && item.isShow"
+            v-if="item.type === 'phone' && item.isShow"
             :src="require('@/assets/images/icons/phone.svg')"
             class="button-icon"
             alt=""
           />
           <img
-            v-if="item.type === '电话' && !item.isShow"
+            v-if="item.type === 'phone' && !item.isShow"
             :src="require('@/assets/images/icons/phone-dark.svg')"
             class="button-icon"
             alt=""
           />
           <img
-            v-if="item.type === '链接' && item.isShow"
+            v-if="item.type === 'link' && item.isShow"
             :src="require('@/assets/images/icons/link.svg')"
             class="button-icon"
             alt=""
           />
           <img
-            v-if="item.type === '链接' && !item.isShow"
+            v-if="item.type === 'link' && !item.isShow"
             :src="require('@/assets/images/icons/link-dark.svg')"
             class="button-icon"
             alt=""
@@ -99,12 +99,13 @@
             {{ item.value }}
           </div>
         </div>
-        <div class="edit-content-item" v-if="item.type !== '电话'">
+        <div class="edit-content-item" v-if="item.type !== 'phone'">
           <span class="item-name">{{
             $i18n.t("edit_settings.button_open_method")
           }}</span>
           <div style="margin-left: 16px">
-            {{ $i18n.t(`zh_key.${item.openMethod}`) }}
+            {{ getCurrentOpenMethodButton(item.openMethod).label }}
+            <!-- {{ $i18n.t(`zh_key.${item.openMethod}`) }} -->
           </div>
         </div>
       </div>
@@ -155,6 +156,7 @@
               class="selector"
               :valueList="buttonOpenMethodList"
               v-model="editingInfo.openMethod"
+              @input="handleClearCurrentValue"
             />
           </div>
         </div>
@@ -188,8 +190,28 @@ export default {
   data() {
     return {
       expandStatus: [],
-      buttonTypeList: ["电话", "链接"],
-      buttonOpenMethodList: ["弹出层打开", "新窗口打开"],
+      buttonTypeList: [
+        {
+          id: "phone",
+          label: i18n.t("customButton.phone"),
+        },
+        {
+          id: "link",
+          label: i18n.t("customButton.link"),
+        },
+      ],
+      buttonOpenMethodList: [
+        {
+          id: "_self",
+          label: i18n.t("customButton.self"),
+        },
+        {
+          id: "_target",
+          label: i18n.t("customButton.target"),
+        },
+      ],
+      // buttonTypeList: ["phone", "link"],
+      // buttonOpenMethodList: ["_self", "_target"],
       isEditing: false,
       editingButtonIdx: -1,
       editingInfo: {
@@ -204,9 +226,36 @@ export default {
     ...mapGetters({
       info: "info",
     }),
+    //1.3.1后用这个过滤中文Key
+    customButton() {
+      if (this.info.customButton && this.info.customButton.length > 0) {
+        return Array.from(this.info.customButton).map((item) => {
+          if (item.type == "电话") {
+            item.type = "phone";
+          }
+          if (item.type == "链接") {
+            item.type = "link";
+          }
+          if (item.openMethod == "弹出层打开") {
+            item.openMethod = "_self";
+          }
+          if (item.openMethod == "新窗口打开") {
+            item.openMethod = "_target";
+          }
+
+          return item;
+        });
+      }
+    },
     isNotPhoneMode() {
-      //TODO 这个模块都有用中文做为key value (惊了?)
-      return this.editingInfo.type === "电话";
+      return this.editingInfo.type === "phone";
+    },
+    getCurrentOpenMethodButton() {
+      return (id) =>
+        this.buttonOpenMethodList.find((i) => i.id === id) || {
+          id: "",
+          label: "",
+        };
     },
     experience_icon() {
       const lang = browser.urlQueryValue("lang");
@@ -217,11 +266,11 @@ export default {
       }
     },
     buttonValueTips() {
-      if (this.info.customButton) {
-        return this.info.customButton.map((item) => {
-          if (item.type === "电话") {
+      if (this.customButton) {
+        return this.customButton.map((item) => {
+          if (item.type === "phone") {
             return i18n.t("edit_settings.phone");
-          } else if (item.type === "链接") {
+          } else if (item.type === "link") {
             return i18n.t("edit_settings.link");
           } else {
             return "";
@@ -232,9 +281,9 @@ export default {
       }
     },
     editingButtonValueTip() {
-      if (this.editingInfo.type === "电话") {
+      if (this.editingInfo.type === "phone") {
         return i18n.t("edit_settings.phone");
-      } else if (this.editingInfo.type === "链接") {
+      } else if (this.editingInfo.type === "link") {
         return i18n.t("edit_settings.link");
       } else {
         return "";
@@ -242,21 +291,12 @@ export default {
     },
   },
   watch: {
-    // editingInfo: {
-    //   handler(val) {
-    //     console.log("editingInfo-1", val);
-    //   },
-    //   immediate: true,
-    //   deep: true,
-    // },
     "editingInfo.type": {
       handler(newValue) {
-        console.log("editingInfo.type", newValue);
-        this.editingInfo.name = i18n.t(`zh_key.${newValue}`);
-
-        // if (oldValue.length > 0 && newValue !== oldValue) {
-        //   this.editingInfo.value = "";
-        // }
+        console.log("editingInfo.type", newValue, this.customButton);
+        const item = this.buttonTypeList.find((i) => i.id === newValue);
+        console.log("label", item);
+        this.editingInfo.name = item.label;
       },
     },
   },
@@ -266,43 +306,39 @@ export default {
       // 这是在v1.2版之前创建的作品,还没设置过自定义按钮,所以还没有customButton字段
       this.info.customButton = [
         {
-          type: "电话",
-          name: "电话",
+          type: "phone",
+          name: i18n.t("customButton.phone"),
           value: "",
-          openMethod: "弹出层打开",
+          openMethod: "_self",
           isShow: false,
         },
         {
-          type: "链接",
-          name: "链接",
+          type: "link",
+          name: i18n.t("customButton.link"),
           value: "",
-          openMethod: "弹出层打开",
+          openMethod: "_self",
           isShow: false,
         },
       ];
     }
+
     if (!this.info.customButton[0].openMethod) {
       // 这是在v1.3版之前创建的作品,还没设置过自定义按钮的打开方式。
-      this.info.customButton[0].openMethod = "弹出层打开";
-      this.info.customButton[1].openMethod = "弹出层打开";
+      this.info.customButton[0].openMethod = "_self";
+      this.info.customButton[1].openMethod = "_self";
     }
   },
   mounted() {
-    this.info.customButton.forEach((item) => {
-      item.name =
-        i18n.t(`zh_key.${item.name}`).indexOf("zh_key") > -1
-          ? item.name
-          : i18n.t(`zh_key.${item.name}`);
-    });
+    // this.handleclearifyData();
   },
   methods: {
     handleClearCurrentValue() {
-      this.editingInfo.value = "";
+      // this.editingInfo.value = "";
     },
     getButtonTypeI18n(buttonType) {
-      if (buttonType === "电话") {
+      if (buttonType === "phone") {
         return i18n.t("edit_settings.phone_short");
-      } else if (buttonType === "链接") {
+      } else if (buttonType === "link") {
         return i18n.t("edit_settings.link_short");
       } else {
         return "";
@@ -313,11 +349,10 @@ export default {
     },
     onRequestForEdit(index) {
       this.editingButtonIdx = index;
-
-      this.editingInfo.type = this.info.customButton[index].type;
-      this.editingInfo.name = this.info.customButton[index].name;
-      this.editingInfo.value = this.info.customButton[index].value;
-      this.editingInfo.openMethod = this.info.customButton[index].openMethod;
+      this.editingInfo.type = this.customButton[index].type;
+      this.editingInfo.name = this.customButton[index].name;
+      this.editingInfo.value = this.customButton[index].value;
+      this.editingInfo.openMethod = this.customButton[index].openMethod;
       this.isEditing = true;
     },
     checkButtonName(name) {
@@ -328,12 +363,12 @@ export default {
       return true;
     },
     checkButtonValue(value, type) {
-      if (type === "电话") {
+      if (type === "phone") {
         if (!isValidPhoneNumber(value)) {
           this.$msg.warning(i18n.t("gather.fill_phone"));
           return false;
         }
-      } else if (type === "链接") {
+      } else if (type === "link") {
         if (!value) {
           this.$msg.warning(i18n.t("gather.fill_complete"));
           return false;
@@ -356,6 +391,10 @@ export default {
         this.editingInfo.name;
       this.info.customButton[this.editingButtonIdx].value =
         this.editingInfo.value;
+      if (this.editingInfo.type === "link") {
+        this.info.customButton[this.editingButtonIdx].openMethod =
+          this.editingInfo.openMethod;
+      }
       this.$msg.success(i18n.t("gather.success"));
       this.isEditing = false;
     },

+ 17 - 13
packages/qjkankan-view/src/components/UIGather/control.vue

@@ -154,19 +154,18 @@ const customLink = computed(() => store.getters["scene/customLink"]);
 const fdkkmetadata = computed(() => store.getters["fdkk/metadata"]);
 const fdkkBGM = computed(() => store.getters["fdkk/fdkkBGM"]);
 
-
-
 const setExplanation = () => {
-  let { audioUrl, openByDefault, repeat } = currentScene.value.explanation;
-  showCommentaryPlaying.value = false;
-  store.commit("functions/setCommentaryUrl", {
-    src: audioUrl,
-    loop: repeat,
-    openByDefault: openByDefault,
-  });
-
-  useSoundPlayer.player.isLock = false;
-  useSoundPlayer.player.watchPlay();
+  if ("audioUrl" in currentScene.value) {
+    let { audioUrl, openByDefault, repeat } = currentScene.value.explanation;
+    showCommentaryPlaying.value = false;
+    store.commit("functions/setCommentaryUrl", {
+      src: audioUrl,
+      loop: repeat,
+      openByDefault: openByDefault,
+    });
+    useSoundPlayer.player.isLock = false;
+    useSoundPlayer.player.watchPlay();
+  }
 };
 const resetExplanation = () => {
   store.commit("functions/setCommentaryUrl", "");
@@ -208,7 +207,12 @@ const onTelephone = () => {
 };
 
 const onLink = () => {
-  store.commit("functions/setShowLink", true);
+  const { openMethod, value } = unref(customLink);
+  if (openMethod == "_target") {
+    window.open(value, "_blank");
+  } else {
+    store.commit("functions/setShowLink", true);
+  }
 };
 
 const onIsBGM = () => {

+ 7 - 2
packages/qjkankan-view/src/components/UIGather/mobile/control.fdkk.vue

@@ -151,8 +151,13 @@ const onIntroduce = () => {
 
 
 const onLink = () => {
-  store.commit("functions/setShowLink", true);
-}
+  const { openMethod, value } = unref(customLink);
+  if (openMethod == "_target") {
+    window.open(value, "_blank");
+  } else {
+    store.commit("functions/setShowLink", true);
+  }
+};
 
 const onIsBGM = () => {
   if (v3IsBgm.value) {

+ 91 - 53
packages/qjkankan-view/src/components/UIGather/mobile/control.pano.vue

@@ -1,13 +1,12 @@
 <template>
-  <ul class="control-pano" >
-
+  <ul class="control-pano">
     <!-- 自定义链接 -->
     <li @click="onLink" v-if="customLink && customLink.isShow">
       <img :src="require(`@/assets/images/icon/link@2x.png`)" alt="" />
     </li>
 
     <!-- 联系电话 -->
-    <li  v-if="customTelephone &&customTelephone.isShow">
+    <li v-if="customTelephone && customTelephone.isShow">
       <a :href="`tel:${customTelephone.value}`">
         <img :src="require(`@/assets/images/icon/telephone@2x.png`)" alt="" />
       </a>
@@ -19,24 +18,50 @@
     </li>
 
     <!-- 背景音乐 -->
-    <li @click="onIsBGM" v-if="metadata.backgroundMusic && metadata.backgroundMusic.id">
-      <img :src="require(`@/assets/images/icon/${showMusicPlaying ? 'music@2x.png' : 'music_disabled@2x.png'}`)" alt="" />
+    <li
+      @click="onIsBGM"
+      v-if="metadata.backgroundMusic && metadata.backgroundMusic.id"
+    >
+      <img
+        :src="
+          require(`@/assets/images/icon/${
+            showMusicPlaying ? 'music@2x.png' : 'music_disabled@2x.png'
+          }`)
+        "
+        alt=""
+      />
     </li>
 
     <!-- 解说音频 -->
-    <li @click="onIsCommentary" v-if="currentScene.explanation&&currentScene.explanation.audioUrl">
-      <img :src="require(`@/assets/images/icon/${showCommentaryPlaying ? 'commentary@2x.png' : 'commentary_disabled@2x.png'}`)"
-        alt="" />
+    <li
+      @click="onIsCommentary"
+      v-if="currentScene.explanation && currentScene.explanation.audioUrl"
+    >
+      <img
+        :src="
+          require(`@/assets/images/icon/${
+            showCommentaryPlaying
+              ? 'commentary@2x.png'
+              : 'commentary_disabled@2x.png'
+          }`)
+        "
+        alt=""
+      />
     </li>
 
     <li @click="onIsAutoRotate">
-      <img :src="require(`@/assets/images/icon/${isAutoRotate ? 'rotation@2x.png' : 'rotation_disabled@2x.png'}`)"
-        alt="" />
+      <img
+        :src="
+          require(`@/assets/images/icon/${
+            isAutoRotate ? 'rotation@2x.png' : 'rotation_disabled@2x.png'
+          }`)
+        "
+        alt=""
+      />
     </li>
-
   </ul>
 
-  <teleport to='body'>
+  <teleport to="body">
     <introduce v-if="showIntroduce" />
     <telephone v-if="showTelephone" />
     <clink v-if="showLink" />
@@ -44,32 +69,38 @@
 </template>
 
 <script setup>
-import { ref, watch, computed, onMounted, watchEffect, nextTick } from "vue";
+import {
+  ref,
+  unref,
+  watch,
+  computed,
+  onMounted,
+  watchEffect,
+  nextTick,
+} from "vue";
 import { useStore } from "vuex";
 import { useApp } from "@/app";
 
 import introduce from "./control/text";
 import telephone from "./control/telephone";
 import clink from "./control/link";
-import { useMusicPlayer,useSoundPlayer } from '@/utils/sound'
-
+import { useMusicPlayer, useSoundPlayer } from "@/utils/sound";
 
 //背景音乐
-const musicPlayer = useMusicPlayer()
+const musicPlayer = useMusicPlayer();
 
 //解说音乐
-const soundPlayer = useSoundPlayer()
+const soundPlayer = useSoundPlayer();
 
 const store = useStore();
 
 const metadata = computed(() => store.getters["scene/metadata"]);
 
-
 const isAutoRotate = computed(() => store.getters["functions/isAutoRotate"]);
 
-const showMusicPlaying = ref(musicPlayer.isPlay)
+const showMusicPlaying = ref(musicPlayer.isPlay);
 
-const showCommentaryPlaying = ref(soundPlayer.isPlay)
+const showCommentaryPlaying = ref(soundPlayer.isPlay);
 
 // const isCommentary = computed(() => store.getters["functions/isCommentary"]);
 
@@ -83,34 +114,37 @@ const showIntroduce = computed(() => store.getters["functions/showIntroduce"]);
 const showTelephone = computed(() => store.getters["functions/showTelephone"]);
 const showLink = computed(() => store.getters["functions/showLink"]);
 
-const isFullscreen = ref(false)
+const isFullscreen = ref(false);
 
 const onIntroduce = () => {
   store.commit("functions/setShowIntroduce", true);
-}
-
+};
 
 const onLink = () => {
-  store.commit("functions/setShowLink", true);
-}
+  const { openMethod, value } = unref(customLink);
 
+  if (openMethod == "_target") {
+    window.open(value, "_blank");
+  } else {
+    store.commit("functions/setShowLink", true);
+  }
+};
 const onIsBGM = () => {
-  showMusicPlaying.value ? musicPlayer.pause() : musicPlayer.play()
-}
+  showMusicPlaying.value ? musicPlayer.pause() : musicPlayer.play();
+};
 
 const onIsAutoRotate = (data) => {
   store.commit("functions/setAutoRotate", !isAutoRotate.value);
 };
 
-
 const onIsCommentary = (data) => {
-  showCommentaryPlaying.value ? soundPlayer.pause() : soundPlayer.play()
+  showCommentaryPlaying.value ? soundPlayer.pause() : soundPlayer.play();
 };
 
 const onVR = (data) => {
   useApp().then((app) => {
-    console.log(app.krpanoDom.get('webvr'));
-    app.krpanoDom.call("webvr.enterVR()")
+    console.log(app.krpanoDom.get("webvr"));
+    app.krpanoDom.call("webvr.enterVR()");
   });
 };
 
@@ -143,27 +177,31 @@ const staticList = ref([
   },
 ]);
 
-
 onMounted(() => {
-  let events = ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'MSFullscreenChange']
+  let events = [
+    "fullscreenchange",
+    "webkitfullscreenchange",
+    "mozfullscreenchange",
+    "MSFullscreenChange",
+  ];
   events.forEach((item, index) => {
     window.addEventListener(item, () => {
-      isFullscreen.value = !isFullscreen.value
-    })
-  })
-})
-
-musicPlayer.on('play', () => {
-  showMusicPlaying.value = true
-  soundPlayer.pause()
-})
-musicPlayer.on('pause', () => (showMusicPlaying.value = false))
-
-soundPlayer.on('play', () => {
-  showCommentaryPlaying.value = true
-  musicPlayer.pause()
-})
-soundPlayer.on('pause', () => (showCommentaryPlaying.value = false))
+      isFullscreen.value = !isFullscreen.value;
+    });
+  });
+});
+
+musicPlayer.on("play", () => {
+  showMusicPlaying.value = true;
+  soundPlayer.pause();
+});
+musicPlayer.on("pause", () => (showMusicPlaying.value = false));
+
+soundPlayer.on("play", () => {
+  showCommentaryPlaying.value = true;
+  musicPlayer.pause();
+});
+soundPlayer.on("pause", () => (showCommentaryPlaying.value = false));
 </script>
 
 <style lang="scss" scoped>
@@ -172,7 +210,7 @@ soundPlayer.on('pause', () => (showCommentaryPlaying.value = false))
   align-items: center;
   height: 100%;
   border: 1px solid rgba(255, 255, 255, 0.2);
-  >li {
+  > li {
     width: 32px;
     height: 32px;
     margin: 0 2px;
@@ -185,11 +223,11 @@ soundPlayer.on('pause', () => (showCommentaryPlaying.value = false))
       width: 26px;
       height: 26px;
     }
-    
-    &:last-of-type{
+
+    &:last-of-type {
       margin-right: 10px;
     }
-    &:first-of-type{
+    &:first-of-type {
       margin-left: 10px;
     }
   }

+ 10 - 8
packages/qjkankan-view/src/components/UIGather/mobile/control.vue

@@ -35,15 +35,17 @@ const isShowCover = computed(
 );
 
 const setExplanation = () => {
-  let { audioUrl, openByDefault, repeat } = currentScene.value.explanation;
-  store.commit("functions/setCommentaryUrl", {
-    src: audioUrl,
-    loop: repeat,
-    openByDefault: openByDefault,
-  });
+  if ("audioUrl" in currentScene.value) {
+    let { audioUrl, openByDefault, repeat } = currentScene.value.explanation;
+    store.commit("functions/setCommentaryUrl", {
+      src: audioUrl,
+      loop: repeat,
+      openByDefault: openByDefault,
+    });
 
-  useSoundPlayer.player.isLock = false;
-  useSoundPlayer.player.watchPlay();
+    useSoundPlayer.player.isLock = false;
+    useSoundPlayer.player.watchPlay();
+  }
 };
 const resetExplanation = () => {
   store.commit("functions/setCommentaryUrl", "");

+ 2 - 2
packages/qjkankan-view/src/store/modules/scene.js

@@ -44,7 +44,7 @@ export default {
       let metadata = getters.metadata
       if (metadata.customButton) {
         let temp = JSON.parse(JSON.stringify(metadata.customButton))
-        return temp.find(item => item.type == '链接')
+        return temp.find(item => item.type == 'link')
       }
 
       return {}
@@ -56,7 +56,7 @@ export default {
       if (metadata.customButton) {
         console.log(metadata.customButton);
         let temp = JSON.parse(JSON.stringify(metadata.customButton))
-        return temp.find(item => item.type == '电话')
+        return temp.find(item => item.type == 'phone')
       }
 
       return {}