Преглед изворни кода

Merge branch 'hqyDev' of http://git.dayaedu.com/liushengqiang/music-score into ktyq-online-1.8.7

黄琪勇 пре 1 година
родитељ
комит
08500f3b67

+ 59 - 0
src/hooks/useDrag/dragbom.tsx

@@ -0,0 +1,59 @@
+import { defineComponent, computed, reactive, onMounted } from 'vue';
+import styles from './index.module.less';
+// 底部拖动区域
+export default defineComponent({
+  name: 'dragBom',
+  emits: ["guideDone"],
+	props: {
+		/** 是否显示引导 */
+		showGuide: {
+			type: Boolean,
+			default: false,
+		},
+	},
+  setup(props, { emit }) {
+    const data = reactive({
+      guidePos: "bottom" as "bottom" | "left" | "right",
+    });
+
+    const initGuidePos = () => {
+      const pageHeight = document.documentElement.clientHeight || document.body.clientHeight;
+      const pageWidth = document.documentElement.clientWidth || document.body.clientWidth;
+      const guideHeight = document.querySelector('.bom_guide')?.clientHeight || 0;
+      const guideWidth = document.querySelector('.bom_guide')?.clientWidth || 0;
+      const dragBBox = document.querySelector('.bom_drag')?.getBoundingClientRect();
+      const dragTop = dragBBox?.top || 0;
+      const dragLeft = dragBBox?.left || 0;
+      // 引导页出现在下边
+      if (pageHeight - dragTop > guideHeight) {
+        data.guidePos = "bottom"
+      } else {
+        // 引导页出现在左边or右边
+        data.guidePos = dragLeft > guideWidth ? "left" : "right"
+      }
+    }
+    onMounted(() => {
+      setTimeout(() => {
+        initGuidePos();
+      }, 0);
+    });
+    return () => (
+      <>
+      <div class={[styles.dragbomBox,"dragbomBox"]}>
+        <div class={[styles.dragBom, 'bom_drag']}>
+          <div class={styles.box}></div>
+          <div class={[styles.box, styles.right]}></div>
+        </div>
+      </div>
+        {
+          props.showGuide && 
+          <div class={[styles.guide, data.guidePos === "left" && styles.guideLeft, data.guidePos === "right" && styles.guideRight, 'bom_guide']} onClick={() => emit("guideDone")}>
+            <div class={styles.guideBg}></div>
+            <div class={styles.guideDone} onClick={(e) => {e.stopPropagation();emit("guideDone")}}></div>
+          </div>          
+        }
+
+      </>
+    );
+  }
+});

BIN
src/hooks/useDrag/img/left.png


BIN
src/hooks/useDrag/img/modalDragBg.png


BIN
src/hooks/useDrag/img/modalDragBg2.png


BIN
src/hooks/useDrag/img/modalDragBgLeft.png


BIN
src/hooks/useDrag/img/modalDragBgRight.png


BIN
src/hooks/useDrag/img/modalDragDone.png


BIN
src/hooks/useDrag/img/right.png


+ 88 - 0
src/hooks/useDrag/index.module.less

@@ -0,0 +1,88 @@
+.dragbomBox{
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  height: 36px;
+  width: 100%;
+  padding: 0 14px 0 15px;
+}
+.dragBom {
+  width: 100%;
+  height: 21px;
+  display: flex;
+  justify-content: space-between;
+  border-radius: 0 0 7px 7px;
+  overflow: hidden;
+  .box {
+    width: 21px;
+    height: 100%;
+    background: url('./img/left.png') no-repeat;
+    background-size: 100% 100%;
+    &.right {
+      background: url('./img/right.png') no-repeat;
+      background-size: 100% 100%;
+    }
+  }
+}
+.guide {
+  position: absolute;
+  left: 0;
+  top: calc(100% - 10px);
+  z-index: 3000;
+  &::before {
+    content: "";
+    display: block;
+    position: fixed;
+    left: -100vw;
+    top: -100vh;
+    z-index: 9;
+    width: 200vw;
+    height: 200vh;
+    background: rgba(0,0,0,0.2);
+  }
+  .guideBg {
+    position: relative;
+    z-index: 99;
+    width: 200px;
+    height: 102px;
+    background: url('./img/modalDragBg.png') no-repeat;
+    background-size: 100% 100%;
+  }
+  .guideDone {
+    position: absolute;
+    z-index: 99;
+    left: 34.6%;
+    top: 72.2%;
+    width: 50px;
+    height: 20px;
+    background: url('./img/modalDragDone.png') no-repeat;
+    background-size: 100% 100%;
+    cursor: pointer;
+  }
+  &.guideTop {
+    top: initial;
+    bottom: 2px;
+    .guideBg {
+      background: url('./img/modalDragBg2.png') no-repeat;
+      background-size: 100% 100%;
+    }
+  }
+  &.guideLeft {
+    top: initial;
+    left: -186px;
+    bottom: -4px;
+    .guideBg {
+      background: url('./img/modalDragBgLeft.png') no-repeat;
+      background-size: 100% 100%;
+    }
+  }
+  &.guideRight {
+    top: initial;
+    left: calc(100% - 12px);
+    bottom: -4px;
+    .guideBg {
+      background: url('./img/modalDragBgRight.png') no-repeat;
+      background-size: 100% 100%;
+    }
+  }
+}

+ 163 - 0
src/hooks/useDrag/index.ts

@@ -0,0 +1,163 @@
+// 弹窗拖动
+import { ref, Ref, watch, nextTick, computed } from 'vue';
+
+type posType = {
+  top: number;
+  left: number;
+};
+
+/**
+ * @params classList  可拖动地方的class值,也为唯一值
+ * @params boxClass  容器class值必须为唯一值,这个class和useid拼接 作为缓存主键
+ * @params dragShow  弹窗是否显示
+ * @params userId    当前用户id
+ */
+export default function useDrag(
+  classList: string[],
+  boxClass: string,
+  dragShow: Ref<boolean>,
+  userId: string
+) {
+  const pos = ref<posType>({
+    top: -1, // -1 为初始值 代表没有缓存 默认居中
+    left: -1
+  });
+  const useIdDargClass = userId + boxClass;
+  watch(dragShow, () => {
+    if (dragShow.value) {
+      // 初始化pos值
+      initPos();
+      window.addEventListener('resize', refreshPos);
+      nextTick(() => {
+        const boxClassDom = document.querySelector(
+          `.${boxClass}`
+        ) as HTMLElement;
+        if (!boxClassDom) {
+          return;
+        }
+        classList.map((className: string) => {
+          const classDom = document.querySelector(
+            `.${className}`
+          ) as HTMLElement;
+          if (classDom) {
+            classDom.style.cursor = 'move';
+            drag(classDom, boxClassDom, pos);
+          }
+        });
+      });
+    } else {
+      window.removeEventListener('resize', refreshPos);
+      setCachePos(useIdDargClass, pos.value);
+    }
+  });
+  const styleDrag = computed(() => {
+    // 没有设置拖动的时候保持原本的
+    return pos.value.left === -1 && pos.value.top === -1
+      ? {}
+      : {
+          position: 'fixed',
+          left: `${pos.value.left}px`,
+          top: `${pos.value.top}px`,
+          transform: 'initial',
+          transformOrigin: 'initial',
+          margin: 'initial',
+          transition: 'initial'
+        };
+  });
+  function initPos() {
+    const posCache = getCachePos(useIdDargClass);
+    // 有缓存 用缓存的值,没有缓存用默认
+    if (posCache) {
+      pos.value = posCache;
+      nextTick(() => {
+        refreshPos();
+      });
+    }
+  }
+  function refreshPos() {
+    if(pos.value.left === -1 && pos.value.top === -1){
+      return
+    }
+    const boxClassDom = document.querySelector(`.${boxClass}`) as HTMLElement;
+    if (!boxClassDom) return;
+    const parentElementRect = boxClassDom.getBoundingClientRect();
+    const clientWidth = document.documentElement.clientWidth;
+    const clientHeight = document.documentElement.clientHeight;
+    const { top, left } = pos.value;
+    const maxLeft = clientWidth - parentElementRect.width;
+    const maxTop = clientHeight - parentElementRect.height;
+    let moveX = left;
+    let moveY = top;
+    const minLeft = 0;
+    const minTop = 0;
+    moveX = moveX < minLeft ? minLeft : moveX > maxLeft ? maxLeft : moveX;
+    moveY = moveY < minTop ? minTop : moveY > maxTop ? maxTop : moveY;
+    pos.value = {
+      top: moveY,
+      left: moveX
+    };
+  }
+  return {
+    pos,
+    styleDrag
+  };
+}
+
+// 拖动
+function drag(el: HTMLElement, parentElement: HTMLElement, pos: Ref<posType>) {
+  function mousedown(e: MouseEvent) {
+    const parentElementRect = parentElement.getBoundingClientRect();
+    const downX = e.clientX;
+    const downY = e.clientY;
+    const clientWidth = document.documentElement.clientWidth;
+    const clientHeight = document.documentElement.clientHeight;
+    const maxLeft = clientWidth - parentElementRect.width;
+    const maxTop = clientHeight - parentElementRect.height;
+    const minLeft = 0;
+    const minTop = 0;
+    function onMousemove(e: MouseEvent) {
+      let moveX = parentElementRect.left + (e.clientX - downX);
+      let moveY = parentElementRect.top + (e.clientY - downY);
+      moveX = moveX < minLeft ? minLeft : moveX > maxLeft ? maxLeft : moveX;
+      moveY = moveY < minTop ? minTop : moveY > maxTop ? maxTop : moveY;
+      pos.value = {
+        top: moveY,
+        left: moveX
+      };
+    }
+    function onMouseup() {
+      document.removeEventListener('mousemove', onMousemove);
+      document.removeEventListener('mouseup', onMouseup);
+    }
+    document.addEventListener('mousemove', onMousemove);
+    document.addEventListener('mouseup', onMouseup);
+  }
+  el.addEventListener('mousedown', mousedown);
+}
+
+// 缓存
+const localStorageName = 'dragCachePos';
+function getCachePos(useIdDargClass: string): null | undefined | posType {
+  const localCachePos = localStorage.getItem(localStorageName);
+  if (localCachePos) {
+    try {
+      return JSON.parse(localCachePos)[useIdDargClass];
+    } catch {
+      return null;
+    }
+  }
+  return null;
+}
+function setCachePos(useIdDargClass: string, pos: posType) {
+  const localCachePos = localStorage.getItem(localStorageName);
+  let cachePosObj: Record<string, any> = {};
+  if (localCachePos) {
+    try {
+      cachePosObj = JSON.parse(localCachePos);
+    } catch {
+      //
+    }
+  }
+  cachePosObj[useIdDargClass] = pos;
+  localStorage.setItem(localStorageName, JSON.stringify(cachePosObj));
+}

+ 39 - 0
src/hooks/useDrag/useDragGuidance.ts

@@ -0,0 +1,39 @@
+import { getGuidance, setGuidance } from "../../page-instrument/custom-plugins/guide-page/api"
+import { ref } from "vue"
+
+export default function useDragGuidance() {
+   // 引导页
+   const guidanceShow = ref(false)
+   let guideInfoData: Record<string, any> = {}
+   getGuidanceShow()
+   async function getGuidanceShow() {
+      try {
+         const res = await getGuidance({ guideTag: "guideInfo" })
+         if (res.code === 200) {
+            if (res.data) {
+               const guideInfo = JSON.parse(res.data?.guideValue) || null
+               if (guideInfo) {
+                  guideInfoData = guideInfo
+                  guidanceShow.value = !guideInfo.teacherDrag
+               }
+            } else {
+               guidanceShow.value = true
+            }
+         }
+      } catch (e) {
+         console.log(e)
+      }
+   }
+   function setGuidanceShow() {
+      try {
+         setGuidance({ guideTag: "guideInfo", guideValue: JSON.stringify(Object.assign(guideInfoData, { teacherDrag: true })) })
+         guidanceShow.value = false
+      } catch (e) {
+         console.log(e)
+      }
+   }
+   return {
+      guidanceShow,
+      setGuidanceShow
+   }
+}

+ 7 - 3
src/page-instrument/view-figner/change-subject/index.tsx

@@ -1,4 +1,4 @@
-import { defineComponent, onMounted, reactive } from "vue";
+import { defineComponent, onMounted, reactive, watch } from "vue";
 import styles from "./index.module.less";
 import { Button, showToast } from "vant";
 
@@ -22,6 +22,10 @@ export default defineComponent({
       selectList: [] as any,
     });
 
+    // subject 变化时候 重新刷新
+    watch(()=>props.subject,()=>{
+      selectItem()
+    })
     //
     const selectItem = () => {
       // const i: any = props.subjectList.find((item: any) => item.value === props.subject);
@@ -89,7 +93,7 @@ export default defineComponent({
             ))}
           </div>
         </div> */}
-        <div class={styles.changeSubjectContainer}>
+        <div class={[styles.changeSubjectContainer,"changeSubjectContainer_pc"]}>
           <div class={styles.title}>声部</div>
 
           <div class={styles.subjectContainer}>
@@ -131,7 +135,7 @@ export default defineComponent({
           )}
         </div>
 
-        <div class={styles.btnGroups}>
+        <div class={[styles.btnGroups,"btnGroups_pc"]}>
           <div
             class={[styles.btn, styles.resetBtn]}
             onClick={() => {

BIN
src/page-instrument/view-figner/image/btnBg.png


BIN
src/page-instrument/view-figner/image/icon_shuo_v.png


BIN
src/page-instrument/view-figner/image/noteImg.png


BIN
src/page-instrument/view-figner/image/subJect-bg2.png


BIN
src/page-instrument/view-figner/image/subJect-bg3.png


+ 240 - 2
src/page-instrument/view-figner/index.module.less

@@ -108,6 +108,28 @@
             }
         }
     }
+    .tipsOverlay{
+        width: 57%;
+        height: 100%;
+        position: fixed;
+        top: 0;
+        left: 0;
+        z-index: 2009;
+        animation: bgIn 0.2s 0.2s forwards;
+    }
+    &.fingerRight .tipsPcBg.tips{
+        animation: bgIn 0.15s 0.25s forwards;
+        border-radius:0;
+        background-image: url('./image/icon_shuo_v.png') !important;
+    }
+    @keyframes bgIn {
+        0%{
+            background-color: initial;
+        }
+        100%{
+            background-color: rgba(0,0,0,0.5);
+        }
+    }
 }
 
 .popoverContainer {
@@ -238,11 +260,130 @@
         display: flex;
         flex-direction: column;
     }
-
+    .userTab{
+        display: flex;
+        justify-content: center;
+        width: 100%;
+        .userTabBox{
+            width: 100%;
+            .notes{
+                padding-bottom: 10px;
+                height: initial;
+                .lastNoteContent{
+                    border-radius: 0 !important; 
+                    .noteBox{
+                        border-radius: 0 !important;
+                    }
+                }
+                .noteContent{
+                    padding: 0 10px;
+                }
+                .changeMusBtn{
+                    margin-right: 8px;
+                    text-align: center;
+                    width: 42px;
+                    background: linear-gradient( 180deg, #F4EFED 0%, #D9CEC7 100%);
+                    box-shadow: 0px 1px 2px 0px #9F9690, inset 0px -2px 0px 0px #CDC0B5, inset 0px 2px 1px 0px #FFFFFF;
+                    border-radius: 21px;
+                    font-weight: 600;
+                    font-size: 12px;
+                    color: #616161;
+                    line-height: 16px;
+                    padding: 7px 6px;
+                    height: 46px;
+                }
+                .backBtn{
+                    line-height: 32px;
+                }
+            }
+            .optionBtns{
+                padding-bottom: 0;
+            }
+            :global{
+                .van-tabs__wrap{
+                    width: 100%;
+                    display: flex;
+                    justify-content: center;
+                    height: 30px;
+                    .van-tabs__nav{
+                        width: 120px;
+                        background-color: initial;
+                        border-bottom: 2px solid rgba(82,138,214,0.15);
+                        height: initial;
+                        padding-bottom: initial;
+                        .van-tab{
+                            font-weight: 400;
+                            font-size: 15px;
+                            color: #616161;
+                            &.van-tab--active{
+                                font-weight: 600;
+                                color: #616161;
+                            }
+                        }
+                        .van-tabs__line{
+                            width: 32px;
+                            bottom: -2px;
+                            height: 2px;
+                            background: #528AD6;
+                            border-radius: 3px;
+                        }
+                    }
+                }
+                .van-tabs__content{
+                    padding-top: 16px;
+                    height: 130px;
+                    .van-tab__panel{
+                        height: 100%;
+                    }
+                }
+            }
+            .btnBox{
+                height: 100%;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                margin-top: -16px;
+                .btnCon{
+                    border-radius: 17px;
+                    display: flex;
+                    background: rgba(255, 255, 255, 0.5);
+                    padding: 6px 5px 3px 6px;
+                    .btnGr{
+                        background: url("./image/btnBg.png") no-repeat;
+                        background-size: 100% 100%;
+                        width: 93px;
+                        height: 56px;
+                        display: flex;
+                        flex-direction: column;
+                        align-items: center;
+                        justify-content: center;
+                        cursor: pointer;
+                        margin-left: 5px;
+                        &:first-child{
+                            margin-left: 0;
+                        }
+                        >img{
+                            width: 19px;
+                            height: 19px;
+                        }
+                        >span{
+                            font-weight: 500;
+                            font-size: 14px;
+                            color: #616161;
+                            line-height: 20px;
+                        }
+                    }
+                }
+            }
+        }
+    }
     .boxFinger {
         flex: 1;
         padding-top: 50px;
         overflow: hidden;
+        &.pcBoxFinger{
+            padding-top: 10px !important;
+        }
     }
 
 
@@ -419,7 +560,45 @@
 
     }
 }
-
+.btnGrToggleBtn{
+    font-weight: 600;
+    font-size: 12px;
+    color: #fff;
+    >div{
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        z-index: 10;
+        &.nameBox{
+            padding-top: 2px;
+            .name{
+                font-size: 10px;
+            }
+            .noteKey{
+                font-size: 12px;
+                position: relative;
+                color: #ffffff;
+            }
+            .dot {
+                display: inline-block;
+                position: absolute;
+                top: 0px;
+                &.botDot{
+                    top: initial;
+                    bottom: -2px;
+                }
+            }
+        }
+    }
+    .name{
+        display: flex;
+    }
+    .arrowImg{
+        margin-top: 2px;
+        width: 9px;
+        height: 5px;
+    }
+}
 .notes {
     position: relative;
     display: flex;
@@ -1265,6 +1444,7 @@
     background: url('./image/subject-bg1.png') no-repeat center;
     border-radius: 12px;
     background-size: contain;
+    overflow: initial;
 }
 
 .linkSourceClass {
@@ -1302,4 +1482,62 @@
     // .backBtn {
     //     display: none;
     // }
+}
+.dragTopBox{
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 40px;
+    width: 100%; 
+}
+:global{
+    .changeSubjectShowBoxClass_drag{
+        height: 307px !important;
+        background: url('./image/subject-bg2.png') no-repeat center !important;
+        background-size: contain !important;
+        .dragbomBox{
+            height: 37px;
+        }
+        .changeSubjectContainer_pc{
+            height: 168px !important;
+        }
+        .btnGroups_pc{
+            padding-top: 12px !important;
+        }
+    }
+    .tnoteShowBoxClass_drag{
+        padding: 49px 17px 30px 24px;
+        width: 375px;
+        overflow: initial;
+        height: 247px !important;
+        background: url('./image/subject-bg3.png') no-repeat center !important;
+        background-size: contain !important;
+        .dragbomBox{
+            height: 37px;
+        }
+        .toneTitle_pc{
+            display: none;
+        }
+        .tipContentbox_pc{
+            background-color: initial;
+            &::after{
+                display: none;
+            }
+            .tipContent_pc{
+                border:none;
+                .tipWrap_pc{
+                    height: 116px !important;
+                    flex: initial;
+                    overflow-y: auto;
+                    &::-webkit-scrollbar {
+                        display: none;
+                    }
+                }
+                .toneAction_pc{
+                    padding-bottom: 0 !important;
+                    padding-top: 12px !important;
+                }
+            }
+        }
+    }
 }

+ 582 - 253
src/page-instrument/view-figner/index.tsx

@@ -1,4 +1,4 @@
-import { PropType, computed, defineComponent, nextTick, onBeforeMount, onMounted, onUnmounted, reactive, ref } from "vue";
+import { PropType, computed, defineComponent, nextTick, onBeforeMount, onMounted, onUnmounted, reactive, ref,toRef } from "vue";
 import styles from "./index.module.less";
 import icons from "./image/icons.json";
 import { FIGNER_INSTRUMENT_DATA, FIGNER_INSTRUMENT_REALKEY, IFIGNER_INSTRUMENT_Note } from "/src/view/figner-preview";
@@ -14,9 +14,14 @@ import { browser } from "/src/utils";
 import { usePageVisibility } from "@vant/use";
 import { watch } from "vue";
 import icon_loading_img from "./image/icon_loading_img.png";
+import noteImg from "./image/noteImg.png";
 import state, { IPlatform } from "/src/state";
 import { api_musicalInstrumentList, api_subjectList, getSubjectList } from "../api";
 import ChangeSubject from "./change-subject";
+import { Tabs,Tab } from "vant"
+import useDrag from '/src/hooks/useDrag';
+import Dragbom from '/src/hooks/useDrag/dragbom';
+import useDragGuidance from '/src/hooks/useDrag/useDragGuidance';
 
 export default defineComponent({
   name: "viewFigner",
@@ -546,15 +551,15 @@ export default defineComponent({
         resetMode(true, 0);
         handleStop();
         gaumntPause();
-
         // 重置乐器
-        if (res?.data?.data.code) {
+        if (res?.data?.data?.code) {
           data.subject = code;
           data.viewIndex = 0;
           data.tipShow = false;
           data.loadingDom = true;
           fingerData.fingeringInfo = subjectFingering(data.subject);
           data.activeTone = {} as any;
+          data.popupActiveTone = {} as any;
           resetElement();
           // 设置屏幕方向
           setTimeout(() => {
@@ -982,6 +987,43 @@ export default defineComponent({
         status: true,
       };
     };
+    const userTabActive=ref<"1"|"2">("1")
+    const userTabs=[
+      {
+        name:"音阶",
+        value:"1"
+      },
+      {
+        name:"功能",
+        value:"2"
+      }
+    ]
+    // 引导页
+    const {guidanceShow,setGuidanceShow}=useDragGuidance()
+    // 切换乐器弹窗
+    let changeSubjectShowBoxDragData: any;
+    let changeSubjectShowBoxClass: string;
+    if (query.platform==="pc") {
+      changeSubjectShowBoxClass = 'changeSubjectShowBoxClass_drag';
+      changeSubjectShowBoxDragData = useDrag(
+        [`${changeSubjectShowBoxClass} .dragTopBox`, `${changeSubjectShowBoxClass} .dragbomBox`],
+        changeSubjectShowBoxClass,
+        toRef(data, 'changeSubjectShow'),
+        storeData.user.id as string
+      );
+    }
+    // 移调弹窗
+    let tnoteShowBoxDragData: any;
+    let tnoteShowBoxClass: string;
+    if (query.platform==="pc") {
+      tnoteShowBoxClass = 'tnoteShowBoxClass_drag';
+      tnoteShowBoxDragData = useDrag(
+        [`${tnoteShowBoxClass} .dragTopBox`, `${tnoteShowBoxClass} .dragbomBox`],
+        tnoteShowBoxClass,
+        toRef(data, 'tnoteShow'),
+        storeData.user.id as string
+      );
+    }
     return () => {
       const relationship = fingerData.subject?.relationship?.[data.realKey] || [];
       const rs: number[] = Array.isArray(relationship[1]) ? relationship[fingerData.relationshipIndex] : relationship;
@@ -1000,46 +1042,51 @@ export default defineComponent({
             }
           }}
         >
-          <div
-            class={styles.head}
-            style={{
-              paddingTop: data.paddingTop && !browser().ios ? data.paddingTop : "",
-              paddingLeft: data.paddingLeft && !browser().ios ? data.paddingLeft : "",
-            }}
-          >
-            <div class={styles.left}>
-              <button class={[styles.backBtn]} onClick={() => handleBack()}>
-                <img src={icons.icon_back} />
-              </button>
-
+          {/* 老师端过来隐藏 */}
+          {
+            query.platform!=='pc'&&(
               <div
-                class={[styles.baseBtn, styles.changeInstrumentBtn]}
-                onClick={(e) => {
-                  e.stopPropagation();
-                  //
-                  // 播放音阶时不能切换
-                  if (playStatus.gamut) {
-                    return;
-                  }
-                  // 开始答题不能切换
-                  if (playAction.listenLock) {
-                    return;
-                  }
-
-                  data.changeSubjectShow = true;
+                class={styles.head}
+                style={{
+                  paddingTop: data.paddingTop && !browser().ios ? data.paddingTop : "",
+                  paddingLeft: data.paddingLeft && !browser().ios ? data.paddingLeft : "",
                 }}
               >
-                <img src={icons.icon_change_instrument} />
-                <span>切换乐器</span>
-              </div>
-              <div class={styles.baseBtn} onClick={onChangeFingeringModel}>
-                <img src={modeText.value.icon} />
-                <span>{modeText.value.text}</span>
+                <div class={styles.left}>
+                  <button class={[styles.backBtn]} onClick={() => handleBack()}>
+                    <img src={icons.icon_back} />
+                  </button>
+    
+                  <div
+                    class={[styles.baseBtn, styles.changeInstrumentBtn]}
+                    onClick={(e) => {
+                      e.stopPropagation();
+                      //
+                      // 播放音阶时不能切换
+                      if (playStatus.gamut) {
+                        return;
+                      }
+                      // 开始答题不能切换
+                      if (playAction.listenLock) {
+                        return;
+                      }
+    
+                      data.changeSubjectShow = true;
+                    }}
+                  >
+                    <img src={icons.icon_change_instrument} />
+                    <span>切换乐器</span>
+                  </div>
+                  <div class={styles.baseBtn} onClick={onChangeFingeringModel}>
+                    <img src={modeText.value.icon} />
+                    <span>{modeText.value.text}</span>
+                  </div>
+                  {/*  */}
+                </div>
+                {/*  */}
               </div>
-              {/*  */}
-            </div>
-            {/*  */}
-          </div>
+            )
+          }
           <div
             class={styles.fingerContent}
             style={{
@@ -1050,7 +1097,7 @@ export default defineComponent({
             <div class={styles.wrapFinger}>
               <div
                 id="fingeringContainer"
-                class={styles.boxFinger}
+                class={[styles.boxFinger,query.platform==='pc'?styles.pcBoxFinger:""]}
                 style={{
                   paddingTop: containerBox.value.paddingTop,
                   paddingBottom: containerBox.value.paddingBottom,
@@ -1076,142 +1123,492 @@ export default defineComponent({
                   </div>
                 </div>
               </div>
-              <div
-                class={styles.notes}
-                style={{
-                  paddingLeft: data.paddingLeft ? data.paddingLeft : "",
-                }}
-              >
-                {playAction.listenTipsStatus && <div class={[styles.tipsT, data.fingeringMode === "fingeringMode" ? styles.playTips2 : styles.playTips]}></div>}
-                {playAction.userAnswerStatus === 1 && <div class={[styles.tipsT, styles.playSuccess]}></div>}
-                {playAction.userAnswerStatus === 2 && <div class={[styles.tipsT, styles.playError]}></div>}
-                {playAction.resetAction && <div class={[styles.tipsT, styles.playTips5]}></div>}
-                {((data.noteType !== "#c" && (orientationDirection.value === 0 || (orientationDirection.value === 1 && state.platform === IPlatform.PC))) || (orientationDirection.value === 1 && state.platform === IPlatform.APP)) && (
-                  <Button
-                    class={styles.noteBtn}
-                    onClick={(e: any) => {
-                      e.stopPropagation();
-                      scrollNoteBox("left");
-                    }}
-                  >
-                    <Icon name="arrow-left" />
-                  </Button>
-                )}
+              {/* 老师端过来隐藏 */}
+              {
+                query.platform==='pc'?(
+                  <div class={styles.userTab}>
+                      <Tabs v-model:active={userTabActive.value} class={styles.userTabBox}>
+                        {
+                          userTabs.map(item=>{
+                            return <Tab title={item.name} name={item.value}>
+                              {
+                                item.value==="1"?(<>
+                                    <div
+                                      class={styles.notes}
+                                      style={{
+                                        paddingLeft: data.paddingLeft ? data.paddingLeft : "",
+                                      }}
+                                    >
+                                      {playAction.listenTipsStatus && <div class={[styles.tipsT, data.fingeringMode === "fingeringMode" ? styles.playTips2 : styles.playTips]}></div>}
+                                      {playAction.userAnswerStatus === 1 && <div class={[styles.tipsT, styles.playSuccess]}></div>}
+                                      {playAction.userAnswerStatus === 2 && <div class={[styles.tipsT, styles.playError]}></div>}
+                                      {playAction.resetAction && <div class={[styles.tipsT, styles.playTips5]}></div>}
+                                      <div class={[styles.backBtn,styles.changeMusBtn]} onClick={() => handleBack()}>
+                                          <span>返回</span>
+                                      </div>
+                                      <div class={styles.changeMusBtn} onClick={onChangeFingeringModel}>
+                                          <span>{modeText.value.text}</span>
+                                      </div>
+                                      <div
+                                        class={[styles.noteContent, data.fingeringMode !== "scaleMode" && orientationDirection.value === 0 && styles.noteContentOther, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad]}
+                                        onClick={(e: any) => {
+                                          e.stopPropagation();
+                                        }}
+                                      >
+                                        {((data.noteType !== "#c" && (orientationDirection.value === 0 || (orientationDirection.value === 1 && state.platform === IPlatform.PC))) || (orientationDirection.value === 1 && state.platform === IPlatform.APP)) && (
+                                          <Button
+                                            class={styles.noteBtn}
+                                            onClick={(e: any) => {
+                                              e.stopPropagation();
+                                              scrollNoteBox("left");
+                                            }}
+                                          >
+                                            <Icon name="arrow-left" />
+                                          </Button>
+                                        )}
+                                        {/* 判断是否为音阶模式 */}
+                                        {data.fingeringMode !== "scaleMode" && (
+                                          <div draggable={false} class={styles.note} onClick={noteChangeShow}>
+                                            <img draggable={false} src={data.noteType === "all" ? icons.icon_btn_orange : icons.icon_btn_orange2} />
+                                          </div>
+                                        )}
+                                        {!!data.tones.length && data.fingeringMode === "scaleMode" && (
+                                          <>
+                                            {fingerData.fingeringInfo.name == "hulusi-flute" ? (
+                                              <div id="finger-note-1" class={[styles.note,styles.btnGrToggleBtn]} onClick={() => (data.tnoteShow = true)}>
+                                                <img draggable={false} src={noteImg} />
+                                                <div class={styles.nameBox}>
+                                                  <div class={styles.name}>全按作</div>
+                                                  <div class={[styles.noteKey, styles.noteKeyBtn]}>
+                                                    {data.activeTone.step > 0 ? <span class={styles.dot}></span> : null}
+                                                    <div class={styles.noteName}>
+                                                      <sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
+                                                      {data.activeTone.key}
+                                                    </div>
+                                                    {data.activeTone.step < 0 ? <span class={[styles.dot,styles.botDot]}></span> : null}
+                                                  </div>
+                                                </div>
+                                              </div>
+                                            ) : (
+                                              <div id="finger-note-1" class={[styles.note,styles.btnGrToggleBtn]} onClick={() => (data.tnoteShow = true)}>
+                                                <img draggable={false} src={noteImg} />
+                                                <div>
+                                                  <div class={styles.name}>
+                                                    <div>
+                                                      <sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
+                                                      {data.activeTone.name}
+                                                    </div>
+                                                    调
+                                                  </div>
+                                                </div>
+                                              </div>
+                                            )}
+                                          </>
+                                        )}
+                                        {/* [styles.noteContent, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad] */}
+                                        <div class={styles.lastNoteContent}>
+                                          <div ref={noteBoxRef} class={styles.noteBox}>
+                                            {data.notes.map((note: IFIGNER_INSTRUMENT_Note, index: number) => {
+                                              const steps = new Array(Math.abs(note.step)).fill(1);
+                                              return (
+                                                <div
+                                                  id={index == 0 ? "finger-note-0" : ""}
+                                                  draggable={false}
+                                                  class={[styles.note, "note-class"]}
+                                                  key={note.realKey}
+                                                  onClick={async () => {
+                                                    // 判断是否在播放音阶
+                                                    if (playStatus.gamut) return;
+                                                    if (playAction.listenLock) return;
+                                                    if (playAction.showAnswerLoading) return;
+                                                    if (playStatus.action) {
+                                                      playAction.userAnswer = note;
+                                                      // 判断用户答题
+                                                      const userResult = note.realKey === playAction.standardAnswer.realKey ? 1 : 2;
+                                                      playAction.userAnswerStatus = userResult;
+                                                      playAction.listenLock = true;
+                                                      data.realKey = note.realKey;
+                                                      await fingeringPlay(note, 1000);
+                                                      resetMode(userResult === 1 ? true : false, 0);
+                                                      data.realKey = 0;
+
+                                                      // 如果是指法模式显示完之后要还原
+                                                      if (data.fingeringMode === "fingeringMode" && userResult === 2) {
+                                                        // 延迟显示,因为重置的时候有一个异步操作
+                                                        setTimeout(() => {
+                                                          data.realKey = playAction.standardAnswer.realKey;
+                                                        }, 10);
+                                                      }
+                                                      playAction.listenLock = false;
+                                                    } else {
+                                                      noteClick(note);
+                                                    }
+                                                  }}
+                                                >
+                                                  <img draggable={false} src={resultImg(note).icon} />
+
+                                                  {playStatus.action && ((playAction.showAnswerLoading && playAction.standardAnswer.realKey === note.realKey) || (playAction.userAnswerStatus === 1 && playAction.userAnswer.realKey === note.realKey)) ? <span class={styles.showAnswer}></span> : ""}
+                                                  {playStatus.action && playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey ? <span class={[styles.showAnswer, styles.errorAnswer]}></span> : ""}
+                                                  <div
+                                                    class={[
+                                                      styles.noteKey,
+                                                      ((data.realKey === note.realKey && !playStatus.action) ||
+                                                        (playStatus.action && playAction.exampleAnser.realKey === note.realKey) ||
+                                                        (playStatus.action && ((playAction.showAnswerLoading && playAction.standardAnswer.realKey === note.realKey) || (playAction.userAnswerStatus === 1 && playAction.userAnswer.realKey === note.realKey))) ||
+                                                        (playStatus.action && playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey)) &&
+                                                        styles.keyActive,
+                                                    ]}
+                                                  >
+                                                    {/* 显示对应的点 */}
+                                                    {note.step > 0 ? steps.map((n: any) => <span class={styles.dot}></span>) : null}
+
+                                                    <div class={styles.noteName}>
+                                                      <sup>{note.mark && (note.mark === "rise" ? "#" : "b")}</sup>
+                                                      {note.key}
+                                                    </div>
+                                                    {/* 显示对应的点 */}
+                                                    {note.step < 0 ? steps.map((n: any) => <span class={styles.dot}></span>) : null}
+                                                  </div>
+                                                </div>
+                                              );
+                                            })}
+                                          </div>
+                                        </div>
+                                        {((data.noteType !== "#c" && (orientationDirection.value === 0 || (orientationDirection.value === 1 && state.platform === IPlatform.PC))) || (orientationDirection.value === 1 && state.platform === IPlatform.APP)) && (
+                                          <Button
+                                            class={styles.noteBtn}
+                                            onClick={(e: any) => {
+                                              e.stopPropagation();
+                                              scrollNoteBox("right");
+                                            }}
+                                          >
+                                            <Icon name="arrow" />
+                                          </Button>
+                                        )}
+                                      </div>
+                                    </div>
+                                    {data.fingeringMode !== "scaleMode" && (
+                                      <div
+                                        class={styles.optionBtns}
+                                        onClick={(e: any) => {
+                                          e.stopPropagation();
+                                        }}
+                                      >
+                                        <Button class={[styles.oBtn, styles.gamut, playStatus.action && styles.disabled]} round onClick={onGamutPlayOrPause}>
+                                          {playStatus.gamut ? "暂停" : "播放音阶"}
+                                        </Button>
+                                        <Button class={[styles.oBtn, styles.play, playStatus.gamut && styles.disabled]} round onClick={onActionPlay}>
+                                          {listenText.value}
+                                        </Button>
+                                        <Button class={[styles.oBtn, styles.success, !playStatus.answer && styles.disabled]} round onClick={onShowAnswer}>
+                                          显示答案
+                                        </Button>
+                                      </div>
+                                    )}
+                                </>):(<>
+                                    <div class={styles.btnBox}>
+                                        <div class={styles.btnCon}>
+                                          <div
+                                              class={[styles.btnGr]}
+                                                onClick={(e) => {
+                                                  e.stopPropagation();
+                                                  //
+                                                  // 播放音阶时不能切换
+                                                  if (playStatus.gamut) {
+                                                    return;
+                                                  }
+                                                  // 开始答题不能切换
+                                                  if (playAction.listenLock) {
+                                                    return;
+                                                  }
+
+                                                  data.changeSubjectShow = true;
+                                                }}
+                                              >
+                                                <img src={icons.icon_change_instrument} />
+                                                <span>切换乐器</span>
+                                          </div>
+                                          {data.subject !== "melodica" && data.fingeringMode === "scaleMode" && (
+                                            <div
+                                              class={styles.btnGr}
+                                              onClick={() => {
+                                                data.viewIndex++;
+                                                if (data.viewIndex > data.viewTotal) {
+                                                  if (["pan-flute", "ocarina", "whistling"].includes(data.subject)) {
+                                                    data.viewIndex = 1;
+                                                  } else {
+                                                    data.viewIndex = 0;
+                                                  }
+                                                }
+                                                getFingeringData();
+                                              }}
+                                            >
+                                              <img src={icons.icon_toggle} />
+                                              <span>视图</span>
+                                            </div>
+                                          )}
+                                          <div
+                                            class={styles.btnGr}
+                                            onClick={() => {
+                                              resetElement();
+                                              data.tipShow = !data.tipShow;
+                                            }}
+                                          >
+                                            <img src={icons.icon_2_1} />
+                                            <span>说明</span>
+                                          </div>
+                                          {
+                                            instrumentTranstion.value &&
+                                            <div class={[styles.btnGr]} onClick={() => resetElement()}>
+                                              <img src={icons.icon_2_0} />
+                                              <span>还原</span>
+                                            </div>
+                                          }
+                                        </div>
+                                    </div>
+                                  </>)
+                              }
+                            </Tab>
+                          })
+                        }
+                      </Tabs>
+                  </div>
+                ):
+                (
+                  <>
+                    <div
+                      class={styles.notes}
+                      style={{
+                        paddingLeft: data.paddingLeft ? data.paddingLeft : "",
+                      }}
+                    >
+                      {playAction.listenTipsStatus && <div class={[styles.tipsT, data.fingeringMode === "fingeringMode" ? styles.playTips2 : styles.playTips]}></div>}
+                      {playAction.userAnswerStatus === 1 && <div class={[styles.tipsT, styles.playSuccess]}></div>}
+                      {playAction.userAnswerStatus === 2 && <div class={[styles.tipsT, styles.playError]}></div>}
+                      {playAction.resetAction && <div class={[styles.tipsT, styles.playTips5]}></div>}
+                      {((data.noteType !== "#c" && (orientationDirection.value === 0 || (orientationDirection.value === 1 && state.platform === IPlatform.PC))) || (orientationDirection.value === 1 && state.platform === IPlatform.APP)) && (
+                        <Button
+                          class={styles.noteBtn}
+                          onClick={(e: any) => {
+                            e.stopPropagation();
+                            scrollNoteBox("left");
+                          }}
+                        >
+                          <Icon name="arrow-left" />
+                        </Button>
+                      )}
+                      <div
+                        class={[styles.noteContent, data.fingeringMode !== "scaleMode" && orientationDirection.value === 0 && styles.noteContentOther, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad]}
+                        onClick={(e: any) => {
+                          e.stopPropagation();
+                        }}
+                      >
+                        {/* 判断是否为音阶模式 */}
+                        {data.fingeringMode !== "scaleMode" && (
+                          <div draggable={false} class={styles.note} onClick={noteChangeShow}>
+                            <img draggable={false} src={data.noteType === "all" ? icons.icon_btn_orange : icons.icon_btn_orange2} />
+                          </div>
+                        )}
+      
+                        {/* [styles.noteContent, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad] */}
+                        <div class={styles.lastNoteContent}>
+                          <div ref={noteBoxRef} class={styles.noteBox}>
+                            {data.notes.map((note: IFIGNER_INSTRUMENT_Note, index: number) => {
+                              const steps = new Array(Math.abs(note.step)).fill(1);
+                              return (
+                                <div
+                                  id={index == 0 ? "finger-note-0" : ""}
+                                  draggable={false}
+                                  class={[styles.note, "note-class"]}
+                                  key={note.realKey}
+                                  onClick={async () => {
+                                    // 判断是否在播放音阶
+                                    if (playStatus.gamut) return;
+                                    if (playAction.listenLock) return;
+                                    if (playAction.showAnswerLoading) return;
+                                    if (playStatus.action) {
+                                      playAction.userAnswer = note;
+                                      // 判断用户答题
+                                      const userResult = note.realKey === playAction.standardAnswer.realKey ? 1 : 2;
+                                      playAction.userAnswerStatus = userResult;
+                                      playAction.listenLock = true;
+                                      data.realKey = note.realKey;
+                                      await fingeringPlay(note, 1000);
+                                      resetMode(userResult === 1 ? true : false, 0);
+                                      data.realKey = 0;
+      
+                                      // 如果是指法模式显示完之后要还原
+                                      if (data.fingeringMode === "fingeringMode" && userResult === 2) {
+                                        // 延迟显示,因为重置的时候有一个异步操作
+                                        setTimeout(() => {
+                                          data.realKey = playAction.standardAnswer.realKey;
+                                        }, 10);
+                                      }
+                                      playAction.listenLock = false;
+                                    } else {
+                                      noteClick(note);
+                                    }
+                                  }}
+                                >
+                                  <img draggable={false} src={resultImg(note).icon} />
+      
+                                  {playStatus.action && ((playAction.showAnswerLoading && playAction.standardAnswer.realKey === note.realKey) || (playAction.userAnswerStatus === 1 && playAction.userAnswer.realKey === note.realKey)) ? <span class={styles.showAnswer}></span> : ""}
+                                  {playStatus.action && playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey ? <span class={[styles.showAnswer, styles.errorAnswer]}></span> : ""}
+                                  <div
+                                    class={[
+                                      styles.noteKey,
+                                      ((data.realKey === note.realKey && !playStatus.action) ||
+                                        (playStatus.action && playAction.exampleAnser.realKey === note.realKey) ||
+                                        (playStatus.action && ((playAction.showAnswerLoading && playAction.standardAnswer.realKey === note.realKey) || (playAction.userAnswerStatus === 1 && playAction.userAnswer.realKey === note.realKey))) ||
+                                        (playStatus.action && playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey)) &&
+                                        styles.keyActive,
+                                    ]}
+                                  >
+                                    {/* 显示对应的点 */}
+                                    {note.step > 0 ? steps.map((n: any) => <span class={styles.dot}></span>) : null}
+      
+                                    <div class={styles.noteName}>
+                                      <sup>{note.mark && (note.mark === "rise" ? "#" : "b")}</sup>
+                                      {note.key}
+                                    </div>
+                                    {/* 显示对应的点 */}
+                                    {note.step < 0 ? steps.map((n: any) => <span class={styles.dot}></span>) : null}
+                                  </div>
+                                </div>
+                              );
+                            })}
+                          </div>
+                        </div>
+                      </div>
+                      {((data.noteType !== "#c" && (orientationDirection.value === 0 || (orientationDirection.value === 1 && state.platform === IPlatform.PC))) || (orientationDirection.value === 1 && state.platform === IPlatform.APP)) && (
+                        <Button
+                          class={styles.noteBtn}
+                          onClick={(e: any) => {
+                            e.stopPropagation();
+                            scrollNoteBox("right");
+                          }}
+                        >
+                          <Icon name="arrow" />
+                        </Button>
+                      )}
+                    </div>
+                    {data.fingeringMode !== "scaleMode" && (
+                      <div
+                        class={styles.optionBtns}
+                        onClick={(e: any) => {
+                          e.stopPropagation();
+                        }}
+                      >
+                        <Button class={[styles.oBtn, styles.gamut, playStatus.action && styles.disabled]} round onClick={onGamutPlayOrPause}>
+                          {playStatus.gamut ? "暂停" : "播放音阶"}
+                        </Button>
+                        <Button class={[styles.oBtn, styles.play, playStatus.gamut && styles.disabled]} round onClick={onActionPlay}>
+                          {listenText.value}
+                        </Button>
+                        <Button class={[styles.oBtn, styles.success, !playStatus.answer && styles.disabled]} round onClick={onShowAnswer}>
+                          显示答案
+                        </Button>
+                      </div>
+                    )}
+                  </>
+                )
+              }
+            </div>
+            {/* 老师端过来隐藏 */}
+            {
+              query.platform!=='pc'&&(
                 <div
-                  class={[styles.noteContent, data.fingeringMode !== "scaleMode" && orientationDirection.value === 0 && styles.noteContentOther, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad]}
+                  class={styles.fixedRightBtns}
+                  style={{
+                    paddingTop: data.paddingTop ? data.paddingTop : "",
+                    paddingLeft: data.paddingLeft ? data.paddingLeft : "",
+                  }}
                   onClick={(e: any) => {
                     e.stopPropagation();
                   }}
                 >
-                  {/* 判断是否为音阶模式 */}
-                  {data.fingeringMode !== "scaleMode" && (
-                    <div draggable={false} class={styles.note} onClick={noteChangeShow}>
-                      <img draggable={false} src={data.noteType === "all" ? icons.icon_btn_orange : icons.icon_btn_orange2} />
+                  <div class={styles.rightBtn}>
+                    {data.subject !== "melodica" && data.fingeringMode === "scaleMode" && (
+                      <div
+                        class={styles.baseBtn}
+                        onClick={() => {
+                          data.viewIndex++;
+                          if (data.viewIndex > data.viewTotal) {
+                            if (["pan-flute", "ocarina", "whistling"].includes(data.subject)) {
+                              data.viewIndex = 1;
+                            } else {
+                              data.viewIndex = 0;
+                            }
+                          }
+                          getFingeringData();
+                        }}
+                      >
+                        <img src={icons.icon_toggle} />
+                        <span>视图</span>
+                      </div>
+                    )}
+                    <div
+                      class={styles.baseBtn}
+                      onClick={() => {
+                        resetElement();
+                        data.tipShow = !data.tipShow;
+                      }}
+                    >
+                      <img src={icons.icon_2_1} />
+                      <span>说明</span>
                     </div>
-                  )}
-
-                  {/* [styles.noteContent, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad] */}
-                  <div class={styles.lastNoteContent}>
-                    <div ref={noteBoxRef} class={styles.noteBox}>
-                      {data.notes.map((note: IFIGNER_INSTRUMENT_Note, index: number) => {
-                        const steps = new Array(Math.abs(note.step)).fill(1);
-                        return (
-                          <div
-                            id={index == 0 ? "finger-note-0" : ""}
-                            draggable={false}
-                            class={[styles.note, "note-class"]}
-                            key={note.realKey}
-                            onClick={async () => {
-                              // 判断是否在播放音阶
-                              if (playStatus.gamut) return;
-                              if (playAction.listenLock) return;
-                              if (playAction.showAnswerLoading) return;
-                              if (playStatus.action) {
-                                playAction.userAnswer = note;
-                                // 判断用户答题
-                                const userResult = note.realKey === playAction.standardAnswer.realKey ? 1 : 2;
-                                playAction.userAnswerStatus = userResult;
-                                playAction.listenLock = true;
-                                data.realKey = note.realKey;
-                                await fingeringPlay(note, 1000);
-                                resetMode(userResult === 1 ? true : false, 0);
-                                data.realKey = 0;
-
-                                // 如果是指法模式显示完之后要还原
-                                if (data.fingeringMode === "fingeringMode" && userResult === 2) {
-                                  // 延迟显示,因为重置的时候有一个异步操作
-                                  setTimeout(() => {
-                                    data.realKey = playAction.standardAnswer.realKey;
-                                  }, 10);
-                                }
-                                playAction.listenLock = false;
-                              } else {
-                                noteClick(note);
-                              }
-                            }}
-                          >
-                            <img draggable={false} src={resultImg(note).icon} />
 
-                            {playStatus.action && ((playAction.showAnswerLoading && playAction.standardAnswer.realKey === note.realKey) || (playAction.userAnswerStatus === 1 && playAction.userAnswer.realKey === note.realKey)) ? <span class={styles.showAnswer}></span> : ""}
-                            {playStatus.action && playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey ? <span class={[styles.showAnswer, styles.errorAnswer]}></span> : ""}
-                            <div
-                              class={[
-                                styles.noteKey,
-                                ((data.realKey === note.realKey && !playStatus.action) ||
-                                  (playStatus.action && playAction.exampleAnser.realKey === note.realKey) ||
-                                  (playStatus.action && ((playAction.showAnswerLoading && playAction.standardAnswer.realKey === note.realKey) || (playAction.userAnswerStatus === 1 && playAction.userAnswer.realKey === note.realKey))) ||
-                                  (playStatus.action && playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey)) &&
-                                  styles.keyActive,
-                              ]}
-                            >
-                              {/* 显示对应的点 */}
-                              {note.step > 0 ? steps.map((n: any) => <span class={styles.dot}></span>) : null}
+                    {!!data.tones.length && data.fingeringMode === "scaleMode" && (
+                      <>
+                        {fingerData.fingeringInfo.name == "hulusi-flute" ? (
+                          <div id="finger-note-1" class={[styles.baseBtn, styles.toggleBtnhulusi, styles.active]} onClick={() => (data.tnoteShow = true)}>
+                            <div>
+                              全按作
+                              <div class={[styles.noteKey, styles.noteKeyBtn]}>
+                                {data.activeTone.step > 0 ? <span class={styles.dot}></span> : null}
+                                <span class={styles.dot}></span>
 
-                              <div class={styles.noteName}>
-                                <sup>{note.mark && (note.mark === "rise" ? "#" : "b")}</sup>
-                                {note.key}
+                                <div class={styles.noteName}>
+                                  <sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
+                                  {data.activeTone.key}
+                                </div>
+                                {data.activeTone.step < 0 ? <span class={styles.dot}></span> : null}
                               </div>
-                              {/* 显示对应的点 */}
-                              {note.step < 0 ? steps.map((n: any) => <span class={styles.dot}></span>) : null}
                             </div>
+                            <img src={icons.icon_arrow} />
                           </div>
-                        );
-                      })}
-                    </div>
+                        ) : (
+                          <div id="finger-note-1" class={[styles.baseBtn, styles.toggleBtnhulusi2, styles.active]} onClick={() => (data.tnoteShow = true)}>
+                            <div class={styles.oterhD}>
+                              <div>
+                                <div style={{ marginTop: "-4px" }}>
+                                  <sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
+                                  {data.activeTone.name}
+                                </div>
+                                调
+                              </div>
+                              <img src={icons.icon_arrow} />
+                            </div>
+                          </div>
+                        )}
+                      </>
+                    )}
+                  </div>
+
+                  <div class={[styles.baseBtn, !instrumentTranstion.value && styles.resetBtn]} style={{ marginTop: "8px" }} onClick={() => resetElement()}>
+                    <img src={icons.icon_2_0} />
+                    <span>还原</span>
                   </div>
                 </div>
-                {((data.noteType !== "#c" && (orientationDirection.value === 0 || (orientationDirection.value === 1 && state.platform === IPlatform.PC))) || (orientationDirection.value === 1 && state.platform === IPlatform.APP)) && (
-                  <Button
-                    class={styles.noteBtn}
-                    onClick={(e: any) => {
-                      e.stopPropagation();
-                      scrollNoteBox("right");
-                    }}
-                  >
-                    <Icon name="arrow" />
-                  </Button>
-                )}
-              </div>
-              {data.fingeringMode !== "scaleMode" && (
-                <div
-                  class={styles.optionBtns}
-                  onClick={(e: any) => {
-                    e.stopPropagation();
-                  }}
-                >
-                  <Button class={[styles.oBtn, styles.gamut, playStatus.action && styles.disabled]} round onClick={onGamutPlayOrPause}>
-                    {playStatus.gamut ? "暂停" : "播放音阶"}
-                  </Button>
-                  <Button class={[styles.oBtn, styles.play, playStatus.gamut && styles.disabled]} round onClick={onActionPlay}>
-                    {listenText.value}
-                  </Button>
-                  <Button class={[styles.oBtn, styles.success, !playStatus.answer && styles.disabled]} round onClick={onShowAnswer}>
-                    显示答案
-                  </Button>
-                </div>
-              )}
-            </div>
-            <div class={[styles.tips, data.loadingDom ? styles.hiddens : "", data.tipShow ? "" : styles.tipHidden]}>
+              )
+            }
+            {/* 老师端加上遮罩点击关闭 */}
+            {
+              query.platform==='pc'&&data.tipShow&&(
+                <div class={[styles.tipsOverlay,data.tipShow?styles.tipsOverlayBg:'']} onClick={()=>{data.tipShow=false}}></div>
+              )
+            }
+            <div class={[styles.tips, data.loadingDom ? styles.hiddens : "", data.tipShow ? "" : styles.tipHidden,query.platform==='pc'&&data.tipShow?styles.tipsPcBg:""]}>
               <div class={styles.tipTitle}>
                 <div class={styles.tipTitleName}>{fingerData.fingeringInfo.code}使用说明</div>
                 <Button
@@ -1250,93 +1647,14 @@ export default defineComponent({
               </div>
             )}
           </div>
-          <div
-            class={styles.fixedRightBtns}
-            style={{
-              paddingTop: data.paddingTop ? data.paddingTop : "",
-              paddingLeft: data.paddingLeft ? data.paddingLeft : "",
-            }}
-            onClick={(e: any) => {
-              e.stopPropagation();
-            }}
-          >
-            <div class={styles.rightBtn}>
-              {data.subject !== "melodica" && data.fingeringMode === "scaleMode" && (
-                <div
-                  class={styles.baseBtn}
-                  onClick={() => {
-                    data.viewIndex++;
-                    if (data.viewIndex > data.viewTotal) {
-                      if (["pan-flute", "ocarina", "whistling"].includes(data.subject)) {
-                        data.viewIndex = 1;
-                      } else {
-                        data.viewIndex = 0;
-                      }
-                    }
-                    getFingeringData();
-                  }}
-                >
-                  <img src={icons.icon_toggle} />
-                  <span>视图</span>
-                </div>
-              )}
-              <div
-                class={styles.baseBtn}
-                onClick={() => {
-                  resetElement();
-                  data.tipShow = !data.tipShow;
-                }}
-              >
-                <img src={icons.icon_2_1} />
-                <span>说明</span>
-              </div>
-
-              {!!data.tones.length && data.fingeringMode === "scaleMode" && (
-                <>
-                  {fingerData.fingeringInfo.name == "hulusi-flute" ? (
-                    <div id="finger-note-1" class={[styles.baseBtn, styles.toggleBtnhulusi, styles.active]} onClick={() => (data.tnoteShow = true)}>
-                      <div>
-                        全按作
-                        <div class={[styles.noteKey, styles.noteKeyBtn]}>
-                          {data.activeTone.step > 0 ? <span class={styles.dot}></span> : null}
-                          <span class={styles.dot}></span>
-
-                          <div class={styles.noteName}>
-                            <sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
-                            {data.activeTone.key}
-                          </div>
-                          {data.activeTone.step < 0 ? <span class={styles.dot}></span> : null}
-                        </div>
-                      </div>
-                      <img src={icons.icon_arrow} />
-                    </div>
-                  ) : (
-                    <div id="finger-note-1" class={[styles.baseBtn, styles.toggleBtnhulusi2, styles.active]} onClick={() => (data.tnoteShow = true)}>
-                      <div class={styles.oterhD}>
-                        <div>
-                          <div style={{ marginTop: "-4px" }}>
-                            <sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
-                            {data.activeTone.name}
-                          </div>
-                          调
-                        </div>
-                        <img src={icons.icon_arrow} />
-                      </div>
-                    </div>
-                  )}
-                </>
-              )}
-            </div>
-
-            <div class={[styles.baseBtn, !instrumentTranstion.value && styles.resetBtn]} style={{ marginTop: "8px" }} onClick={() => resetElement()}>
-              <img src={icons.icon_2_0} />
-              <span>还原</span>
-            </div>
-          </div>
 
-          <Popup class="tonePopup" v-model:show={data.tnoteShow} position={state.platform !== IPlatform.PC && !query.modelType && fingerData.fingeringInfo.orientation === 1 ? "bottom" : "right"}>
+          <Popup class={["tonePopup",tnoteShowBoxClass]} style={
+              query.platform==="pc" ? tnoteShowBoxDragData.styleDrag.value : {}
+            } 
+            v-model:show={data.tnoteShow} 
+            position={state.platform === IPlatform.PC?"center":!query.modelType && fingerData.fingeringInfo.orientation === 1 ? "bottom" : "right"}>
             <div class={styles.tones}>
-              <div class={styles.toneTitle}>
+              <div class={[styles.toneTitle,"toneTitle_pc"]}>
                 <div class={styles.tipTitleName}>移调</div>
                 <Button
                   class={styles.tipClose}
@@ -1348,9 +1666,9 @@ export default defineComponent({
                   <Icon name="cross" size={19} color="#fff" />
                 </Button>
               </div>
-              <div class={styles.tipContentbox}>
-                <div class={styles.tipContent}>
-                  <div class={styles.tipWrap}>
+              <div class={[styles.tipContentbox,"tipContentbox_pc"]}>
+                <div class={[styles.tipContent,"tipContent_pc"]}>
+                  <div class={[styles.tipWrap,"tipWrap_pc"]}>
                     <Space size={0} class={styles.toneContent}>
                       {data.tones.map((tone: IFIGNER_INSTRUMENT_Note) => {
                         const steps = new Array(Math.abs(tone.step)).fill(1);
@@ -1389,7 +1707,7 @@ export default defineComponent({
                       })}
                     </Space>
                   </div>
-                  <div class={styles.toneAction}>
+                  <div class={[styles.toneAction,"toneAction_pc"]}>
                     <img
                       onClick={(e: any) => {
                         e.stopPropagation();
@@ -1410,11 +1728,18 @@ export default defineComponent({
                 </div>
               </div>
             </div>
+            {query.platform==="pc" && <>
+              <div class={[styles.dragTopBox,"dragTopBox"]}></div>
+              <Dragbom showGuide={guidanceShow.value} onGuideDone={setGuidanceShow}></Dragbom>
+            </>}
           </Popup>
 
           <Popup
+            style={
+              query.platform==="pc" ? changeSubjectShowBoxDragData.styleDrag.value : {}
+            }
             v-model:show={data.changeSubjectShow}
-            class={styles.changeSubjectPopup}
+            class={[styles.changeSubjectPopup,changeSubjectShowBoxClass]}
             onClick={(e: any) => {
               e.stopPropagation();
             }}
@@ -1452,6 +1777,10 @@ export default defineComponent({
                 }, 100);
               }}
             />
+            {query.platform==="pc" && <>
+              <div class={[styles.dragTopBox,"dragTopBox"]}></div>
+              <Dragbom showGuide={guidanceShow.value} onGuideDone={setGuidanceShow}></Dragbom>
+            </>}
           </Popup>
 
           {props.show && !data.loading && !data.loadingSoundFonts && <GuideIndex fingeringMode={data.fingeringMode} showGuide={false} list={["finger"]} />}