Browse Source

添加搜索条件

lex 1 năm trước cách đây
mục cha
commit
220119d498

+ 42 - 0
src/tenant/music/album-detail/index.module.less

@@ -292,6 +292,40 @@
     min-height: 40vh;
   }
 
+  .alumnTitleSection {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+
+  .subjectSearch {
+    position: relative;
+    font-size: 14px;
+    color: #333;
+    padding-right: 12px;
+
+    &::after {
+      position: absolute;
+      top: 2px;
+      right: 0;
+      border: 4px solid;
+      border-color: transparent transparent var(--van-gray-4) var(--van-gray-4);
+      transform: rotate(-45deg);
+      opacity: .8;
+      content: "";
+    }
+
+    &.active {
+      color: #FE2451;
+
+      &::after {
+        border-color: transparent transparent #FE2451 #FE2451;
+        transform: rotate(135deg);
+        top: 6px;
+      }
+    }
+  }
+
   .alumnTitle {
     display: flex;
     align-items: center;
@@ -449,3 +483,11 @@
     }
   }
 }
+
+.popupTitle {
+  padding: 20px 0 12px;
+  text-align: center;
+  font-size: 16px;
+  font-weight: bold;
+  color: #333;
+}

+ 55 - 7
src/tenant/music/album-detail/index.tsx

@@ -32,6 +32,7 @@ import SongShare from '../component/song-share'
 import icon_music_list from './icon_music_list.png'
 import iconMenu from './icon-menu.png'
 import TheSticky from '@/components/the-sticky'
+import SelectSubject from '../search/select-subject'
 
 const noop = () => {}
 
@@ -47,6 +48,10 @@ export default defineComponent({
     localStorage.setItem('behaviorId', getRandomKey())
     const router = useRouter()
     const route = useRoute()
+    const subjects = reactive({
+      name: route.query.subjectName || '全部声部',
+      id: route.query.subjectId || null
+    })
     const params = reactive({
       search: '',
       relatedNum: 6, //相关专辑数
@@ -54,6 +59,7 @@ export default defineComponent({
       rows: 200
     })
     const albumDetail = ref<any>(null)
+    const subjectPopup = ref(false)
     // const data = ref<any>(null)
     const rows = ref<any[]>([])
     const loading = ref(false)
@@ -76,7 +82,11 @@ export default defineComponent({
         const res = await request.post('/music/album/detail', {
           prefix:
             state.platformType === 'TEACHER' ? '/api-teacher' : '/api-student',
-          data: { id: id || route.params.id, ...params }
+          data: {
+            id: id || route.params.id,
+            ...params,
+            subjectIds: subjects.id
+          }
         })
         const { musicSheetList, ...rest } = res.data
         rows.value = [...musicSheetList.rows]
@@ -209,7 +219,16 @@ export default defineComponent({
           }
         })
         // this.routerTo()
-      } catch {}
+      } catch {
+        //
+      }
+    }
+
+    const onComfirmSubject = item => {
+      subjects.name = item.name
+      subjects.id = item.id
+      subjectPopup.value = false
+      FetchList()
     }
 
     const shareStatus = ref<boolean>(false)
@@ -330,10 +349,23 @@ export default defineComponent({
           <div class={styles.alumnContainer}>
             <div class={styles.alumnList}>
               {/* <Title title="曲目列表" isMore={false} /> */}
-              <div class={styles.alumnTitle}>
-                <img src={iconMenu} class={styles.iconMenu} />
-                曲目列表{' '}
-                <span>({albumDetail.value?.musicSheetCount || 0})</span>
+              <div class={styles.alumnTitleSection}>
+                <div class={styles.alumnTitle}>
+                  <img src={iconMenu} class={styles.iconMenu} />
+                  曲目列表{' '}
+                  <span>({albumDetail.value?.musicSheetCount || 0})</span>
+                </div>
+                {albumDetail.value?.albumType !== 'CONCERT' && (
+                  <div
+                    class={[
+                      styles.subjectSearch,
+                      subjectPopup.value ? styles.active : ''
+                    ]}
+                    onClick={() => (subjectPopup.value = true)}
+                  >
+                    {subjects.name}
+                  </div>
+                )}
               </div>
               <Song
                 showNumber
@@ -362,7 +394,7 @@ export default defineComponent({
                 }}
               />
 
-              {rows.value && rows.value.length <= 0 && (
+              {rows.value && rows.value.length <= 0 && !loading.value && (
                 <ColResult btnStatus={false} tips="暂无曲目" />
               )}
             </div>
@@ -499,6 +531,22 @@ export default defineComponent({
               </div>
             </ColShare>
           </Popup>
+
+          <Popup
+            position="bottom"
+            round
+            v-model:show={subjectPopup.value}
+            closeable
+          >
+            <div class={styles.popupTitle}>选择声部</div>
+            <SelectSubject
+              type="ALBUM"
+              isShowAllSubject
+              // isReset
+              searchParams={subjects}
+              onComfirm={onComfirmSubject}
+            />
+          </Popup>
         </div>
       )
     }

+ 6 - 3
src/tenant/music/album/index.module.less

@@ -54,12 +54,15 @@
 
     .van-dropdown-item__content {
       border-radius: 0px 0px 20px 20px;
+    }
 
+    .van-dropdown-menu__title--active {
+      color: #FE2451;
     }
-  }
 
-  .titleActive {
-    color: #FE2451;
+    .van-dropdown-menu__title--down:after {
+      border-color: transparent transparent #FE2451 #FE2451
+    }
   }
 }
 

+ 10 - 0
src/tenant/music/album/index.tsx

@@ -362,10 +362,20 @@ export default defineComponent({
                   lightText={lightTextC.value}
                   list={data.value.rows}
                   onGoto={(n: any) => {
+                    const subjects =
+                      baseState.platformType === 'TEACHER'
+                        ? teacherDetaultSubject.value
+                        : subject
+
+                    console.log(subjects)
                     router.push({
                       name: 'music-album-detail',
                       params: {
                         id: n.id
+                      },
+                      query: {
+                        subjectId: subjects.id,
+                        subjectName: subjects.name
                       }
                     })
                   }}

+ 27 - 0
src/tenant/music/search/select-subject.tsx

@@ -20,6 +20,11 @@ export default defineComponent({
         id: ''
       }
     },
+    // 是否显示全部声部
+    isShowAllSubject: {
+      type: Boolean,
+      default: false
+    },
     type: {
       type: String,
       default: 'MUSIC'
@@ -65,6 +70,28 @@ export default defineComponent({
           class={styles.searchResult}
           style={{ maxHeight: '45vh', overflowY: 'auto' }}
         >
+          {this.isShowAllSubject && (
+            <div
+              class={[
+                styles['radio-group'],
+                styles.radio,
+                styles['organ-radio']
+              ]}
+            >
+              <Tag
+                size="large"
+                plain={'' == this.subject.id}
+                type={'' == this.subject.id ? 'primary' : 'default'}
+                round
+                onClick={() => {
+                  this.subject = { id: '', name: '全部声部' } as any
+                }}
+              >
+                全部声部
+              </Tag>
+            </div>
+          )}
+
           {this.subjectList.map(
             (item: any) =>
               item.subjects &&

+ 99 - 20
src/views/music/album-detail/index.module.less

@@ -1,7 +1,8 @@
-.base > div {
+.base>div {
   background: url(./header-bg.png) no-repeat top center;
   // background-attachment: fixed;
 }
+
 .detail {
   overflow: hidden;
 
@@ -10,22 +11,26 @@
   --van-nav-bar-text-color: #fff;
   --van-nav-bar-title-text-color: #fff;
 }
+
 .base {
   :global(.van-sticky--fixed) {
     box-shadow: 10px 10px 10px var(--box-shadow-color);
   }
 }
+
 .img {
   width: 94px;
   height: 94px;
   margin-right: 18px;
   position: relative;
-  > img,
-  > div {
+
+  >img,
+  >div {
     position: absolute;
     border-radius: 10px;
     overflow: hidden;
   }
+
   &::before {
     content: '';
     width: 80px;
@@ -52,53 +57,64 @@
     z-index: 9;
   }
 }
+
 .shareBtn {
   display: flex;
   align-items: flex-start;
   color: #fff;
   font-size: 14px;
   line-height: 20px !important;
+
   :global(.van-image) {
     width: 18px;
     height: 18px;
     margin-right: 6px;
   }
 }
+
 .detailContent {
   background-color: white;
   padding: 0 14px;
   border-radius: 17px 17px 0px 0px;
+
   .main {
     padding-top: 24px;
     padding-bottom: 20px;
     display: flex;
   }
+
   .favoriteContaineer {
     border: none;
     color: var(--music-list-item-mate-color);
     height: auto;
+
     :global(.van-button__text) {
       display: flex;
       align-items: center;
+
       span {
         line-height: 1;
         padding-top: 2px;
       }
     }
-    > span {
+
+    >span {
       display: inline-block;
       line-height: 16px;
       margin-top: 1px;
     }
   }
+
   .favorite {
     font-size: 16px;
     margin-right: 5px;
   }
+
   .content {
     flex: 1;
     display: inline-grid;
-    > h4 {
+
+    >h4 {
       color: var(--music-list-item-title-color);
       font-size: 14px;
       height: 20px;
@@ -107,7 +123,8 @@
       // word-break: break-all;
       // text-overflow: ellipsis;
     }
-    > p {
+
+    >p {
       margin-top: 6px;
       /* prettier-ignore */
       font-size: 12PX;
@@ -119,11 +136,13 @@
     }
   }
 }
+
 .footerBar {
   padding: 12px 0;
   display: flex;
   justify-content: space-between;
-  > footer {
+
+  >footer {
     margin-top: 0;
   }
 }
@@ -137,6 +156,7 @@
   object-fit: cover;
   filter: blur(10px);
 }
+
 .musicContent {
   position: absolute;
   top: 0;
@@ -155,9 +175,11 @@
   padding: 16px;
   z-index: 11;
 }
+
 .alumWrap {
   display: flex;
   align-items: center;
+
   .img {
     width: 115px;
     height: 115px;
@@ -166,21 +188,26 @@
     overflow: hidden;
     margin-right: 14px;
   }
+
   .alumTitle {
     font-size: 18px;
     font-weight: 500;
     color: #fff;
     padding-bottom: 8px;
   }
+
   .alumDes {
     width: calc(100% - 129px);
+
     .des {
       color: #999;
     }
   }
 }
+
 .tags {
   margin: 6px -2px 22px -2px;
+
   .tag {
     margin: 0 2px;
     padding: 2px 6px;
@@ -189,27 +216,32 @@
     border-radius: 20px;
   }
 }
+
 .alumCollect {
   display: flex;
   align-items: center;
   padding-top: 20px;
   color: #999;
   font-size: 14px;
+
   img {
     display: inline-block;
     width: 14px;
     height: 14px;
     margin-right: 6px;
   }
+
   span {
     padding-top: 1px;
   }
+
   .right {
     display: flex;
     align-items: center;
     margin-left: 26px;
   }
 }
+
 .albumTips {
   background: rgba(0, 0, 0, 0.32);
   border-radius: 16px;
@@ -221,23 +253,57 @@
   color: #999999;
   display: flex;
   justify-content: space-between;
+
   .albumPrice {
     font-size: 14px;
     font-weight: bold;
     color: #ffaa00;
   }
 }
+
 .alumnContainer {
   position: relative;
   padding: 0 16px;
   // margin-top: -16px;
   z-index: 12;
+
   .alumnList {
     padding: 0 12px;
     border-radius: 18px;
     background-color: #fff;
     margin-bottom: 16px;
   }
+
+  .subjectSearch {
+    position: relative;
+    display: flex;
+    align-items: center;
+    margin-left: auto;
+    font-size: 14px;
+    color: #333;
+    padding-right: 12px;
+
+    &::after {
+      position: absolute;
+      top: 2px;
+      right: 0;
+      border: 4px solid;
+      border-color: transparent transparent var(--van-gray-4) var(--van-gray-4);
+      transform: rotate(-45deg);
+      opacity: .8;
+      content: "";
+    }
+
+    &.active {
+      color: var(--van-primary);
+
+      &::after {
+        border-color: transparent transparent var(--van-primary) var(--van-primary);
+        transform: rotate(135deg);
+        top: 6px;
+      }
+    }
+  }
 }
 
 .shareVip {
@@ -255,36 +321,43 @@
     height: 72px;
     border-radius: 10px;
   }
+
   .info {
     display: flex;
     flex-direction: column;
     margin-left: 6px;
     flex: 1;
     word-break: break-all;
-    > h4 {
+
+    >h4 {
       color: var(--music-list-item-title-color);
       font-size: 16px;
       font-weight: 600;
     }
-    > p {
+
+    >p {
       color: var(--music-list-item-mate-color);
       line-height: 17px;
     }
   }
-  .shareAlumCollect{
+
+  .shareAlumCollect {
     display: flex;
     align-items: center;
     color: #999;
     font-size: 14px;
+
     img {
       display: inline-block;
       width: 14px;
       height: 14px;
       margin-right: 6px;
     }
+
     span {
       padding-top: 1px;
     }
+
     .right {
       display: flex;
       align-items: center;
@@ -306,6 +379,7 @@
   color: #ffffff;
   line-height: 24px;
 }
+
 .buttonDiscount {
   position: absolute;
   top: -23px;
@@ -319,30 +393,35 @@
   color: #ffffff;
   line-height: 24px;
 }
-.shareMusicList{
+
+.shareMusicList {
   margin-top: 12px;
   box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.05);
   padding: 0 10px;
 }
-.albumShare{
-  :global{
-    .btnGroup{
-      .van-button{
+
+.albumShare {
+  :global {
+    .btnGroup {
+      .van-button {
         border: none;
       }
     }
-    .shareTeacherCustom{
+
+    .shareTeacherCustom {
       background: linear-gradient(270deg, #BAFFE7 0%, #C0DCFF 100%);
-      & > div:first-child{
+
+      &>div:first-child {
         display: flex;
         align-items: center;
         justify-content: center;
       }
     }
-    .downloadCustom{
-       & > div:last-child{
+
+    .downloadCustom {
+      &>div:last-child {
         border-left-style: dashed;
-       }
+      }
     }
   }
 }

+ 54 - 4
src/views/music/album-detail/index.tsx

@@ -38,6 +38,7 @@ import ColShare from '@/components/col-share'
 import iconShareMusic from '/src/views/music/component/images/icon_album_active.png'
 import SongShare from '../component/song-share'
 import icon_music_list from './icon_music_list.png'
+import SelectSubject from '../search/select-subject'
 
 const noop = () => {}
 
@@ -73,6 +74,11 @@ export default defineComponent({
     const background = ref<string>('rgba(55, 205, 177, 0)')
     const color = ref<string>('#fff')
     const heightInfo = ref<any>('auto')
+    const subjects = reactive({
+      show: false,
+      name: route.query.subjectName || '全部声部',
+      id: route.query.subjectId || null
+    })
 
     const FetchList = async (id?: any) => {
       if (loading.value) {
@@ -84,7 +90,11 @@ export default defineComponent({
         const res = await request.post('/music/album/detail', {
           prefix:
             state.platformType === 'TEACHER' ? '/api-teacher' : '/api-student',
-          data: { id: id || route.params.id, ...params }
+          data: {
+            id: id || route.params.id,
+            ...params,
+            subjectIds: subjects.id
+          }
         })
         const { musicSheetList, ...rest } = res.data
         rows.value = [...musicSheetList.rows]
@@ -220,8 +230,16 @@ export default defineComponent({
             orderNo
           }
         })
-        // this.routerTo()
-      } catch {}
+      } catch {
+        //
+      }
+    }
+
+    const onComfirmSubject = item => {
+      subjects.name = item.name
+      subjects.id = item.id
+      subjects.show = false
+      FetchList()
     }
 
     const shareStatus = ref<boolean>(false)
@@ -352,7 +370,22 @@ export default defineComponent({
           </div>
           <div class={styles.alumnContainer}>
             <div class={styles.alumnList}>
-              <Title title="曲目列表" isMore={false} />
+              <Title title="曲目列表" isMore={false}>
+                {{
+                  right: () =>
+                    albumDetail.value?.albumType === 'CONCERT' && (
+                      <div
+                        class={[
+                          styles.subjectSearch,
+                          subjects.show ? styles.active : ''
+                        ]}
+                        onClick={() => (subjects.show = true)}
+                      >
+                        {subjects.name}
+                      </div>
+                    )
+                }}
+              </Title>
               <Song
                 list={rows.value}
                 onDetail={(item: any) => {
@@ -513,6 +546,23 @@ export default defineComponent({
               </div>
             </ColShare>
           </Popup>
+
+          <Popup
+            position="bottom"
+            round
+            v-model:show={subjects.show}
+            closeable
+            safe-area-inset-bottom
+            onClose={() => (subjects.show = false)}
+            onClosed={() => (subjects.show = false)}
+          >
+            <SelectSubject
+              type="ALBUM"
+              isShowAllSubject
+              searchParams={subjects}
+              onComfirm={onComfirmSubject}
+            />
+          </Popup>
         </div>
       )
     }

+ 2 - 1
src/views/music/component/title/index.tsx

@@ -18,7 +18,7 @@ export default defineComponent({
       type: Function
     }
   },
-  setup(props) {
+  setup(props, { slots }) {
     return () => (
       <div class={styles.theTitle}>
         <div class={styles.title}>{props.title}</div>
@@ -34,6 +34,7 @@ export default defineComponent({
             <Icon name={IconArrow} size={17} />
           </div>
         )}
+        {slots.right && slots.right()}
       </div>
     )
   }

+ 25 - 0
src/views/music/search/select-subject.tsx

@@ -24,6 +24,10 @@ export default defineComponent({
       type: String,
       default: 'MUSIC'
     },
+    isShowAllSubject: {
+      type: Boolean,
+      default: false
+    },
     onComfirm: {
       type: Function,
       default: (item: any) => {}
@@ -66,6 +70,27 @@ export default defineComponent({
           class={styles.searchResult}
           style={{ maxHeight: '45vh', overflowY: 'auto' }}
         >
+          {this.isShowAllSubject && (
+            <div
+              class={[
+                styles['radio-group'],
+                styles.radio,
+                styles['organ-radio']
+              ]}
+            >
+              <Tag
+                size="large"
+                plain={'' == this.subject.id}
+                type={'' == this.subject.id ? 'primary' : 'default'}
+                round
+                onClick={() => {
+                  this.subject = { id: '', name: '全部声部' } as any
+                }}
+              >
+                全部声部
+              </Tag>
+            </div>
+          )}
           {this.subjectList.map(
             (item: any) =>
               item.subjects &&