Selaa lähdekoodia

Merge branch 'master' of http://git.dayaedu.com/lex/classroom-instruments

mo 2 vuotta sitten
vanhempi
commit
d75fbe2129
85 muutettua tiedostoa jossa 1392 lisäystä ja 439 poistoa
  1. 1 1
      .gitignore
  2. BIN
      dist/assets/bannerPerson-c4a83458.png
  3. BIN
      dist/assets/boxIcon-df16f0d5.png
  4. BIN
      dist/assets/cloundIcon-423edd7b.png
  5. BIN
      dist/assets/headerD-b79bc401.png
  6. 62 0
      dist/assets/icon-assignHomework-b4738536.svg
  7. 42 0
      dist/assets/icon-down-disabled-d75c5d5b.svg
  8. 42 0
      dist/assets/icon-down-f45a4700.svg
  9. 42 0
      dist/assets/icon-menu-3cfdd93c.svg
  10. 12 0
      dist/assets/icon-pause-84bc84aa.svg
  11. 15 0
      dist/assets/icon-play-96c1202b.svg
  12. 42 0
      dist/assets/icon-up-0e5abc74.svg
  13. 42 0
      dist/assets/icon-up-disabled-47abbc4d.svg
  14. 162 0
      dist/assets/icon-whiteboard-8c8fe475.svg
  15. 1 0
      dist/assets/index-02d05aca.js
  16. 0 0
      dist/assets/index-1996fb58.js
  17. 0 0
      dist/assets/index-216aad3e.js
  18. 1 0
      dist/assets/index-2632cac7.js
  19. 0 0
      dist/assets/index-2ef18519.css
  20. 0 0
      dist/assets/index-32d347e6.js
  21. 0 0
      dist/assets/index-502dca1b.js
  22. 0 0
      dist/assets/index-6217671a.css
  23. 1 0
      dist/assets/index-693222ef.js
  24. 0 0
      dist/assets/index-6a3bb250.js
  25. 0 0
      dist/assets/index-8f0673fc.css
  26. 0 0
      dist/assets/index-a9346fdc.js
  27. 0 0
      dist/assets/index-acc023fc.css
  28. 0 0
      dist/assets/index-d3e3199c.css
  29. 1 0
      dist/assets/index-da6c026c.js
  30. 0 0
      dist/assets/index-de142f33.css
  31. 0 0
      dist/assets/index-e2bf8f51.css
  32. 0 0
      dist/assets/index-f000b6d4.js
  33. BIN
      dist/assets/leftDot-5a0f1cca.png
  34. BIN
      dist/assets/login_bg-19ea25e8.png
  35. BIN
      dist/assets/login_styles-21dea017.png
  36. BIN
      dist/assets/logo-654be404.png
  37. BIN
      dist/assets/musicIcon-2ab1b215.png
  38. BIN
      dist/assets/rightDot-4b44ee64.png
  39. BIN
      dist/assets/teacherIcon-288bbd9f.png
  40. 1 0
      dist/assets/teacherIcon-c36f70fa.js
  41. 36 0
      dist/index.html
  42. 158 8
      package-lock.json
  43. 14 0
      src/common/images/icon_search.svg
  44. 7 0
      src/components/TheSearch/index.module.less
  45. 40 0
      src/components/TheSearch/index.tsx
  46. 6 5
      src/components/layout/index.module.less
  47. 1 3
      src/components/layout/index.tsx
  48. 2 1
      src/components/layout/layoutSilder.tsx
  49. 0 1
      src/components/layout/layoutTop.tsx
  50. 1 1
      src/components/layout/modals/silderItem.tsx
  51. 1 1
      src/enums/pageEnum.ts
  52. 0 3
      src/hooks/index.ts
  53. 0 34
      src/hooks/setting/index.ts
  54. 1 1
      src/hooks/setting/useDesignSetting.ts
  55. 0 42
      src/hooks/setting/useProjectSetting.ts
  56. 42 35
      src/hooks/web/usePage.ts
  57. 23 16
      src/hooks/web/usePermission.ts
  58. 1 1
      src/main.ts
  59. 19 1
      src/router/routes/index.ts
  60. 8 8
      src/styles/index.less
  61. 86 42
      src/views/attend-class/component/audio-pay.tsx
  62. 65 0
      src/views/attend-class/component/audio.module.less
  63. 0 110
      src/views/attend-class/component/point.module.less
  64. 0 102
      src/views/attend-class/component/points.tsx
  65. 3 3
      src/views/attend-class/component/tool.tsx
  66. 1 1
      src/views/attend-class/component/video.module.less
  67. 63 0
      src/views/attend-class/index.module.less
  68. 66 12
      src/views/attend-class/index.tsx
  69. 61 0
      src/views/attend-class/model/train-settings/index.module.less
  70. 39 0
      src/views/attend-class/model/train-settings/index.tsx
  71. 1 4
      src/views/home/index.tsx
  72. 3 3
      src/views/prepare-lessons/index.module.less
  73. BIN
      src/views/xiaoku-ai/image/0.png
  74. BIN
      src/views/xiaoku-ai/image/1.png
  75. BIN
      src/views/xiaoku-ai/image/2.png
  76. BIN
      src/views/xiaoku-ai/image/3.png
  77. BIN
      src/views/xiaoku-ai/image/4.png
  78. BIN
      src/views/xiaoku-ai/image/5.png
  79. 5 0
      src/views/xiaoku-ai/image/index.tsx
  80. 78 0
      src/views/xiaoku-ai/index.module.less
  81. 84 0
      src/views/xiaoku-ai/index.tsx
  82. 0 0
      src/views/xiaoku-music/index.module.less
  83. 8 0
      src/views/xiaoku-music/index.tsx
  84. 1 0
      tsconfig.json
  85. 1 0
      vite.config.ts

+ 1 - 1
.gitignore

@@ -1,6 +1,6 @@
 node_modules
 .DS_Store
-dist
+#dist
 dist-ssr
 *.local
 

BIN
dist/assets/bannerPerson-c4a83458.png


BIN
dist/assets/boxIcon-df16f0d5.png


BIN
dist/assets/cloundIcon-423edd7b.png


BIN
dist/assets/headerD-b79bc401.png


+ 62 - 0
dist/assets/icon-assignHomework-b4738536.svg

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="187px" height="60px" viewBox="0 0 187 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>切片</title>
+    <defs>
+        <linearGradient x1="1.51267887e-13%" y1="15.1852058%" x2="100%" y2="70.279218%" id="linearGradient-1">
+            <stop stop-color="#88E1FF" offset="0%"></stop>
+            <stop stop-color="#2C8DFF" offset="100%"></stop>
+        </linearGradient>
+        <circle id="path-2" cx="30" cy="30" r="30"></circle>
+        <filter x="-8.3%" y="-5.0%" width="116.7%" height="120.0%" filterUnits="objectBoundingBox" id="filter-3">
+            <feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.43649793   0 0 0 0 0.550193556   0 0 0 0 0.741508152  0 0 0 0.273082386 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-10.0%" y="-6.7%" width="120.0%" height="123.3%" filterUnits="objectBoundingBox" id="filter-4">
+            <feGaussianBlur stdDeviation="3" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
+            <feOffset dx="0" dy="2" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.5 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
+            <feGaussianBlur stdDeviation="1" in="SourceAlpha" result="shadowBlurInner2"></feGaussianBlur>
+            <feOffset dx="-2" dy="-6" in="shadowBlurInner2" result="shadowOffsetInner2"></feOffset>
+            <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.108247927   0 0 0 0 0.476908508   0 0 0 0 0.983016304  0 0 0 0.462194056 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixInner1"></feMergeNode>
+                <feMergeNode in="shadowMatrixInner2"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-104.3%" y="-87.6%" width="308.7%" height="275.2%" filterUnits="objectBoundingBox" id="filter-5">
+            <feOffset dx="2" dy="5" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.127134146   0 0 0 0 0.509284371   0 0 0 0 1  0 0 0 1 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="50、上课页面" transform="translate(-40.000000, -40.000000)">
+            <g id="布置作业" transform="translate(40.000000, 40.000000)">
+                <g id="编组-11备份-2">
+                    <rect id="矩形" fill="#DCEDFF" x="20" y="6" width="167" height="48" rx="24"></rect>
+                    <g id="椭圆形">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-2"></use>
+                        <use fill="url(#linearGradient-1)" fill-rule="evenodd" xlink:href="#path-2"></use>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
+                    </g>
+                    <text id="布置作业" font-family="STYuanti-SC-Bold, Yuanti SC" font-size="24" font-weight="bold" letter-spacing="0.857142857" fill="#0378EC">
+                        <tspan x="70" y="38">布置作业</tspan>
+                    </text>
+                </g>
+                <g id="编组-20备份" filter="url(#filter-5)" transform="translate(16.979034, 13.000000)" stroke="#FFFFFF" stroke-linecap="round" stroke-width="3.3">
+                    <path d="M11.0629156,2.92618064 L11.0629156,2.92618064 L22.3036849,2.92618064 C24.3566824,2.92618064 26.0209657,4.60205759 26.0209657,6.66935656 L26.0209657,27.2568241 C26.0209657,29.3241231 24.3566824,31 22.3036849,31 L3.71728082,31 C1.66428331,31 0,29.3241231 0,27.2568241 L0,12.842191 L0,12.842191" id="路径"></path>
+                    <line x1="13.2497405" y1="16.9630903" x2="20.3053273" y2="16.9630903" id="路径-12"></line>
+                    <line x1="7.43456164" y1="23.5136482" x2="20.3053273" y2="23.5136482" id="路径-12备份"></line>
+                    <line x1="-1.36638462e-13" y1="5.28647048e-13" x2="9.98808831" y2="12.9965999" id="路径-13"></line>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 42 - 0
dist/assets/icon-down-disabled-d75c5d5b.svg

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="66px" viewBox="0 0 64 66" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组 11</title>
+    <defs>
+        <linearGradient x1="1.51267887e-13%" y1="15.1852058%" x2="100%" y2="70.279218%" id="linearGradient-1">
+            <stop stop-color="#E4E4E4" offset="0%"></stop>
+            <stop stop-color="#AAAAAA" offset="100%"></stop>
+        </linearGradient>
+        <circle id="path-2" cx="30" cy="30" r="30"></circle>
+        <filter x="-8.3%" y="-5.0%" width="116.7%" height="120.0%" filterUnits="objectBoundingBox" id="filter-3">
+            <feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.808310688   0 0 0 0 0.808310688   0 0 0 0 0.808310688  0 0 0 0.126502404 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-10.0%" y="-6.7%" width="120.0%" height="123.3%" filterUnits="objectBoundingBox" id="filter-4">
+            <feGaussianBlur stdDeviation="3" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
+            <feOffset dx="0" dy="2" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.5 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
+            <feGaussianBlur stdDeviation="1" in="SourceAlpha" result="shadowBlurInner2"></feGaussianBlur>
+            <feOffset dx="-2" dy="-6" in="shadowBlurInner2" result="shadowOffsetInner2"></feOffset>
+            <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.466145833   0 0 0 0 0.466145833   0 0 0 0 0.466145833  0 0 0 0.462194056 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixInner1"></feMergeNode>
+                <feMergeNode in="shadowMatrixInner2"></feMergeNode>
+            </feMerge>
+        </filter>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="55、音频预览" transform="translate(-1818.000000, -975.000000)">
+            <g id="编组-11" transform="translate(1820.000000, 975.000000)">
+                <g id="椭圆形">
+                    <use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-2"></use>
+                    <use fill="url(#linearGradient-1)" fill-rule="evenodd" xlink:href="#path-2"></use>
+                    <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
+                </g>
+                <polyline id="Stroke-1" stroke="#FFFFFF" stroke-width="5.65714286" stroke-linecap="round" stroke-linejoin="round" transform="translate(30.142857, 30.142857) rotate(-90.000000) translate(-30.142857, -30.142857) " points="37.4285714 44.2857143 22.8571429 30.1428571 37.4285714 16"></polyline>
+            </g>
+        </g>
+    </g>
+</svg>

+ 42 - 0
dist/assets/icon-down-f45a4700.svg

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="66px" viewBox="0 0 64 66" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组 11</title>
+    <defs>
+        <linearGradient x1="1.51267887e-13%" y1="15.1852058%" x2="100%" y2="70.279218%" id="linearGradient-1">
+            <stop stop-color="#88E1FF" offset="0%"></stop>
+            <stop stop-color="#2C8DFF" offset="100%"></stop>
+        </linearGradient>
+        <circle id="path-2" cx="30" cy="30" r="30"></circle>
+        <filter x="-8.3%" y="-5.0%" width="116.7%" height="120.0%" filterUnits="objectBoundingBox" id="filter-3">
+            <feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.43649793   0 0 0 0 0.550193556   0 0 0 0 0.741508152  0 0 0 0.273082386 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-10.0%" y="-6.7%" width="120.0%" height="123.3%" filterUnits="objectBoundingBox" id="filter-4">
+            <feGaussianBlur stdDeviation="3" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
+            <feOffset dx="0" dy="2" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.5 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
+            <feGaussianBlur stdDeviation="1" in="SourceAlpha" result="shadowBlurInner2"></feGaussianBlur>
+            <feOffset dx="-2" dy="-6" in="shadowBlurInner2" result="shadowOffsetInner2"></feOffset>
+            <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.108247927   0 0 0 0 0.476908508   0 0 0 0 0.983016304  0 0 0 0.462194056 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixInner1"></feMergeNode>
+                <feMergeNode in="shadowMatrixInner2"></feMergeNode>
+            </feMerge>
+        </filter>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="52、乐谱预览" transform="translate(-1818.000000, -980.000000)">
+            <g id="编组-11" transform="translate(1820.000000, 980.000000)">
+                <g id="椭圆形">
+                    <use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-2"></use>
+                    <use fill="url(#linearGradient-1)" fill-rule="evenodd" xlink:href="#path-2"></use>
+                    <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
+                </g>
+                <polyline id="Stroke-1" stroke="#FFFFFF" stroke-width="5.65714286" stroke-linecap="round" stroke-linejoin="round" transform="translate(30.142857, 30.142857) rotate(-90.000000) translate(-30.142857, -30.142857) " points="37.4285714 44.2857143 22.8571429 30.1428571 37.4285714 16"></polyline>
+            </g>
+        </g>
+    </g>
+</svg>

+ 42 - 0
dist/assets/icon-menu-3cfdd93c.svg

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="95px" height="107px" viewBox="0 0 95 107" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>切片</title>
+    <defs>
+        <rect id="path-1" x="0" y="4.72906404" width="56.7487685" height="59.1133005" rx="9.45812808"></rect>
+        <filter x="-1.8%" y="-1.7%" width="103.5%" height="103.4%" filterUnits="objectBoundingBox" id="filter-2">
+            <feOffset dx="-2" dy="-2" in="SourceAlpha" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.918931159   0 0 0 0 0.883965387   0 0 0 0 0.832431161  0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
+        </filter>
+        <path d="M18.9162562,0 L37.8325123,0 C41.7501972,1.68511374e-16 44.9261084,3.17591113 44.9261084,7.09359606 L44.9261084,11.8226601 C44.9261084,13.1285551 43.8674713,14.1871921 42.5615764,14.1871921 L14.1871921,14.1871921 C12.8812971,14.1871921 11.8226601,13.1285551 11.8226601,11.8226601 L11.8226601,7.09359606 C11.8226601,3.17591113 14.9985712,7.19667046e-16 18.9162562,0 Z" id="path-3"></path>
+        <filter x="-7.6%" y="-17.6%" width="121.1%" height="149.3%" filterUnits="objectBoundingBox" id="filter-4">
+            <feOffset dx="1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.939254982   0 0 0 0 0.859970658   0 0 0 0 0.652735679  0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-6.0%" y="-14.1%" width="118.1%" height="142.3%" filterUnits="objectBoundingBox" id="filter-5">
+            <feOffset dx="-2" dy="-2" in="SourceAlpha" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 0.780047784   0 0 0 0 0.293807165  0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="50、上课页面" transform="translate(-1825.000000, -487.000000)">
+            <g id="目录" transform="translate(1825.000000, 487.000000)">
+                <path d="M23.6453202,0 L94.5812808,0 L94.5812808,0 L94.5812808,106.403941 L23.6453202,106.403941 C10.5863704,106.403941 1.5992601e-15,95.8175704 0,82.7586207 L0,23.6453202 C-1.5992601e-15,10.5863704 10.5863704,5.95160383e-15 23.6453202,0 Z" id="矩形" fill-opacity="0.25" fill="#000000"></path>
+                <g id="编组-18" transform="translate(21.280788, 18.916256)">
+                    <g id="矩形">
+                        <use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
+                    </g>
+                    <path d="M13.0049261,33.1034483 C14.9637686,33.1034483 16.5517241,31.5154927 16.5517241,29.5566502 C16.5517241,27.5978078 14.9637686,26.0098522 13.0049261,26.0098522 C11.0460836,26.0098522 9.45812808,27.5978078 9.45812808,29.5566502 C9.45812808,31.5154927 11.0460836,33.1034483 13.0049261,33.1034483 Z M13.0049261,47.2906404 C14.9637686,47.2906404 16.5517241,45.7026848 16.5517241,43.7438424 C16.5517241,41.7849999 14.9637686,40.1970443 13.0049261,40.1970443 C11.0460836,40.1970443 9.45812808,41.7849999 9.45812808,43.7438424 C9.45812808,45.7026848 11.0460836,47.2906404 13.0049261,47.2906404 Z M27.1921182,26.0098522 L43.7438424,26.0098522 C45.7026848,26.0098522 47.2906404,27.5978078 47.2906404,29.5566502 C47.2906404,31.5154927 45.7026848,33.1034483 43.7438424,33.1034483 L27.1921182,33.1034483 C25.2332758,33.1034483 23.6453202,31.5154927 23.6453202,29.5566502 C23.6453202,27.5978078 25.2332758,26.0098522 27.1921182,26.0098522 Z M27.1921182,40.1970443 L36.6502463,40.1970443 C38.6090888,40.1970443 40.1970443,41.7849999 40.1970443,43.7438424 C40.1970443,45.7026848 38.6090888,47.2906404 36.6502463,47.2906404 L27.1921182,47.2906404 C25.2332758,47.2906404 23.6453202,45.7026848 23.6453202,43.7438424 C23.6453202,41.7849999 25.2332758,40.1970443 27.1921182,40.1970443 Z" id="形状结合" fill="#FF9E31"></path>
+                    <g id="矩形">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
+                        <use fill="#FCDA67" fill-rule="evenodd" xlink:href="#path-3"></use>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-3"></use>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 12 - 0
dist/assets/icon-pause-84bc84aa.svg

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="82px" height="82px" viewBox="0 0 82 82" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组 2</title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="55、音频预览" transform="translate(-280.000000, -964.000000)">
+            <g id="编组-2" transform="translate(280.000000, 964.000000)">
+                <rect id="矩形" fill="#198CFE" x="0" y="0" width="82" height="82" rx="26"></rect>
+                <path d="M47.5235354,32.9254996 L57.0285389,47.7110606 C57.9244954,49.1047707 57.5209864,50.9609122 56.1272763,51.8568688 C55.6433843,52.1679422 55.0802584,52.3333333 54.5050035,52.3333333 L35.4949965,52.3333333 C33.8381422,52.3333333 32.4949965,50.9901876 32.4949965,49.3333333 C32.4949965,48.7580785 32.6603876,48.1949526 32.9714611,47.7110606 L42.4764646,32.9254996 C43.3724211,31.5317894 45.2285626,31.1282804 46.6222728,32.0242369 C46.9837807,32.2566349 47.2911375,32.5639916 47.5235354,32.9254996 Z" id="三角形" fill="#FFFFFF" transform="translate(45.000000, 40.666667) rotate(-270.000000) translate(-45.000000, -40.666667) "></path>
+            </g>
+        </g>
+    </g>
+</svg>

+ 15 - 0
dist/assets/icon-play-96c1202b.svg

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="82px" height="82px" viewBox="0 0 82 82" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组 2</title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="54、视频预览" transform="translate(-280.000000, -964.000000)">
+            <g id="编组-2" transform="translate(280.000000, 964.000000)">
+                <rect id="矩形" fill="#198CFE" x="0" y="0" width="82" height="82" rx="26"></rect>
+                <g id="编组-3" transform="translate(26.000000, 27.000000)" fill="#FFFFFF">
+                    <rect id="矩形" x="0" y="0" width="9" height="28" rx="4.5"></rect>
+                    <rect id="矩形备份-85" x="21" y="0" width="9" height="28" rx="4.5"></rect>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 42 - 0
dist/assets/icon-up-0e5abc74.svg

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="66px" viewBox="0 0 64 66" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组 11备份 2</title>
+    <defs>
+        <linearGradient x1="1.51267887e-13%" y1="15.1852058%" x2="100%" y2="70.279218%" id="linearGradient-1">
+            <stop stop-color="#88E1FF" offset="0%"></stop>
+            <stop stop-color="#2C8DFF" offset="100%"></stop>
+        </linearGradient>
+        <circle id="path-2" cx="30" cy="30" r="30"></circle>
+        <filter x="-8.3%" y="-5.0%" width="116.7%" height="120.0%" filterUnits="objectBoundingBox" id="filter-3">
+            <feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.43649793   0 0 0 0 0.550193556   0 0 0 0 0.741508152  0 0 0 0.273082386 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-10.0%" y="-6.7%" width="120.0%" height="123.3%" filterUnits="objectBoundingBox" id="filter-4">
+            <feGaussianBlur stdDeviation="3" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
+            <feOffset dx="0" dy="2" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.5 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
+            <feGaussianBlur stdDeviation="1" in="SourceAlpha" result="shadowBlurInner2"></feGaussianBlur>
+            <feOffset dx="-2" dy="-6" in="shadowBlurInner2" result="shadowOffsetInner2"></feOffset>
+            <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.108247927   0 0 0 0 0.476908508   0 0 0 0 0.983016304  0 0 0 0.462194056 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixInner1"></feMergeNode>
+                <feMergeNode in="shadowMatrixInner2"></feMergeNode>
+            </feMerge>
+        </filter>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="53、图片预览" transform="translate(-1718.000000, -980.000000)">
+            <g id="编组-11备份-2" transform="translate(1720.000000, 980.000000)">
+                <g id="椭圆形">
+                    <use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-2"></use>
+                    <use fill="url(#linearGradient-1)" fill-rule="evenodd" xlink:href="#path-2"></use>
+                    <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
+                </g>
+                <polyline id="Stroke-1" stroke="#FFFFFF" stroke-width="5.65714286" stroke-linecap="round" stroke-linejoin="round" transform="translate(30.142857, 29.142857) rotate(-270.000000) translate(-30.142857, -29.142857) " points="37.4285714 43.2857143 22.8571429 29.1428571 37.4285714 15"></polyline>
+            </g>
+        </g>
+    </g>
+</svg>

+ 42 - 0
dist/assets/icon-up-disabled-47abbc4d.svg

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="66px" viewBox="0 0 64 66" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组 11备份 2</title>
+    <defs>
+        <linearGradient x1="1.51267887e-13%" y1="15.1852058%" x2="100%" y2="70.279218%" id="linearGradient-1">
+            <stop stop-color="#E4E4E4" offset="0%"></stop>
+            <stop stop-color="#AAAAAA" offset="100%"></stop>
+        </linearGradient>
+        <circle id="path-2" cx="30" cy="30" r="30"></circle>
+        <filter x="-8.3%" y="-5.0%" width="116.7%" height="120.0%" filterUnits="objectBoundingBox" id="filter-3">
+            <feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.808310688   0 0 0 0 0.808310688   0 0 0 0 0.808310688  0 0 0 0.273082386 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-10.0%" y="-6.7%" width="120.0%" height="123.3%" filterUnits="objectBoundingBox" id="filter-4">
+            <feGaussianBlur stdDeviation="3" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
+            <feOffset dx="0" dy="2" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.5 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
+            <feGaussianBlur stdDeviation="1" in="SourceAlpha" result="shadowBlurInner2"></feGaussianBlur>
+            <feOffset dx="-2" dy="-6" in="shadowBlurInner2" result="shadowOffsetInner2"></feOffset>
+            <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.466145833   0 0 0 0 0.466145833   0 0 0 0 0.466145833  0 0 0 0.462194056 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixInner1"></feMergeNode>
+                <feMergeNode in="shadowMatrixInner2"></feMergeNode>
+            </feMerge>
+        </filter>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="52、乐谱预览" transform="translate(-1718.000000, -980.000000)">
+            <g id="编组-11备份-2" transform="translate(1720.000000, 980.000000)">
+                <g id="椭圆形">
+                    <use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-2"></use>
+                    <use fill="url(#linearGradient-1)" fill-rule="evenodd" xlink:href="#path-2"></use>
+                    <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
+                </g>
+                <polyline id="Stroke-1" stroke="#FFFFFF" stroke-width="5.65714286" stroke-linecap="round" stroke-linejoin="round" transform="translate(30.142857, 29.142857) rotate(-270.000000) translate(-30.142857, -29.142857) " points="37.4285714 43.2857143 22.8571429 29.1428571 37.4285714 15"></polyline>
+            </g>
+        </g>
+    </g>
+</svg>

+ 162 - 0
dist/assets/icon-whiteboard-8c8fe475.svg

@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="70px" height="70px" viewBox="0 0 70 70" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>切片</title>
+    <defs>
+        <linearGradient x1="1.51267887e-13%" y1="15.1852058%" x2="100%" y2="70.279218%" id="linearGradient-1">
+            <stop stop-color="#A4A8FF" offset="0%"></stop>
+            <stop stop-color="#959AFF" offset="100%"></stop>
+        </linearGradient>
+        <circle id="path-2" cx="35" cy="35" r="35"></circle>
+        <filter x="-7.1%" y="-4.3%" width="114.3%" height="117.1%" filterUnits="objectBoundingBox" id="filter-3">
+            <feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.438230942   0 0 0 0 0.43649793   0 0 0 0 0.741508152  0 0 0 0.273082386 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-8.6%" y="-5.7%" width="117.1%" height="120.0%" filterUnits="objectBoundingBox" id="filter-4">
+            <feGaussianBlur stdDeviation="3" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
+            <feOffset dx="0" dy="2" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.5 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
+            <feGaussianBlur stdDeviation="1" in="SourceAlpha" result="shadowBlurInner2"></feGaussianBlur>
+            <feOffset dx="-2" dy="-6" in="shadowBlurInner2" result="shadowOffsetInner2"></feOffset>
+            <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.529973323   0 0 0 0 0.550633836   0 0 0 0 1  0 0 0 1 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixInner1"></feMergeNode>
+                <feMergeNode in="shadowMatrixInner2"></feMergeNode>
+            </feMerge>
+        </filter>
+        <path d="M11.7637958,36 L15.6907496,36 C16.2430344,36 16.6907496,36.4477153 16.6907496,37 C16.6907496,37.088882 16.6788998,37.1773673 16.6555134,37.2631174 L14.200968,46.2631174 C14.0823149,46.6981787 13.6871552,47 13.2362042,47 L9.30925039,47 C8.75696564,47 8.30925039,46.5522847 8.30925039,46 C8.30925039,45.911118 8.32110017,45.8226327 8.34448657,45.7368826 L10.799032,36.7368826 C10.9176851,36.3018213 11.3128448,36 11.7637958,36 Z" id="path-5"></path>
+        <filter x="-2.1%" y="-4.5%" width="115.3%" height="109.1%" filterUnits="objectBoundingBox" id="filter-6">
+            <feOffset dx="1" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.898039216   0 0 0 0 0.694117647   0 0 0 0 0.443137255  0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <filter x="0.7%" y="-2.3%" width="109.8%" height="104.5%" filterUnits="objectBoundingBox" id="filter-7">
+            <feOffset dx="-0.5" dy="0" in="SourceAlpha" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.648983829 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
+        </filter>
+        <path d="M30.3092504,36 L34.2362042,36 C34.6871552,36 35.0823149,36.3018213 35.200968,36.7368826 L37.6555134,45.7368826 C37.8008292,46.2697069 37.4866914,46.8194481 36.953867,46.9647638 C36.8681169,46.9881502 36.7796316,47 36.6907496,47 L32.7637958,47 C32.3128448,47 31.9176851,46.6981787 31.799032,46.2631174 L29.3444866,37.2631174 C29.1991708,36.7302931 29.5133086,36.1805519 30.046133,36.0352362 C30.1318831,36.0118498 30.2203684,36 30.3092504,36 Z" id="path-8"></path>
+        <filter x="-13.2%" y="-4.5%" width="115.4%" height="109.1%" filterUnits="objectBoundingBox" id="filter-9">
+            <feOffset dx="-1" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.898039216   0 0 0 0 0.694117647   0 0 0 0 0.443137255  0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-10.5%" y="-2.3%" width="109.8%" height="104.5%" filterUnits="objectBoundingBox" id="filter-10">
+            <feOffset dx="0.5" dy="0" in="SourceAlpha" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.5 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
+        </filter>
+        <path d="M21.2297059,0 L24.7702941,0 C25.4853157,-1.31347324e-16 26.1009379,0.504689502 26.2411652,1.2058258 L27,5 L27,5 L19,5 L19.7588348,1.2058258 C19.8990621,0.504689502 20.5146843,5.75436534e-16 21.2297059,0 Z" id="path-11"></path>
+        <filter x="-3.1%" y="-5.0%" width="106.2%" height="110.0%" filterUnits="objectBoundingBox" id="filter-12">
+            <feOffset dx="-0.5" dy="0" in="SourceAlpha" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.648983829 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
+        </filter>
+        <path d="M7,4 L39,4 C41.7614237,4 44,6.23857625 44,9 L44,34 L44,34 L2,34 L2,9 C2,6.23857625 4.23857625,4 7,4 Z" id="path-13"></path>
+        <filter x="-6.0%" y="-8.3%" width="111.9%" height="116.7%" filterUnits="objectBoundingBox" id="filter-14">
+            <feGaussianBlur stdDeviation="1.5" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
+            <feOffset dx="0" dy="-2" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.08 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
+        </filter>
+        <rect id="path-15" x="7" y="9" width="25" height="11" rx="2"></rect>
+        <filter x="-8.0%" y="-9.1%" width="116.0%" height="136.4%" filterUnits="objectBoundingBox" id="filter-16">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.890196078   0 0 0 0 0.890196078   0 0 0 0 0.933333333  0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-6.0%" y="-4.5%" width="112.0%" height="127.3%" filterUnits="objectBoundingBox" id="filter-17">
+            <feOffset dx="0" dy="-1" in="SourceAlpha" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.996078431   0 0 0 0 0.721568627   0 0 0 0 0.0352941176  0 0 0 1 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
+            <feOffset dx="0" dy="0.5" in="SourceAlpha" result="shadowOffsetInner2"></feOffset>
+            <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.5 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixInner1"></feMergeNode>
+                <feMergeNode in="shadowMatrixInner2"></feMergeNode>
+            </feMerge>
+        </filter>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-18">
+            <stop stop-color="#FF8632" offset="0%"></stop>
+            <stop stop-color="#FF5400" offset="100%"></stop>
+        </linearGradient>
+        <rect id="path-19" x="7" y="23.5" width="18" height="4" rx="2"></rect>
+        <filter x="-11.1%" y="-25.0%" width="122.2%" height="200.0%" filterUnits="objectBoundingBox" id="filter-20">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.890196078   0 0 0 0 0.890196078   0 0 0 0 0.933333333  0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-6.9%" y="-6.2%" width="113.9%" height="162.5%" filterUnits="objectBoundingBox" id="filter-21">
+            <feOffset dx="0" dy="-0.5" in="SourceAlpha" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.898039216   0 0 0 0 0.184313725   0 0 0 0 0  0 0 0 1 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
+            <feOffset dx="0" dy="0.5" in="SourceAlpha" result="shadowOffsetInner2"></feOffset>
+            <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 0.568627451   0 0 0 0 0.258823529  0 0 0 1 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixInner1"></feMergeNode>
+                <feMergeNode in="shadowMatrixInner2"></feMergeNode>
+            </feMerge>
+        </filter>
+        <path d="M2.5,32 L43.5,32 C44.8807119,32 46,33.1192881 46,34.5 L46,36 C46,36.5522847 45.5522847,37 45,37 L1,37 C0.44771525,37 -5.9849844e-16,36.5522847 0,36 L0,34.5 C-1.69088438e-16,33.1192881 1.11928813,32 2.5,32 Z" id="path-22"></path>
+        <filter x="-0.5%" y="-5.0%" width="101.1%" height="110.0%" filterUnits="objectBoundingBox" id="filter-23">
+            <feOffset dx="0" dy="-0.5" in="SourceAlpha" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.941176471   0 0 0 0 0.749019608   0 0 0 0 0.501960784  0 0 0 1 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
+            <feOffset dx="0" dy="0.5" in="SourceAlpha" result="shadowOffsetInner2"></feOffset>
+            <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
+            <feColorMatrix values="0 0 0 0 1   0 0 0 0 1   0 0 0 0 1  0 0 0 0.5 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixInner1"></feMergeNode>
+                <feMergeNode in="shadowMatrixInner2"></feMergeNode>
+            </feMerge>
+        </filter>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.5">
+        <g id="52、乐谱预览" transform="translate(-40.000000, -970.000000)">
+            <g id="画板" transform="translate(40.000000, 970.000000)">
+                <g id="椭圆形">
+                    <use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-2"></use>
+                    <use fill="url(#linearGradient-1)" fill-rule="evenodd" xlink:href="#path-2"></use>
+                    <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
+                </g>
+                <g id="编组-17" transform="translate(12.000000, 12.000000)">
+                    <g id="矩形">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
+                        <use fill="#FDD99A" fill-rule="evenodd" xlink:href="#path-5"></use>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-7)" xlink:href="#path-5"></use>
+                    </g>
+                    <g id="矩形备份-10">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-9)" xlink:href="#path-8"></use>
+                        <use fill="#FDD99A" fill-rule="evenodd" xlink:href="#path-8"></use>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-10)" xlink:href="#path-8"></use>
+                    </g>
+                    <g id="矩形">
+                        <use fill="#FDD99A" fill-rule="evenodd" xlink:href="#path-11"></use>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-12)" xlink:href="#path-11"></use>
+                    </g>
+                    <g id="矩形">
+                        <use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-13"></use>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-14)" xlink:href="#path-13"></use>
+                    </g>
+                    <g id="矩形">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-16)" xlink:href="#path-15"></use>
+                        <use fill="#FFD200" fill-rule="evenodd" xlink:href="#path-15"></use>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-17)" xlink:href="#path-15"></use>
+                    </g>
+                    <rect id="矩形备份-9" fill="#E5E6EE" x="7" y="24" width="32" height="3" rx="1.5"></rect>
+                    <g id="矩形备份-9">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-20)" xlink:href="#path-19"></use>
+                        <use fill="url(#linearGradient-18)" fill-rule="evenodd" xlink:href="#path-19"></use>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-21)" xlink:href="#path-19"></use>
+                    </g>
+                    <g id="矩形">
+                        <use fill="#FFE0A1" fill-rule="evenodd" xlink:href="#path-22"></use>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-23)" xlink:href="#path-22"></use>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 1 - 0
dist/assets/index-02d05aca.js

@@ -0,0 +1 @@
+import{a as t,f as e,av as a,k as p,g as n}from"./index-1996fb58.js";const i=t({name:"404-page",setup(){return()=>e("div",{style:{height:"220px","margin-top":"150px","padding-top":"30px","font-size":"15px","text-align":"center"}},[e(a,{description:"你访问的页面不见了,你还可以",size:"large"},null),e(p,{type:"primary",text:!0},{default:()=>[n("返回上一页")]})])}});export{i as default};

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-1996fb58.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-216aad3e.js


+ 1 - 0
dist/assets/index-2632cac7.js

@@ -0,0 +1 @@
+import{a as e,f as n}from"./index-1996fb58.js";const o=e({name:"XiaokuAi",setup(){return()=>n("div",null,null)}});export{o as default};

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-2ef18519.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-32d347e6.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-502dca1b.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-6217671a.css


+ 1 - 0
dist/assets/index-693222ef.js

@@ -0,0 +1 @@
+import{a as e,f as t,g as a,F as n}from"./index-1996fb58.js";const r=e({name:"student-studentList",setup(s,{emit:u}){return()=>t(n,null,[a("学生列表")])}});export{r as default};

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-6a3bb250.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-8f0673fc.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-a9346fdc.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-acc023fc.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-d3e3199c.css


+ 1 - 0
dist/assets/index-da6c026c.js

@@ -0,0 +1 @@
+import{Y as y,Z as C,O as F,H as P,C as O}from"./index-1996fb58.js";function g(e){return y()?(C(e),!0):!1}function w(e){return typeof e=="function"?e():O(e)}const R=typeof window<"u",m=()=>{};function D(e,i){function n(...t){return new Promise((o,r)=>{Promise.resolve(e(()=>i.apply(this,t),{fn:i,thisArg:this,args:t})).then(o).catch(r)})}return n}function b(e,i={}){let n,t,o=m;const r=u=>{clearTimeout(u),o(),o=m};return u=>{const a=w(e),s=w(i.maxWait);return n&&r(n),a<=0||s!==void 0&&s<=0?(t&&(r(t),t=null),Promise.resolve(u())):new Promise((c,p)=>{o=i.rejectOnCancel?p:c,s&&!t&&(t=setTimeout(()=>{n&&r(n),t=null,c(u())},s)),n=setTimeout(()=>{t&&r(t),t=null,c(u())},a)})}}function j(e,i=!0,n=!0,t=!1){let o=0,r,l=!0,u=m,a;const s=()=>{r&&(clearTimeout(r),r=void 0,u(),u=m)};return p=>{const f=w(e),T=Date.now()-o,d=()=>a=p();return s(),f<=0?(o=Date.now(),d()):(T>f&&(n||!l)?(o=Date.now(),d()):i&&(a=new Promise((h,x)=>{u=t?x:h,r=setTimeout(()=>{o=Date.now(),l=!0,h(d()),s()},Math.max(0,f-T))})),!n&&!r&&(r=setTimeout(()=>l=!0,f)),l=!1,a)}}function U(e,i=200,n={}){return D(b(i,n),e)}function V(e,i=200,n=!1,t=!0,o=!1){return D(j(i,n,t,o),e)}function W(e){F()&&P(e)}export{V as a,g as b,w as c,R as i,W as t,U as u};

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-de142f33.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-e2bf8f51.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/assets/index-f000b6d4.js


BIN
dist/assets/leftDot-5a0f1cca.png


BIN
dist/assets/login_bg-19ea25e8.png


BIN
dist/assets/login_styles-21dea017.png


BIN
dist/assets/logo-654be404.png


BIN
dist/assets/musicIcon-2ab1b215.png


BIN
dist/assets/rightDot-4b44ee64.png


BIN
dist/assets/teacherIcon-288bbd9f.png


+ 1 - 0
dist/assets/teacherIcon-c36f70fa.js

@@ -0,0 +1 @@
+const e="/assets/teacherIcon-288bbd9f.png";export{e as d};

+ 36 - 0
dist/index.html

@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8" />
+  <link rel="icon" href="/favicon.ico" />
+  <meta name="viewport"
+    content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover">
+  <meta http-equiv="Cache-control" content="no-cache">
+  <meta http-equiv="Cache" content="no-cache">
+  <meta name="apple-mobile-web-app-capable" content="yes" />
+  <!-- 设置苹果工具栏颜色 -->
+  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+  <!-- 忽略页面中的数字识别为电话,忽略email识别 -->
+  <meta name="format-detection" content="telphone=no, email=no" />
+  <!-- 启用360浏览器的极速模式(webkit) -->
+  <meta name="renderer" content="webkit" />
+  <!-- 避免IE使用兼容模式 -->
+  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+  <meta name="HandheldFriendly" content="true" />
+  <!-- 设置在apple上以应用模式启动时,是否全屏 -->
+  <meta name="apple-touch-fullscreen" content="yes" />
+  <!-- windows phone 点击无高光 -->
+  <meta name="msapplication-tap-highlight" content="no" />
+  <meta name="referrer" content="no-referrer" />
+  <title>老师端</title>
+  <script type="module" crossorigin src="/assets/index-1996fb58.js"></script>
+  <link rel="stylesheet" href="/assets/index-8f0673fc.css">
+</head>
+
+<body>
+  <div id="app"></div>
+  
+</body>
+
+</html>

+ 158 - 8
package-lock.json

@@ -9,17 +9,20 @@
       "version": "0.2.0",
       "license": "MIT",
       "dependencies": {
-        "@vant/use": "^1.5.1",
+        "@vant/use": "^1.5.2",
         "@vueuse/core": "^10.2.0",
         "clean-deep": "^3.4.0",
         "dayjs": "^1.11.7",
         "echarts": "^5.4.2",
         "numeral": "^2.0.6",
         "pinia": "^2.1.4",
+        "plyr": "^3.7.8",
+        "query-string": "^8.1.0",
         "umi-request": "^1.4.0",
         "vue": "^3.3.4",
         "vue-router": "^4.1.6",
-        "vue3-lottie": "^2.7.0"
+        "vue3-lottie": "^2.7.0",
+        "wavesurfer.js": "^7.0.0-beta.11"
       },
       "devDependencies": {
         "@babel/core": "^7.21.4",
@@ -2852,9 +2855,9 @@
       }
     },
     "node_modules/@vant/use": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.5.1.tgz",
-      "integrity": "sha512-Zxd7lDz/LliVYEQi3PR9a8CQa/kGCVzF0u9hqDMaTlgXlbG0wHMFPllrcG0ThR6bfs8xrYVuSFM9pJn6HSoUGQ==",
+      "version": "1.5.2",
+      "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.5.2.tgz",
+      "integrity": "sha512-CBK61iT568dCHUwFFsErGbW6/5tmrPnZJKGtcSy7Tjcrmws8Ku+YZo7IUFD9Xkj9MfSJ4pfhQ7pU2KouP5Cojg==",
       "peerDependencies": {
         "vue": "^3.0.0"
       }
@@ -3766,6 +3769,12 @@
         "is-what": "^3.14.1"
       }
     },
+    "node_modules/core-js": {
+      "version": "3.31.0",
+      "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.31.0.tgz",
+      "integrity": "sha512-NIp2TQSGfR6ba5aalZD+ZQ1fSxGhDo/s1w0nx3RYzf2pnJxt7YynxFlFScP6eV7+GZsKO95NSjGxyJsU3DZgeQ==",
+      "hasInstallScript": true
+    },
     "node_modules/core-js-compat": {
       "version": "3.30.1",
       "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.30.1.tgz",
@@ -3828,6 +3837,11 @@
       "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz",
       "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
     },
+    "node_modules/custom-event-polyfill": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz",
+      "integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w=="
+    },
     "node_modules/date-fns": {
       "version": "2.30.0",
       "resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-2.30.0.tgz",
@@ -3877,6 +3891,14 @@
         }
       }
     },
+    "node_modules/decode-uri-component": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.4.1.tgz",
+      "integrity": "sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==",
+      "engines": {
+        "node": ">=14.16"
+      }
+    },
     "node_modules/deep-is": {
       "version": "0.1.4",
       "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz",
@@ -4614,6 +4636,14 @@
         "node": ">=8"
       }
     },
+    "node_modules/filter-obj": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/filter-obj/-/filter-obj-5.1.0.tgz",
+      "integrity": "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==",
+      "engines": {
+        "node": ">=14.16"
+      }
+    },
     "node_modules/find-up": {
       "version": "5.0.0",
       "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz",
@@ -5823,6 +5853,11 @@
         "node": ">=8"
       }
     },
+    "node_modules/loadjs": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/loadjs/-/loadjs-4.2.0.tgz",
+      "integrity": "sha512-AgQGZisAlTPbTEzrHPb6q+NYBMD+DP9uvGSIjSUM5uG+0jG15cb8axWpxuOIqrmQjn6scaaH8JwloiP27b2KXA=="
+    },
     "node_modules/local-pkg": {
       "version": "0.4.3",
       "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz",
@@ -6939,6 +6974,18 @@
         "node": "^12.17.0 || ^14.13 || >=16.0.0"
       }
     },
+    "node_modules/plyr": {
+      "version": "3.7.8",
+      "resolved": "https://registry.npmmirror.com/plyr/-/plyr-3.7.8.tgz",
+      "integrity": "sha512-yG/EHDobwbB/uP+4Bm6eUpJ93f8xxHjjk2dYcD1Oqpe1EcuQl5tzzw9Oq+uVAzd2lkM11qZfydSiyIpiB8pgdA==",
+      "dependencies": {
+        "core-js": "^3.26.1",
+        "custom-event-polyfill": "^1.0.7",
+        "loadjs": "^4.2.0",
+        "rangetouch": "^2.0.1",
+        "url-polyfill": "^1.1.12"
+      }
+    },
     "node_modules/postcss": {
       "version": "8.4.23",
       "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.23.tgz",
@@ -7053,12 +7100,30 @@
         "node": ">=0.6"
       }
     },
+    "node_modules/query-string": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmmirror.com/query-string/-/query-string-8.1.0.tgz",
+      "integrity": "sha512-BFQeWxJOZxZGix7y+SByG3F36dA0AbTy9o6pSmKFcFz7DAj0re9Frkty3saBn3nHo3D0oZJ/+rx3r8H8r8Jbpw==",
+      "dependencies": {
+        "decode-uri-component": "^0.4.1",
+        "filter-obj": "^5.1.0",
+        "split-on-first": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=14.16"
+      }
+    },
     "node_modules/queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
       "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
       "dev": true
     },
+    "node_modules/rangetouch": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/rangetouch/-/rangetouch-2.0.1.tgz",
+      "integrity": "sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA=="
+    },
     "node_modules/readable-stream": {
       "version": "3.6.2",
       "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -7448,6 +7513,14 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/split-on-first": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/split-on-first/-/split-on-first-3.0.0.tgz",
+      "integrity": "sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/stdin-discarder": {
       "version": "0.1.0",
       "resolved": "https://registry.npmmirror.com/stdin-discarder/-/stdin-discarder-0.1.0.tgz",
@@ -7902,6 +7975,11 @@
         "punycode": "^2.1.0"
       }
     },
+    "node_modules/url-polyfill": {
+      "version": "1.1.12",
+      "resolved": "https://registry.npmmirror.com/url-polyfill/-/url-polyfill-1.1.12.tgz",
+      "integrity": "sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A=="
+    },
     "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -8264,6 +8342,11 @@
         "vue": "^3.0.11"
       }
     },
+    "node_modules/wavesurfer.js": {
+      "version": "7.0.0-beta.11",
+      "resolved": "https://registry.npmmirror.com/wavesurfer.js/-/wavesurfer.js-7.0.0-beta.11.tgz",
+      "integrity": "sha512-PwcnEIcV3x8Zi0XMWFkzRy0NsJyTaFITIXByoQn/y6OqtJn9W5jzryTvt/mxv+FcKAWA7yGqkxRGX336D0iWTQ=="
+    },
     "node_modules/wcwidth": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz",
@@ -10521,9 +10604,9 @@
       }
     },
     "@vant/use": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.5.1.tgz",
-      "integrity": "sha512-Zxd7lDz/LliVYEQi3PR9a8CQa/kGCVzF0u9hqDMaTlgXlbG0wHMFPllrcG0ThR6bfs8xrYVuSFM9pJn6HSoUGQ=="
+      "version": "1.5.2",
+      "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.5.2.tgz",
+      "integrity": "sha512-CBK61iT568dCHUwFFsErGbW6/5tmrPnZJKGtcSy7Tjcrmws8Ku+YZo7IUFD9Xkj9MfSJ4pfhQ7pU2KouP5Cojg=="
     },
     "@vitejs/plugin-vue": {
       "version": "4.1.0",
@@ -11283,6 +11366,11 @@
         "is-what": "^3.14.1"
       }
     },
+    "core-js": {
+      "version": "3.31.0",
+      "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.31.0.tgz",
+      "integrity": "sha512-NIp2TQSGfR6ba5aalZD+ZQ1fSxGhDo/s1w0nx3RYzf2pnJxt7YynxFlFScP6eV7+GZsKO95NSjGxyJsU3DZgeQ=="
+    },
     "core-js-compat": {
       "version": "3.30.1",
       "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.30.1.tgz",
@@ -11338,6 +11426,11 @@
       "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz",
       "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
     },
+    "custom-event-polyfill": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz",
+      "integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w=="
+    },
     "date-fns": {
       "version": "2.30.0",
       "resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-2.30.0.tgz",
@@ -11373,6 +11466,11 @@
         "ms": "2.1.2"
       }
     },
+    "decode-uri-component": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.4.1.tgz",
+      "integrity": "sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ=="
+    },
     "deep-is": {
       "version": "0.1.4",
       "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz",
@@ -11967,6 +12065,11 @@
         "to-regex-range": "^5.0.1"
       }
     },
+    "filter-obj": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/filter-obj/-/filter-obj-5.1.0.tgz",
+      "integrity": "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng=="
+    },
     "find-up": {
       "version": "5.0.0",
       "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz",
@@ -12890,6 +12993,11 @@
         }
       }
     },
+    "loadjs": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/loadjs/-/loadjs-4.2.0.tgz",
+      "integrity": "sha512-AgQGZisAlTPbTEzrHPb6q+NYBMD+DP9uvGSIjSUM5uG+0jG15cb8axWpxuOIqrmQjn6scaaH8JwloiP27b2KXA=="
+    },
     "local-pkg": {
       "version": "0.4.3",
       "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz",
@@ -13774,6 +13882,18 @@
         }
       }
     },
+    "plyr": {
+      "version": "3.7.8",
+      "resolved": "https://registry.npmmirror.com/plyr/-/plyr-3.7.8.tgz",
+      "integrity": "sha512-yG/EHDobwbB/uP+4Bm6eUpJ93f8xxHjjk2dYcD1Oqpe1EcuQl5tzzw9Oq+uVAzd2lkM11qZfydSiyIpiB8pgdA==",
+      "requires": {
+        "core-js": "^3.26.1",
+        "custom-event-polyfill": "^1.0.7",
+        "loadjs": "^4.2.0",
+        "rangetouch": "^2.0.1",
+        "url-polyfill": "^1.1.12"
+      }
+    },
     "postcss": {
       "version": "8.4.23",
       "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.23.tgz",
@@ -13864,12 +13984,27 @@
         "side-channel": "^1.0.4"
       }
     },
+    "query-string": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmmirror.com/query-string/-/query-string-8.1.0.tgz",
+      "integrity": "sha512-BFQeWxJOZxZGix7y+SByG3F36dA0AbTy9o6pSmKFcFz7DAj0re9Frkty3saBn3nHo3D0oZJ/+rx3r8H8r8Jbpw==",
+      "requires": {
+        "decode-uri-component": "^0.4.1",
+        "filter-obj": "^5.1.0",
+        "split-on-first": "^3.0.0"
+      }
+    },
     "queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
       "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
       "dev": true
     },
+    "rangetouch": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/rangetouch/-/rangetouch-2.0.1.tgz",
+      "integrity": "sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA=="
+    },
     "readable-stream": {
       "version": "3.6.2",
       "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -14185,6 +14320,11 @@
       "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz",
       "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
     },
+    "split-on-first": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/split-on-first/-/split-on-first-3.0.0.tgz",
+      "integrity": "sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA=="
+    },
     "stdin-discarder": {
       "version": "0.1.0",
       "resolved": "https://registry.npmmirror.com/stdin-discarder/-/stdin-discarder-0.1.0.tgz",
@@ -14535,6 +14675,11 @@
         "punycode": "^2.1.0"
       }
     },
+    "url-polyfill": {
+      "version": "1.1.12",
+      "resolved": "https://registry.npmmirror.com/url-polyfill/-/url-polyfill-1.1.12.tgz",
+      "integrity": "sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A=="
+    },
     "util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -14774,6 +14919,11 @@
         "vooks": "^0.2.4"
       }
     },
+    "wavesurfer.js": {
+      "version": "7.0.0-beta.11",
+      "resolved": "https://registry.npmmirror.com/wavesurfer.js/-/wavesurfer.js-7.0.0-beta.11.tgz",
+      "integrity": "sha512-PwcnEIcV3x8Zi0XMWFkzRy0NsJyTaFITIXByoQn/y6OqtJn9W5jzryTvt/mxv+FcKAWA7yGqkxRGX336D0iWTQ=="
+    },
     "wcwidth": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz",

+ 14 - 0
src/common/images/icon_search.svg

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>切片</title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.399879092" stroke-linejoin="round">
+        <g id="67、小酷AI" transform="translate(-1507.000000, -138.000000)" stroke="#2089FF" stroke-width="1.81438256">
+            <g id="编组-17" transform="translate(1495.000000, 126.000000)">
+                <g id="搜索" transform="translate(12.000000, 12.000000)">
+                    <path d="M7.53172346,13.9386396 C11.0702243,13.9386396 13.9384469,11.0703739 13.9384469,7.53181981 C13.9384469,3.99444998 11.0702243,1.125 7.53172346,1.125 C3.99440683,1.125 1.125,3.99444998 1.125,7.53181981 C1.125,11.0703739 3.99440683,13.9386396 7.53172346,13.9386396 Z" id="Stroke-1"></path>
+                    <line x1="12.138051" y1="12.1379798" x2="16.5200841" y2="16.5203156" id="Stroke-3" stroke-linecap="round"></line>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 7 - 0
src/components/TheSearch/index.module.less

@@ -0,0 +1,7 @@
+.TheSearch{
+ :global{
+    .n-input-wrapper{
+        padding-right: 4Px;
+    }
+ }   
+}

+ 40 - 0
src/components/TheSearch/index.tsx

@@ -0,0 +1,40 @@
+import { PropType, defineComponent, reactive } from 'vue';
+import styles from './index.module.less';
+import { InputProps, NButton, NIcon, NImage, NInput } from 'naive-ui';
+import icon_search from '/src/common/images/icon_search.svg';
+
+export default defineComponent({
+  name: 'TheSearch',
+  props: {
+    /** 圆角 */
+    round: {
+      type: Boolean as PropType<InputProps['round']>,
+      default: false
+    }
+  },
+  emits: ['search'],
+  setup(props, { emit }) {
+    const searchData = reactive({
+      value: ''
+    });
+    return () => (
+      <NInput
+        class={styles.TheSearch}
+        round={props.round}
+        v-model={searchData.value}>
+        {{
+          prefix: () => <img src={icon_search} />,
+          suffix: () => (
+            <NButton
+              size="small"
+              round
+              type="primary"
+              onClick={() => emit('search', searchData.value)}>
+              搜索
+            </NButton>
+          )
+        }}
+      </NInput>
+    );
+  }
+});

+ 6 - 5
src/components/layout/index.module.less

@@ -1,13 +1,14 @@
 .wrap {
-  width: 100%;
+  width: 100vw;
+  height: 100vh;
   display: flex;
   flex-direction: row;
   background: #f1f5ff;
+  overflow: hidden;
   .WrapcoreView {
-    margin: 32px;
-    background-color: #fff;
-    border-radius: 20px;
-    overflow: hidden;
+    padding: 32px;
+    height: calc(100vh - 64px);
+    overflow-y: auto;
   }
 }
 .silder {

+ 1 - 3
src/components/layout/index.tsx

@@ -2,8 +2,6 @@ import { Transition, defineComponent } from 'vue';
 import LayoutSilder from './layoutSilder';
 import LayoutTop from './layoutTop';
 import styles from './index.module.less';
-import { NScrollbar } from 'naive-ui';
-import { RouterView } from 'vue-router';
 export default defineComponent({
   name: 'layoutView',
   setup() {
@@ -19,7 +17,7 @@ export default defineComponent({
               <div class={styles.WrapcoreView}>
                 <router-view>
                   {(obj: any) => (
-                    <Transition name="fade-slide">
+                    <Transition name="fade-slide" mode="out-in">
                       <obj.Component />
                     </Transition>
                   )}

+ 2 - 1
src/components/layout/layoutSilder.tsx

@@ -60,7 +60,8 @@ export default defineComponent({
         name: '小酷AI',
         normalIcon: kuNormal,
         isActive: false,
-        id: 5
+        id: 5,
+        path: '/xiaoku-ai'
       },
       {
         activeIcon: resourceIcon,

+ 0 - 1
src/components/layout/layoutTop.tsx

@@ -52,7 +52,6 @@ export default defineComponent({
                       }>
                       <svg
                         xmlns="http://www.w3.org/2000/svg"
-                        xmlns:xlink="http://www.w3.org/1999/xlink"
                         viewBox="0 0 24 24">
                         <path
                           d="M7.38 21.01c.49.49 1.28.49 1.77 0l8.31-8.31a.996.996 0 0 0 0-1.41L9.15 2.98c-.49-.49-1.28-.49-1.77 0s-.49 1.28 0 1.77L14.62 12l-7.25 7.25c-.48.48-.48 1.28.01 1.76z"

+ 1 - 1
src/components/layout/modals/silderItem.tsx

@@ -1,4 +1,4 @@
-import { defineComponent, reactive, ref, watch } from 'vue';
+import { defineComponent, ref, watch } from 'vue';
 import styles from '../index.module.less';
 import { NImage } from 'naive-ui';
 import radiusIcon from '../images/radiusIcon.png';

+ 1 - 1
src/enums/pageEnum.ts

@@ -3,7 +3,7 @@ export enum PageEnum {
   BASE_LOGIN = '/login',
   BASE_LOGIN_NAME = 'Login',
   //重定向
-  // REDIRECT = '/redirect',
+  REDIRECT = '/redirect',
   // REDIRECT_NAME = 'Redirect',
   // 首页
   BASE_HOME = '/home'

+ 0 - 3
src/hooks/index.ts

@@ -1,3 +0,0 @@
-import { useAsync } from './use-async';
-
-export { useAsync };

+ 0 - 34
src/hooks/setting/index.ts

@@ -1,34 +0,0 @@
-// import type { GlobConfig } from '/#/config';
-
-import { warn } from '@/utils/log';
-import { getAppEnvConfig } from '@/utils/env';
-
-export const useGlobSetting = (): Readonly<any> => {
-  const {
-    VITE_GLOB_APP_TITLE,
-    VITE_GLOB_API_URL,
-    VITE_GLOB_APP_SHORT_NAME,
-    VITE_GLOB_API_URL_PREFIX,
-    VITE_GLOB_UPLOAD_URL,
-    VITE_GLOB_PROD_MOCK,
-    VITE_GLOB_IMG_URL,
-  } = getAppEnvConfig();
-
-  if (!/[a-zA-Z\_]*/.test(VITE_GLOB_APP_SHORT_NAME)) {
-    warn(
-      `VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.`
-    );
-  }
-
-  // Take global configuration
-  const glob: Readonly<any> = {
-    title: VITE_GLOB_APP_TITLE,
-    apiUrl: VITE_GLOB_API_URL,
-    shortName: VITE_GLOB_APP_SHORT_NAME,
-    urlPrefix: VITE_GLOB_API_URL_PREFIX,
-    uploadUrl: VITE_GLOB_UPLOAD_URL,
-    prodMock: VITE_GLOB_PROD_MOCK,
-    imgUrl: VITE_GLOB_IMG_URL,
-  };
-  return glob as Readonly<any>;
-};

+ 1 - 1
src/hooks/setting/useDesignSetting.ts

@@ -13,6 +13,6 @@ export function useDesignSetting() {
   return {
     getDarkTheme,
     getAppTheme,
-    getAppThemeList,
+    getAppThemeList
   };
 }

+ 0 - 42
src/hooks/setting/useProjectSetting.ts

@@ -1,42 +0,0 @@
-import { computed } from 'vue';
-import { useProjectSettingStore } from '@/store/modules/projectSetting';
-
-export function useProjectSetting() {
-  const projectStore = useProjectSettingStore();
-
-  const getNavMode = computed(() => projectStore.navMode);
-
-  const getNavTheme = computed(() => projectStore.navTheme);
-
-  const getIsMobile = computed(() => projectStore.isMobile);
-
-  const getHeaderSetting = computed(() => projectStore.headerSetting);
-
-  const getMultiTabsSetting = computed(() => projectStore.multiTabsSetting);
-
-  const getMenuSetting = computed(() => projectStore.menuSetting);
-
-  const getCrumbsSetting = computed(() => projectStore.crumbsSetting);
-
-  const getPermissionMode = computed(() => projectStore.permissionMode);
-
-  const getShowFooter = computed(() => projectStore.showFooter);
-
-  const getIsPageAnimate = computed(() => projectStore.isPageAnimate);
-
-  const getPageAnimateType = computed(() => projectStore.pageAnimateType);
-
-  return {
-    getNavMode,
-    getNavTheme,
-    getIsMobile,
-    getHeaderSetting,
-    getMultiTabsSetting,
-    getMenuSetting,
-    getCrumbsSetting,
-    getPermissionMode,
-    getShowFooter,
-    getIsPageAnimate,
-    getPageAnimateType,
-  };
-}

+ 42 - 35
src/hooks/web/usePage.ts

@@ -1,63 +1,70 @@
-import type { RouteLocationRaw, Router } from 'vue-router'
+import type { RouteLocationRaw, Router } from 'vue-router';
 
-import { PageEnum } from '@/enums/pageEnum'
-import { RedirectName } from '@/router/constant'
+import { PageEnum } from '@/enums/pageEnum';
+// import { RedirectName } from '@/router/constant'
 
-import { useRouter } from 'vue-router'
-import { isString } from '@/utils/is'
-import { unref } from 'vue'
+import { useRouter } from 'vue-router';
+import { isString } from '@/utils/is';
+import { unref } from 'vue';
 
-export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEnum }
+export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & {
+  path: PageEnum;
+};
 
 function handleError(e: Error) {
-  console.error(e)
+  console.error(e);
 }
 
 /**
  * 页面切换
  */
 export function useGo(_router?: Router) {
-  let router
+  let router;
   if (!_router) {
-    router = useRouter()
+    router = useRouter();
   }
-  const { push, replace }: any = _router || router
+  const { push, replace }: any = _router || router;
 
-  function go(opt: PageEnum | RouteLocationRawEx | string = PageEnum.BASE_HOME, isReplace = false) {
+  function go(
+    opt: PageEnum | RouteLocationRawEx | string = PageEnum.BASE_HOME,
+    isReplace = false
+  ) {
     if (!opt) {
-      return
+      return;
     }
     if (isString(opt)) {
-      isReplace ? replace(opt).catch(handleError) : push(opt).catch(handleError)
+      isReplace
+        ? replace(opt).catch(handleError)
+        : push(opt).catch(handleError);
     } else {
-      const o = opt as RouteLocationRaw
-      isReplace ? replace(o).catch(handleError) : push(o).catch(handleError)
+      const o = opt as RouteLocationRaw;
+      isReplace ? replace(o).catch(handleError) : push(o).catch(handleError);
     }
   }
-  return go
+  return go;
 }
 
 /**
  * 重做当前页面
  */
 export const useRedo = (_router?: Router) => {
-  const { push, currentRoute } = _router || useRouter()
-  const { query, params = {}, name, fullPath } = unref(currentRoute.value)
+  const { push, currentRoute } = _router || useRouter();
+  const { query, params = {}, name, fullPath } = unref(currentRoute.value);
   function redo(): Promise<boolean> {
-    return new Promise((resolve) => {
-      if (name === RedirectName) {
-        resolve(false)
-        return
-      }
-      if (name && Object.keys(params).length > 0) {
-        params['_redirect_type'] = 'name'
-        params['path'] = String(name)
-      } else {
-        params['_redirect_type'] = 'path'
-        params['path'] = fullPath
-      }
-      push({ name: RedirectName, params, query }).then(() => resolve(true))
-    })
+    return new Promise(resolve => {
+      // if (name === RedirectName) {
+      //   resolve(false)
+      //   return
+      // }
+      // if (name && Object.keys(params).length > 0) {
+      //   params['_redirect_type'] = 'name'
+      //   params['path'] = String(name)
+      // } else {
+      //   params['_redirect_type'] = 'path'
+      //   params['path'] = fullPath
+      // }
+      // push({ name: RedirectName, params, query }).then(() => resolve(true))
+    });
   }
-  return redo
-}
+  return redo;
+};

+ 23 - 16
src/hooks/web/usePermission.ts

@@ -1,17 +1,18 @@
-import { useUserStore } from '@/store/modules/user';
+// import { useUserStore } from '@/store/modules/user';
 
 export function usePermission() {
-  const userStore = useUserStore();
+  // const userStore = useUserStore();
 
   /**
    * 检查权限
    * @param accesses
    */
   function _somePermissions(accesses: string[]) {
-    return userStore.getPermissions.some((item) => {
-      const { value }: any = item;
-      return accesses.includes(value);
-    });
+    // return userStore.getPermissions.some((item: any) => {
+    //   const { value }: any = item;
+    //   return accesses.includes(value);
+    // });
+    return false;
   }
 
   /**
@@ -28,11 +29,14 @@ export function usePermission() {
    * @param accesses
    */
   function hasEveryPermission(accesses: string[]): boolean {
-    const permissionsList = userStore.getPermissions;
-    if (Array.isArray(accesses)) {
-      return permissionsList.every((access: any) => accesses.includes(access.value));
-    }
-    throw new Error(`[hasEveryPermission]: ${accesses} should be a array !`);
+    // const permissionsList = userStore.getPermissions;
+    // if (Array.isArray(accesses)) {
+    //   return permissionsList.every((access: any) =>
+    //     accesses.includes(access.value)
+    //   );
+    // }
+    return false;
+    // throw new Error(`[hasEveryPermission]: ${accesses} should be a array !`);
   }
 
   /**
@@ -41,11 +45,14 @@ export function usePermission() {
    * @param accessMap
    */
   function hasSomePermission(accesses: string[]): boolean {
-    const permissionsList = userStore.getPermissions;
-    if (Array.isArray(accesses)) {
-      return permissionsList.some((access: any) => accesses.includes(access.value));
-    }
-    throw new Error(`[hasSomePermission]: ${accesses} should be a array !`);
+    // const permissionsList = userStore.getPermissions;
+    // if (Array.isArray(accesses)) {
+    //   return permissionsList.some((access: any) =>
+    //     accesses.includes(access.value)
+    //   );
+    // }
+    return false;
+    // throw new Error(`[hasSomePermission]: ${accesses} should be a array !`);
   }
 
   return { hasPermission, hasEveryPermission, hasSomePermission };

+ 1 - 1
src/main.ts

@@ -1,5 +1,5 @@
 import { createApp } from 'vue';
-import App from './App.tsx';
+import App from './App';
 import router from './router/index';
 import dayjs from 'dayjs';
 import { setupNaive } from './plugins';

+ 19 - 1
src/router/routes/index.ts

@@ -1,4 +1,6 @@
-export const constantRoutes: any[] = [
+import { RouteRecordRaw } from 'vue-router';
+
+export const constantRoutes: RouteRecordRaw[] = [
   {
     name: 'login',
     path: '/login',
@@ -36,6 +38,22 @@ export const constantRoutes: any[] = [
           title: '学生列表',
           singleLayout: 'blank'
         }
+      },
+      {
+        path: '/xiaoku-ai',
+        name: 'xiaoku-ai',
+        component: () => import('@/views/xiaoku-ai/index'),
+        meta: {
+          title: '小酷AI'
+        }
+      },
+      {
+        path: '/xiaoku-music',
+        name: 'xiaoku-music',
+        component: () => import('@/views/xiaoku-music/index'),
+        meta: {
+          title: '曲谱库'
+        }
       }
     ]
   },

+ 8 - 8
src/styles/index.less

@@ -53,24 +53,24 @@ body {
 }
 
 ::-webkit-scrollbar {
-  width: 8px;
-  height: 12px;
+  width: 8Px;
+  height: 12Px;
   background-color: #fff;
 }
 
 ::-webkit-scrollbar-thumb {
   display: block;
-  min-height: 12px;
-  min-width: 8px;
-  border-radius: 6px;
+  min-height: 12Px;
+  min-width: 8Px;
+  border-radius: 6Px;
   background-color: rgb(217, 217, 217);
 }
 
 ::-webkit-scrollbar-thumb:hover {
   display: block;
-  min-height: 12px;
-  min-width: 8px;
-  border-radius: 6px;
+  min-height: 12Px;
+  min-width: 8Px;
+  border-radius: 6Px;
   background-color: rgb(159, 159, 159);
 }
 

+ 86 - 42
src/views/attend-class/component/audio-pay.tsx

@@ -1,8 +1,9 @@
-import { defineComponent, onMounted, toRefs } from 'vue';
+import { defineComponent, onMounted, toRefs, reactive } from 'vue';
 import styles from './audio.module.less';
 import WaveSurfer from 'wavesurfer.js';
 import iconplay from '../image/icon-pause.svg';
 import iconpause from '../image/icon-play.svg';
+import { NSlider } from 'naive-ui';
 
 export default defineComponent({
   name: 'audio-play',
@@ -19,14 +20,21 @@ export default defineComponent({
     }
   },
   setup(props) {
-    const { item, isEmtry } = toRefs(props);
+    const { item } = toRefs(props);
     const audioId = 'a' + +Date.now() + Math.floor(Math.random() * 100);
+    const audioForms = reactive({
+      paused: true,
+      currentTimeNum: 0,
+      currentTime: '00:00',
+      duration: '00:00'
+    });
+    const audioDom = new Audio();
+    audioDom.controls = true;
+    audioDom.style.width = '100%';
+    audioDom.className = styles.audio;
+    document.querySelector(`#${audioId}`)?.appendChild(audioDom);
+
     onMounted(() => {
-      const audio = new Audio();
-      audio.controls = true;
-      audio.style.width = '100%';
-      audio.className = styles.audio;
-      document.querySelector(`#${audioId}`)?.appendChild(audio);
       const wavesurfer = WaveSurfer.create({
         container: document.querySelector(`#${audioId}`) as HTMLElement,
         waveColor: '#C5C5C5',
@@ -45,66 +53,102 @@ export default defineComponent({
         /** If autoScroll is enabled, keep the cursor in the center of the waveform during playback */
         autoCenter: true,
         hideScrollbar: false,
-        media: audio
+        media: audioDom
       });
 
       wavesurfer.once('interaction', () => {
         // wavesurfer.play();
       });
+      wavesurfer.once('ready', () => {
+        audioForms.paused = audioDom.paused;
+        audioForms.duration = timeFormat(Math.round(audioDom.duration));
+      });
+
+      wavesurfer.on('finish', () => {
+        audioForms.paused = true;
+      });
+    });
+
+    // 切换音频播放
+    const onToggleAudio = (e: MouseEvent) => {
+      e.stopPropagation();
+      if (audioDom.paused) {
+        audioDom.play();
+      } else {
+        audioDom.pause();
+      }
+
+      audioForms.paused = audioDom.paused;
+    };
+
+    // 播放时监听
+    audioDom.addEventListener('timeupdate', () => {
+      audioForms.currentTime = timeFormat(Math.round(audioDom.currentTime));
+      audioForms.currentTimeNum = audioDom.currentTime;
     });
 
+    // 播放结束时
+
+    // 对时间进行格式化
+    const timeFormat = (num: number) => {
+      if (num > 0) {
+        const m = Math.floor(num / 60);
+        const s = num % 60;
+        return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
+      } else {
+        return '00:00';
+      }
+    };
+
     return () => (
       <div class={styles.audioWrap}>
         <div class={styles.audioContainer}>
-          <div id={audioId}></div>
+          <div
+            id={audioId}
+            onClick={(e: MouseEvent) => {
+              e.stopPropagation();
+            }}></div>
         </div>
 
-        <div class={styles.controls}></div>
-        {/* <div
-          class="plyr__controls bottomFixed ${styles.controls}">
-          <div class="${styles.actions}">
-            <div class="${styles.actionWrap}">
-              <button id="${playBtnId}" class="${styles.actionBtn}">
-                <div
-                  class="van-loading van-loading--circular"
-                  aria-live="polite"
-                  aria-busy="true">
-                  <span
-                    class="van-loading__spinner van-loading__spinner--circular"
-                    style="color: rgb(255, 255, 255);">
-                    <svg class="van-loading__circular" viewBox="25 25 50 50">
-                      <circle cx="50" cy="50" r="20" fill="none"></circle>
-                    </svg>
-                  </span>
-                </div>
-                <img class="${styles.playIcon}" src="${iconplay}" />
-                <img class="${styles.playIcon}" src="${iconpause}" />
+        <div
+          class={styles.controls}
+          onClick={(e: MouseEvent) => {
+            e.stopPropagation();
+          }}>
+          <div class={styles.actions}>
+            <div class={styles.actionWrap}>
+              <button class={styles.actionBtn} onClick={onToggleAudio}>
+                {audioForms.paused ? (
+                  <img class={styles.playIcon} src={iconplay} />
+                ) : (
+                  <img class={styles.playIcon} src={iconpause} />
+                )}
               </button>
             </div>
-            <div class="${styles.time}">
+            <div class={styles.time}>
               <div
                 class="plyr__time plyr__time--current"
                 aria-label="Current time">
-                00:00
+                {audioForms.currentTime}
               </div>
-              <span class="${styles.line}">/</span>
+              <span class={styles.line}>/</span>
               <div
                 class="plyr__time plyr__time--duration"
                 aria-label="Duration">
-                00:00
+                {audioForms.duration}
               </div>
             </div>
           </div>
-          <div class="${styles.slider}">
-            <div class="plyr__progress">
-              <input data-plyr="seek" type="range" min="0" max="100" step="0.01" value="0" aria-label="Seek">
-                        <progress class="plyr__progress__buffer" min="0" max="100" value="0">% buffered</progress>
-              <span role="tooltip" class="plyr__tooltip">
-                00:00
-              </span>
-            </div>
+
+          <div class={styles.slider}>
+            <NSlider
+              v-model:value={audioForms.currentTimeNum}
+              step={0.01}
+              max={audioDom.duration}
+              tooltip={false}
+            />
           </div>
-        </div> */}
+        </div>
       </div>
     );
   }

+ 65 - 0
src/views/attend-class/component/audio.module.less

@@ -34,4 +34,69 @@
   height: 150px;
   padding: 0 260px 0 200px !important;
   transition: all 0.5s;
+  display: flex;
+  align-items: center;
+
+  .time {
+    display: flex;
+    justify-content: space-between;
+    color: #fff;
+    // font-size: 10px;
+    padding: 4px 0 4px 20px;
+    font-size: 24px;
+    font-weight: 600;
+    line-height: 33px;
+
+    .line {
+      font-size: 12px;
+    }
+
+    :global {
+      .plyr__time+.plyr__time:before {
+        content: '';
+        margin-right: 0;
+      }
+    }
+  }
+}
+
+.actions {
+  display: flex;
+  justify-content: space-between;
+  // width: 100%;
+  height: 100%;
+  color: #fff;
+  font-size: 12px;
+  padding: 0 0 0 20px;
+  align-items: center;
+
+  .actionWrap {
+    display: flex;
+  }
+
+  .actionBtn {
+    display: flex;
+    width: 82px;
+    height: 82px;
+    padding: 4px 0;
+    background: transparent;
+  }
+
+  .actionBtn>img {
+    width: 100%;
+    height: 100%;
+  }
 }
+
+.slider {
+  width: 100%;
+  padding: 0 20px 0 12px;
+
+  :global {
+
+    .n-slider .n-slider-rail .n-slider-rail__fill,
+    .n-slider .n-slider-handles .n-slider-handle-wrapper {
+      transition: all .2s;
+    }
+  }
+}

+ 0 - 110
src/views/attend-class/component/point.module.less

@@ -1,110 +0,0 @@
-.container {
-  display: flex;
-  flex-direction: column;
-  min-width: 288px;
-  max-width: 288px;
-  height: 100vh;
-  color: #333;
-  font-size: 12px;
-  box-sizing: border-box;
-  background:#fff;
-}
-.pointHead {
-  display: flex;
-  align-items: center;
-  padding: 13px 10px 15px 15px;
-  flex-shrink: 0;
-  font-size: 14px;
-  img {
-    width: 16px;
-    height: 16px;
-    margin-right: 7px;
-  }
-}
-.content {
-  flex: 1;
-  overflow-y: auto;
-  padding: 0 20px;
-}
-.collapse {
-  &.childActive {
-    :global {
-      .van-cell {
-        color: #fff;
-      }
-    }
-    .arrow {
-      opacity: 1;
-    }
-  }
-  &:after {
-    display: none;
-    border-width: 0;
-  }
-
-  .borderTop {
-    border-top: 1px solid rgba(255, 255, 255, 0.2);
-  }
-  :global {
-    .van-cell {
-      background: transparent;
-      font-size: 14px;
-      color: rgba(255, 255, 255, 0.5);
-      padding: 6px 0;
-    }
-    .van-cell__title {
-      font-weight: 600;
-    }
-    .van-collapse-item__title--expanded {
-      color: #fff;
-    }
-    .van-collapse-item--border:after {
-      display: none;
-    }
-    .van-collapse-item__content {
-      background: transparent;
-      color: #fff;
-      font-size: 10px;
-      padding: 0 0 6px;
-    }
-  }
-  .arrow {
-    display: block;
-    width: 10px;
-    height: 10px;
-    margin-right: 6px;
-    transition: all 0.3s;
-    opacity: 0.5;
-  }
-}
-.item {
-  display: flex;
-  align-items: center;
-  justify-content: flex-start;
-  padding: 6px 11px;
-  border-radius: 6px;
-  font-size: 12px;
-  :global {
-    .van-icon {
-      display: none;
-    }
-    .van-image {
-      margin-right: 6px;
-      margin-top: -1px;
-      width: 15px;
-      height: 16px;
-    }
-  }
-}
-.name{
-  flex: 1;
-}
-.itemActive {
-  background: #E0E0E0;
-  color: var(--van-primary);
-  :global {
-    .van-icon {
-      display: block;
-    }
-  }
-}

+ 0 - 102
src/views/attend-class/component/points.tsx

@@ -1,102 +0,0 @@
-import { defineComponent, reactive, watch } from 'vue';
-import styles from './point.module.less';
-import iconMulv from '../image/icon-mulv.svg';
-import iconArrow from '../image/icon-arrow.svg';
-import iconZhibo from '../image/icon-load.gif';
-import iconImage from '../image/icon-image.svg';
-import iconImageActive from '../image/icon-image-active.svg';
-import iconVideo from '../image/icon-video.svg';
-import iconVideoActive from '../image/icon-video-active.svg';
-import iconSong from '../image/icon-song.svg';
-import iconSongActive from '../image/icon-song-active.svg';
-import { Collapse, Icon, Image } from 'vant';
-export default defineComponent({
-  name: 'points',
-  props: {
-    data: {
-      type: Array,
-      default: () => []
-    },
-    tabActive: {
-      type: String,
-      default: ''
-    },
-    itemActive: {
-      type: String,
-      default: ''
-    }
-  },
-  emits: ['handleSelect'],
-  setup(props, { emit }) {
-    const pointData = reactive({
-      active: props.tabActive[0] || '',
-      childActive: props.tabActive[1] || ''
-    });
-    watch(
-      () => props.tabActive,
-      () => {
-        pointData.active = props.tabActive[0] || '';
-        pointData.childActive = props.tabActive[1] || '';
-      }
-    );
-
-    console.log(
-      pointData.active,
-      'pointData.active',
-      props.data,
-      props.tabActive
-    );
-
-    // 获取对应图片
-    const getImage = (item: any) => {
-      if (item.type === 'VIDEO') {
-        return props.itemActive == item.id ? iconVideoActive : iconVideo;
-      } else if (['IMAGE', 'IMG'].includes(item.type)) {
-        return props.itemActive == item.id ? iconImageActive : iconImage;
-      } else if (item.type === 'SONG') {
-        return props.itemActive == item.id ? iconSongActive : iconSong;
-      } else {
-        return props.itemActive == item.id ? iconVideoActive : iconVideo;
-      }
-    };
-    return () => (
-      <div class={styles.container}>
-        <div class={styles.pointHead}>
-          <img src={iconMulv} />
-          课件列表
-        </div>
-        <div class={styles.content}>
-          <Collapse
-            class={styles.collapse}
-            modelValue={pointData.active}
-            onUpdate:modelValue={(val: any) => {
-              pointData.active = val;
-            }}
-            accordion>
-            {props.data.map((item: any, index: number) => {
-              return (
-                <div
-                  class={[
-                    styles.item,
-                    props.itemActive == item.id ? styles.itemActive : ''
-                  ]}
-                  onClick={() => {
-                    emit('handleSelect', {
-                      itemActive: item.id,
-                      tabName: item.name
-                    });
-                  }}>
-                  <Image src={getImage(item)} class={styles.itemImage} />
-                  <span class={["van-ellipsis", styles.name]}>
-                    {item.name}
-                  </span>
-                  <Icon name={iconZhibo} />
-                </div>
-              );
-            })}
-          </Collapse>
-        </div>
-      </div>
-    );
-  }
-});

+ 3 - 3
src/views/attend-class/component/tool.tsx

@@ -1,4 +1,4 @@
-import { Grid, GridItem } from 'vant';
+// import { Grid, GridItem } from 'vant';
 import { defineComponent } from 'vue';
 import styles from './tool.module.less';
 import iconPen from '../image/icon-pen.png';
@@ -25,14 +25,14 @@ export default defineComponent({
     return () => (
       <div class={styles.tool}>
         <div class={styles.title}>教学功能</div>
-        <Grid class={styles.grid} columnNum={3} border={false}>
+        {/* <Grid class={styles.grid} columnNum={3} border={false}>
           {tool.map(item => (
             <GridItem
               icon={item.icon}
               text={item.name}
               onClick={() => emit('handleTool', item)}></GridItem>
           ))}
-        </Grid>
+        </Grid> */}
       </div>
     );
   }

+ 1 - 1
src/views/attend-class/component/video.module.less

@@ -150,4 +150,4 @@
     }
 
   }
-}
+}

+ 63 - 0
src/views/attend-class/index.module.less

@@ -357,4 +357,67 @@
   pointer-events: none;
   transform: translateY(100%);
   transition: all .5s;
+}
+
+
+.attendClassModal {
+  width: 442px;
+  border-radius: 16px;
+  overflow: hidden;
+
+  :global {
+    .n-card-header {
+      position: relative;
+      padding: 20px 18px;
+      text-align: center;
+      // background: #F5F6FA;
+      font-size: 22px;
+      font-weight: 600;
+      color: #131415;
+      line-height: 30px;
+    }
+
+    .n-card-header__close {
+      position: absolute;
+      right: 18px;
+    }
+
+    .n-card__content {
+      padding: 0;
+    }
+
+    .n-base-select-menu .n-base-select-option {
+      font-size: 18px !important;
+    }
+  }
+
+  .modelAttendContent {
+    font-size: 18px;
+    color: #777777;
+    line-height: 30px;
+    text-align: center;
+  }
+
+  .modelAttendBtnGroup {
+    padding: 40px 0;
+    justify-content: center !important;
+
+    :global {
+      .n-button {
+        height: 48px !important;
+        min-width: 156px;
+
+      }
+    }
+  }
+}
+
+.trainClassModal {
+  width: 1028px;
+
+  :global {
+    .n-card-header {
+      background: #F5F6FA;
+    }
+  }
 }

+ 66 - 12
src/views/attend-class/index.tsx

@@ -27,11 +27,19 @@ import { Vue3Lottie } from 'vue3-lottie';
 import playLoadData from './datas/data.json';
 import { usePageVisibility } from '@vant/use';
 import VideoPlay from './component/video-play';
-import { useMessage, NDrawer, NDrawerContent } from 'naive-ui';
+import {
+  useMessage,
+  NDrawer,
+  NDrawerContent,
+  NModal,
+  NSpace,
+  NButton
+} from 'naive-ui';
 import CardType from '@/components/card-type';
 import { ToolItem, ToolType } from './component/tool';
 import Pen from './component/tools/pen';
 import AudioPay from './component/audio-pay';
+import TrainSettings from './model/train-settings';
 
 export default defineComponent({
   name: 'CoursewarePlay',
@@ -85,7 +93,9 @@ export default defineComponent({
       showHead: true,
       isCourse: false,
       isRecordPlay: false,
-      videoRefs: {} as any[]
+      videoRefs: {} as any[],
+      modelAttendStatus: false, // 布置作业提示弹窗
+      modelTrainStatus: false // 训练设置
     });
     const activeData = reactive({
       isAutoPlay: true, // 是否自动播放
@@ -118,15 +128,15 @@ export default defineComponent({
     // };
     const getDetail = async () => {
       data.knowledgePointList = [
-        {
-          id: '5',
-          name: '歌曲表演 大鹿',
-          title: '歌曲表演 大鹿',
-          type: 'AUDIO',
-          content:
-            'https://cloud-coach.ks3-cn-beijing.ksyuncs.com/1686819360752.mp3',
-          url: 'https://lanhu-dds-backend.oss-cn-beijing.aliyuncs.com/merge_image/imgs/23cc71b5d7874dcf8752cd257483e687_mergeImage.png'
-        },
+        // {
+        //   id: '5',
+        //   name: '歌曲表演 大鹿',
+        //   title: '歌曲表演 大鹿',
+        //   type: 'AUDIO',
+        //   content:
+        //     'https://cloud-coach.ks3-cn-beijing.ksyuncs.com/1686819360752.mp3',
+        //   url: 'https://lanhu-dds-backend.oss-cn-beijing.aliyuncs.com/merge_image/imgs/23cc71b5d7874dcf8752cd257483e687_mergeImage.png'
+        // },
         {
           id: '1',
           name: '歌曲表演 大鹿',
@@ -610,7 +620,9 @@ export default defineComponent({
           <div class={styles.menu}>{popupData.itemName}</div>
         </div> */}
         {/* 布置作业按钮 */}
-        <div class={styles.assignHomework}>
+        <div
+          class={styles.assignHomework}
+          onClick={() => (data.modelAttendStatus = true)}>
           <img src={iconAssignHomework} />
         </div>
 
@@ -664,6 +676,7 @@ export default defineComponent({
           </div>
         </div>
 
+        {/* 显示列表 */}
         <NDrawer
           v-model:show={popupData.open}
           class={styles.drawerContainer}
@@ -684,9 +697,50 @@ export default defineComponent({
           </NDrawerContent>
         </NDrawer>
 
+        {/* 批注 */}
         {studyData.penShow && (
           <Pen show={studyData.type === 'pen'} close={() => closeStudyTool()} />
         )}
+
+        {/* 布置作业 */}
+        <NModal
+          v-model:show={data.modelAttendStatus}
+          preset="card"
+          class={styles.attendClassModal}
+          title={'课后训练'}>
+          <div class={styles.modelAttendContent}>
+            本节课已设置课后训练,是否布置?
+          </div>
+          <NSpace class={styles.modelAttendBtnGroup}>
+            <NButton
+              type="default"
+              round
+              onClick={() => {
+                // window.close();
+                data.modelAttendStatus = false;
+              }}>
+              暂无布置
+            </NButton>
+            <NButton
+              type="primary"
+              round
+              onClick={() => {
+                data.modelTrainStatus = true;
+                data.modelAttendStatus = false;
+              }}>
+              布置
+            </NButton>
+          </NSpace>
+        </NModal>
+
+        {/* 训练设置 */}
+        <NModal
+          v-model:show={data.modelTrainStatus}
+          preset="card"
+          class={[styles.attendClassModal, styles.trainClassModal]}
+          title={'训练设置'}>
+          <TrainSettings onClose={() => (data.modelTrainStatus = false)} />
+        </NModal>
       </div>
     );
   }

+ 61 - 0
src/views/attend-class/model/train-settings/index.module.less

@@ -0,0 +1,61 @@
+.trainSettings {
+  .trainBtnGroup {
+    padding: 40px 0;
+    justify-content: center !important;
+
+    :global {
+      .n-button {
+        height: 48px !important;
+      }
+    }
+  }
+
+  .searchGroup {
+    display: flex;
+    padding: 26px 40px 0;
+
+    .datetime {
+      margin-left: 40px;
+      display: inline-flex;
+      align-items: center;
+
+      label {
+        font-size: 15px;
+        color: #666666;
+        line-height: 21px;
+      }
+    }
+
+    :global {
+      .n-button {
+        border-radius: 8px;
+        height: 42px;
+        font-size: 17px;
+        font-weight: 600 !important;
+        padding: 0 27px;
+      }
+
+      .n-button--default-type {
+        background: #E8F4FF;
+        color: #0378EC;
+
+        &:not(.n-button--disabled):hover {
+          background: #E8F4FF;
+        }
+
+        .n-button__border {
+          border: 1px solid #198CFE;
+        }
+      }
+
+      .n-input {
+        border-radius: 8px !important;
+      }
+    }
+  }
+
+  .trainList {
+    margin-top: 28px;
+    max-height: 50vh;
+  }
+}

+ 39 - 0
src/views/attend-class/model/train-settings/index.tsx

@@ -0,0 +1,39 @@
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+import { NButton, NDatePicker, NEmpty, NScrollbar, NSpace } from 'naive-ui';
+
+export default defineComponent({
+  name: 'train-settings',
+  emits: ['close'],
+  setup(props, { emit }) {
+    return () => (
+      <div class={styles.trainSettings}>
+        <div class={styles.searchGroup}>
+          <NButton>添加训练</NButton>
+
+          <div class={styles.datetime}>
+            <label>截止时间:</label>
+            <NDatePicker
+              style={{ width: '200px' }}
+              value-format="yyyy-MM-dd"
+              type="date"
+              clearable
+              placeholder="请选择截止日期"
+            />
+          </div>
+        </div>
+        <NScrollbar class={styles.trainList}>
+          <NEmpty description="暂无训练" />
+        </NScrollbar>
+        <NSpace class={styles.trainBtnGroup}>
+          <NButton type="default" round onClick={() => emit('close')}>
+            取消布置
+          </NButton>
+          <NButton type="primary" round>
+            立即布置
+          </NButton>
+        </NSpace>
+      </div>
+    );
+  }
+});

+ 1 - 4
src/views/home/index.tsx

@@ -89,10 +89,7 @@ export default defineComponent({
               <div class={styles.bannerBtn}>
                 立即处理{' '}
                 <NIcon class={styles.rotueRight}>
-                  <svg
-                    xmlns="http://www.w3.org/2000/svg"
-                    xmlns:xlink="http://www.w3.org/1999/xlink"
-                    viewBox="0 0 24 24">
+                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                     <path
                       d="M7.38 21.01c.49.49 1.28.49 1.77 0l8.31-8.31a.996.996 0 0 0 0-1.41L9.15 2.98c-.49-.49-1.28-.49-1.77 0s-.49 1.28 0 1.77L14.62 12l-7.25 7.25c-.48.48-.48 1.28.01 1.76z"
                       fill="currentColor"></path>

+ 3 - 3
src/views/prepare-lessons/index.module.less

@@ -1,8 +1,8 @@
 .prepareLessons {
   display: flex;
   // padding: 32px;
-  padding-bottom: 32px;
-  height: calc(100vh - 96px);
+  // padding-bottom: 32px;
+  height: calc(100vh - 128px);
 
 
   .directoryMain,
@@ -18,4 +18,4 @@
     background-color: #fff;
     border-radius: 20px;
   }
-}
+}

BIN
src/views/xiaoku-ai/image/0.png


BIN
src/views/xiaoku-ai/image/1.png


BIN
src/views/xiaoku-ai/image/2.png


BIN
src/views/xiaoku-ai/image/3.png


BIN
src/views/xiaoku-ai/image/4.png


BIN
src/views/xiaoku-ai/image/5.png


+ 5 - 0
src/views/xiaoku-ai/image/index.tsx

@@ -0,0 +1,5 @@
+const icons = import.meta.glob("./*", { import: "default", eager: true });
+export const getImage = (name: string) => {
+    const src = icons[`./${name}`] as unknown as string || ''
+	return src;
+};

+ 78 - 0
src/views/xiaoku-ai/index.module.less

@@ -0,0 +1,78 @@
+.container {
+    display: flex;
+    flex-direction: column;
+    background: #FFFFFF;
+    border-radius: 20Px;
+    height: 100%;
+}
+
+.tools {
+    padding: 32Px 32px 20px 32px;
+    display: flex;
+    align-items: center;
+    flex-shrink: 0;
+
+    :global {
+        .n-input {
+            margin-left: auto;
+            width: 361Px;
+        }
+    }
+}
+
+.content {
+    flex: 1;
+    overflow-y: auto;
+    padding: 20Px 36Px 36Px 36Px;
+}
+
+.item {
+    position: relative;
+    width: 214Px;
+    cursor: pointer;
+    transition: all .3s;
+
+    .cover {
+        position: relative;
+        overflow: hidden;
+
+        &::before {
+            content: '';
+            position: absolute;
+            top: 107Px;
+            left: 0;
+            width: 214Px;
+            height: 214Px;
+            background: #DDF2FF;
+            border-radius: 50%;
+        }
+    }
+
+    &:hover {
+        transform: scale(1.1);
+    }
+
+    .itemImg {
+        position: relative;
+        width: 158Px;
+        height: 223Px;
+        margin: auto;
+        background-color: antiquewhite;
+
+
+        :global {
+            .n-image {
+                width: 100%;
+                height: 100%;
+            }
+        }
+    }
+
+    .itemName{
+        margin-top: 16Px;
+        font-size: 16Px;
+        font-weight: 500;
+        color: #333;
+        text-align: center;
+    }
+}

+ 84 - 0
src/views/xiaoku-ai/index.tsx

@@ -0,0 +1,84 @@
+import {
+  TransitionGroup,
+  defineComponent,
+  onMounted,
+  reactive,
+  ref
+} from 'vue';
+import styles from './index.module.less';
+import TheSearch from '@/components/TheSearch';
+import { NButton, NImage, NSpace } from 'naive-ui';
+import { getImage } from './image';
+import { useRouter } from 'vue-router';
+
+export default defineComponent({
+  name: 'XiaokuAi',
+  setup() {
+    const router = useRouter();
+    const data = reactive({
+      tags: [
+        { name: '全部', id: 0 },
+        { name: '人教版', id: 1 },
+        { name: '声部训练', id: 2 },
+        { name: '小曲目', id: 3 },
+        { name: '考级曲目', id: 4 }
+      ],
+      tagIndex: 0,
+      list: [
+        {
+          name: '一年级上册人教版(2013版)',
+          src: ''
+        }
+      ]
+    });
+    return () => (
+      <div class={styles.container}>
+        <div class={styles.tools}>
+          <div class={styles.tags}>
+            <NSpace size={[24, 12]}>
+              {data.tags.map((item, index) => (
+                <NButton
+                  round
+                  secondary={data.tagIndex !== index}
+                  type={data.tagIndex === index ? 'primary' : 'default'}
+                  class={[
+                    styles.tag,
+                    data.tagIndex === index ? styles.active : ''
+                  ]}
+                  onClick={() => (data.tagIndex = index)}>
+                  {item.name}
+                </NButton>
+              ))}
+            </NSpace>
+          </div>
+          <TheSearch round />
+        </div>
+        <div class={styles.content}>
+          <NSpace size={[50, 40]}>
+            {new Array(30).fill(data.list[0]).map((item, index) => {
+              const _index = index > 5 ? index % 5 : index;
+              return (
+                <div
+                  class={styles.item}
+                  key={`item-${index}`}
+                  onClick={() => router.push({ path: '/xiaoku-music' })}>
+                  <div class={styles.cover}>
+                    <div class={styles.itemImg}>
+                      <NImage
+                        objectFit="contain"
+                        src={getImage(`${_index}.png`)}
+                        lazy
+                        previewDisabled={true}
+                      />
+                    </div>
+                  </div>
+                  <div class={styles.itemName}>{item.name}</div>
+                </div>
+              );
+            })}
+          </NSpace>
+        </div>
+      </div>
+    );
+  }
+});

+ 0 - 0
src/views/xiaoku-music/index.module.less


+ 8 - 0
src/views/xiaoku-music/index.tsx

@@ -0,0 +1,8 @@
+import { defineComponent } from "vue";
+
+export default defineComponent({
+    name: 'XiaokuMusic',
+    setup(){
+        return () => <div>music</div>
+    }
+})

+ 1 - 0
tsconfig.json

@@ -19,6 +19,7 @@
       "node"
     ],
     "paths": {
+      "/src/*": ["src/*"],
       "@/*": ["src/*"],
       "@common/*": ["src/common/*"],
       "@components/*": ["src/components/*"],

+ 1 - 0
vite.config.ts

@@ -13,6 +13,7 @@ function resolve(dir: string) {
 // https://vitejs.dev/config/
 // https://github.com/vitejs/vite/issues/1930 .env
 export default defineConfig({
+  base: './',
   plugins: [
     vue(),
     vueJsx(),

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä