Browse Source

云教练数据结构改为妙极客的数据结构

黄琪勇 3 months ago
parent
commit
00de6f66cf

+ 4 - 4
src/hooks/useCreateElement.ts

@@ -322,17 +322,17 @@ export default () => {
    * 创建云教练元素
    * @param url 云教练地址
    */
-  const createCloudCoachElement = (url: string) => {
+  const createCloudCoachElement = (sid: string) => {
     createElement({
-      type: "cloudCoach",
+      type: "elf",
+      subtype: "elf-sing-play",
       id: nanoid(10),
       width: viewportSize.value,
       height: viewportSize.value * viewportRatio.value,
       rotate: 0,
       left: 0,
       top: 0,
-      url,
-      isMove: false
+      sid
     })
   }
 

+ 9 - 9
src/types/slides.ts

@@ -28,13 +28,13 @@ export const enum ElementTypes {
   CHART = "chart",
   TABLE = "table",
   LATEX = "latex",
-  ELF = "elf",
-  CLOUDCOACH = "cloudCoach"
+  ELF = "elf"
 }
 
 export const enum ElementSubtypeTypes {
   VIDEO = "elf-video",
-  AUDIO = "elf-audio"
+  AUDIO = "elf-audio",
+  SING_PLAY = "elf-sing-play"
 }
 
 /**
@@ -620,16 +620,16 @@ export interface PPTAudioElement extends PPTBaseElement {
 /**
  * 云教练元素
  *
- * type: 元素类型(cloudCoach)
+ * type: elf
  *
- * url: 云练习地址
+ * subtype: elf-sing-play
  *
- * isMove: 当前元素 是否在移动
+ * sid: 曲子id
  */
 export interface PPTCloudCoachElement extends PPTBaseElement {
-  type: "cloudCoach"
-  url: string
-  isMove: boolean
+  type: "elf"
+  subtype: "elf-sing-play"
+  sid: string
 }
 
 export type PPTElement =

+ 2 - 2
src/views/Editor/Canvas/EditableElement.vue

@@ -54,12 +54,12 @@ const currentElementComponent = computed<unknown>(() => {
     [ElementTypes.CHART]: ChartElement,
     [ElementTypes.TABLE]: TableElement,
     [ElementTypes.LATEX]: LatexElement,
-    [ElementTypes.CLOUDCOACH]: cloudCoachElement,
     [ElementTypes.ELF]: null
   }
   const elementSubtypeMap = {
     [ElementSubtypeTypes.AUDIO]: AudioElement,
-    [ElementSubtypeTypes.VIDEO]: VideoElement
+    [ElementSubtypeTypes.VIDEO]: VideoElement,
+    [ElementSubtypeTypes.SING_PLAY]: cloudCoachElement
   }
   return elementTypeMap[props.elementInfo.type] || elementSubtypeMap[props.elementInfo.subtype] || null
 })

+ 0 - 1
src/views/Editor/Canvas/Operate/index.vue

@@ -82,7 +82,6 @@ const currentOperateComponent = computed<unknown>(() => {
     [ElementTypes.TABLE]: TableElementOperate,
     [ElementTypes.CHART]: CommonElementOperate,
     [ElementTypes.LATEX]: CommonElementOperate,
-    [ElementTypes.CLOUDCOACH]: CommonElementOperate,
     [ElementTypes.ELF]: CommonElementOperate
   }
   return elementTypeMap[props.elementInfo.type] || null

+ 2 - 2
src/views/Editor/Canvas/hooks/useDragElement.ts

@@ -22,7 +22,7 @@ export default (elementList: Ref<PPTElement[]>, alignmentLines: Ref<AlignmentLin
     let isMouseDown = true
     /* 选中移动的时候 云教练模块标记移动中 */
     elementList.value.map(item => {
-      if (activeElementIdList.value.includes(item.id) && item.type === "cloudCoach") {
+      if (activeElementIdList.value.includes(item.id) && item.type === "elf" && item.subtype === "elf-sing-play") {
         item.isMove = true
       }
     })
@@ -291,7 +291,7 @@ export default (elementList: Ref<PPTElement[]>, alignmentLines: Ref<AlignmentLin
       isMouseDown = false
       /* 选中取消移动的时候 云教练模块取消标记移动中 */
       elementList.value.map(item => {
-        if (activeElementIdList.value.includes(item.id) && item.type === "cloudCoach") {
+        if (activeElementIdList.value.includes(item.id) && item.type === "elf" && item.subtype === "elf-sing-play") {
           item.isMove = false
         }
       })

+ 1 - 3
src/views/Editor/CanvasTool/index.vue

@@ -273,7 +273,6 @@ import Popover from "@/components/Popover.vue"
 import PopoverMenuItem from "@/components/PopoverMenuItem.vue"
 import { ElUpload, ElMessage, type UploadRequestOptions } from "element-plus"
 import cloudCoachList from "@/views/components/element/cloudCoachElement/cloudCoachList"
-import { YJL_URL_API } from "@/config/index"
 import fileUpload from "@/utils/oss-file-upload"
 
 const mainStore = useMainStore()
@@ -342,8 +341,7 @@ function handleUpload(fileData: UploadRequestOptions) {
 
 // 处理云教练创建
 function handleCloudCoach(id: string) {
-  const YJL_URL = `${YJL_URL_API}?v=${Date.now()}&modelType=practise&id=${id}&platform=pc&zoom=0.8&instrumentId=`
-  createCloudCoachElement(YJL_URL)
+  createCloudCoachElement(id)
   cloudCoachVisible.value = false
 }
 

+ 15 - 17
src/views/Editor/Toolbar/ElementStylePanel/ImageStylePanel.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="image-style-panel">
-    <div 
+    <div
       class="origin-image"
       :style="{ backgroundImage: `url(${handleImageElement.src})` }"
     ></div>
@@ -14,9 +14,9 @@
           <div class="clip">
             <div class="title">按形状:</div>
             <div class="shape-clip">
-              <div 
-                class="shape-clip-item" 
-                v-for="(item, key) in shapeClipPathOptions" 
+              <div
+                class="shape-clip-item"
+                v-for="(item, key) in shapeClipPathOptions"
                 :key="key"
                 @click="presetImageClip(key as string)"
               >
@@ -27,7 +27,7 @@
             <template v-for="typeItem in ratioClipOptions" :key="typeItem.label">
               <div class="title" v-if="typeItem.label">按{{typeItem.label}}:</div>
               <ButtonGroup class="row">
-                <Button 
+                <Button
                   style="flex: 1;"
                   v-for="item in typeItem.children"
                   :key="item.key"
@@ -40,13 +40,13 @@
         <Button last class="popover-btn" style="width: 100%;"><IconDown /></Button>
       </Popover>
     </ButtonGroup>
-    
+
     <div class="row">
       <div style="width: 40%;">圆角半径:</div>
-      <NumberInput 
-        :value="handleImageElement.radius || 0" 
-        @update:value="value => updateImage({ radius: value })" 
-        style="width: 60%;" 
+      <NumberInput
+        :value="handleImageElement.radius || 0"
+        @update:value="value => updateImage({ radius: value })"
+        style="width: 60%;"
       />
     </div>
 
@@ -59,7 +59,7 @@
     <Divider />
     <ElementShadow />
     <Divider />
-    
+
     <FileInput @change="files => replaceImage(files)">
       <Button class="full-width-btn"><IconTransform class="btn-icon" /> 替换图片</Button>
     </FileInput>
@@ -182,7 +182,7 @@ const presetImageClip = (shape: string, ratio = 0) => {
     originLeft,
     originTop,
   } = getImageElementDataBeforeClip()
-  
+
   // 纵横比裁剪(形状固定为矩形)
   if (ratio) {
     const imageRatio = originHeight / originWidth
@@ -261,10 +261,8 @@ const setBackgroundImage = () => {
   const background: SlideBackground = {
     ...currentSlide.value.background,
     type: 'image',
-    image: {
-      src: _handleElement.src,
-      size: 'cover'
-    },
+    image: _handleElement.src,
+    imageSize: "cover"
   }
   slidesStore.updateSlide({ background })
   addHistorySnapshot()
@@ -331,4 +329,4 @@ const setBackgroundImage = () => {
 .popover-btn {
   padding: 0 3px;
 }
-</style>
+</style>

+ 2 - 2
src/views/Editor/Toolbar/ElementStylePanel/index.vue

@@ -30,12 +30,12 @@ const panelMap = {
   [ElementTypes.CHART]: ChartStylePanel,
   [ElementTypes.TABLE]: TableStylePanel,
   [ElementTypes.LATEX]: LatexStylePanel,
-  [ElementTypes.CLOUDCOACH]: CloudCoachStylePanel,
   [ElementTypes.ELF]: null
 }
 const elementSubtypeMap = {
   [ElementSubtypeTypes.AUDIO]: AudioStylePanel,
-  [ElementSubtypeTypes.VIDEO]: VideoStylePanel
+  [ElementSubtypeTypes.VIDEO]: VideoStylePanel,
+  [ElementSubtypeTypes.SING_PLAY]: CloudCoachStylePanel
 }
 const { activeElementIdList, activeElementList, handleElement, activeGroupElementId } = storeToRefs(useMainStore())
 

+ 1 - 1
src/views/Editor/Toolbar/index.vue

@@ -39,7 +39,7 @@ const elementTabs = computed<ElementTabs[]>(() => {
       { label: "动画", key: ToolbarStates.EL_ANIMATION }
     ]
   }
-  if (handleElement.value?.type === "cloudCoach") {
+  if (handleElement.value?.type === "elf" && handleElement.value?.subtype === "elf-sing-play") {
     return [
       { label: "位置", key: ToolbarStates.EL_POSITION },
       { label: "动画", key: ToolbarStates.EL_ANIMATION }

+ 2 - 2
src/views/Mobile/MobileEditor/MobileEditableElement.vue

@@ -39,12 +39,12 @@ const currentElementComponent = computed<unknown>(() => {
     [ElementTypes.CHART]: ChartElement,
     [ElementTypes.TABLE]: TableElement,
     [ElementTypes.LATEX]: LatexElement,
-    [ElementTypes.CLOUDCOACH]: cloudCoachElement,
     [ElementTypes.ELF]: null
   }
   const elementSubtypeMap = {
     [ElementSubtypeTypes.AUDIO]: AudioElement,
-    [ElementSubtypeTypes.VIDEO]: VideoElement
+    [ElementSubtypeTypes.VIDEO]: VideoElement,
+    [ElementSubtypeTypes.SING_PLAY]: cloudCoachElement
   }
   return elementTypeMap[props.elementInfo.type] || elementSubtypeMap[props.elementInfo.subtype] || null
 })

+ 2 - 2
src/views/Screen/ScreenElement.vue

@@ -51,12 +51,12 @@ const currentElementComponent = computed<unknown>(() => {
     [ElementTypes.CHART]: BaseChartElement,
     [ElementTypes.TABLE]: BaseTableElement,
     [ElementTypes.LATEX]: BaseLatexElement,
-    [ElementTypes.CLOUDCOACH]: ScreenCloudCoachElement,
     [ElementTypes.ELF]: null
   }
   const elementSubtypeMap = {
     [ElementSubtypeTypes.AUDIO]: ScreenAudioElement,
-    [ElementSubtypeTypes.VIDEO]: ScreenVideoElement
+    [ElementSubtypeTypes.VIDEO]: ScreenVideoElement,
+    [ElementSubtypeTypes.SING_PLAY]: ScreenCloudCoachElement
   }
   return elementTypeMap[props.elementInfo.type] || elementSubtypeMap[props.elementInfo.subtype] || null
 })

+ 2 - 2
src/views/components/ThumbnailSlide/ThumbnailElement.vue

@@ -39,12 +39,12 @@ const currentElementComponent = computed<unknown>(() => {
     [ElementTypes.CHART]: BaseChartElement,
     [ElementTypes.TABLE]: BaseTableElement,
     [ElementTypes.LATEX]: BaseLatexElement,
-    [ElementTypes.CLOUDCOACH]: BaseCloudCoachElement,
     [ElementTypes.ELF]: null
   }
   const elementSubtypeMap = {
     [ElementSubtypeTypes.AUDIO]: BaseAudioElement,
-    [ElementSubtypeTypes.VIDEO]: BaseVideoElement
+    [ElementSubtypeTypes.VIDEO]: BaseVideoElement,
+    [ElementSubtypeTypes.SING_PLAY]: BaseCloudCoachElement
   }
   return elementTypeMap[props.elementInfo.type] || elementSubtypeMap[props.elementInfo.subtype] || null
 })

+ 1 - 1
src/views/components/element/cloudCoachElement/ScreenCloudCoachElement.vue

@@ -10,7 +10,7 @@
   >
     <div class="rotate-wrapper" :style="{ transform: `rotate(${elementInfo.rotate}deg)` }">
       <div class="element-content">
-        <cloudCoachPlayer v-if="inCurrentSlide" :url="elementInfo.url" :width="elementInfo.width" :height="elementInfo.height" :scale="scale" />
+        <cloudCoachPlayer v-if="inCurrentSlide" :id="elementInfo.sid" :width="elementInfo.width" :height="elementInfo.height" :scale="scale" />
       </div>
     </div>
   </div>

+ 1 - 1
src/views/components/element/cloudCoachElement/cloudCoachElement.vue

@@ -22,7 +22,7 @@
           @touchstart.stop="$event => handleSelectElement($event, false)"
           class="mask"
         ></div>
-        <cloudCoachPlayer :url="elementInfo.url" :width="elementInfo.width" :height="elementInfo.height" :scale="canvasScale" />
+        <cloudCoachPlayer :id="elementInfo.sid" :width="elementInfo.width" :height="elementInfo.height" :scale="canvasScale" />
         <div
           :class="['handler-border', item]"
           v-for="item in ['t', 'b', 'l', 'r']"

+ 7 - 4
src/views/components/element/cloudCoachElement/cloudCoachPlayer/cloudCoachPlayer.vue

@@ -11,26 +11,29 @@
       <div class="spinner"></div>
       <div class="text">云教练加载中...</div>
     </div>
-    <iframe class="musicIframe" frameborder="0" :src="url + `&Authorization=${getToken()}`" @load="handleIframeLoad"></iframe>
+    <iframe class="musicIframe" frameborder="0" :src="url" @load="handleIframeLoad"></iframe>
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from "vue"
+import { ref, computed } from "vue"
 import { getToken } from "@/libs/auth"
+import { YJL_URL_API } from "@/config/index"
 
 const props = withDefaults(
   defineProps<{
     width: number
     height: number
-    url: string
+    id: string
     scale?: number
   }>(),
   {
     scale: 1
   }
 )
-
+const url = computed(() => {
+  return `${YJL_URL_API}?v=${Date.now()}&modelType=practise&id=${props.id}&platform=pc&zoom=0.8&instrumentId=&Authorization=${getToken()}`
+})
 const loading = ref(true)
 function handleIframeLoad() {
   loading.value = false