lex-xin пре 7 месеци
родитељ
комит
fc9a42aae7

+ 2 - 1
src/components/col-header/index.tsx

@@ -187,7 +187,8 @@ export default defineComponent({
                 onClick-left={this.onClickLeft}
                 onClick-left={this.onClickLeft}
                 v-slots={{
                 v-slots={{
                   right: () =>
                   right: () =>
-                    (this.$slots.right && this.$slots.right()) || this.rightText
+                    (this.$slots.right && this.$slots.right()) || this.rightText,
+                  title: () => (this.$slots.title && this.$slots.title()) || this.headerTitle
                 }}
                 }}
               ></NavBar>
               ></NavBar>
             </div>
             </div>

+ 43 - 3
src/tenant/music/courseList/index.module.less

@@ -1,10 +1,11 @@
 .courseList {
 .courseList {
   min-height: 100vh;
   min-height: 100vh;
-  background-image: url('../../images/bg.png');
+  // background-image: url('../../images/bg.png');
+  background: linear-gradient( 180deg, #FFE8CE 0%, rgba(251,233,213,0) 100%) #F8F8F8;
   background-size: 100% 346px;
   background-size: 100% 346px;
   background-repeat: no-repeat;
   background-repeat: no-repeat;
   box-sizing: border-box;
   box-sizing: border-box;
-  background-color: #fafafa;
+  // background-color: #fafafa;
 }
 }
 
 
 .periodContent {
 .periodContent {
@@ -70,10 +71,49 @@
   }
   }
 }
 }
 
 
+.periodSection {
+  flex: 1;
+  background: #FFFFFF;
+  border-radius: 20px 20px 0px 0px;
+  // min-height: 40vh;
+}
+
+.periodHeader {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 20px 20px 12px;
+  .searchGroup {
+    padding: 3px 10px 3px 7px;
+    border-radius: 19px;
+    border: 1px solid rgba(255,128,87,0.5);
+    font-size: 14px;
+    color: rgba(0,0,0,0.4);
+    line-height: 20px;
+    display: flex;
+    align-items: center;
+    cursor: pointer;
+    .iconSearch {
+      // width: 20px;
+      flex-shrink: 0;
+      margin-right: 5px;
+      height: 12px;
+      // /deep/.van-icon__image {
+      //   margin: auto;
+      //   vertical-align: middle;
+      // }
+    }
+    span {
+      flex-shrink: 0;
+    }
+  }
+}
+
+
 .periodTitle {
 .periodTitle {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
-  padding: 20px 20px 0;
+  padding: 0;
 
 
   .pIcon {
   .pIcon {
     width: 20px;
     width: 20px;

+ 20 - 16
src/tenant/music/courseList/index.tsx

@@ -407,25 +407,28 @@ export default defineComponent({
               </div>
               </div>
             </div>
             </div>
           </div>
           </div>
+          <div class={styles.periodSection}>
           <TransitionGroup name="van-fade">
           <TransitionGroup name="van-fade">
             {!data.loading && (
             {!data.loading && (
               <>
               <>
-                <div key="periodTitle" class={styles.periodTitle}>
-                    <img class={styles.pIcon} src={iconList} />
-                    <div class={styles.pTitle}>课程列表</div>
-                    <div class={styles.pNum}>共{data.list.length}课</div>
-                  </div>
-                  <div class={styles.searchGroup} onClick={() => {
-                    router.push({
-                      path: '/courseListSearch',
-                      query: {
-                        id: route.query.id
-                      }
-                    })
-                  }}>
-                    <img src={iconSearch} class={styles.iconSearch} />
-                    <span class={styles.searchContent}>搜索素材</span>
-                  </div>
+                <div class={styles.periodHeader}>
+                  <div key="periodTitle" class={styles.periodTitle}>
+                      <img class={styles.pIcon} src={iconList} />
+                      <div class={styles.pTitle}>课程列表</div>
+                      <div class={styles.pNum}>共{data.list.length}课</div>
+                    </div>
+                    <div class={styles.searchGroup} onClick={() => {
+                      router.push({
+                        path: '/courseListSearch',
+                        query: {
+                          id: route.query.id
+                        }
+                      })
+                    }}>
+                      <img src={iconSearch} class={styles.iconSearch} />
+                      <span class={styles.searchContent}>搜索素材</span>
+                    </div>
+                </div>
 
 
                 <div key="list" class={styles.periodList}>
                 <div key="list" class={styles.periodList}>
                   <CellGroup inset>
                   <CellGroup inset>
@@ -516,6 +519,7 @@ export default defineComponent({
           {!data.loading && !data.list.length && (
           {!data.loading && !data.list.length && (
             <ColResult tips="暂无内容" classImgSize="SMALL" btnStatus={false} />
             <ColResult tips="暂无内容" classImgSize="SMALL" btnStatus={false} />
           )}
           )}
+          </div>
         </div>
         </div>
         <TheSticky position="bottom" varName="--bottom-height">
         <TheSticky position="bottom" varName="--bottom-height">
           {data.detail.id && !data.detail.play && (
           {data.detail.id && !data.detail.play && (

+ 1 - 7
src/tenant/music/courseListSearch/child-node.tsx

@@ -4,7 +4,6 @@ import { Cell, Collapse, CollapseItem } from "vant";
 import iconVideo from './image/icon-video.png'
 import iconVideo from './image/icon-video.png'
 import iconSong from './image/icon-song.png'
 import iconSong from './image/icon-song.png'
 import iconImage from './image/icon-image.png'
 import iconImage from './image/icon-image.png'
-import { handleShowVip } from "@/state";
 import { browser } from "@/helpers/utils";
 import { browser } from "@/helpers/utils";
 import {  postMessage } from '@/helpers/native-message';
 import {  postMessage } from '@/helpers/native-message';
 import { useRouter } from "vue-router";
 import { useRouter } from "vue-router";
@@ -50,12 +49,7 @@ const ChildNode = defineComponent({
   setup(props, { emit }) {
   setup(props, { emit }) {
     const router = useRouter()
     const router = useRouter()
     const toDetail = (item: any) => {
     const toDetail = (item: any) => {
-      // 
-      if(props.isLock) {
-        handleShowVip(props.id, "LESSON")
-        return
-      }
-
+      //
       if (browser().isApp) {
       if (browser().isApp) {
         postMessage({
         postMessage({
           api: 'openWebView',
           api: 'openWebView',

BIN
src/tenant/music/courseListSearch/image/icon-image.png


BIN
src/tenant/music/courseListSearch/image/icon-menu.png


BIN
src/tenant/music/courseListSearch/image/icon-search.png


BIN
src/tenant/music/courseListSearch/image/icon-song.png


BIN
src/tenant/music/courseListSearch/image/icon-video.png


+ 27 - 1
src/tenant/music/courseListSearch/index.module.less

@@ -1,7 +1,8 @@
 .courseListSearch {
 .courseListSearch {
   min-height: 100vh;
   min-height: 100vh;
   background-color: #F8F8F8;
   background-color: #F8F8F8;
-  background: linear-gradient(180deg, #7defe6 0%, rgba(255, 255, 255, 0) 170px);
+  // background: linear-gradient(180deg, #7defe6 0%, rgba(255, 255, 255, 0) 170px);
+  background: linear-gradient( 180deg, #FCE5FA 0%, rgba(255,255,255,0) 100%);
   box-sizing: border-box;
   box-sizing: border-box;
 
 
   :global {
   :global {
@@ -22,6 +23,17 @@
     }
     }
   }
   }
 }
 }
+.title {
+  :global {
+    .van-search {
+      padding-top: 10px !important;
+      padding-bottom: 10px !important;
+    }
+    .van-search__content {
+      background: #fff !important; 
+    }
+  }
+}
 
 
 .collapseParent {
 .collapseParent {
   padding-top: 12px;
   padding-top: 12px;
@@ -139,3 +151,17 @@
     background-size: contain;
     background-size: contain;
   }
   }
 }
 }
+
+
+.finch {
+  width: 150px;
+  margin: 140px auto 0;
+}
+
+.finchLoad {
+  text-align: center;
+  color: #333;
+  font-size: 15px;
+  margin-top: 4px;
+  margin-bottom: 120px;
+}

+ 25 - 46
src/tenant/music/courseListSearch/index.tsx

@@ -6,18 +6,22 @@ import {
   watch
   watch
 } from 'vue';
 } from 'vue';
 import styles from './index.module.less';
 import styles from './index.module.less';
-import OHeader from '@/components/o-header';
-import OSearch from '@/components/o-search';
 import request from '@/helpers/request';
 import request from '@/helpers/request';
 import { state } from '@/state';
 import { state } from '@/state';
 import { useRoute } from 'vue-router';
 import { useRoute } from 'vue-router';
-import OLoading from '@/components/o-loading';
-import OEmpty from '@/components/o-empty';
+// import OLoading from '@/components/o-loading';
+// import OEmpty from '@/components/o-empty';
 import { Cell, Collapse, CollapseItem } from 'vant';
 import { Cell, Collapse, CollapseItem } from 'vant';
 import ChildNode, { getImage } from './child-node';
 import ChildNode, { getImage } from './child-node';
-import { usePageVisibility } from '@vant/use';
+import iconSearch from './image/icon-search.png'
 import iconMenu from './image/icon-menu.png';
 import iconMenu from './image/icon-menu.png';
-import OSticky from '@/components/o-sticky';
+import TheSticky from '@/components/the-sticky';
+import ColHeader from '@/components/col-header';
+import ColSearch from '@/components/col-search';
+import { Vue3Lottie } from 'vue3-lottie';
+import AstronautJSON from '../music-detail/animate/refresh_anim.json'
+import ColResult from '@/components/col-result';
+// import OSticky from '@/components/o-sticky';
 
 
 export default defineComponent({
 export default defineComponent({
   name: 'course-list-search',
   name: 'course-list-search',
@@ -38,7 +42,6 @@ export default defineComponent({
       parentCollapse: '' as any
       parentCollapse: '' as any
       // childrenCollapse: '' as any
       // childrenCollapse: '' as any
     });
     });
-    const pageVisibility = usePageVisibility();
     /** 是否锁定 */
     /** 是否锁定 */
     const isLock = computed(() => {
     const isLock = computed(() => {
       return data.detail.useStatus === 'LOCK' &&
       return data.detail.useStatus === 'LOCK' &&
@@ -127,25 +130,12 @@ export default defineComponent({
       });
       });
     }
     }
 
 
-    /** 获取课件详情 */
-    const getDetail = async () => {
-      const res: any = await request.get(
-        `${state.platformApi}/lessonCourseware/getLessonCoursewareDetail/${route.query.id}`
-      );
-      if (res?.data) {
-        // data.detail.id = res.data.id;
-        // data.detail.cover = res.data.coverImg;
-        // data.detail.name = res.data.name;
-        // data.detail.des = res.data.lessonTargetDesc;
-        data.detail.useStatus = res.data.useStatus;
-      }
-    };
     const getList = async (search?: string) => {
     const getList = async (search?: string) => {
       data.loading = true;
       data.loading = true;
       try {
       try {
         const res: any = await request.get(
         const res: any = await request.get(
           state.platformApi +
           state.platformApi +
-            '/lessonCourseware/getLessonCoursewareCourseList/' +
+            '/tenantAlbumMusic/getLessonCoursewareCourseList/' +
             route.query.id,
             route.query.id,
           {
           {
             requestType: 'form',
             requestType: 'form',
@@ -179,36 +169,19 @@ export default defineComponent({
       }
       }
       data.loading = false;
       data.loading = false;
     };
     };
-    getDetail();
     getList();
     getList();
 
 
-    /** 页面显示和隐藏 */
-    watch(
-      () => pageVisibility.value,
-      value => {
-        if (value === 'visible') {
-          getDetail();
-        }
-      }
-    );
-
-    // useEventListener('scroll', () => {
-    //   const height =
-    //     window.scrollY ||
-    //     window.pageYOffset ||
-    //     document.documentElement.scrollTop;
-    //   data.titleOpacity = height > 30 ? 1 : 0;
-    // });
     return () => (
     return () => (
       <div class={styles.courseListSearch}>
       <div class={styles.courseListSearch}>
-        <OSticky position="top">
-          <OHeader
+        <TheSticky position="top">
+          <ColHeader
             background={`rgba(255,255,255, ${data.titleOpacity})`}
             background={`rgba(255,255,255, ${data.titleOpacity})`}
             border={false}>
             border={false}>
             {{
             {{
               title: () => (
               title: () => (
                 <div class={styles.title}>
                 <div class={styles.title}>
-                  <OSearch
+                  <ColSearch
+                    type={state.projectType === "tenant" ? "tenant" : "person"}
                     background="transparent"
                     background="transparent"
                     placeholder="请输入素材关键词"
                     placeholder="请输入素材关键词"
                     onSearch={(val: string) => {
                     onSearch={(val: string) => {
@@ -218,8 +191,8 @@ export default defineComponent({
                 </div>
                 </div>
               )
               )
             }}
             }}
-          </OHeader>
-        </OSticky>
+          </ColHeader>
+        </TheSticky>
 
 
         <div style="height: calc(100vh - var(--header-height)); overflow-x: hidden; overflow-y: auto;">
         <div style="height: calc(100vh - var(--header-height)); overflow-x: hidden; overflow-y: auto;">
           <TransitionGroup name="van-fade">
           <TransitionGroup name="van-fade">
@@ -295,8 +268,14 @@ export default defineComponent({
               </Collapse>
               </Collapse>
             )}
             )}
           </TransitionGroup>
           </TransitionGroup>
-          {data.loading && <OLoading />}
-          {!data.loading && !data.list.length && <OEmpty tips="暂无搜索结果" />}
+          {data.loading && <div>
+              <Vue3Lottie
+                animationData={AstronautJSON}
+                class={styles.finch}
+              ></Vue3Lottie>
+              {/* <p class={styles.finchLoad}>加载中...</p> */}
+            </div>}
+          {!data.loading && !data.list.length && <ColResult btnStatus={false} tips="暂无搜索结果" />}
         </div>
         </div>
       </div>
       </div>
     );
     );

+ 38 - 0
src/tenant/music/coursewarePlay/component/point.module.less

@@ -28,6 +28,44 @@
   }
   }
 }
 }
 
 
+.pointHeadSearch {
+  // :global {
+  //   .van-search {
+  //     padding-top: 17px;
+  //     padding-left: 20px;
+  //     padding-right: 20px;
+
+  //     input {
+  //       color: rgba(255,255,255, 1);
+  //     }
+  //   }
+  // }
+  :global {
+    .van-search {
+      padding-top: 10px !important;
+      padding-bottom: 10px !important;
+    }
+    .van-search__content {
+      background: rgba(255,255,255,0.15) !important; 
+      border-color: transparent !important;
+
+      input::placeholder {
+        color: rgba(255,255,255,0.6) !important;
+      }
+
+      input {
+        color: rgba(255,255,255,0.9) !important;
+      }
+    }
+    // .van-button {
+    //   border-color: #FF8057 !important;
+    //   background-color: #FF8057 !important;
+    // }
+    .van-cell {
+      --van-cell-line-height: 20px !important;
+    }
+  }
+}
 
 
 .content {
 .content {
   flex: 1;
   flex: 1;

+ 321 - 0
src/tenant/music/coursewarePlay/component/points-search.tsx

@@ -0,0 +1,321 @@
+import { defineComponent, reactive, watch } from 'vue';
+import styles from './point.module.less';
+import { iconArrow } from '../image/icons.json';
+import {
+  iconImage,
+  iconImageActive,
+  iconVideo,
+  iconVideoActive,
+  iconSong,
+  iconSongActive
+} from '../image/icons.json';
+import { Collapse, CollapseItem, Image, Loading } from 'vant';
+import PlayLoading from './play-loading';
+import ColResult from '@/components/col-result';
+import ColSearch from '@/components/col-search';
+import iconSearch from '../../courseListSearch/image/icon-search.png'
+export default defineComponent({
+  name: 'points-list',
+  props: {
+    data: {
+      type: Array,
+      default: () => []
+    },
+    tabActive: {
+      type: String,
+      default: ''
+    },
+    itemActive: {
+      type: String,
+      default: ''
+    },
+    search: {
+      type: String,
+      default: ''
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    },
+    open: {
+      type: Boolean,
+      default: false,
+    }
+  },
+  emits: ['handleSelect', 'handleSearch'],
+  setup(props, { emit }) {
+    const pointData = reactive({
+      search: props.search,
+      isSearch: false, // 判断是否搜索过
+      active: props.tabActive[0] || '',
+      childActive: props.tabActive[1] || '',
+      liftChildActive: props.tabActive[2] || '',
+    });
+    watch(
+      () => props.tabActive,
+      () => {
+        pointData.active = props.tabActive[0] || '';
+        pointData.childActive = props.tabActive[1] || '';
+        pointData.liftChildActive = props.tabActive[2] || '';
+      }
+    );
+    
+    watch(() => props.open, () => {
+      pointData.search = props.search
+    })
+
+    // 获取对应图片
+    const getImage = (item: any) => {
+      if (item.typeCode === 'VIDEO') {
+        return props.itemActive == item.id ? iconVideoActive : iconVideo;
+      } else if (['IMAGE', 'IMG'].includes(item.typeCode)) {
+        return props.itemActive == item.id ? iconImageActive : iconImage;
+      } else if (item.typeCode === 'SONG') {
+        return props.itemActive == item.id ? iconSongActive : iconSong;
+      } else {
+        return props.itemActive == item.id ? iconVideoActive : iconVideo;
+      }
+    };
+
+    function formatName(name: string) {
+      if (!name || !pointData.search) return name
+      const search: any = pointData.search
+      return name.replace(search, `<span style="color: #01C1B5;">${search}</span>`)
+   }
+    return () => (
+      <div class={styles.container}>
+        <div class={styles.pointHeadSearch}>
+          <ColSearch type={'tenant'} placeholder='请输入素材关键词' modelValue={pointData.search} background='transparent' onSearch={(val: any) => {
+            // 
+            if(props.loading) return
+            pointData.isSearch = true
+            pointData.search = val
+            emit('handleSearch', {
+              search: val
+            })
+          }} />
+        </div>
+        <div class={styles.content}>
+        {props.loading && <div class={styles.lading}>
+            <Loading size={24} color='rgba(255, 255, 255, 0.8)' /> <span class={styles.loadingText}>加载中...</span>
+          </div>}
+          
+          {/* {props.loading && <OLoading />} */}
+          {!props.loading && !props.data.length &&  <ColResult btnStatus={false} tips="暂无搜索结果" />}
+          {props.data.length > 0 ? <Collapse
+            class={styles.collapse}
+            modelValue={pointData.active}
+            onUpdate:modelValue={(val: any) => {
+              pointData.active = val;
+            }}
+            accordion>
+            {props.data.map((item: any, index: number) => {
+              return (
+                <CollapseItem
+                  center
+                  border={false}
+                  class={index > 0 ? styles.borderTop : ''}
+                  isLink={false}
+                  title={item.name}
+                  name={item.id}>
+                  {{
+                    default: () => (
+                      <>
+                        {Array.isArray(item?.materialList) &&
+                          item.materialList.map((n: any) => {
+                            return (
+                              <div
+                                class={[
+                                  styles.item,
+                                  props.itemActive == n.id
+                                    ? styles.itemActive
+                                    : ''
+                                ]}
+                                onClick={() => {
+                                  emit('handleSelect', {
+                                    isSearch: pointData.isSearch,
+                                    itemActive: n.id,
+                                    tabActive: item.id,
+                                    tabName: item.name
+                                  });
+                                  pointData.isSearch = false
+                                }}>
+                                <Image
+                                  src={getImage(n)}
+                                  class={styles.itemImage}
+                                />
+                                <span
+                                  style={{ width: '80%' }}
+                                  class="van-ellipsis">
+                                  {n.name}
+                                </span>
+                                {/* <Icon name={iconZhibo} /> */}
+                                <div class={styles.playLoading}>
+                                  <PlayLoading />
+                                </div>
+                              </div>
+                            );
+                          })}
+
+                        {Array.isArray(item?.children) && (
+                          <Collapse
+                            class={[
+                              styles.collapse,
+                              pointData.active === item.id
+                                ? styles.childActive
+                                : ''
+                            ]}
+                            modelValue={pointData.childActive}
+                            onUpdate:modelValue={(val: any) => {
+                              pointData.childActive = val;
+                            }}
+                            accordion>
+                            {item?.children.map((child: any) => {
+                              return (
+                                <CollapseItem
+                                  center
+                                  border={false}
+                                  isLink={false}
+                                  title={child.name}
+                                  name={child.id}
+                                  class={styles.childCollapseItem}>
+                                  {{
+                                    default: () => (
+                                      <>
+                                        {Array.isArray(child?.materialList) &&
+                                          child.materialList.map((n: any) => {
+                                            return (
+                                              <div
+                                                class={[
+                                                  styles.item,
+                                                  props.itemActive == n.id
+                                                    ? styles.itemActive
+                                                    : ''
+                                                ]}
+                                                onClick={() => {
+                                                  emit('handleSelect', {
+                                                    isSearch: pointData.isSearch,
+                                                    itemActive: n.id,
+                                                    tabActive: child.id,
+                                                    tabName: child.name
+                                                  });
+                                                  pointData.isSearch = false
+                                                }}>
+                                                <Image
+                                                  src={getImage(n)}
+                                                  class={styles.itemImage}
+                                                />
+                                                <span
+                                                  style={{ width: '73%' }}
+                                                  class="van-ellipsis" v-html={formatName(n.name)}>
+                                                  {/* {n.name} */}
+                                                </span>
+                                                {/* <Icon name={iconZhibo} /> */}
+                                                <div class={styles.playLoading}>
+                                                  <PlayLoading />
+                                                </div>
+                                              </div>
+                                            );
+                                          })}
+
+                                          {Array.isArray(child?.children) && (
+                                            <Collapse
+                                              class={[
+                                                styles.collapse,
+                                                pointData.liftChildActive === child.id
+                                                  ? styles.childActive
+                                                  : ''
+                                              ]}
+                                              modelValue={pointData.liftChildActive}
+                                              onUpdate:modelValue={(val: any) => {
+                                                pointData.liftChildActive = val;
+                                              }}
+                                              accordion>
+                                              {child?.children.map((liftChild: any) => {
+                                                return (
+                                                  <CollapseItem
+                                                    center
+                                                    border={false}
+                                                    isLink={false}
+                                                    title={liftChild.name}
+                                                    name={liftChild.id}
+                                                    class={styles.childCollapseItem}>
+                                                    {{
+                                                      default: () => (
+                                                        <>
+                                                          {Array.isArray(liftChild?.materialList) &&
+                                                            liftChild.materialList.map((n: any) => {
+                                                              return (
+                                                                <div
+                                                                  class={[
+                                                                    styles.item,
+                                                                    props.itemActive == n.id
+                                                                      ? styles.itemActive
+                                                                      : ''
+                                                                  ]}
+                                                                  onClick={() => {
+                                                                    emit('handleSelect', {
+                                                                      isSearch: pointData.isSearch,
+                                                                      itemActive: n.id,
+                                                                      tabActive: liftChild.id,
+                                                                      tabName: liftChild.name
+                                                                    });
+                                                                    pointData.isSearch = false
+                                                                  }}>
+                                                                  <Image
+                                                                    src={getImage(n)}
+                                                                    class={styles.itemImage}
+                                                                  />
+                                                                  <span
+                                                                    style={{ width: '73%' }}
+                                                                    class="van-ellipsis" v-html={formatName(n.name)}>
+                                                                    {/* {n.name} */}
+                                                                  </span>
+                                                                  {/* <Icon name={iconZhibo} /> */}
+                                                                  <div class={styles.playLoading}>
+                                                                    <PlayLoading />
+                                                                  </div>
+                                                                </div>
+                                                              );
+                                                            })}
+                                                        </>
+                                                      ),
+                                                      icon: () => (
+                                                        <img
+                                                          class={styles.arrow}
+                                                          src={iconArrow}
+                                                        />
+                                                      )
+                                                    }}
+                                                  </CollapseItem>
+                                                );
+                                              })}
+                                            </Collapse>
+                                          )}
+                                      </>
+                                    ),
+                                    icon: () => (
+                                      <img
+                                        class={styles.arrow}
+                                        src={iconArrow}
+                                      />
+                                    )
+                                  }}
+                                </CollapseItem>
+                              );
+                            })}
+                          </Collapse>
+                        )}
+                      </>
+                    ),
+                    icon: () => <img class={styles.arrow} src={iconArrow} />
+                  }}
+                </CollapseItem>
+              );
+            })}
+          </Collapse>: ""}
+        </div>
+      </div>
+    );
+  }
+});

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
src/tenant/music/coursewarePlay/image/icons.json


+ 291 - 54
src/tenant/music/coursewarePlay/index.tsx

@@ -9,7 +9,8 @@ import {
   watch,
   watch,
   Transition,
   Transition,
   computed,
   computed,
-  onBeforeUnmount
+  onBeforeUnmount,
+  shallowRef
 } from 'vue'
 } from 'vue'
 import iconBack from './image/back.svg'
 import iconBack from './image/back.svg'
 import styles from './index.module.less'
 import styles from './index.module.less'
@@ -32,6 +33,7 @@ import {
   // iconPen,
   // iconPen,
   iconTouping,
   iconTouping,
   iconCourseType,
   iconCourseType,
+  iconSearch,
   iconMenu
   iconMenu
 } from './image/icons.json'
 } from './image/icons.json'
 import Points from './component/points'
 import Points from './component/points'
@@ -52,6 +54,7 @@ import CoursewareTips from './component/courseware-tips'
 import GlobalTools from '@/components/globalTools'
 import GlobalTools from '@/components/globalTools'
 import CoursewareType from './component/courseware-type'
 import CoursewareType from './component/courseware-type'
 import { useNetwork } from '@vueuse/core'
 import { useNetwork } from '@vueuse/core'
+import PointsSearch from './component/points-search'
 
 
 export default defineComponent({
 export default defineComponent({
   name: 'CoursewarePlay',
   name: 'CoursewarePlay',
@@ -130,7 +133,13 @@ export default defineComponent({
 
 
     const route = useRoute()
     const route = useRoute()
     const headeRef = ref()
     const headeRef = ref()
+    const detailTempSearchList = shallowRef<any[]>()
+    const detailList = shallowRef<any[]>()// 搜索来的所有数据
     const data = reactive({
     const data = reactive({
+      source: route.query.source as any, // 来源 search  搜索
+      searchLoading: false, // 搜索加载状态
+      search: route.query.search as any, // 默认的搜索条件 - 
+      searchTemp: route.query.search as any, // 默认的搜索条件 - 
       currentId: route.query.id as any,
       currentId: route.query.id as any,
       detail: null as any,
       detail: null as any,
       knowledgePointList: [] as any,
       knowledgePointList: [] as any,
@@ -382,17 +391,185 @@ export default defineComponent({
       }
       }
     }
     }
 
 
-      const onTitleTip = (type: "phaseGoals" | "checkItem", text: string) => {
-        handleStop()
-        popupData.pointOpen = true
-        popupData.pointContent = text
-        if(type === "checkItem") {
-          popupData.pointTitle = '检查事项'
-        } else if(type === "phaseGoals") {
-          popupData.pointTitle = '阶段目标'
+    const getSearchItemList = async (knowledgePointList: any[]) => {
+      const list: any = [];
+
+      for (let i = 0; i < knowledgePointList.length; i++) {
+        const item = knowledgePointList[i];
+        if (item.materialList && item.materialList.length > 0) {
+          const tempList = await getTempList(item.materialList, item.name);
+          list.push(...tempList);
+        }
+
+        // 第二层级
+        if (item.children && item.children.length > 0) {
+          const childrenList = item.children || [];
+          for (let j = 0; j < childrenList.length; j++) {
+            const childItem = childrenList[j];
+            const tempList = await getTempList(
+              childItem.materialList,
+              childItem.name
+            );
+            list.push(...tempList);
+          }
         }
         }
       }
       }
 
 
+      return list
+    };
+
+    /** 从搜索页面来的 */
+    const getSearchDetail = async (params: { type?: string, id?: any, search?: string }) => {
+      try {
+        const res = await request.get(
+          state.platformApi +
+            `/tenantAlbumMusic/getLessonCoursewareCourseList/${params.id || route.query.lessonId}`,
+          {
+            hideLoading: true,
+            params: {
+              detailFlag: "1",
+              search: params.search
+            }
+          }
+        );
+        const result = res.data || []
+        const allList: any[] = []
+        for(let i = 0; i < result.length; i++) {
+          const itemResult = result[i];
+          itemResult.name = itemResult.coursewareDetailName;
+          itemResult.id = itemResult.coursewareDetailId;
+          itemResult.lessonTargetDesc = itemResult.lessonTargetDesc ? itemResult.lessonTargetDesc.replace(/\n/g, "<br />") : ""
+          if (Array.isArray(itemResult?.knowledgePointList)) {
+            let index = 0;
+            itemResult.children = itemResult.knowledgePointList.map(
+              (n: any) => {
+                if (Array.isArray(n.materialList)) {
+                  n.materialList = n.materialList.map((item: any) => {
+                    index++;
+                    const materialRefs = item.materialRefs
+                      ? item.materialRefs
+                      : [];
+                    const materialMusicId =
+                      materialRefs.length > 0
+                        ? materialRefs[0].resourceIdStr
+                        : null;
+                    return {
+                      ...item,
+                      materialMusicId,
+                      content: item.content,
+                      coursewareDetailId: itemResult.coursewareDetailId,
+                      knowledgePointId: [itemResult.coursewareDetailId, item.knowledgePointId],
+                      materialId: item.id,
+                      id: index + ''
+                    };
+                  });
+                }
+                if (Array.isArray(n.children)) {
+                  n.children = n.children.map((cn: any) => {
+                    cn.materialList = cn.materialList.map((item: any) => {
+                      index++;
+                      const materialRefs = item.materialRefs
+                        ? item.materialRefs
+                        : [];
+                      const materialMusicId =
+                        materialRefs.length > 0
+                          ? materialRefs[0].resourceIdStr
+                          : null;
+                      return {
+                        ...item,
+                        materialMusicId,
+                        coursewareDetailId: itemResult.coursewareDetailId,
+                        content: item.content,
+                        knowledgePointId: [itemResult.coursewareDetailId, n.id, item.knowledgePointId],
+                        materialId: item.id,
+                        id: index + ''
+                      };
+                    });
+                    return cn;
+                  });
+                }
+                return n;
+              }
+            );
+            itemResult.knowledgePointList = null // 去掉不要的
+            itemResult.list = await getSearchItemList(itemResult.children);
+
+            allList.push(...itemResult.list)
+          }
+        }
+        if(params.type === 'pointSearch') {
+          detailTempSearchList.value = result
+
+          // 初始化选中的数据 临时
+          popupData.tempTabActive = allList.length > 0 ? allList[0].knowledgePointId : []
+          popupData.tempItemActive = "-1"
+          data.searchTemp = params.search
+          return
+        }
+        detailList.value = result
+        detailTempSearchList.value = result
+
+        if(!params.type) {
+          let _firstIndex = allList.findIndex(
+            (n: any) =>
+              n.knowledgePointMaterialRelationId == route.query.kId ||
+              n.materialId == route.query.kId
+          );
+          _firstIndex = _firstIndex > -1 ? _firstIndex : 0;
+          const item = allList[_firstIndex];
+          // console.log(item, 'item')
+          // console.log(_firstIndex, '_firstIndex', route.query.kId, 'route.query.kId', item)
+          // 是否自动播放
+          if (activeData.isAutoPlay) {
+            item.autoPlay = true;
+          }
+          popupData.activeIndex = _firstIndex;
+          popupData.playIndex = _firstIndex;
+          popupData.tabName = item.tabName;
+          popupData.tabActive = item.knowledgePointId;
+          popupData.itemActive = item.id;
+          popupData.itemName = item.name;
+
+          data.detail = detailList.value?.find((child: any) => child.coursewareDetailId === item.coursewareDetailId)
+        }
+        
+        nextTick(() => {
+          data.itemList = allList;
+          checkedAnimation(popupData.activeIndex);
+          postMessage({
+            api: 'courseLoading',
+            content: {
+              show: false,
+              type: 'fullscreen'
+            }
+          });
+
+          if (data.disableScreenRecordingFlag === '1') {
+            // 检测是否录屏
+            handleLimitScreenRecord();
+          }
+          setTimeout(() => {
+            data.animationState = 'end';
+          }, 500);
+        });
+
+        
+        return true
+      } catch (error) {
+        console.log(error);
+      }
+    }
+
+    const onTitleTip = (type: "phaseGoals" | "checkItem", text: string) => {
+      handleStop()
+      popupData.pointOpen = true
+      popupData.pointContent = text
+      if(type === "checkItem") {
+        popupData.pointTitle = '检查事项'
+      } else if(type === "phaseGoals") {
+        popupData.pointTitle = '阶段目标'
+      }
+    }
 
 
     // ifram事件处理
     // ifram事件处理
     const iframeHandle = (ev: MessageEvent) => {
     const iframeHandle = (ev: MessageEvent) => {
@@ -498,11 +675,17 @@ export default defineComponent({
 
 
     onMounted(async () => {
     onMounted(async () => {
       await sysParamConfig()
       await sysParamConfig()
-      // 只有老师端才有课程类型
-      if(baseState.platformType === "TEACHER") {
-        await getRefLevel()
+      
+
+      if(data.source === 'search') {
+        await getSearchDetail({search: data.search})
+      } else {
+        // 只有老师端才有课程类型
+        if(baseState.platformType === "TEACHER") {
+          await getRefLevel()
+        }
+        await getDetail()
       }
       }
-      await getDetail()
       // getCourseSchedule();
       // getCourseSchedule();
       window.addEventListener('message', iframeHandle)
       window.addEventListener('message', iframeHandle)
 
 
@@ -552,6 +735,8 @@ export default defineComponent({
       open: false,
       open: false,
       activeIndex: 0,
       activeIndex: 0,
       playIndex: 0,
       playIndex: 0,
+      tempTabActive: '', // 临时选中
+      tempItemActive: "", // 临时编号 
       tabActive: '',
       tabActive: '',
       tabName: '',
       tabName: '',
       itemActive: '',
       itemActive: '',
@@ -703,6 +888,10 @@ export default defineComponent({
     const acitveTimer = ref()
     const acitveTimer = ref()
     // 轮播切换
     // 轮播切换
     const handleSwipeChange = async (index: number) => {
     const handleSwipeChange = async (index: number) => {
+      if(data.source === 'search') {
+        const item = data.itemList[index];
+        data.detail = detailList.value?.find((child: any) => child.coursewareDetailId === item.coursewareDetailId)
+      }
       // 如果是当前正在播放 或者是视频最后一个
       // 如果是当前正在播放 或者是视频最后一个
       if (popupData.activeIndex == index) return
       if (popupData.activeIndex == index) return
       await handleStop()
       await handleStop()
@@ -1045,39 +1234,53 @@ export default defineComponent({
               >
               >
 
 
                 <div class={[styles.btnsWrap, styles.prePoint]}>
                 <div class={[styles.btnsWrap, styles.prePoint]}>
-                  {baseState.platformType === "TEACHER" && <div class={styles.fullBtn} onClick={() => {
-                    handleStop()
-                    popupData.coursewareOpen = true
-                  }}>
-                    <img src={iconCourseType} />
-                  </div>}
+
+                {data.source === 'search' ? 
+                    <div class={styles.fullBtn} onClick={() => {
+                      handleStop()
+                      detailTempSearchList.value = detailList.value
+                      popupData.tempItemActive = ""
+                      popupData.tempTabActive = ""
+                      data.searchTemp = ""
+                      // data.searchTemp = JSON.parse(JSON.stringify(data.search))
+                      popupData.open = true
+                    }}>
+                      <img src={iconSearch} />
+                    </div> : <>
+                    {baseState.platformType === "TEACHER" && <div class={styles.fullBtn} onClick={() => {
+                        handleStop()
+                        popupData.coursewareOpen = true
+                      }}>
+                        <img src={iconCourseType} />
+                      </div>}
+                      
+                      <div class={styles.fullBtn} onClick={() => {
+                        handleStop()
+                        popupData.open = true
+                      }}>
+                        <img src={iconMenu} />
+                        {/* <span>知识点</span> */}
+                      </div>
+                  </>}
                   
                   
-                  <div class={styles.fullBtn} onClick={() => {
-                    handleStop()
-                    popupData.open = true
-                  }}>
-                    <img src={iconMenu} />
-                    {/* <span>知识点</span> */}
+                  <div
+                    class={[styles.fullBtn, !(popupData.activeIndex != 0) && styles.disabled]}
+                    onClick={() => {
+                      if(popupData.activeIndex != 0) handlePreAndNext('up')
+                    }}
+                  >
+                    <img src={iconUp} />
+                    {/* <span style={{ textAlign: 'center' }}>上一个</span> */}
+                  </div>
+                  <div
+                    class={[styles.fullBtn, !(popupData.activeIndex != data.itemList.length - 1) && styles.disabled]}
+                    onClick={() => {
+                      if(popupData.activeIndex != data.itemList.length - 1) handlePreAndNext('down')
+                    }}
+                  >
+                    {/* <span style={{ textAlign: 'center' }}>下一个</span> */}
+                    <img src={iconDown} />
                   </div>
                   </div>
-                  
-                    <div
-                      class={[styles.fullBtn, !(popupData.activeIndex != 0) && styles.disabled]}
-                      onClick={() => {
-                        if(popupData.activeIndex != 0) handlePreAndNext('up')
-                      }}
-                    >
-                      <img src={iconUp} />
-                      {/* <span style={{ textAlign: 'center' }}>上一个</span> */}
-                    </div>
-                    <div
-                      class={[styles.fullBtn, !(popupData.activeIndex != data.itemList.length - 1) && styles.disabled]}
-                      onClick={() => {
-                        if(popupData.activeIndex != data.itemList.length - 1) handlePreAndNext('down')
-                      }}
-                    >
-                      {/* <span style={{ textAlign: 'center' }}>下一个</span> */}
-                      <img src={iconDown} />
-                    </div>
                  </div>
                  </div>
               </div>
               </div>
             )}
             )}
@@ -1165,16 +1368,50 @@ export default defineComponent({
           v-model:show={popupData.open}
           v-model:show={popupData.open}
           onClose={handleClosePopup}
           onClose={handleClosePopup}
         >
         >
-          <Points
-            data={data.knowledgePointList}
-            tabActive={popupData.tabActive}
-            itemActive={popupData.itemActive}
-            onHandleSelect={(res: any) => {
-              // onChangeSwiper('change', res.itemActive)
-              popupData.open = false
-              toggleMaterial(res.itemActive)
-            }}
-          />
+          {data.source === 'search' ? 
+              <PointsSearch
+                data={detailTempSearchList.value}
+                search={data.searchTemp || data.search}
+                loading={data.searchLoading}
+                tabActive={popupData.tempTabActive || popupData.tabActive}
+                itemActive={popupData.tempItemActive || popupData.itemActive}
+                open={popupData.open}
+                onHandleSelect={(res: any) => {
+                  popupData.open = false;
+                  if(res.isSearch) {
+                    detailList.value = detailTempSearchList.value
+                    const tempList: any[] = []
+                    detailTempSearchList.value?.forEach((item: any) => {
+                      if(Array.isArray(item.list)) {
+                        tempList.push(...item.list)
+                      }
+                    })
+                    data.itemList = tempList || []
+                    data.search = JSON.parse(JSON.stringify(data.searchTemp))
+                  }
+                  toggleMaterial(res.itemActive);
+                }}
+                onHandleSearch={async (val: any) => {
+                  data.searchLoading = true
+                  detailTempSearchList.value = []
+                  await getSearchDetail({
+                    type: 'pointSearch',
+                    search: val.search
+                  })
+                  data.searchTemp = val.search;
+                  data.searchLoading = false
+                }} /> : 
+                <Points
+                data={data.knowledgePointList}
+                tabActive={popupData.tabActive}
+                itemActive={popupData.itemActive}
+                onHandleSelect={(res: any) => {
+                  // onChangeSwiper('change', res.itemActive)
+                  popupData.open = false
+                  toggleMaterial(res.itemActive)
+                }}
+              />}
+          
         </Popup>
         </Popup>
 
 
         <Popup
         <Popup

Неке датотеке нису приказане због велике количине промена