lex před 1 rokem
rodič
revize
9656abdb71
75 změnil soubory, kde provedl 1524 přidání a 88 odebrání
  1. 122 3
      package-lock.json
  2. 5 1
      package.json
  3. binární
      public/favicon.ico
  4. binární
      src/common/assets/logo-bottom.png
  5. binární
      src/common/assets/logo-large.png
  6. binární
      src/common/assets/logo.png
  7. 0 79
      src/components/HelloWorld.vue
  8. 42 0
      src/components/m-footer/index.module.less
  9. 31 0
      src/components/m-footer/index.tsx
  10. 94 0
      src/components/m-header/index.module.less
  11. 69 0
      src/components/m-header/index.tsx
  12. 14 0
      src/components/m-sticky/index.module.less
  13. 107 0
      src/components/m-sticky/index.tsx
  14. 0 0
      src/data/ensemble.json
  15. 0 0
      src/data/solo.json
  16. 0 0
      src/data/subject.json
  17. 1 0
      src/main.ts
  18. 5 0
      src/styles/index.less
  19. 88 0
      src/views/home/co-ai/index.module.less
  20. 64 0
      src/views/home/co-ai/index.tsx
  21. 66 0
      src/views/home/co-person/index.module.less
  22. 58 0
      src/views/home/co-person/index.tsx
  23. 152 0
      src/views/home/co-tenant/index.module.less
  24. 166 0
      src/views/home/co-tenant/index.tsx
  25. binární
      src/views/home/images/co-ai/banner.png
  26. binární
      src/views/home/images/co-ai/change.png
  27. binární
      src/views/home/images/co-ai/co-ai.png
  28. binární
      src/views/home/images/co-ai/evaluation-bg.png
  29. binární
      src/views/home/images/co-ai/evaluation.png
  30. binární
      src/views/home/images/co-ai/music-bg.png
  31. binární
      src/views/home/images/co-ai/music.png
  32. binární
      src/views/home/images/co-ai/title-1.png
  33. binární
      src/views/home/images/co-ai/title-2.png
  34. binární
      src/views/home/images/co-person/banner.png
  35. binární
      src/views/home/images/co-person/icon-tip.png
  36. binární
      src/views/home/images/co-person/img1.png
  37. binární
      src/views/home/images/co-person/img2-bg.png
  38. binární
      src/views/home/images/co-person/img2.png
  39. binární
      src/views/home/images/co-person/img3.png
  40. binární
      src/views/home/images/co-person/img4-bg.png
  41. binární
      src/views/home/images/co-person/img4.png
  42. binární
      src/views/home/images/co-person/title-1.png
  43. binární
      src/views/home/images/co-tenant/banner.png
  44. binární
      src/views/home/images/co-tenant/img1-bg.png
  45. binární
      src/views/home/images/co-tenant/img1.png
  46. binární
      src/views/home/images/co-tenant/img2.png
  47. binární
      src/views/home/images/co-tenant/img3-bg.png
  48. binární
      src/views/home/images/co-tenant/img3.png
  49. binární
      src/views/home/images/co-tenant/title-1.png
  50. binární
      src/views/home/images/co-tenant/title-2.png
  51. binární
      src/views/home/images/music-room/banner.png
  52. binární
      src/views/home/images/music-room/img1.png
  53. binární
      src/views/home/images/music-room/img2-bg.png
  54. binární
      src/views/home/images/music-room/img2.png
  55. binární
      src/views/home/images/music-room/img3.png
  56. binární
      src/views/home/images/music-room/img4-bg.png
  57. binární
      src/views/home/images/music-room/img4.png
  58. binární
      src/views/home/images/music-room/title-1.png
  59. binární
      src/views/home/images/music-room/title-2.png
  60. binární
      src/views/home/images/piano-room/banner.png
  61. binární
      src/views/home/images/piano-room/img1.png
  62. binární
      src/views/home/images/piano-room/img2.png
  63. binární
      src/views/home/images/piano-room/img3-bg.png
  64. binární
      src/views/home/images/piano-room/img3.png
  65. binární
      src/views/home/images/piano-room/img4.png
  66. binární
      src/views/home/images/piano-room/img5.png
  67. binární
      src/views/home/images/piano-room/img6-bg.png
  68. binární
      src/views/home/images/piano-room/img6.png
  69. binární
      src/views/home/images/piano-room/title-1.png
  70. 71 3
      src/views/home/index.module.less
  71. 65 2
      src/views/home/index.tsx
  72. 81 0
      src/views/home/music-room/index.module.less
  73. 59 0
      src/views/home/music-room/index.tsx
  74. 88 0
      src/views/home/piano-room/index.module.less
  75. 76 0
      src/views/home/piano-room/index.tsx

+ 122 - 3
package-lock.json

@@ -1,19 +1,23 @@
 {
-  "name": "vue-vite-h5",
+  "name": "h5-colexiu-website",
   "version": "0.2.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
-      "name": "vue-vite-h5",
+      "name": "h5-colexiu-website",
       "version": "0.2.0",
       "license": "MIT",
       "dependencies": {
+        "@vant/use": "^1.6.0",
+        "@vueuse/core": "^10.5.0",
         "dayjs": "^1.11.7",
         "pinia": "^2.0.34",
+        "swiper": "^11.0.3",
         "vant": "^4.1.2",
         "vue": "^3.2.47",
-        "vue-router": "^4.1.6"
+        "vue-router": "^4.1.6",
+        "vue3-lottie": "^3.2.0"
       },
       "devDependencies": {
         "@babel/core": "^7.21.4",
@@ -2399,6 +2403,11 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/web-bluetooth": {
+      "version": "0.0.18",
+      "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.18.tgz",
+      "integrity": "sha512-v/ZHEj9xh82usl8LMR3GarzFY1IrbXJw5L4QfQhokjRV91q+SelFqxQWSep1ucXEZ22+dSTwLFkXeur25sPIbw=="
+    },
     "node_modules/@typescript-eslint/eslint-plugin": {
       "version": "5.62.0",
       "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
@@ -2976,6 +2985,30 @@
       "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.7.tgz",
       "integrity": "sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg=="
     },
+    "node_modules/@vueuse/core": {
+      "version": "10.5.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-10.5.0.tgz",
+      "integrity": "sha512-z/tI2eSvxwLRjOhDm0h/SXAjNm8N5ld6/SC/JQs6o6kpJ6Ya50LnEL8g5hoYu005i28L0zqB5L5yAl8Jl26K3A==",
+      "dependencies": {
+        "@types/web-bluetooth": "^0.0.18",
+        "@vueuse/metadata": "10.5.0",
+        "@vueuse/shared": "10.5.0",
+        "vue-demi": ">=0.14.6"
+      }
+    },
+    "node_modules/@vueuse/metadata": {
+      "version": "10.5.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-10.5.0.tgz",
+      "integrity": "sha512-fEbElR+MaIYyCkeM0SzWkdoMtOpIwO72x8WsZHRE7IggiOlILttqttM69AS13nrDxosnDBYdyy3C5mR1LCxHsw=="
+    },
+    "node_modules/@vueuse/shared": {
+      "version": "10.5.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-10.5.0.tgz",
+      "integrity": "sha512-18iyxbbHYLst9MqU1X1QNdMHIjks6wC7XTVf0KNOv5es/Ms6gjVFCAAWTVP2JStuGqydg3DT+ExpFORUEi9yhg==",
+      "dependencies": {
+        "vue-demi": ">=0.14.6"
+      }
+    },
     "node_modules/acorn": {
       "version": "8.11.2",
       "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.11.2.tgz",
@@ -5508,6 +5541,11 @@
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
+    "node_modules/lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+    },
     "node_modules/lodash.debounce": {
       "version": "4.0.8",
       "resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -5585,6 +5623,11 @@
         "node": ">=12"
       }
     },
+    "node_modules/lottie-web": {
+      "version": "5.12.2",
+      "resolved": "https://registry.npmmirror.com/lottie-web/-/lottie-web-5.12.2.tgz",
+      "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg=="
+    },
     "node_modules/lower-case": {
       "version": "2.0.2",
       "resolved": "https://registry.npmmirror.com/lower-case/-/lower-case-2.0.2.tgz",
@@ -7019,6 +7062,14 @@
       "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
       "dev": true
     },
+    "node_modules/swiper": {
+      "version": "11.0.3",
+      "resolved": "https://registry.npmmirror.com/swiper/-/swiper-11.0.3.tgz",
+      "integrity": "sha512-MyV9ooQsriAe2EibeamqewLjgCfSvl2xoyratl6S3ln5BXDL4BzlO6mxcbLMCzQL6Z60b/u0AS/nKrepL0+TAg==",
+      "engines": {
+        "node": ">= 4.7.0"
+      }
+    },
     "node_modules/systemjs": {
       "version": "6.14.2",
       "resolved": "https://registry.npmmirror.com/systemjs/-/systemjs-6.14.2.tgz",
@@ -7648,6 +7699,21 @@
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
       "dev": true
     },
+    "node_modules/vue3-lottie": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/vue3-lottie/-/vue3-lottie-3.2.0.tgz",
+      "integrity": "sha512-PtNXbv7iD4XGmK8CXd71aLWmILIR6P6VzLMDw6ZzmDAeuJZuJ0MdOVnn50LOARgq+cOFJsn/2z+7tZh0F9T9qw==",
+      "dependencies": {
+        "lodash-es": "^4.17.21",
+        "lottie-web": "5.12.2"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "peerDependencies": {
+        "vue": "^3.2"
+      }
+    },
     "node_modules/wcwidth": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz",
@@ -9484,6 +9550,11 @@
         "@types/node": "*"
       }
     },
+    "@types/web-bluetooth": {
+      "version": "0.0.18",
+      "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.18.tgz",
+      "integrity": "sha512-v/ZHEj9xh82usl8LMR3GarzFY1IrbXJw5L4QfQhokjRV91q+SelFqxQWSep1ucXEZ22+dSTwLFkXeur25sPIbw=="
+    },
     "@typescript-eslint/eslint-plugin": {
       "version": "5.62.0",
       "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
@@ -9929,6 +10000,30 @@
       "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.7.tgz",
       "integrity": "sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg=="
     },
+    "@vueuse/core": {
+      "version": "10.5.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-10.5.0.tgz",
+      "integrity": "sha512-z/tI2eSvxwLRjOhDm0h/SXAjNm8N5ld6/SC/JQs6o6kpJ6Ya50LnEL8g5hoYu005i28L0zqB5L5yAl8Jl26K3A==",
+      "requires": {
+        "@types/web-bluetooth": "^0.0.18",
+        "@vueuse/metadata": "10.5.0",
+        "@vueuse/shared": "10.5.0",
+        "vue-demi": ">=0.14.6"
+      }
+    },
+    "@vueuse/metadata": {
+      "version": "10.5.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-10.5.0.tgz",
+      "integrity": "sha512-fEbElR+MaIYyCkeM0SzWkdoMtOpIwO72x8WsZHRE7IggiOlILttqttM69AS13nrDxosnDBYdyy3C5mR1LCxHsw=="
+    },
+    "@vueuse/shared": {
+      "version": "10.5.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-10.5.0.tgz",
+      "integrity": "sha512-18iyxbbHYLst9MqU1X1QNdMHIjks6wC7XTVf0KNOv5es/Ms6gjVFCAAWTVP2JStuGqydg3DT+ExpFORUEi9yhg==",
+      "requires": {
+        "vue-demi": ">=0.14.6"
+      }
+    },
     "acorn": {
       "version": "8.11.2",
       "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.11.2.tgz",
@@ -11920,6 +12015,11 @@
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
+    "lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+    },
     "lodash.debounce": {
       "version": "4.0.8",
       "resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -11986,6 +12086,11 @@
         }
       }
     },
+    "lottie-web": {
+      "version": "5.12.2",
+      "resolved": "https://registry.npmmirror.com/lottie-web/-/lottie-web-5.12.2.tgz",
+      "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg=="
+    },
     "lower-case": {
       "version": "2.0.2",
       "resolved": "https://registry.npmmirror.com/lower-case/-/lower-case-2.0.2.tgz",
@@ -13110,6 +13215,11 @@
       "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
       "dev": true
     },
+    "swiper": {
+      "version": "11.0.3",
+      "resolved": "https://registry.npmmirror.com/swiper/-/swiper-11.0.3.tgz",
+      "integrity": "sha512-MyV9ooQsriAe2EibeamqewLjgCfSvl2xoyratl6S3ln5BXDL4BzlO6mxcbLMCzQL6Z60b/u0AS/nKrepL0+TAg=="
+    },
     "systemjs": {
       "version": "6.14.2",
       "resolved": "https://registry.npmmirror.com/systemjs/-/systemjs-6.14.2.tgz",
@@ -13548,6 +13658,15 @@
         }
       }
     },
+    "vue3-lottie": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/vue3-lottie/-/vue3-lottie-3.2.0.tgz",
+      "integrity": "sha512-PtNXbv7iD4XGmK8CXd71aLWmILIR6P6VzLMDw6ZzmDAeuJZuJ0MdOVnn50LOARgq+cOFJsn/2z+7tZh0F9T9qw==",
+      "requires": {
+        "lodash-es": "^4.17.21",
+        "lottie-web": "5.12.2"
+      }
+    },
     "wcwidth": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz",

+ 5 - 1
package.json

@@ -21,11 +21,15 @@
     "generate": "plop"
   },
   "dependencies": {
+    "@vant/use": "^1.6.0",
+    "@vueuse/core": "^10.5.0",
     "dayjs": "^1.11.7",
     "pinia": "^2.0.34",
+    "swiper": "^11.0.3",
     "vant": "^4.1.2",
     "vue": "^3.2.47",
-    "vue-router": "^4.1.6"
+    "vue-router": "^4.1.6",
+    "vue3-lottie": "^3.2.0"
   },
   "devDependencies": {
     "@babel/core": "^7.21.4",

binární
public/favicon.ico


binární
src/common/assets/logo-bottom.png


binární
src/common/assets/logo-large.png


binární
src/common/assets/logo.png


+ 0 - 79
src/components/HelloWorld.vue

@@ -1,79 +0,0 @@
-<template>
-  <h1>{{ msg }}</h1>
-
-  <p>
-    Recommended IDE setup:
-    <a href="https://code.visualstudio.com/" target="_blank">VSCode</a>
-    +
-    <a
-      href="https://marketplace.visualstudio.com/items?itemName=octref.vetur"
-      target="_blank"
-    >
-      Vetur
-    </a>
-    or
-    <a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
-    (if using
-    <code>&lt;script setup&gt;</code>
-    )
-  </p>
-
-  <p>
-    See
-    <code>README.md</code>
-    for more information.
-  </p>
-
-  <p>
-    <a href="https://vitejs.dev/guide/features.html" target="_blank">
-      Vite Docs
-    </a>
-    |
-    <a href="https://v3.vuejs.org/" target="_blank">Vue 3 Docs</a>
-  </p>
-
-  <button type="button" @click="count++">count is: {{ count }}</button>
-  <p>
-    Edit
-    <code>components/HelloWorld.vue</code>
-    to test hot module replacement.
-  </p>
-  <van-button type="primary" round @click="count++">
-    count is: {{ count }}
-  </van-button>
-</template>
-
-<script lang="ts">
-import { ref, defineComponent } from 'vue';
-export default defineComponent({
-  name: 'HelloWorld',
-  props: {
-    msg: {
-      type: String,
-      required: true
-    }
-  },
-  setup: () => {
-    const count = ref(0);
-    return { count };
-  }
-});
-</script>
-
-<style scoped>
-a {
-  color: #42b983;
-}
-
-label {
-  margin: 0 0.5em;
-  font-weight: bold;
-}
-
-code {
-  background-color: #eee;
-  padding: 2px 4px;
-  border-radius: 4px;
-  color: #304455;
-}
-</style>

+ 42 - 0
src/components/m-footer/index.module.less

@@ -0,0 +1,42 @@
+.footer {
+  background: #262D45;
+
+  .bottomLogo {
+    width: 167px;
+    height: 40px;
+    object-fit: contain;
+    margin: 20px 24px;
+  }
+
+  .friendLink {
+    display: flex;
+  }
+
+  .link {
+    padding: 0 24px 20px;
+
+    .linkTitle {
+      font-size: 12px;
+      color: rgba(255, 255, 255, 0.5);
+      line-height: 16px;
+      padding-bottom: 2px;
+    }
+
+    .linkContent {
+      font-size: 12px;
+      font-weight: 500;
+      color: #FFFFFF;
+      line-height: 20px;
+      letter-spacing: 1px;
+    }
+  }
+
+  .copyright {
+    border-top: 1px solid #585858;
+    font-size: 10px;
+    line-height: 16px;
+    color: rgba(255, 255, 255, 0.5);
+    padding: 16px 0 calc(20px);
+    text-align: center;
+  }
+}

+ 31 - 0
src/components/m-footer/index.tsx

@@ -0,0 +1,31 @@
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+import logoBottom from '@common/assets/logo-bottom.png';
+
+export default defineComponent({
+  name: 'm-footer',
+  setup() {
+    return () => (
+      <div class={styles.footer}>
+        <img class={styles.bottomLogo} src={logoBottom} />
+
+        <div class={styles.friendLink}>
+          <div class={styles.link}>
+            <p class={styles.linkTitle}>友情链接</p>
+            <p class={styles.linkContent}>
+              中国音乐家协会
+              <br />
+              中国音协管乐学会低音铜管
+            </p>
+          </div>
+          <div class={styles.logoUrl}></div>
+        </div>
+
+        <div class={styles.copyright}>
+          Copyright © 2022 武汉酷乐秀网络科技有限公司 <br />
+          All Rights Reserved.鄂ICP备2021020787号-1
+        </div>
+      </div>
+    );
+  }
+});

+ 94 - 0
src/components/m-header/index.module.less

@@ -0,0 +1,94 @@
+.headerSection {
+  position: relative;
+  height: 56px;
+}
+
+.header {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  z-index: 9999;
+  height: 56px;
+  background-color: #fff;
+  padding: 0 18px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+
+  .logo {
+    width: 87px;
+    height: 26px;
+    object-fit: contain;
+  }
+}
+
+.navMenu {
+  .line {
+    width: 20px;
+    height: 3px;
+    background: #727272;
+    border-radius: 6px;
+    display: block;
+    margin: 3px auto;
+    transition: all 0.3s ease-in-out;
+
+    &:first-child {
+      margin-top: 0;
+    }
+
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+
+  &.is-active {
+    .line:nth-child(1) {
+      transform: translateY(6px) rotate(45deg);
+    }
+
+    .line:nth-child(2) {
+      opacity: 0;
+    }
+
+    .line:nth-child(3) {
+      transform: translateY(-6px) rotate(-45deg)
+    }
+  }
+}
+
+.menuPopup {
+  top: 56px;
+
+  :global {
+    .van-cell {
+      padding: 16px 24px;
+      font-size: 16px;
+      color: #777777;
+    }
+
+    .van-cell__right-icon {
+      color: #AAAAAA;
+      font-size: 15px;
+    }
+  }
+
+  .is-active {
+    color: #000000;
+    font-size: 16px;
+    font-weight: 600;
+    background: #FAFAFA;
+  }
+
+  .subCell {
+    padding-left: 16px;
+    height: 0;
+    overflow: hidden;
+    transition: height 0.2s ease;
+
+    &.arrowActive {
+      transition: height 0.2s ease;
+      height: calc(3 * (32px + var(--van-cell-line-height)))
+    }
+  }
+}

+ 69 - 0
src/components/m-header/index.tsx

@@ -0,0 +1,69 @@
+import { defineComponent, ref } from 'vue';
+import styles from './index.module.less';
+import logoLarge from '@common/assets/logo-large.png';
+import { Cell, Popup } from 'vant';
+import { useRoute, useRouter } from 'vue-router';
+
+export default defineComponent({
+  name: 'm-header',
+  setup() {
+    const route = useRoute();
+    const router = useRouter();
+    const isActive = ref(false);
+    const showMenu = ref(false);
+    const arrowStatus = ref(false);
+
+    const onGoDetail = (path: string) => {
+      showMenu.value = false;
+      isActive.value = false;
+      router.push(path);
+    };
+    return () => (
+      <div class={styles.headerSection} id="headerSection">
+        <div class={styles.header}>
+          <img class={styles.logo} src={logoLarge} />
+          <div
+            class={[styles.navMenu, isActive.value && styles['is-active']]}
+            onClick={() => {
+              isActive.value = !isActive.value;
+              showMenu.value = !showMenu.value;
+            }}>
+            <span class={[styles.line, styles.line1]}></span>
+            <span class={[styles.line, styles.line2]}></span>
+            <span class={[styles.line, styles.line3]}></span>
+          </div>
+        </div>
+
+        <Popup
+          position="top"
+          v-model:show={showMenu.value}
+          class={styles.menuPopup}
+          onUpdate:show={(val: boolean) => {
+            isActive.value = val;
+          }}
+          teleport={'body'}>
+          <Cell
+            title={'首页'}
+            border={false}
+            class={['/', '/home'].includes(route.path) && styles['is-active']}
+            onClick={() => onGoDetail('/')}></Cell>
+          <Cell title={'产品'} border={false}></Cell>
+          <Cell
+            title={'解决方案'}
+            isLink
+            arrowDirection={arrowStatus.value ? 'up' : 'down'}
+            border={false}
+            onClick={() => (arrowStatus.value = !arrowStatus.value)}></Cell>
+          <div
+            class={[styles.subCell, arrowStatus.value && styles.arrowActive]}>
+            <Cell title={'数字化音乐课堂'} border={false}></Cell>
+            <Cell title={'器乐教培行业解决方案'} border={false}></Cell>
+            <Cell title={'音乐达人展示平台'} border={false}></Cell>
+          </div>
+          <Cell title={'渠道合作'} border={false}></Cell>
+          <Cell title={'关于我们'} border={false}></Cell>
+        </Popup>
+      </div>
+    );
+  }
+});

+ 14 - 0
src/components/m-sticky/index.module.less

@@ -0,0 +1,14 @@
+.sticky {
+  position: sticky;
+  top: 0;
+  z-index: 99;
+}
+
+.white {
+  background-color: #fff;
+
+  >div {
+    padding-top: 15px;
+    box-shadow: 0px 0px 10px 0px rgba(216, 216, 216, 0.5);
+  }
+}

+ 107 - 0
src/components/m-sticky/index.tsx

@@ -0,0 +1,107 @@
+import {
+  PropType,
+  defineComponent,
+  onMounted,
+  reactive,
+  ref,
+  watch
+} from 'vue';
+import styles from './index.module.less';
+import { useResizeObserver } from '@vueuse/core';
+
+export default defineComponent({
+  name: 'm-sticky',
+  props: {
+    position: {
+      type: String as PropType<'top' | 'bottom'>,
+      default: 'top'
+    },
+    mode: {
+      type: String as PropType<'fixed' | 'sticky'>,
+      default: 'fixed'
+    },
+    offsetTop: {
+      type: String,
+      default: '0px'
+    },
+    offsetBottom: {
+      default: '0px'
+    },
+    // 变量名
+    varName: {
+      type: String,
+      default: '--header-height'
+    }
+  },
+  emits: ['barHeight'],
+  setup(props, { slots, emit }) {
+    const forms = reactive({
+      divStyle: {} as any,
+      heightV: 0,
+      sectionStyle: {
+        width: '100%',
+        height: 'auto',
+        left: '0'
+      }
+    });
+
+    const __initHeight = (height: any) => {
+      forms.sectionStyle.height = `${height}px`;
+      forms.heightV = height;
+      // 设置名称
+      document.documentElement.style.setProperty(props.varName, `${height}px`);
+      emit('barHeight', height);
+    };
+
+    const divRef = ref();
+    const div2Ref = ref();
+    onMounted(() => {
+      if (props.position === 'top') {
+        forms.divStyle.top = props.offsetTop || '0px';
+      } else {
+        forms.divStyle.bottom = props.offsetBottom || '0px';
+      }
+      try {
+        useResizeObserver(divRef.value, (entries: any) => {
+          const entry = entries[0];
+          const { height } = entry.contentRect;
+          if (Math.abs(height - forms.heightV) > 1) {
+            setTimeout(() => {
+              __initHeight(height);
+            }, 10);
+          }
+        });
+      } catch {
+        //
+      }
+    });
+
+    watch(
+      () => props.offsetTop,
+      () => {
+        forms.divStyle.top = props.offsetTop;
+      }
+    );
+    watch(
+      () => props.offsetBottom,
+      () => {
+        forms.divStyle.bottom = props.offsetBottom;
+      }
+    );
+    return () => (
+      <div
+        style={[forms.sectionStyle]}
+        class={props.mode === 'sticky' && styles.sticky}>
+        <div
+          ref={divRef}
+          class={[
+            'van-sticky',
+            props.mode === 'fixed' ? 'van-sticky--fixed' : ''
+          ]}
+          style={[forms.divStyle, forms.sectionStyle]}>
+          <div ref={div2Ref}>{slots.default && slots.default()}</div>
+        </div>
+      </div>
+    );
+  }
+});

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
src/data/ensemble.json


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
src/data/solo.json


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
src/data/subject.json


+ 1 - 0
src/main.ts

@@ -3,6 +3,7 @@ import App from './App';
 import dayjs from 'dayjs';
 import 'dayjs/locale/zh-cn';
 import { setupStore } from '@/stores';
+import 'vant/lib/index.css';
 import './styles/index.less';
 import router from '@/router';
 

+ 5 - 0
src/styles/index.less

@@ -25,8 +25,13 @@ textarea {
 }
 
 #app {
+  background: #f2f2f2;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
   color: #333;
   min-height: 100vh;
+}
+
+.w100 {
+  width: 100%;
 }

+ 88 - 0
src/views/home/co-ai/index.module.less

@@ -0,0 +1,88 @@
+.title {
+  position: relative;
+  text-align: center;
+  font-size: 22px;
+  font-weight: 600;
+  color: #000000;
+  line-height: 30px;
+  letter-spacing: 1px;
+
+  span {
+    position: relative;
+    z-index: 9;
+  }
+}
+
+.title1::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 50%;
+  width: 99px;
+  height: 18px;
+  transform: translate(-50%, 50%);
+  background: url('../images/co-ai/title-1.png') no-repeat center;
+  background-size: contain;
+}
+
+.title2::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 50%;
+  width: 73px;
+  height: 16px;
+  transform: translate(-50%, 50%);
+  background: url('../images/co-ai/title-2.png') no-repeat center;
+  background-size: contain;
+}
+
+.content {
+  padding: 8px 24px 0;
+  font-size: 14px;
+  color: rgba(0, 0, 0, 0.5);
+  line-height: 24px;
+}
+
+.sectionAi {
+  background: #fff;
+  padding: 20px 0 60px;
+
+  .aiContent {
+    padding: 8px 24px 30px;
+    font-size: 14px;
+    color: rgba(0, 0, 0, 0.5);
+    line-height: 24px;
+  }
+}
+
+.sectionEval {
+  padding: 40px 0 56px;
+  background: url('../images/co-ai/evaluation-bg.png') no-repeat center #fff;
+  background-size: cover;
+
+  .content {
+    p {
+      text-indent: 2em;
+    }
+  }
+}
+
+.sectionChange {
+  padding: 40px 0 42px;
+  background: #fff;
+
+  .content {
+    padding-bottom: 36px;
+  }
+}
+
+.sectionMusic {
+  padding: 40px 0 56px;
+  background: url('../images/co-ai/music-bg.png') no-repeat center #fff;
+  background-size: cover;
+
+  .content {
+    padding-bottom: 13px;
+  }
+}

+ 64 - 0
src/views/home/co-ai/index.tsx

@@ -0,0 +1,64 @@
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+import coAi from '../images/co-ai/co-ai.png';
+import evaluation from '../images/co-ai/evaluation.png';
+import change from '../images/co-ai/change.png';
+import music from '../images/co-ai/music.png';
+
+export default defineComponent({
+  name: 'co-ai',
+  setup() {
+    return () => (
+      <div class={styles.coAi}>
+        <div class={styles.sectionAi}>
+          <div class={[styles.title, styles.title1]}>
+            <span>小酷AI</span>
+          </div>
+          <div class={styles.aiContent}>
+            三大练习模式,20多项练习辅助功能,让老师讲课更生动,让学生练习更高效
+          </div>
+
+          <img src={coAi} class={'w100'} />
+        </div>
+
+        <div class={styles.sectionEval}>
+          <div class={[styles.title, styles.title2]}>
+            <span>智能评测</span>
+          </div>
+          <div class={styles.content}>
+            <p>
+              拥有完全自主知识产权,通过演奏音频采集与标准曲谱比对,实时提供智能点评报告,自动提示练习对错,并生成评测报告。
+            </p>
+            <p>
+              让学生和家长能够及时发现乐器练习过程中讯在的问题,提高练习效率,可谓是学生学习乐器的“随身教练”
+            </p>
+          </div>
+
+          <img src={evaluation} class={'w100'} />
+        </div>
+
+        <div class={styles.sectionChange}>
+          <div class={[styles.title, styles.title1]}>
+            <span>五线谱/简谱一键转换</span>
+          </div>
+          <div class={styles.content}>
+            五线谱可一键转换简谱,再也不用为找谱而“奔波”,支持达人端自行上传五线谱
+          </div>
+
+          <img src={change} class={'w100'} />
+        </div>
+
+        <div class={styles.sectionMusic}>
+          <div class={[styles.title, styles.title2]}>
+            <span>海量曲目</span>
+          </div>
+          <div class={styles.content}>
+            完善的曲目级别,丰富的曲目风格,海量曲目满足声部训练、独奏练习、乐团合奏等多场景训练需求
+          </div>
+
+          <img src={music} class={'w100'} />
+        </div>
+      </div>
+    );
+  }
+});

+ 66 - 0
src/views/home/co-person/index.module.less

@@ -0,0 +1,66 @@
+.title {
+  position: relative;
+  text-align: center;
+  font-size: 22px;
+  font-weight: 600;
+  color: #000000;
+  line-height: 30px;
+  letter-spacing: 1px;
+
+  span {
+    position: relative;
+    z-index: 9;
+
+    &::before {
+      content: '';
+      position: absolute;
+      bottom: -6px;
+      right: -15px;
+      width: 111px;
+      height: 39px;
+      background: url('../images/co-person/title-1.png') no-repeat center;
+      background-size: contain;
+      z-index: -1;
+    }
+  }
+}
+
+
+
+.content {
+  padding: 8px 24px 17px;
+  font-size: 14px;
+  color: rgba(0, 0, 0, 0.5);
+  line-height: 24px;
+}
+
+.section1 {
+  background: #fff;
+  padding: 20px 0 30px;
+}
+
+.section2 {
+  padding: 40px 0 50px;
+  background: url('../images/co-person/img2-bg.png') no-repeat center #fff;
+  background-size: cover;
+
+  .content {
+    padding-bottom: 22px;
+  }
+}
+
+.section3 {
+  background: #fff;
+  padding: 20px 0 30px;
+}
+
+.section4 {
+  padding: 40px 0 50px;
+  background: url('../images/co-person/img4-bg.png') no-repeat center #fff;
+  background-size: cover;
+
+  .content {
+    text-align: center;
+    padding-bottom: 20px;
+  }
+}

+ 58 - 0
src/views/home/co-person/index.tsx

@@ -0,0 +1,58 @@
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+import img1 from '../images/co-person/img1.png';
+import img2 from '../images/co-person/img2.png';
+import img3 from '../images/co-person/img3.png';
+import img4 from '../images/co-person/img4.png';
+
+export default defineComponent({
+  name: 'music-room',
+  setup() {
+    return () => (
+      <div class={styles.coPerson}>
+        <div class={styles.section1}>
+          <div class={[styles.title]}>
+            <span>演奏Mlog达人</span>
+          </div>
+          <div class={styles.content}>
+            展示个人演奏风采,吸引学员约课。个人风采资料填写、演奏视频上传
+          </div>
+
+          <img src={img1} class={'w100'} />
+        </div>
+
+        <div class={styles.section2}>
+          <div class={[styles.title]}>
+            <span>教学视频达人</span>
+          </div>
+          <div class={styles.content}>
+            可自行创建上传演奏教学的课程组,学员可购买或免费观看课程。可查看已上传视频课,创建与设置视频课参数
+          </div>
+
+          <img src={img2} class={'w100'} />
+        </div>
+
+        <div class={styles.section3}>
+          <div class={[styles.title]}>
+            <span>直播UP达人</span>
+          </div>
+          <div class={styles.content}>
+            可开启演奏live直播,与粉丝互动。可自行创建收费课程的慕课,邀请学员购买或免费观看课程
+          </div>
+
+          <img src={img3} class={'w100'} />
+        </div>
+
+        <div class={styles.section4}>
+          <i class={styles.iconTip}></i>
+          <div class={[styles.title]}>
+            <span>乐谱歌单达人</span>
+          </div>
+          <div class={styles.content}>上传分享曲谱伴奏,可自由定价曲目</div>
+
+          <img src={img4} class={'w100'} />
+        </div>
+      </div>
+    );
+  }
+});

+ 152 - 0
src/views/home/co-tenant/index.module.less

@@ -0,0 +1,152 @@
+.title {
+  position: relative;
+  text-align: center;
+  font-size: 22px;
+  font-weight: 600;
+  color: #000000;
+  line-height: 30px;
+  letter-spacing: 1px;
+
+  span {
+    position: relative;
+    z-index: 9;
+
+    &::before {
+      content: '';
+      position: absolute;
+      top: -3px;
+      left: -7px;
+      width: 20px;
+      height: 20px;
+      background: url('../images/co-tenant/title-1.png') no-repeat center;
+      background-size: contain;
+      z-index: -1;
+    }
+  }
+}
+
+.content {
+  padding: 8px 24px 16px;
+  font-size: 14px;
+  color: rgba(0, 0, 0, 0.5);
+  line-height: 24px;
+}
+
+.center {
+  text-align: center;
+}
+
+.section1 {
+  background: #fff;
+  padding: 20px 0 40px;
+
+  .pagination {
+    text-align: center;
+    padding-top: 20px;
+
+    .paginationItem {
+      display: inline-block;
+      margin: 0 3px;
+      width: 6px;
+      height: 6px;
+      background: #D8D8D8;
+      opacity: 0.7;
+      border-radius: 6px;
+
+      &.active {
+        width: 14px;
+        background: #FE2451;
+        border-radius: 3px;
+      }
+    }
+  }
+}
+
+.swipe {
+  :global {
+
+    .swiper-slide,
+    .lottie-animation-container {
+      width: 240px !important;
+      height: 464px;
+    }
+
+    .swiper-slide {
+      border-radius: 10px;
+      overflow: hidden;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      transition: all .2s ease-in;
+    }
+
+    .swiper-slide-prev,
+    .swiper-slide-next {
+      transform: scale(0.9) !important;
+      transition: all .2s ease-in;
+    }
+  }
+
+  .swipeContainer {
+    position: relative;
+    width: 240px !important;
+    height: 464px;
+  }
+
+  .desc {
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    z-index: 999;
+    height: 117px;
+    background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%);
+
+    &::before {
+      position: absolute;
+      content: '';
+      background: url('../images/co-tenant/title-2.png') no-repeat center;
+      background-size: contain;
+      width: 12px;
+      height: 10px;
+      display: inline-block;
+      top: 21px;
+      left: 10px;
+    }
+
+    p {
+      padding: 41px 10px 0;
+      font-size: 13px;
+      font-weight: 500;
+      color: #FFFFFF;
+      line-height: 22px;
+      text-shadow: 0px 2px 8px rgba(151, 90, 90, 0.24);
+    }
+  }
+}
+
+
+.section2 {
+  padding: 40px 0 37px;
+  background: url('../images/co-tenant/img1-bg.png') no-repeat center #fff;
+  background-size: cover;
+}
+
+.section3 {
+  background: #fff;
+  padding: 40px 0 46px;
+
+  .content {
+    padding-bottom: 10px;
+  }
+}
+
+.section4 {
+  padding: 40px 0 32px;
+  background: url('../images/co-tenant/img3-bg.png') no-repeat center #fff;
+  background-size: cover;
+
+  .content {
+    padding-bottom: 15px;
+  }
+}

+ 166 - 0
src/views/home/co-tenant/index.tsx

@@ -0,0 +1,166 @@
+import { defineComponent, reactive, ref } from 'vue';
+
+import styles from './index.module.less';
+import img1 from '../images/co-tenant/img1.png';
+import img2 from '../images/co-tenant/img2.png';
+import img3 from '../images/co-tenant/img3.png';
+// Import Swiper Vue.js components
+import { Swiper, SwiperSlide } from 'swiper/vue';
+// Import Swiper styles
+import 'swiper/css';
+
+import { Vue3Lottie } from 'vue3-lottie';
+import subjectJSON from '@/data/subject.json';
+import ensembleJSON from '@/data/ensemble.json';
+import soloJSON from '@/data/solo.json';
+
+export default defineComponent({
+  name: 'music-room',
+  setup() {
+    const swipeIndex = ref(1);
+    const animation = reactive({
+      animaRef1: null as any,
+      animaRef2: null as any,
+      animaRef3: null as any
+    });
+
+    return () => (
+      <div class={styles.coTenant}>
+        <div class={styles.section1}>
+          <div class={[styles.title]}>
+            <span>客制化训练教程</span>
+          </div>
+          <div class={[styles.content, styles.center]}>
+            专属定制训练教程,让学员所学即所练
+          </div>
+
+          <Swiper
+            class={styles.swipe}
+            initialSlide={1}
+            slidesPerView={'auto'}
+            centeredSlides={true}
+            onSlideChange={swiper => {
+              swipeIndex.value = swiper.activeIndex;
+              if (swiper.activeIndex === 0) {
+                //   animation.animPlay = true;
+                //   animation.animPlay2 = false;
+                //   animation.animPlay3 = false;
+                animation.animaRef1?.play();
+                animation.animaRef2?.stop();
+                animation.animaRef3?.stop();
+              } else if (swiper.activeIndex === 1) {
+                //   animation.animPlay = false;
+                //   animation.animPlay2 = true;
+                //   animation.animPlay3 = false;
+                animation.animaRef1?.stop();
+                animation.animaRef2?.play();
+                animation.animaRef3?.stop();
+              } else if (swiper.activeIndex === 2) {
+                //   animation.animPlay = false;
+                //   animation.animPlay2 = false;
+                //   animation.animPlay3 = true;
+                console.log(animation.animaRef3);
+                animation.animaRef1?.stop();
+                animation.animaRef2?.stop();
+                animation.animaRef3?.play();
+              }
+            }}>
+            <SwiperSlide>
+              <div class={styles.swipeContainer}>
+                <Vue3Lottie
+                  ref={el => (animation.animaRef1 = el)}
+                  animationData={subjectJSON}
+                  autoPlay={false}></Vue3Lottie>
+                <div class={styles.desc}>
+                  <p>
+                    声部教材全量制作为练习曲目,课堂所学即课后所练。让学生循序渐进逐步掌握器乐演奏技能
+                  </p>
+                </div>
+              </div>
+            </SwiperSlide>
+            <SwiperSlide>
+              <div class={styles.swipeContainer}>
+                <Vue3Lottie
+                  ref={el => (animation.animaRef2 = el)}
+                  animationData={ensembleJSON}
+                  autoPlay={true}></Vue3Lottie>
+
+                <div class={styles.desc}>
+                  <p>
+                    不同难度的小曲目、流行乐曲持续更新,每首曲目都带有伴奏,在课程之外提升练习兴趣
+                  </p>
+                </div>
+              </div>
+            </SwiperSlide>
+            <SwiperSlide>
+              <div class={styles.swipeContainer}>
+                <Vue3Lottie
+                  ref={el => {
+                    animation.animaRef3 = el;
+                  }}
+                  animationData={soloJSON}
+                  autoPlay={false}></Vue3Lottie>
+                <div class={styles.desc}>
+                  <p>
+                    每首合奏曲目都包含多分轨和对应分轨伴奏。同一教学体系下的合奏训练,合排更容易,演出更出彩
+                  </p>
+                </div>
+              </div>
+            </SwiperSlide>
+          </Swiper>
+
+          <div class={styles.pagination}>
+            <i
+              class={[
+                styles.paginationItem,
+                swipeIndex.value === 0 && styles.active
+              ]}></i>
+            <i
+              class={[
+                styles.paginationItem,
+                swipeIndex.value === 1 && styles.active
+              ]}></i>
+            <i
+              class={[
+                styles.paginationItem,
+                swipeIndex.value === 2 && styles.active
+              ]}></i>
+          </div>
+        </div>
+
+        <div class={styles.section2}>
+          <div class={[styles.title]}>
+            <span>训练统计</span>
+          </div>
+          <div class={[styles.content, styles.center]}>
+            学生练习情况统计,让您随时掌握训练情况
+          </div>
+
+          <img src={img1} class={'w100'} />
+        </div>
+
+        <div class={styles.section3}>
+          <div class={[styles.title]}>
+            <span>即时通讯</span>
+          </div>
+          <div class={[styles.content]}>
+            自定义教学群组,让学生的问题及时解决,让学生和家长感受到全方面的优秀服务
+          </div>
+
+          <img src={img2} class={'w100'} />
+        </div>
+
+        <div class={styles.section4}>
+          <div class={[styles.title]}>
+            <span>高效管理</span>
+          </div>
+          <div class={[styles.content, styles.center]}>
+            老师、学生信息一首掌握,让您的管理更加高效
+          </div>
+
+          <img src={img3} class={'w100'} />
+        </div>
+      </div>
+    );
+  }
+});

binární
src/views/home/images/co-ai/banner.png


binární
src/views/home/images/co-ai/change.png


binární
src/views/home/images/co-ai/co-ai.png


binární
src/views/home/images/co-ai/evaluation-bg.png


binární
src/views/home/images/co-ai/evaluation.png


binární
src/views/home/images/co-ai/music-bg.png


binární
src/views/home/images/co-ai/music.png


binární
src/views/home/images/co-ai/title-1.png


binární
src/views/home/images/co-ai/title-2.png


binární
src/views/home/images/co-person/banner.png


binární
src/views/home/images/co-person/icon-tip.png


binární
src/views/home/images/co-person/img1.png


binární
src/views/home/images/co-person/img2-bg.png


binární
src/views/home/images/co-person/img2.png


binární
src/views/home/images/co-person/img3.png


binární
src/views/home/images/co-person/img4-bg.png


binární
src/views/home/images/co-person/img4.png


binární
src/views/home/images/co-person/title-1.png


binární
src/views/home/images/co-tenant/banner.png


binární
src/views/home/images/co-tenant/img1-bg.png


binární
src/views/home/images/co-tenant/img1.png


binární
src/views/home/images/co-tenant/img2.png


binární
src/views/home/images/co-tenant/img3-bg.png


binární
src/views/home/images/co-tenant/img3.png


binární
src/views/home/images/co-tenant/title-1.png


binární
src/views/home/images/co-tenant/title-2.png


binární
src/views/home/images/music-room/banner.png


binární
src/views/home/images/music-room/img1.png


binární
src/views/home/images/music-room/img2-bg.png


binární
src/views/home/images/music-room/img2.png


binární
src/views/home/images/music-room/img3.png


binární
src/views/home/images/music-room/img4-bg.png


binární
src/views/home/images/music-room/img4.png


binární
src/views/home/images/music-room/title-1.png


binární
src/views/home/images/music-room/title-2.png


binární
src/views/home/images/piano-room/banner.png


binární
src/views/home/images/piano-room/img1.png


binární
src/views/home/images/piano-room/img2.png


binární
src/views/home/images/piano-room/img3-bg.png


binární
src/views/home/images/piano-room/img3.png


binární
src/views/home/images/piano-room/img4.png


binární
src/views/home/images/piano-room/img5.png


binární
src/views/home/images/piano-room/img6-bg.png


binární
src/views/home/images/piano-room/img6.png


binární
src/views/home/images/piano-room/title-1.png


+ 71 - 3
src/views/home/index.module.less

@@ -1,4 +1,72 @@
-.home {
-  font-size: 20px;
-  color: var(--k-primary);
+.banner {
+  width: 100%;
+  height: 422px;
+
+  .bannerImg {
+    width: 100%;
+    height: 422px;
+    object-fit: cover;
+    transition: all 0.2s ease-in-out;
+  }
+}
+
+.tabs {
+  :global {
+    .van-tabs__nav--line {
+      padding-bottom: 0;
+      display: flex;
+      align-items: center;
+    }
+
+    .van-tabs__wrap {
+      height: 74px;
+    }
+
+    .van-tab {
+      height: 34px;
+      padding: 0 19px;
+      border-radius: 17px;
+      background: #F4F5F6;
+      font-size: 14px;
+      color: rgba(0, 0, 0, 0.5);
+      margin-right: 8px;
+
+      &.van-tab--active {
+        color: #FFFFFF;
+        font-weight: 600;
+      }
+
+      &:nth-child(1) {
+        &.van-tab--active {
+          background: linear-gradient(270deg, #52E6AD 0%, #00C7BB 100%);
+        }
+      }
+
+      &:nth-child(2) {
+        &.van-tab--active {
+          background: linear-gradient(274deg, #00E3D7 0%, #00B1FF 100%);
+        }
+      }
+
+      &:nth-child(3) {
+        &.van-tab--active {
+          background: linear-gradient(270deg, #1BD2FF 0%, #1AADFF 100%);
+        }
+      }
+
+      &:nth-child(4) {
+        &.van-tab--active {
+          background: linear-gradient(270deg, #FF3C81 0%, #FF76A6 100%);
+        }
+      }
+
+      &:nth-child(5) {
+        margin-right: 0;
+
+        &.van-tab--active {
+          background: linear-gradient(270deg, #52E6AD 0%, #00C7BB 100%);
+        }
+      }
+    }
+  }
 }

+ 65 - 2
src/views/home/index.tsx

@@ -1,9 +1,72 @@
-import { defineComponent } from 'vue';
+import { defineComponent, reactive } from 'vue';
 import styles from './index.module.less';
+import MHeader from '@/components/m-header';
+import MFooter from '@/components/m-footer';
+import { Tab, Tabs } from 'vant';
+import aiBanner from './images/co-ai/banner.png';
+import painoBanner from './images/piano-room/banner.png';
+import musicBanner from './images/music-room/banner.png';
+import tenantBanner from './images/co-tenant/banner.png';
+import personBanner from './images/co-person/banner.png';
+import CoAi from './co-ai';
+import PianoRoom from './piano-room';
+import MusicRoom from './music-room';
+import CoTenant from './co-tenant';
+import CoPerson from './co-person';
 
 export default defineComponent({
   name: 'home-page',
   setup() {
-    return () => <div class={styles.home}>首页</div>;
+    const state = reactive({
+      activeTab: 4,
+      banner: aiBanner
+    });
+    return () => (
+      <div class={styles.home}>
+        <MHeader />
+
+        <div class={styles.banner}>
+          <img class={styles.bannerImg} src={state.banner} />
+        </div>
+
+        <Tabs
+          v-model:active={state.activeTab}
+          lazyRender={false}
+          class={styles.tabs}
+          lineHeight={0}
+          shrink
+          onUpdate:active={(val: number) => {
+            if (val === 1) {
+              state.banner = aiBanner;
+            } else if (val === 2) {
+              state.banner = painoBanner;
+            } else if (val === 3) {
+              state.banner = musicBanner;
+            } else if (val === 4) {
+              state.banner = tenantBanner;
+            } else if (val === 5) {
+              state.banner = personBanner;
+            }
+          }}>
+          <Tab title="小酷Ai" name={1}>
+            <CoAi />
+          </Tab>
+          <Tab title="云酷琴房" name={2}>
+            <PianoRoom />
+          </Tab>
+          <Tab title="音乐数字课堂" name={3}>
+            <MusicRoom />
+          </Tab>
+          <Tab title="酷乐秀机构版" name={4}>
+            <CoTenant />
+          </Tab>
+          <Tab title="酷乐秀个人版" name={5}>
+            <CoPerson />
+          </Tab>
+        </Tabs>
+
+        <MFooter />
+      </div>
+    );
   }
 });

+ 81 - 0
src/views/home/music-room/index.module.less

@@ -0,0 +1,81 @@
+.title {
+  position: relative;
+  text-align: center;
+  font-size: 22px;
+  font-weight: 600;
+  color: #000000;
+  line-height: 30px;
+  letter-spacing: 1px;
+
+  span {
+    position: relative;
+    z-index: 9;
+  }
+
+  &::before {
+    content: '';
+    position: absolute;
+    bottom: 0;
+    left: 50%;
+    width: 88px;
+    height: 7px;
+    transform: translate(-50%, 0);
+    background: url('../images/music-room/title-1.png') no-repeat center;
+    background-size: contain;
+  }
+}
+
+.title::before {
+  width: 110px;
+  background: url('../images/music-room/title-2.png') no-repeat center;
+  background-size: contain;
+}
+
+
+.content {
+  padding: 8px 24px 0;
+  font-size: 14px;
+  color: rgba(0, 0, 0, 0.5);
+  line-height: 24px;
+}
+
+.section1 {
+  background: #fff;
+  padding: 20px 0 30px;
+
+  .content {
+    padding-bottom: 22px;
+  }
+}
+
+.section2 {
+  padding: 40px 0;
+  background: url('../images/music-room/img2-bg.png') no-repeat center #fff;
+  background-size: cover;
+
+  .content {
+    padding-top: 8px;
+    padding-bottom: 17px;
+  }
+}
+
+.section3 {
+  padding: 40px 0 46px;
+  background-color: #fff;
+
+  .content {
+    padding-top: 8px;
+    padding-bottom: 14px;
+  }
+}
+
+.section4 {
+  padding: 40px 0 46px;
+  background: url('../images/music-room/img4-bg.png') no-repeat center #fff;
+  background-size: cover;
+
+  .content {
+    padding-top: 8px;
+    padding-bottom: 12px;
+  }
+}

+ 59 - 0
src/views/home/music-room/index.tsx

@@ -0,0 +1,59 @@
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+import img1 from '../images/music-room/img1.png';
+import img2 from '../images/music-room/img2.png';
+import img3 from '../images/music-room/img3.png';
+import img4 from '../images/music-room/img4.png';
+
+export default defineComponent({
+  name: 'music-room',
+  setup() {
+    return () => (
+      <div class={styles.musicRoom}>
+        <div class={styles.section1}>
+          <div class={[styles.title]}>
+            <span>教学资源</span>
+          </div>
+          <div class={styles.content}>
+            教学资源即拿即用,原创资源共享,使您优秀的教学方式影响更多人
+          </div>
+
+          <img src={img1} class={'w100'} />
+        </div>
+
+        <div class={styles.section2}>
+          <div class={[styles.title]}>
+            <span>课后作业</span>
+          </div>
+          <div class={styles.content}>
+            练习、评测两种作业模式混合练习,让学生的作业不再枯燥。学生演奏问题精准呈现,老师因地制宜
+          </div>
+
+          <img src={img2} class={'w100'} />
+        </div>
+
+        <div class={styles.section3}>
+          <div class={[styles.title]}>
+            <span>家校互通</span>
+          </div>
+          <div class={styles.content}>
+            班级群聊、老师联系人即时沟通,在家练习遇到困难随时请教,不限时间、不限地点,老师就在你身边
+          </div>
+
+          <img src={img3} class={'w100'} />
+        </div>
+
+        <div class={styles.section4}>
+          <div class={[styles.title, styles.title1]}>
+            <span>自定义教材</span>
+          </div>
+          <div class={styles.content}>
+            自定义教材内容,让老师潜心研究的校本设计转化为现实可执行的课堂教学内容,海量共享资源辅助校本课程设计
+          </div>
+
+          <img src={img4} class={'w100'} />
+        </div>
+      </div>
+    );
+  }
+});

+ 88 - 0
src/views/home/piano-room/index.module.less

@@ -0,0 +1,88 @@
+.title {
+  position: relative;
+  text-align: center;
+  font-size: 22px;
+  font-weight: 600;
+  color: #000000;
+  line-height: 30px;
+  letter-spacing: 1px;
+  padding-bottom: 13px;
+
+  span {
+    position: relative;
+    z-index: 9;
+  }
+
+  &::before {
+    content: '';
+    position: absolute;
+    bottom: 0;
+    left: 50%;
+    width: 34px;
+    height: 11px;
+    transform: translate(-50%, 4px);
+    background: url('../images/piano-room/title-1.png') no-repeat center;
+    background-size: contain;
+  }
+}
+
+
+
+.content {
+  padding: 8px 24px 0;
+  font-size: 14px;
+  color: rgba(0, 0, 0, 0.5);
+  line-height: 24px;
+}
+
+.section1 {
+  background: #fff;
+  padding: 20px 0 60px;
+
+  .content {
+    padding-bottom: 22px;
+  }
+
+  .content1 {
+    padding-top: 26px;
+    padding-bottom: 22px;
+  }
+}
+
+.section2 {
+  padding: 40px 0 60px;
+  background: url('../images/piano-room/img3-bg.png') no-repeat center #fff;
+  background-size: cover;
+
+  .content {
+    padding-bottom: 10px;
+  }
+
+  .content1 {
+    padding-top: 38px;
+    padding-bottom: 10px;
+  }
+
+  .content2 {
+    padding: 0 24px;
+  }
+}
+
+.section3 {
+  background: #fff;
+  padding: 40px 0 60px;
+
+  .content {
+    padding: 0 24px 12px;
+  }
+}
+
+.section4 {
+  padding: 40px 0 49px;
+  background: url('../images/piano-room/img6-bg.png') no-repeat center #fff;
+  background-size: cover;
+
+  .content {
+    padding-bottom: 12px;
+  }
+}

+ 76 - 0
src/views/home/piano-room/index.tsx

@@ -0,0 +1,76 @@
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+import img1 from '../images/piano-room/img1.png';
+import img2 from '../images/piano-room/img2.png';
+import img3 from '../images/piano-room/img3.png';
+import img4 from '../images/piano-room/img4.png';
+import img5 from '../images/piano-room/img5.png';
+import img6 from '../images/piano-room/img6.png';
+
+export default defineComponent({
+  name: 'piano-room',
+  setup() {
+    return () => (
+      <div class={styles.pianoRoom}>
+        <div class={styles.section1}>
+          <div class={[styles.title]}>
+            <span>多人上课,还可以独奏哦!</span>
+          </div>
+          <div class={styles.content}>
+            与一般的网课不同,云酷琴房的“音乐演奏模式”,高度还原乐器演奏和管乐学习的现场感,多人课堂在线传播稳定流畅。最大支持1对9人的多人在线教学。当然一对一的模式,更是不在话下了。
+          </div>
+
+          <img src={img1} class={'w100'} />
+
+          <div class={[styles.content, styles.content1]}>
+            学员和老师可以即时通讯,互动交流更便捷。上课时间提前预约,既可以合理利用学员的碎片化时间,还能够让学员平时学习管乐薄弱的地方得到老师的直接辅导,全程教学记录,学习成果清晰可见。
+          </div>
+
+          <img src={img2} class={'w100'} />
+        </div>
+
+        <div class={styles.section2}>
+          <div class={[styles.title]}>
+            <span>
+              高保真,回声消除
+              <br />
+              给你一双灵敏的耳朵
+            </span>
+          </div>
+          <div class={styles.content}>
+            在线上教学中,老师能听到学员演奏中的问题,全靠“云酷琴房”的高保真技术。技术上做到了全频带音频编码、智能降噪、音质高度还原。
+          </div>
+          <img src={img3} class={'w100'} />
+          <div class={[styles.content, styles.content1]}>
+            针对管乐不同的声部做了不同的解析,保证我们的音频还原度为95%以上,基本与线下无异,安卓设备和ios设备有不同的模式,安卓为“音乐模式”,ios为“长音模式”。
+          </div>
+          <img src={img4} class={'w100'} />
+          <div class={[styles.content, styles.content2]}>
+            软件设计中也做到了回声消除,5等级、自适应噪声抑制;专有长音演奏保真算法。
+          </div>
+        </div>
+
+        <div class={styles.section3}>
+          <div class={[styles.title]}>
+            <span>低延迟,师生互动更流畅!</span>
+          </div>
+          <div class={styles.content}>
+            在低延迟的教学环境中,师生沟通更加顺畅,还原面对面教学体验
+          </div>
+
+          <img src={img5} class={'w100'} />
+        </div>
+
+        <div class={styles.section4}>
+          <div class={[styles.title]}>
+            <span>界面方便,多维度教学</span>
+          </div>
+          <div class={styles.content}>
+            软件中具备白板互动教学,内置白板书写工具;自有教学资源共享教学;本地曲谱上传,能够为学员提供线下教学体验不到的便利。
+          </div>
+          <img src={img6} class={'w100'} />
+        </div>
+      </div>
+    );
+  }
+});

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů