lex 2 yıl önce
ebeveyn
işleme
cde890dad6

+ 56 - 0
package-lock.json

@@ -12,6 +12,7 @@
         "@vant/compat": "^1.0.0",
         "@vant/use": "^1.3.6",
         "@vueuse/core": "^8.4.1",
+        "animate.css": "^4.1.1",
         "browserslist": "^4.20.2",
         "classnames": "^2.3.1",
         "clean-deep": "^3.4.0",
@@ -31,10 +32,12 @@
         "qrcode.vue": "^3.3.3",
         "query-string": "^7.1.1",
         "sortablejs": "^1.15.0",
+        "swiper": "^9.0.5",
         "umi-request": "^1.4.0",
         "vant": "^4.0.0",
         "vconsole": "^3.15.0",
         "vue": "^3.2.26",
+        "vue-awesome-swiper": "^5.0.1",
         "vue-cropper": "^1.0.3",
         "vue-echarts": "^6.2.3",
         "vue-qr": "^4.0.9",
@@ -2767,6 +2770,11 @@
         "url": "https://github.com/sponsors/epoberezkin"
       }
     },
+    "node_modules/animate.css": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/animate.css/-/animate.css-4.1.1.tgz",
+      "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="
+    },
     "node_modules/ansi-colors": {
       "version": "4.1.1",
       "resolved": "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-4.1.1.tgz",
@@ -8544,6 +8552,11 @@
         "node": ">=6"
       }
     },
+    "node_modules/ssr-window": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-4.0.2.tgz",
+      "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ=="
+    },
     "node_modules/strict-uri-encode": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
@@ -8736,6 +8749,17 @@
       "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
       "dev": true
     },
+    "node_modules/swiper": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmmirror.com/swiper/-/swiper-9.0.5.tgz",
+      "integrity": "sha512-UiLQ5fvn8L3ZZpaPa+9oiwKwhVGQt5TVc0UuXxFKHyTQe8g2E3vbPMiMfIGb6NhNGj5ntsSDyyNgg4qVmWlJkQ==",
+      "dependencies": {
+        "ssr-window": "^4.0.2"
+      },
+      "engines": {
+        "node": ">= 4.7.0"
+      }
+    },
     "node_modules/systemjs": {
       "version": "6.12.1",
       "resolved": "https://registry.npmmirror.com/systemjs/-/systemjs-6.12.1.tgz",
@@ -9372,6 +9396,15 @@
         "@vue/shared": "3.2.26"
       }
     },
+    "node_modules/vue-awesome-swiper": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/vue-awesome-swiper/-/vue-awesome-swiper-5.0.1.tgz",
+      "integrity": "sha512-mWjFJzUqA4lG+DmsmibvMpoiBnl+IH2SSeiiQ3i5M0t1y9FknTxnGT0DsMb2YdJLgjYMEK3sYOWzqgLnZMH8Lg==",
+      "peerDependencies": {
+        "swiper": "^7.0.0  || ^8.0.0",
+        "vue": "3.x"
+      }
+    },
     "node_modules/vue-cropper": {
       "version": "1.0.3",
       "resolved": "https://registry.npmmirror.com/vue-cropper/-/vue-cropper-1.0.3.tgz",
@@ -11834,6 +11867,11 @@
         "uri-js": "^4.2.2"
       }
     },
+    "animate.css": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/animate.css/-/animate.css-4.1.1.tgz",
+      "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="
+    },
     "ansi-colors": {
       "version": "4.1.1",
       "resolved": "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-4.1.1.tgz",
@@ -15715,6 +15753,11 @@
       "resolved": "https://registry.npmmirror.com/split-on-first/-/split-on-first-1.1.0.tgz",
       "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
     },
+    "ssr-window": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-4.0.2.tgz",
+      "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ=="
+    },
     "strict-uri-encode": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
@@ -15832,6 +15875,14 @@
       "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
       "dev": true
     },
+    "swiper": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmmirror.com/swiper/-/swiper-9.0.5.tgz",
+      "integrity": "sha512-UiLQ5fvn8L3ZZpaPa+9oiwKwhVGQt5TVc0UuXxFKHyTQe8g2E3vbPMiMfIGb6NhNGj5ntsSDyyNgg4qVmWlJkQ==",
+      "requires": {
+        "ssr-window": "^4.0.2"
+      }
+    },
     "systemjs": {
       "version": "6.12.1",
       "resolved": "https://registry.npmmirror.com/systemjs/-/systemjs-6.12.1.tgz",
@@ -16301,6 +16352,11 @@
         "@vue/shared": "3.2.26"
       }
     },
+    "vue-awesome-swiper": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/vue-awesome-swiper/-/vue-awesome-swiper-5.0.1.tgz",
+      "integrity": "sha512-mWjFJzUqA4lG+DmsmibvMpoiBnl+IH2SSeiiQ3i5M0t1y9FknTxnGT0DsMb2YdJLgjYMEK3sYOWzqgLnZMH8Lg=="
+    },
     "vue-cropper": {
       "version": "1.0.3",
       "resolved": "https://registry.npmmirror.com/vue-cropper/-/vue-cropper-1.0.3.tgz",

+ 3 - 0
package.json

@@ -24,6 +24,7 @@
     "@vant/compat": "^1.0.0",
     "@vant/use": "^1.3.6",
     "@vueuse/core": "^8.4.1",
+    "animate.css": "^4.1.1",
     "browserslist": "^4.20.2",
     "classnames": "^2.3.1",
     "clean-deep": "^3.4.0",
@@ -43,10 +44,12 @@
     "qrcode.vue": "^3.3.3",
     "query-string": "^7.1.1",
     "sortablejs": "^1.15.0",
+    "swiper": "^9.0.5",
     "umi-request": "^1.4.0",
     "vant": "^4.0.0",
     "vconsole": "^3.15.0",
     "vue": "^3.2.26",
+    "vue-awesome-swiper": "^5.0.1",
     "vue-cropper": "^1.0.3",
     "vue-echarts": "^6.2.3",
     "vue-qr": "^4.0.9",

+ 1 - 1
src/student/download/transfer.tsx

@@ -21,7 +21,7 @@ export default defineComponent({
     const { origin, pathname } = location
     let tempPathname = pathname
     let beforeIos = 'BandMusicTeam://linkUrl='
-    let beforeAndroid = 'colexiustudent://html:8888/SplashActivity?url='
+    let beforeAndroid = 'orchestrastudent://html:8888/SplashActivity?url='
 
     if (pn === 's') {
       tempPathname = '/orchestra-student/'

+ 61 - 5
src/views/coursewarePlay/index.module.less

@@ -3,6 +3,15 @@
   height: 100vh;
   background-color: #000;
   overflow: hidden;
+
+  // :global {
+  //   // 更改动画样式
+  //   .van-swipe__track {
+  //     height: 100% !important;
+  //     transform: translateY(0px) !important;
+  //     position: relative;
+  //   }
+  // }
 }
 .coursewarePlay {
   position: relative;
@@ -75,6 +84,7 @@
   position: relative;
   width: 100%;
   height: 100%;
+  background-color: #000;
   video {
     width: 100%;
     height: 100%;
@@ -243,7 +253,7 @@
     width: 5px;
     height: 5px;
     background: #ff4e19;
-    border: .5px solid #ffffff;
+    border: 0.5px solid #ffffff;
     border-radius: 50%;
     margin-right: 3px;
     animation: loadFade 1s ease-in-out infinite;
@@ -251,13 +261,59 @@
 }
 
 @keyframes loadFade {
-  0%{
+  0% {
     opacity: 0;
   }
-  50%{
-    opacity: .5;
+  50% {
+    opacity: 0.5;
   }
-  100%{
+  100% {
     opacity: 1;
   }
 }
+
+/* ----------------------------------------------
+ * Generated by Animista on 2023-2-13 18:55:56
+ * Licensed under FreeBSD License.
+ * See http://animista.net/license for more info. 
+ * w: http://animista.net, t: @cssanimista
+ * ---------------------------------------------- */
+
+/**
+ * ----------------------------------------
+ * animation rotate-vert-right
+ * ----------------------------------------
+ */
+@-webkit-keyframes rotate-vert-right {
+  0% {
+    -webkit-transform: rotateY(0);
+    transform: rotateY(0);
+    -webkit-transform-origin: right;
+    transform-origin: right;
+  }
+  100% {
+    -webkit-transform: rotateY(-360deg);
+    transform: rotateY(-360deg);
+    -webkit-transform-origin: right;
+    transform-origin: right;
+  }
+}
+@keyframes rotate-vert-right {
+  0% {
+    -webkit-transform: rotateY(0);
+    transform: rotateY(0);
+    -webkit-transform-origin: right;
+    transform-origin: right;
+  }
+  100% {
+    -webkit-transform: rotateY(-360deg);
+    transform: rotateY(-360deg);
+    -webkit-transform-origin: right;
+    transform-origin: right;
+  }
+}
+
+.rotate-vert-right {
+  -webkit-animation: rotate-vert-right 0.5s cubic-bezier(0.645, 0.045, 0.355, 1) both;
+  animation: rotate-vert-right 0.5s cubic-bezier(0.645, 0.045, 0.355, 1) both;
+}

+ 317 - 180
src/views/coursewarePlay/index.tsx

@@ -17,7 +17,8 @@ import {
   onUnmounted,
   ref,
   watch,
-  Transition
+  Transition,
+  TransitionGroup
 } from 'vue'
 import iconBack from './image/back.svg'
 import styles from './index.module.less'
@@ -40,10 +41,17 @@ import Points from './component/points'
 import { browser, getSecondRPM } from '@/helpers/utils'
 import { Vue3Lottie } from 'vue3-lottie'
 import playLoadData from './datas/data.json'
-import { usePageVisibility } from '@vant/use'
+import { usePageVisibility, useRect } from '@vant/use'
 import PlayRecordTime from './playRecordTime'
 import dayjs from 'dayjs'
 
+import { Pagination, Navigation, EffectFade, EffectFlip, EffectCreative, Lazy } from 'swiper'
+import { Swiper, SwiperSlide } from 'swiper/vue'
+import 'swiper/less'
+import 'swiper/less/effect-fade'
+import 'swiper/less/effect-flip'
+import 'swiper/less/effect-creative'
+
 export default defineComponent({
   name: 'CoursewarePlay',
   setup() {
@@ -290,6 +298,7 @@ export default defineComponent({
       }
     }
 
+    const swiperDom = ref()
     onMounted(() => {
       getDetail()
       getCourseSchedule()
@@ -347,9 +356,10 @@ export default defineComponent({
     const toggleMaterial = () => {
       const index = data.itemList.findIndex((n: any) => n.id == popupData.itemActive)
       if (index > -1) {
-        swipeRef.value?.swipeTo(index, {
-          immediate: true
-        })
+        // swipeRef.value?.swipeTo(index, {
+        //   immediate: true
+        // })
+        swiperDom.value?.slideTo(index, 1000)
       }
     }
     /** 延迟收起模态框 */
@@ -389,14 +399,6 @@ export default defineComponent({
         }
       }
     }
-    // 上一个知识点, 下一个知识点
-    const handlePreAndNext = (type: string) => {
-      if (type === 'up') {
-        swipeRef.value?.prev()
-      } else {
-        swipeRef.value?.next()
-      }
-    }
 
     // 去点名,签退
     const gotoRollCall = (pageTag: string) => {
@@ -452,187 +454,325 @@ export default defineComponent({
     const handleEnded = (m: any) => {
       // console.log(m)
       if (popupData.activeIndex != data.itemList.length - 1) {
-        swipeRef.value?.next()
+        swiperDom.value.slideNext(800)
+
+        // setTimeout(() => {
+        // swipeRef.value?.next()
+        // ;(document.querySelector('.swiper-button-next') as any)?.click()
+        // swiperDom.value.navigation.nextEl.click()
+        // swiperDom.value.slideNext(800)
+        // }, 300)
       }
     }
 
+    const effects = [
+      {
+        prev: {
+          shadow: true,
+          translate: [0, 0, -400]
+        },
+        next: {
+          translate: ['100%', 0, 0]
+        }
+      },
+      {
+        prev: {
+          shadow: true,
+          translate: ['-120%', 0, -500]
+        },
+        next: {
+          shadow: true,
+          translate: ['120%', 0, -500]
+        }
+      },
+      {
+        prev: {
+          shadow: true,
+          translate: ['-20%', 0, -1]
+        },
+        next: {
+          translate: ['100%', 0, 0]
+        }
+      },
+      {
+        prev: {
+          shadow: true,
+          translate: [0, 0, -800],
+          rotate: [180, 0, 0]
+        },
+        next: {
+          shadow: true,
+          translate: [0, 0, -800],
+          rotate: [-180, 0, 0]
+        }
+      },
+      {
+        prev: {
+          shadow: true,
+          translate: ['-125%', 0, -800],
+          rotate: [0, 0, -90]
+        },
+        next: {
+          shadow: true,
+          translate: ['125%', 0, -800],
+          rotate: [0, 0, 90]
+        }
+      },
+      {
+        prev: {
+          shadow: true,
+          origin: 'right center',
+          translate: ['5%', 0, -200],
+          rotate: [0, -100, 0]
+        },
+        next: {
+          origin: 'left center',
+          translate: ['-5%', 0, -200],
+          rotate: [0, 100, 0]
+        }
+      },
+      {
+        prev: {
+          scale: 0.3,
+          opacity: 0.4
+        },
+        next: {
+          opacity: 0.4,
+          scale: 0.3
+        }
+      }
+    ]
+    const swiperType = ref(effects[2])
+    // 上一个知识点, 下一个知识点
+    const handlePreAndNext = (type: string) => {
+      setTimeout(() => {
+        if (type === 'up') {
+          // swiperRef.value?.allowSlidePrev()
+
+          // ;(document.querySelector('.swiper-button-prev') as any)?.click()
+          // swiperDom.value.navigation.prevEl.click()
+          swiperDom.value.slidePrev(800)
+        } else {
+          // swiperRef.value?.allowSlideNext()
+
+          // ;(document.querySelector('.swiper-button-next') as any)?.click()
+          // swiperDom.value.navigation.nextEl.click()
+          // const nextKonwledgeId = data.itemList[popupData.activeIndex + 1].knowledgePointId
+          // console.log(nextKonwledgeId === popupData.tabActive)
+          // if (nextKonwledgeId === popupData.tabActive) {
+          //   swiperType.value = effects[2]
+          // } else {
+          //   swiperType.value = effects[3]
+          // }
+
+          swiperDom.value.slideNext(800)
+        }
+      }, 400)
+    }
+
     return () => (
       <div class={styles.playContent}>
         <div class={styles.coursewarePlay} style={{ width: parentContainer.width }}>
-          <Swipe
+          {/* <swiper :modules="modules" :pagination="{ clickable: true }">
+    <swiper-slide>Slide 1</swiper-slide>
+    <swiper-slide>Slide 2</swiper-slide>
+    <swiper-slide>Slide 3</swiper-slide>
+  </swiper> */}
+
+          {/* 
+            知识点 翻
+            素材滑
+          */}
+          <Swiper
             style={{ height: '100%' }}
-            ref={swipeRef}
-            showIndicators={false}
-            loop={false}
-            duration={0}
-            vertical
-            lazyRender={true}
-            touchable={false}
-            initialSwipe={popupData.firstIndex}
-            onChange={handleSwipeChange}
+            effect="creative"
+            modules={[Pagination, Navigation, EffectFade, EffectFlip, EffectCreative]}
+            creativeEffect={swiperType.value}
+            direction="vertical"
+            navigation
+            allowTouchMove={false}
+            onSwiper={(swiper: any) => {
+              // console.log(swiper, 'index')
+              swiperDom.value = swiper
+            }}
+            onSlideChange={(swiper: any) => {
+              // console.log(swiper, 'index')
+              handleSwipeChange(swiper.activeIndex)
+            }}
           >
             {data.itemList.map((m: any, mIndex: number) => {
               return (
-                <SwipeItem class={styles.swipeItem}>
-                  <>
-                    <div
-                      class={styles.itemDiv}
-                      onClick={() => {
-                        clearTimeout(activeData.timer)
-                        if (Date.now() - activeData.nowTime < 300) {
-                          handleDbClick(m)
-                          return
-                        }
-                        activeData.nowTime = Date.now()
-                        activeData.timer = setTimeout(() => {
-                          activeData.model = !activeData.model
-                          setModelOpen()
-                        }, 300)
-                      }}
-                    >
-                      {m.type === 'VIDEO' ? (
-                        <>
-                          <video
-                            playsinline="false"
-                            muted={m.muted}
-                            preload="auto"
-                            class="player"
-                            data-vid={m.id}
-                            src={m.content}
-                            loop={m.loop}
-                            autoplay={m.autoPlay}
-                            onLoadedmetadata={(e: Event) => {
-                              const videoEle = e.target as unknown as HTMLVideoElement
-                              m.currentTime = videoEle.currentTime
-                              m.duration = videoEle.duration
-                              m.videoEle = videoEle
-                              m.isprepare = true
-                            }}
-                            onTimeupdate={(e: Event) => {
-                              if (!m.isprepare) return
-                              const videoEle = e.target as unknown as HTMLVideoElement
-                              m.currentTime = videoEle.currentTime
-                              m.progress = Number((videoEle.currentTime / m.duration) * 100)
-                            }}
-                            onPlay={() => {
-                              // 播放
-                              m.paused = false
-                              console.log('播放')
-                              setModelOpen()
-                              // 第一次播放
-                              if (m.muted) {
-                                m.muted = false
-                                m.autoPlay = false
-                              }
-                            }}
-                            onPause={() => {
-                              //暂停
-                              clearTimeout(activeData.timer)
-                              m.paused = true
-                            }}
-                            onEnded={() => handleEnded(m)}
-                          >
-                            <source src={m.content} type="video/mp4" />
-                          </video>
-                          {m.muted && (
-                            <div class={styles.loadWrap}>
-                              <Vue3Lottie animationData={playLoadData}></Vue3Lottie>
+                <SwiperSlide class={styles.swipeItem}>
+                  <div
+                    // class={[styles.itemDiv]}
+
+                    class={[styles.itemDiv]}
+                    onClick={() => {
+                      clearTimeout(activeData.timer)
+                      if (Date.now() - activeData.nowTime < 300) {
+                        handleDbClick(m)
+                        return
+                      }
+                      activeData.nowTime = Date.now()
+                      activeData.timer = setTimeout(() => {
+                        activeData.model = !activeData.model
+                        setModelOpen()
+                      }, 300)
+                    }}
+                  >
+                    {m.type === 'VIDEO' ? (
+                      <>
+                        <video
+                          class={['player']}
+                          playsinline="false"
+                          muted={m.muted}
+                          preload="auto"
+                          // class="player"
+                          data-vid={m.id}
+                          src={m.content}
+                          loop={m.loop}
+                          autoplay={m.autoPlay}
+                          onLoadedmetadata={(e: Event) => {
+                            const videoEle = e.target as unknown as HTMLVideoElement
+                            m.currentTime = videoEle.currentTime
+                            m.duration = videoEle.duration
+                            m.videoEle = videoEle
+                            m.isprepare = true
+                          }}
+                          onTimeupdate={(e: Event) => {
+                            if (!m.isprepare) return
+                            const videoEle = e.target as unknown as HTMLVideoElement
+                            m.currentTime = videoEle.currentTime
+                            m.progress = Number((videoEle.currentTime / m.duration) * 100)
+                          }}
+                          onPlay={() => {
+                            // 播放
+                            m.paused = false
+                            console.log('播放')
+                            setModelOpen()
+                            // 第一次播放
+                            if (m.muted) {
+                              m.muted = false
+                              m.autoPlay = false
+                            }
+                          }}
+                          onPause={() => {
+                            //暂停
+                            clearTimeout(activeData.timer)
+                            m.paused = true
+                          }}
+                          onEnded={() => handleEnded(m)}
+                        >
+                          <source src={m.content} type="video/mp4" />
+                        </video>
+                        {m.muted && (
+                          <div class={styles.loadWrap}>
+                            <Vue3Lottie animationData={playLoadData}></Vue3Lottie>
+                          </div>
+                        )}
+                        <div
+                          style={{ transform: activeData.model ? '' : 'translateY(100%)' }}
+                          class={styles.bottomFixedContainer}
+                          onClick={(e: Event) => {
+                            e.stopPropagation()
+                            setModelOpen()
+                          }}
+                        >
+                          <div style={{ opacity: m.isprepare ? '1' : '0' }}>
+                            <div class={styles.time}>
+                              <span>{getSecondRPM(m.currentTime)}</span>
+                              <span>{getSecondRPM(m.duration)}</span>
                             </div>
-                          )}
-                          <div
-                            style={{ transform: activeData.model ? '' : 'translateY(100%)' }}
-                            class={styles.bottomFixedContainer}
-                            onClick={(e: Event) => {
-                              e.stopPropagation()
-                              setModelOpen()
-                            }}
-                          >
-                            <div style={{ opacity: m.isprepare ? '1' : '0' }}>
-                              <div class={styles.time}>
-                                <span>{getSecondRPM(m.currentTime)}</span>
-                                <span>{getSecondRPM(m.duration)}</span>
-                              </div>
-                              <div class={styles.slider}>
-                                <Slider
-                                  onClick={() => setModelOpen()}
-                                  buttonSize={16}
-                                  step={1}
-                                  modelValue={m.progress}
-                                  onUpdate:modelValue={(val: any) => {
-                                    console.log('val', val)
-                                    m.progress = val
-                                    handleChangeSlider(m)
-                                  }}
-                                  onDragStart={(e: Event) => {
-                                    // 开始拖动,暂停播放
-                                    console.log('开始拖动')
-                                    // 如果拖动之前,视频是播放状态,拖动完毕后继续播放
-                                    if (!m.paused) {
-                                      m.isDrage = true
-                                    }
-                                    handlePaused(m)
-                                  }}
-                                  onDragEnd={(e: Event) => {
-                                    console.log('结束拖动')
-                                    if (m.isDrage) {
-                                      m.isDrage = false
-                                      handlePlay(m)
-                                    }
-                                  }}
-                                  min={0}
-                                  max={100}
-                                />
-                              </div>
+                            <div class={styles.slider}>
+                              <Slider
+                                onClick={() => setModelOpen()}
+                                buttonSize={16}
+                                step={1}
+                                modelValue={m.progress}
+                                onUpdate:modelValue={(val: any) => {
+                                  console.log('val', val)
+                                  m.progress = val
+                                  handleChangeSlider(m)
+                                }}
+                                onDragStart={(e: Event) => {
+                                  // 开始拖动,暂停播放
+                                  console.log('开始拖动')
+                                  // 如果拖动之前,视频是播放状态,拖动完毕后继续播放
+                                  if (!m.paused) {
+                                    m.isDrage = true
+                                  }
+                                  handlePaused(m)
+                                }}
+                                onDragEnd={(e: Event) => {
+                                  console.log('结束拖动')
+                                  if (m.isDrage) {
+                                    m.isDrage = false
+                                    handlePlay(m)
+                                  }
+                                }}
+                                min={0}
+                                max={100}
+                              />
                             </div>
+                          </div>
 
-                            <div class={styles.actions}>
-                              <div class={styles.actionBtn}>
-                                {m.isprepare ? (
-                                  <>
-                                    {m.paused ? (
-                                      <img src={iconplay} onClick={(e: Event) => handlePlay(m)} />
-                                    ) : (
-                                      <img
-                                        src={iconpause}
-                                        onClick={(e: Event) => handlePaused(m)}
-                                      />
-                                    )}
-                                  </>
-                                ) : (
-                                  <Loading color="#fff" />
-                                )}
+                          <div class={styles.actions}>
+                            <div class={styles.actionBtn}>
+                              {m.isprepare ? (
+                                <>
+                                  {m.paused ? (
+                                    <img src={iconplay} onClick={(e: Event) => handlePlay(m)} />
+                                  ) : (
+                                    <img src={iconpause} onClick={(e: Event) => handlePaused(m)} />
+                                  )}
+                                </>
+                              ) : (
+                                <Loading color="#fff" />
+                              )}
 
-                                {m.loop ? (
-                                  <img
-                                    src={iconLoopActive}
-                                    onClick={(e: Event) => (m.loop = false)}
-                                  />
-                                ) : (
-                                  <img src={iconLoop} onClick={(e: Event) => (m.loop = true)} />
-                                )}
-                              </div>
-                              <div>{m.name}</div>
+                              {m.loop ? (
+                                <img
+                                  src={iconLoopActive}
+                                  onClick={(e: Event) => (m.loop = false)}
+                                />
+                              ) : (
+                                <img src={iconLoop} onClick={(e: Event) => (m.loop = true)} />
+                              )}
                             </div>
+                            <div>{m.name}</div>
                           </div>
-                        </>
-                      ) : m.type === 'IMG' ? (
-                        <img src={m.content} />
-                      ) : (
-                        <MusicScore
-                          data-vid={m.id}
-                          music={m}
-                          onSetIframe={(el: any) => {
-                            m.iframeRef = el
-                          }}
-                        />
-                      )}
-                    </div>
-                  </>
-                </SwipeItem>
+                        </div>
+                      </>
+                    ) : m.type === 'IMG' ? (
+                      <img src={m.content} />
+                    ) : (
+                      <MusicScore
+                        data-vid={m.id}
+                        music={m}
+                        onSetIframe={(el: any) => {
+                          m.iframeRef = el
+                        }}
+                      />
+                    )}
+                  </div>
+                </SwiperSlide>
               )
             })}
-          </Swipe>
-
+          </Swiper>
+          {/* <Swipe
+            style={{ height: '100%' }}
+            ref={swipeRef}
+            showIndicators={false}
+            loop={false}
+            duration={0}
+            // vertical
+            lazyRender={true}
+            touchable={false}
+            initialSwipe={popupData.firstIndex}
+            onChange={handleSwipeChange}
+          >
+            
+          </Swipe> */}
           <div
             style={{ transform: activeData.model ? '' : 'translateY(-100%)' }}
             id="coursePlayHeader"
@@ -648,7 +788,6 @@ export default defineComponent({
               <PlayRecordTime ref={playRef} list={data.itemList} />
             )}
           </div>
-
           <Transition name="right">
             {activeData.model && (
               <div class={styles.rightFixedBtns}>
@@ -680,7 +819,6 @@ export default defineComponent({
               </div>
             )}
           </Transition>
-
           <Transition name="left">
             {activeData.model && (
               <div class={styles.leftFixedBtns}>
@@ -694,7 +832,7 @@ export default defineComponent({
                   </div>
                 )}
                 {popupData.activeIndex != data.itemList.length - 1 && (
-                  <div class={styles.fullBtn} onClick={() => handlePreAndNext('down')}>
+                  <div class={[styles.fullBtn]} onClick={() => handlePreAndNext('down')}>
                     <span style={{ textAlign: 'center' }}>下一个</span>
                     <img src={iconDown} />
                   </div>
@@ -702,7 +840,6 @@ export default defineComponent({
               </div>
             )}
           </Transition>
-
           <Popup
             class={styles.popup}
             overlayClass={styles.overlayClass}

+ 83 - 85
src/views/unit-test/index.tsx

@@ -91,11 +91,15 @@ export default defineComponent({
         }
         // 是不是未开始
         if (item.status === 'D_NO_SUBMIT') {
-          const { data } = await request.get('/api-student/unitExamination/detail', {
-            params: {
-              unitExaminationId: item.unitExaminationId
+          const { data } = await request.post(
+            '/api-student/studentUnitExamination/getExaminationDetail',
+            {
+              requestType: 'form',
+              data: {
+                studentUnitExaminationId: item.id
+              }
             }
-          })
+          )
           form.unitExam = data || {}
           form.visiableNotice = true
         }
@@ -214,95 +218,89 @@ export default defineComponent({
                 <source src="horse.ogg" type="audio/ogg" />
                 您的浏览器不支持该音频格式。
               </audio> */}
-              <TransitionGroup name="van-fade">
-                {form.list.map((item: any) => (
-                  <CellGroup inset class={styles.cellGroup} border={false}>
-                    <Cell
-                      center
-                      // isLink
-                      clickable={false}
-                      titleStyle={{ flex: '1 auto' }}
-                      valueClass={[
-                        styles['no-start'],
-                        item.status === 'A_PASS' && styles.pass,
-                        item.status === 'B_NO_PASS' && styles['no-pass']
-                      ]}
-                    >
-                      {{
-                        icon: () => <Image src={iconEdit} class={styles.img} />,
-                        title: () => (
-                          <div class={[styles.unitTitle, 'van-ellipsis']}>{item.name}</div>
-                        ),
-                        value: () => unitTestStatus[item.status]
-                      }}
-                    </Cell>
-                    <Cell center class={styles.unitSection}>
-                      {{
-                        title: () => (
-                          <div class={styles.unitInformation}>
-                            <div>
-                              <div class={styles.name}>{item.orchestraName}</div>
-                              <div class={styles.endTime}>
-                                截止时间:
-                                {dayjs(item.expiryDate || new Date()).format('YYYY-MM-DD HH:mm')}
-                              </div>
+
+              {form.list.map((item: any) => (
+                <CellGroup inset class={styles.cellGroup} border={false}>
+                  <Cell
+                    center
+                    // isLink
+                    clickable={false}
+                    titleStyle={{ flex: '1 auto' }}
+                    valueClass={[
+                      styles['no-start'],
+                      item.status === 'A_PASS' && styles.pass,
+                      item.status === 'B_NO_PASS' && styles['no-pass']
+                    ]}
+                  >
+                    {{
+                      icon: () => <Image src={iconEdit} class={styles.img} />,
+                      title: () => (
+                        <div class={[styles.unitTitle, 'van-ellipsis']}>{item.name}</div>
+                      ),
+                      value: () => unitTestStatus[item.status]
+                    }}
+                  </Cell>
+                  <Cell center class={styles.unitSection}>
+                    {{
+                      title: () => (
+                        <div class={styles.unitInformation}>
+                          <div>
+                            <div class={styles.name}>{item.orchestraName}</div>
+                            <div class={styles.endTime}>
+                              截止时间:
+                              {dayjs(item.expiryDate || new Date()).format('YYYY-MM-DD HH:mm')}
                             </div>
-                            {item.status === 'A_PASS' || item.status === 'B_NO_PASS' ? (
-                              <span>
-                                {item.score || 0}
-                                <i>分</i>
-                              </span>
-                            ) : (
-                              ''
-                            )}
                           </div>
-                        ),
+                          {item.status === 'A_PASS' || item.status === 'B_NO_PASS' ? (
+                            <span>
+                              {item.score || 0}
+                              <i>分</i>
+                            </span>
+                          ) : (
+                            ''
+                          )}
+                        </div>
+                      ),
 
-                        label: () => (
-                          <div class={styles.unitBtnGroup}>
+                      label: () => (
+                        <div class={styles.unitBtnGroup}>
+                          <Button
+                            color="#FFF0E6"
+                            round
+                            block
+                            style={{ color: '#F67146' }}
+                            onClick={() => {
+                              router.push({
+                                path: '/test-exercise',
+                                query: {
+                                  id: item.unitExaminationId
+                                }
+                              })
+                            }}
+                          >
+                            练习模式
+                          </Button>
+                          {item.status === 'A_PASS' || item.status === 'B_NO_PASS' ? (
+                            <Button type="primary" round block onClick={() => onUnitTestLook(item)}>
+                              查看测验
+                            </Button>
+                          ) : (
                             <Button
-                              color="#FFF0E6"
+                              type="primary"
                               round
                               block
-                              style={{ color: '#F67146' }}
-                              onClick={() => {
-                                router.push({
-                                  path: '/test-exercise',
-                                  query: {
-                                    id: item.unitExaminationId
-                                  }
-                                })
-                              }}
+                              disabled={dayjs().isAfter(dayjs(item.expiryDate))}
+                              onClick={() => onUnitTestStart(item)}
                             >
-                              练习模式
+                              {item.status === 'C_ING' ? '继续测验' : '开始测验'}
                             </Button>
-                            {item.status === 'A_PASS' || item.status === 'B_NO_PASS' ? (
-                              <Button
-                                type="primary"
-                                round
-                                block
-                                onClick={() => onUnitTestLook(item)}
-                              >
-                                查看测验
-                              </Button>
-                            ) : (
-                              <Button
-                                type="primary"
-                                round
-                                block
-                                disabled={dayjs().isAfter(dayjs(item.expiryDate))}
-                                onClick={() => onUnitTestStart(item)}
-                              >
-                                {item.status === 'C_ING' ? '继续测验' : '开始测验'}
-                              </Button>
-                            )}
-                          </div>
-                        )
-                      }}
-                    </Cell>
-                  </CellGroup>
-                ))}
-              </TransitionGroup>
+                          )}
+                        </div>
+                      )
+                    }}
+                  </Cell>
+                </CellGroup>
+              ))}
             </List>
           </OFullRefresh>
         ) : (

+ 100 - 44
src/views/unit-test/model/drag-question/index.tsx

@@ -72,6 +72,9 @@ export default defineComponent({
           animation: 150,
           sort: true,
           fallbackTolerance: 3,
+          onAdd(ele: any, e: any) {
+            console.log(ele, e, 'add information')
+          },
           onUpdate: (evt: any) => {
             const updatePosition = (list: any) =>
               list.splice(evt.newIndex, 0, list.splice(evt.oldIndex, 1)[0])
@@ -81,11 +84,13 @@ export default defineComponent({
               state.list = [...state.options]
               updatePosition(state.list)
             }
-            setTimeout(() => {
-              onSelect()
-            }, 100)
+            // setTimeout(() => {
+            onSelect()
+            // }, 100)
           }
         })
+
+        console.log(state.sortable)
       })
     }
 
@@ -95,13 +100,15 @@ export default defineComponent({
       const result: any = []
 
       list.forEach((item: any, index: number) => {
-        // console.log(item, 'item')
+        console.log(item, 'item')
         result.push({
           answerId: item.answerId,
           answer: item.answer,
           answerExtra: index + 1
         })
       })
+
+      console.log('🚀 ~ onSelect ~ result', result)
       emit('update:value', result)
     }
 
@@ -110,6 +117,7 @@ export default defineComponent({
       // 判断是否已经选中了
       if (item.checked || props.readOnly) return
       const result: any = []
+      console.log(state.options, 'state.options')
       state.options.forEach((option: any, index: any) => {
         // console.log(option, '------')
         result.push({
@@ -118,6 +126,7 @@ export default defineComponent({
           answerExtra: index + 1
         })
       })
+
       result.push({
         answerId: item.examinationQuestionAnswerId,
         answer: item.questionAnswer,
@@ -129,15 +138,19 @@ export default defineComponent({
         answer: item.questionAnswer,
         answerExtra: state.list.length + 1
       })
-      // console.log(state.list, result, 'result lis4t')
+
+      console.log(state.list, '------', result, 'result lis4t')
       emit('update:value', result)
 
-      initOptions()
+      nextTick(() => {
+        initOptions()
+      })
     }
 
     const answers = computed(() => {
       const list: any = props.data.answers || []
       const value: any = props.value || []
+      console.log(value, 'answer')
       list.forEach((item: any) => {
         const tempIndex = value.findIndex(
           (c: any) => c.answerId === item.examinationQuestionAnswerId
@@ -152,27 +165,43 @@ export default defineComponent({
       const answers = props.data.answers || []
       const userAnswer = props.data.userAnswer || [] // 用户填写的答案
       // console.log(answers, userAnswer)
-      state.options = []
-      if (userAnswer.length > 0) {
-        userAnswer.forEach((answer: any, index: any) => {
-          const rightOption = answers.find(
-            (child: any) => answer.answerId === child.examinationQuestionAnswerId
-          )
-          const rightValue = answers.find((child: any) => answer.answerExtra == child.questionExtra)
-          const tmp = {
-            itemIndex: index,
-            index: answer.answerId, // 左边的值
-            leftValue: answer.answer, // 左边的值
-            rightValue: answer.answerExtra, // 右边的值
-            leftType: rightOption ? rightOption.questionAnswerTypeCode || 'TXT' : 'TXT', // 左边类型
-            rightType: rightOption ? rightOption.questionExtraTypeCode || 'TXT' : 'TXT', // 右边类型
-            rightIndex: rightValue ? rightValue.examinationQuestionAnswerId : ''
-          }
-          state.options.push(tmp)
-        })
-        // console.log(state.options, 'after options')
-        // state.list = state.options
-      }
+      // state.options = []
+      nextTick(() => {
+        if (userAnswer.length > 0) {
+          const tempList: any = []
+          userAnswer.forEach((answer: any, index: any) => {
+            const rightOption = answers.find(
+              (child: any) => answer.answerId === child.examinationQuestionAnswerId
+            )
+            const rightValue = answers.find(
+              (child: any) => answer.answerExtra == child.questionExtra
+            )
+            const tmp = {
+              itemIndex: index,
+              index: answer.answerId, // 左边的值
+              leftValue: answer.answer, // 左边的值
+              rightValue: answer.answerExtra, // 右边的值
+              leftType: rightOption ? rightOption.questionAnswerTypeCode || 'TXT' : 'TXT', // 左边类型
+              rightType: rightOption ? rightOption.questionExtraTypeCode || 'TXT' : 'TXT', // 右边类型
+              rightIndex: rightValue ? rightValue.examinationQuestionAnswerId : ''
+            }
+            // state.options.push(tmp)
+            tempList.push(tmp)
+          })
+          state.options = tempList
+          console.log(state.options, 'after options')
+
+          // console.log(state.sortable.toArray())
+          // answers.forEach((item: any) => {
+          //   ids.push(item.itemIndex)
+          // })
+          // state.sortable.sort(
+          //   ids.sort((a: any, b: any) => a - b),
+          //   true
+          // )
+          // state.list = state.options
+        }
+      })
       // else {
       //   const resultValue: any = []
       //   answers.forEach((answer: any) => {
@@ -250,24 +279,51 @@ export default defineComponent({
               </Button>
             </div>
             <div id={state.domId}>
-              {state.options.map((item: any) => (
-                <>
-                  {item.leftType === AnswerType.TXT && (
-                    <Tag class={[styles.items]} data-id={item.itemIndex}>
-                      {item.leftValue}
-                    </Tag>
-                  )}
-                  {item.leftType === AnswerType.IMAGE && (
-                    <Image
-                      src={item.leftValue}
-                      data-id={item.itemIndex}
-                      class={[styles.imgs, 'van-hairline--surround']}
-                      fit="cover"
-                    />
-                  )}
-                </>
-              ))}
+              {state.options.length > 0 &&
+                state.options.map((item: any) => (
+                  <>
+                    {item.leftType === AnswerType.TXT && (
+                      <Tag class={[styles.items]} data-id={item.itemIndex}>
+                        {item.leftValue}
+                      </Tag>
+                    )}
+                    {item.leftType === AnswerType.IMAGE && (
+                      <Image
+                        src={item.leftValue}
+                        data-id={item.itemIndex}
+                        class={[styles.imgs, 'van-hairline--surround']}
+                        fit="cover"
+                      />
+                    )}
+                  </>
+                ))}
             </div>
+
+            {/* <Draggable v-model:modelValue={state.options} itemKey="itemIndex" componentData={}>
+              {{
+                item: (element: any) => {
+                  console.log(element)
+                  const item = element.element
+                  return (
+                    <>
+                      {item.leftType === AnswerType.TXT && (
+                        <Tag class={[styles.items]} data-id={item.itemIndex}>
+                          {item.leftValue}
+                        </Tag>
+                      )}
+                      {item.leftType === AnswerType.IMAGE && (
+                        <Image
+                          src={item.leftValue}
+                          data-id={item.itemIndex}
+                          class={[styles.imgs, 'van-hairline--surround']}
+                          fit="cover"
+                        />
+                      )}
+                    </>
+                  )
+                }
+              }}
+            </Draggable> */}
           </div>
         </div>
         {props.showAnalysis && (

+ 3 - 0
src/views/unit-test/model/keep-look-question/index.tsx

@@ -456,6 +456,9 @@ export default defineComponent({
                 })
                 // 清除所有的选择的内容
                 state.selectItem = []
+
+                // 初始化数据
+                onSelect()
               }}
             >
               重置