skyblued 2 лет назад
Родитель
Сommit
162d825f83

+ 46 - 33
src/views/accompany/category.tsx

@@ -1,37 +1,50 @@
-import { defineComponent } from "vue";
-import { getImage } from "./images";
+import request from '@/helpers/request'
+import { state } from '@/state'
+import { Icon } from 'vant'
+import { defineComponent, reactive, onMounted } from 'vue'
+import { useRouter } from 'vue-router'
+import { getImage } from './images'
 import styles from './index.module.less'
 
 export default defineComponent({
-    name: 'accompany-category',
-    setup(props, ctx) {
-        const svgs = [
-            {
-                icon: getImage('l1.png'),
-                title: '声部训练',
-                subtitle: '乐器基础,巩固自己的基本功'
-            },
-            {
-                icon: getImage('l2.png'),
-                title: '合奏训练',
-                subtitle: '团队协作,加强协调配合能力'
-            },
-            {
-                icon: getImage('l3.png'),
-                title: '独奏曲目',
-                subtitle: '热播金曲,练习更加有趣'
-            },
-        ]
-        return () => (
-            <div class={styles.accompanyCategory}>
-                {svgs.map((item: any) => {
-                    return (
-                        <div class={styles.container} style={{backgroundImage: `url(${item.icon})`}}>
-                            {/* <img src={item.icon} /> */}
-                        </div>
-                    )
-                })}
+  name: 'accompany-category',
+  props: {
+    musicTree: {
+      type: Array,
+      default: () => []
+    }
+  },
+  setup(props, ctx) {
+    const router = useRouter()
+
+    return () => (
+      <div class={styles.accompanyCategory}>
+        {props.musicTree.map((item: any) => {
+          return (
+            <div
+              class={styles.container}
+              style={{ backgroundImage: `url(${item.icon})` }}
+              onClick={() => {
+                router.push({
+                  path: '/accompany/musicList',
+                  query: {
+                    categorieid: item.id
+                  }
+                })
+              }}
+            >
+              <div class={styles.title}>{item.title}</div>
+              <div class={styles.sub}>{item.subtitle}</div>
+              <div
+                class={styles.btn}
+                style={{ backgroundImage: `url(${item.btnIcon})`, color: item.color }}
+              >
+                GO <Icon name="arrow" />
+              </div>
             </div>
-        )
-    },
-})
+          )
+        })}
+      </div>
+    )
+  }
+})

+ 21 - 0
src/views/accompany/images/icon-music.svg

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>切片</title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#FFF5EF" offset="0%"></stop>
+            <stop stop-color="#FFE7DA" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="选中曲目" transform="translate(-25.000000, -207.000000)">
+            <g id="icon" transform="translate(25.000000, 207.000000)">
+                <rect id="矩形" fill="url(#linearGradient-1)" x="0" y="0" width="40" height="40" rx="20"></rect>
+                <path d="M25.3693897,8.27934435 C23.7347804,7.52928137 21.9162246,7.11111111 20,7.11111111 C12.8816632,7.11111111 7.11111111,12.8816632 7.11111111,20 C7.11111111,27.1183368 12.8816632,32.8888889 20,32.8888889 C27.1183368,32.8888889 32.8888889,27.1183368 32.8888889,20 C32.8888889,17.374186 32.1036745,14.9317685 30.7552445,12.8947465" id="路径" stroke="#FF8057" stroke-width="1.2" stroke-linecap="round"></path>
+                <path d="M23.7133437,10.1276901 C22.3364421,9.60881141 20.8283531,9.37130665 19.2644166,9.48066774 C13.4547498,9.88691922 9.07441626,14.9259166 9.48066774,20.7355834 C9.88691922,26.5452502 14.9259166,30.9255837 20.7355834,30.5193323 C26.5452502,30.1130808 30.9255837,25.0740834 30.5193323,19.2644166 C30.3694741,17.1213451 29.5892259,15.1727668 28.3724427,13.5871973" id="路径备份" stroke="#FF8057" stroke-width="0.8" stroke-linecap="round"></path>
+                <circle id="椭圆形" stroke="#FF8057" stroke-width="2.53846154" cx="20.1658253" cy="20.7811988" r="4.12667408"></circle>
+                <polyline id="路径-9" stroke="#FF8057" stroke-width="2.53846154" stroke-linecap="round" stroke-linejoin="round" points="24.372921 21.428711 25.536191 12.2110011 30.2870439 10.1771036"></polyline>
+            </g>
+        </g>
+    </g>
+</svg>

+ 83 - 7
src/views/accompany/index.module.less

@@ -1,8 +1,84 @@
-.accompanyCategory{
-    .container{
-        margin: 8px 12px;
-        height: 140px;
-        background-repeat: no-repeat;
-        background-size: 100% 100%;
+.accompanyCategory {
+  box-sizing: border-box;
+  div {
+    box-sizing: border-box;
+  }
+  .container {
+    margin: 16px 12px;
+    height: 140px;
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    padding: 8px 20px;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-evenly;
+    align-items: flex-start;
+  }
+  .title {
+    font-size: 20px;
+    font-weight: 600;
+    color: #ffffff;
+    text-shadow: 0px 2px 4px #7b63ff;
+  }
+  .sub {
+    font-size: 14px;
+    font-weight: 500;
+    color: #ffffff;
+    text-shadow: 0px 2px 4px #8771ff;
+  }
+  .btn {
+    width: 90px;
+    height: 34px;
+    line-height: 28px;
+    padding-left: 20px;
+    background-repeat: no-repeat;
+    background-size: 100% 110%;
+    margin-left: -10px;
+    font-size: 18px;
+    font-weight: 500;
+  }
+}
+
+.accompany-music-list{
+    div{
+        box-sizing: border-box;
     }
-}
+    .filter{
+        display: flex;
+        align-items: center;
+        height: 60px;
+        background-color: #F8F8F8;
+        :global{
+            .van-search{
+                flex: 1;
+                padding: 0 12px;
+            }
+            .van-search__field{
+                background-color: #fff;
+                border-radius: 20px 0 0 20px;
+                padding-left: 12px;
+                height: 36px;
+            }
+            .van-search__action{
+                border-radius: 0 20px 20px 0;
+                background-color: #fff;
+                height: 36px;
+                display: flex;
+                align-items: center;
+            }
+        }
+        .searchBtn{
+            width: 56px;
+            height: 27px;
+            line-height: 27px;
+            border-radius: 20px;
+            background-color: var(--van-primary);
+            font-size: 14px;
+            text-align: center;
+            color: #fff;
+            &:active{
+                opacity: .8;
+            }
+        }
+    }
+}

+ 69 - 10
src/views/accompany/index.tsx

@@ -1,14 +1,73 @@
-import { defineComponent } from "vue";
-import { RouterView } from "vue-router";
+import request from '@/helpers/request'
+import { state } from '@/state'
+import { defineComponent, reactive, onMounted } from 'vue'
+import { RouterView } from 'vue-router'
+import { getImage } from './images'
 import styles from './index.module.less'
 
 export default defineComponent({
-    name: 'accompany',
-    setup(props, ctx) {
-        return () => (
-            <div class={styles.accompany}>
-                <RouterView />
-            </div>
+  name: 'accompany',
+  setup(props, ctx) {
+    const svgs = [
+      {
+        icon: getImage('l1.png'),
+        btnIcon: getImage('b1.svg'),
+        color: '#9881FF',
+        title: '声部训练',
+        subtitle: '乐器基础,巩固自己的基本功',
+        btnText: 'GO >'
+      },
+      {
+        icon: getImage('l2.png'),
+        btnIcon: getImage('b2.svg'),
+        color: '#F67146',
+        title: '合奏训练',
+        subtitle: '团队协作,加强协调配合能力',
+        btnText: 'GO >'
+      },
+      {
+        icon: getImage('l3.png'),
+        btnIcon: getImage('b2.svg'),
+        color: '#4698FF',
+        title: '独奏曲目',
+        subtitle: '热播金曲,练习更加有趣',
+        btnText: 'GO >'
+      }
+    ]
+    const data = reactive({
+      svgs: [] as any,
+      musicTreeActive: ''
+    })
+    const getTree = async () => {
+      try {
+        const res: any = await request.get(
+          state.platformApi + '/musicSheetCategories/queryTree?enable=true'
         )
-    },
-})
+        if (Array.isArray(res?.data)) {
+          data.svgs = res.data.map((n: any, index: number) => {
+            // console.log('🚀 ~ n', n)
+            return {
+              ...n,
+              id: n.id,
+              icon: n.coverImg,
+              btnIcon: getImage('b2.svg'),
+              color: svgs[index].color,
+              title: n.name,
+              subtitle: svgs[index].subtitle,
+              btnText: 'GO >'
+            }
+          })
+          //   console.log('🚀 ~ data.svgs', data.svgs)
+        }
+      } catch (error) {}
+    }
+    onMounted(() => {
+      getTree()
+    })
+    return () => (
+      <div class={styles.accompany}>
+        <RouterView musicTree={data.svgs} />
+      </div>
+    )
+  }
+})

+ 231 - 10
src/views/accompany/music-list.tsx

@@ -1,13 +1,234 @@
-import { defineComponent } from "vue";
+import OEmpty from '@/components/o-empty'
+import { postMessage } from '@/helpers/native-message'
+import request from '@/helpers/request'
+import { state } from '@/state'
+import {
+  Cell,
+  CellGroup,
+  DropdownItem,
+  DropdownMenu,
+  Icon,
+  List,
+  Popover,
+  PullRefresh,
+  Search,
+  Sticky
+} from 'vant'
+import { defineComponent, reactive, ref, onMounted, nextTick, computed } from 'vue'
+import { useRoute } from 'vue-router'
+import { getImage } from './images'
 import styles from './index.module.less'
 
 export default defineComponent({
-    name: 'accompany-music-list',
-    setup(props, ctx) {
-        return () => (
-            <div class={styles.accompany}>
-                曲谱
-            </div>
-        )
-    },
-})
+  name: 'accompany-music-list',
+  props: {
+    musicTree: {
+      type: Array,
+      default: () => []
+    }
+  },
+  setup(props, ctx) {
+    const route = useRoute()
+    const imgDefault = getImage('icon-music.svg')
+    const data = reactive({
+      loading: true,
+      finished: false,
+      refreshing: false,
+      pagenation: {
+        page: 1,
+        rows: 20
+      },
+      value1: null,
+      value2: null,
+      PopoverOpen: false,
+      list: [] as any,
+      keyword: ''
+    })
+    const option1 = computed(() => {
+      const v1: any = props.musicTree.find((n: any) => n.id == route.query.categorieid)
+      console.log('🚀 ~ v1', v1)
+      if (Array.isArray(v1?.musicSheetCategoriesList)) {
+        const list = v1.musicSheetCategoriesList.map((m: any) => {
+          if (!data.value1) {
+            data.value1 = m.id
+            data.value2 = null
+          }
+          return {
+            text: m.name,
+            value: m.id
+          }
+        })
+        return list
+      }
+      return []
+    })
+    const option2 = computed(() => {
+      const v1: any = props.musicTree.find((n: any) => n.id == route.query.categorieid)
+      //   console.log('🚀 ~ v1', v1)
+      if (Array.isArray(v1?.musicSheetCategoriesList)) {
+        const v2: any = v1.musicSheetCategoriesList.find((n: any) => n.id == data.value1)
+        if (Array.isArray(v2?.musicSheetCategoriesList)) {
+          const list = [{ text: '全部', value: null }].concat(
+            v2.musicSheetCategoriesList.map((m: any) => {
+              return {
+                text: m.name,
+                value: m.id
+              }
+            })
+          )
+          return list
+        }
+      }
+      return [{ text: '全部', value: null }]
+    })
+
+    const getList = async () => {
+      try {
+        const res: any = await request.post(state.platformApi + '/musicSheet/page', {
+          data: {
+            ...data.pagenation,
+            keyword: data.keyword,
+            musicTag: data.value2 || data.value1
+          }
+        })
+        if (Array.isArray(res?.data?.rows)) {
+          data.list = [].concat(data.list, res.data.rows)
+          data.pagenation.page += 1
+          if (!res.data.rows.length) {
+            data.finished = true
+          }
+          if (data.refreshing) {
+            data.refreshing = false
+          }
+        } else {
+          data.finished = true
+        }
+      } catch (error) {}
+      nextTick(() => {
+        data.loading = false
+      })
+    }
+    const onRefresh = () => {
+      console.log('下拉刷新')
+      // 清空列表数据
+      data.pagenation.page = 1
+      data.finished = false
+      data.loading = false
+      data.list = []
+      // 重新加载数据
+      getList()
+    }
+    // 重置搜索
+    const onSearch = () => {
+      console.log(234)
+      data.pagenation.page = 1
+      data.finished = false
+      data.loading = false
+      data.list = []
+      getList()
+    }
+    onMounted(() => {
+      getList()
+    })
+    //进入云教练
+    const openView = (item: any) => {
+      const Authorization = sessionStorage.getItem('Authorization') || ''
+      const dev = /(localhost|192)/.test(location.host)
+      console.log(dev, 'https://ponline.colexiu.com')
+      let src = `${
+        dev ? `http://192.168.3.114:3000` : location.origin
+      }/orchestra-music-score/#/?id=${item.id}&Authorization=${Authorization}`
+      postMessage({
+        api: 'openAccompanyWebView',
+        content: {
+          url: src,
+          orientation: 0,
+          isHideTitle: true,
+          statusBarTextColor: false,
+          isOpenLight: true
+        }
+      })
+    }
+    return () => (
+      <div class={styles['accompany-music-list']}>
+        <Sticky>
+          <DropdownMenu>
+            <DropdownItem
+              v-model:modelValue={data.value1}
+              options={option1.value}
+              onChange={() => onSearch()}
+            ></DropdownItem>
+            <DropdownItem
+              v-model:modelValue={data.value2}
+              options={option2.value as any}
+              onChange={() => onSearch()}
+            ></DropdownItem>
+          </DropdownMenu>
+          <div class={styles.filter}>
+            <Search
+              placeholder="请输入搜索关键词"
+              background="#F8F8F8"
+              shape="round"
+              showAction={true}
+              v-model:modelValue={data.keyword}
+            >
+              {{
+                // label: () => (
+                //   <Popover
+                //     v-model:show={data.PopoverOpen}
+                //     actions={actions}
+                //     placement="bottom-start"
+                //   >
+                //     {{
+                //       reference: () => (
+                //         <div>
+                //           长笛 <Icon name="arrow" />
+                //         </div>
+                //       )
+                //     }}
+                //   </Popover>
+                // ),
+                action: () => (
+                  <div class={styles.searchBtn} onClick={() => onSearch()}>
+                    搜索
+                  </div>
+                )
+              }}
+            </Search>
+          </div>
+        </Sticky>
+        <PullRefresh v-model:modelValue={data.refreshing} onRefresh={onRefresh}>
+          <List
+            immediateCheck={false}
+            v-model:loading={data.loading}
+            v-model:finished={data.finished}
+            finishedText="没有更多了"
+            onLoad={() => {
+              getList()
+            }}
+          >
+            <CellGroup inset>
+              {data.list.map((item: any) => {
+                return (
+                  <Cell
+                    center
+                    title={item.musicSheetName}
+                    isLink
+                    onClick={() => openView(item)}
+                  >
+                    {{
+                      icon: () => (
+                        <Icon style={{ marginRight: '12px' }} size={40} name={imgDefault} />
+                      )
+                    }}
+                  </Cell>
+                )
+              })}
+            </CellGroup>
+          </List>
+        </PullRefresh>
+        {!data.loading && !data.list.length && <OEmpty tips="空空如也" />}
+      </div>
+    )
+  }
+})