|  | @@ -0,0 +1,304 @@
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  computed,
 | 
	
		
			
				|  |  | +  defineComponent,
 | 
	
		
			
				|  |  | +  reactive,
 | 
	
		
			
				|  |  | +  TransitionGroup,
 | 
	
		
			
				|  |  | +  watch
 | 
	
		
			
				|  |  | +} from 'vue';
 | 
	
		
			
				|  |  | +import styles from './index.module.less';
 | 
	
		
			
				|  |  | +import OHeader from '@/components/o-header';
 | 
	
		
			
				|  |  | +import OSearch from '@/components/o-search';
 | 
	
		
			
				|  |  | +import request from '@/helpers/request';
 | 
	
		
			
				|  |  | +import { state } from '@/state';
 | 
	
		
			
				|  |  | +import { useRoute } from 'vue-router';
 | 
	
		
			
				|  |  | +import OLoading from '@/components/o-loading';
 | 
	
		
			
				|  |  | +import OEmpty from '@/components/o-empty';
 | 
	
		
			
				|  |  | +import { Cell, Collapse, CollapseItem } from 'vant';
 | 
	
		
			
				|  |  | +import ChildNode, { getImage } from './child-node';
 | 
	
		
			
				|  |  | +import { usePageVisibility } from '@vant/use';
 | 
	
		
			
				|  |  | +import iconMenu from './image/icon-menu.png';
 | 
	
		
			
				|  |  | +import OSticky from '@/components/o-sticky';
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export default defineComponent({
 | 
	
		
			
				|  |  | +  name: 'course-list-search',
 | 
	
		
			
				|  |  | +  setup() {
 | 
	
		
			
				|  |  | +    const route = useRoute();
 | 
	
		
			
				|  |  | +    const data = reactive({
 | 
	
		
			
				|  |  | +      titleOpacity: 0,
 | 
	
		
			
				|  |  | +      loading: true,
 | 
	
		
			
				|  |  | +      detail: {
 | 
	
		
			
				|  |  | +        // id: '',
 | 
	
		
			
				|  |  | +        // cover: '',
 | 
	
		
			
				|  |  | +        // name: '',
 | 
	
		
			
				|  |  | +        // des: '',
 | 
	
		
			
				|  |  | +        useStatus: ''
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      list: [] as any,
 | 
	
		
			
				|  |  | +      search: '' as string | undefined,
 | 
	
		
			
				|  |  | +      parentCollapse: '' as any
 | 
	
		
			
				|  |  | +      // childrenCollapse: '' as any
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const pageVisibility = usePageVisibility();
 | 
	
		
			
				|  |  | +    /** 是否锁定 */
 | 
	
		
			
				|  |  | +    const isLock = computed(() => {
 | 
	
		
			
				|  |  | +      return data.detail.useStatus === 'LOCK' &&
 | 
	
		
			
				|  |  | +        state.platformType === 'STUDENT'
 | 
	
		
			
				|  |  | +        ? true
 | 
	
		
			
				|  |  | +        : false;
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const formatDataList = (list: any = []) => {
 | 
	
		
			
				|  |  | +      const tempList: any = [];
 | 
	
		
			
				|  |  | +      list.forEach((item: any) => {
 | 
	
		
			
				|  |  | +        let tempChild: any = {};
 | 
	
		
			
				|  |  | +        item.collapse = '';
 | 
	
		
			
				|  |  | +        tempChild = item;
 | 
	
		
			
				|  |  | +        if (Array.isArray(item.children)) {
 | 
	
		
			
				|  |  | +          tempChild.children = formatDataList(item.children);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        tempList.push({
 | 
	
		
			
				|  |  | +          ...tempChild
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +      return tempList;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const formatSelectFirstChild = (list: any = []): any => {
 | 
	
		
			
				|  |  | +      for (let i = 0; i < list.length; i++) {
 | 
	
		
			
				|  |  | +        if (
 | 
	
		
			
				|  |  | +          Array.isArray(list[i].materialList) &&
 | 
	
		
			
				|  |  | +          list[i].materialList.length > 0
 | 
	
		
			
				|  |  | +        ) {
 | 
	
		
			
				|  |  | +          const materialItem = list[i].materialList[0] || {};
 | 
	
		
			
				|  |  | +          if (materialItem) {
 | 
	
		
			
				|  |  | +            return materialItem;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          return formatSelectFirstChild(list[i].children || []);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //
 | 
	
		
			
				|  |  | +    function selectFirstChild(pointList: any[], ids: any[]): any[] {
 | 
	
		
			
				|  |  | +      return pointList.map(point => {
 | 
	
		
			
				|  |  | +        if (point.children) {
 | 
	
		
			
				|  |  | +          let id = '';
 | 
	
		
			
				|  |  | +          point.children.map((item: any) => {
 | 
	
		
			
				|  |  | +            if (!id) {
 | 
	
		
			
				|  |  | +              id = ids.includes(item.id) ? item.id : '';
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          point.collapse = id;
 | 
	
		
			
				|  |  | +          return Object.assign(point, {
 | 
	
		
			
				|  |  | +            children: selectFirstChild(point.children, ids)
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          return Object.assign(point, {
 | 
	
		
			
				|  |  | +            materialList: point.materialList
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    function filterPointList(
 | 
	
		
			
				|  |  | +      pointList: any[],
 | 
	
		
			
				|  |  | +      parentData?: { ids: string[]; name: string }
 | 
	
		
			
				|  |  | +    ): any[] {
 | 
	
		
			
				|  |  | +      // 设置父级及以上id数组和父级name
 | 
	
		
			
				|  |  | +      return pointList.map(point => {
 | 
	
		
			
				|  |  | +        if (point.children) {
 | 
	
		
			
				|  |  | +          return Object.assign(point, {
 | 
	
		
			
				|  |  | +            children: filterPointList(point.children, {
 | 
	
		
			
				|  |  | +              ids: [...(parentData?.ids || []), point.id],
 | 
	
		
			
				|  |  | +              name: point.name
 | 
	
		
			
				|  |  | +            })
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          return Object.assign(point, {
 | 
	
		
			
				|  |  | +            materialList: point.materialList.map((item: any) => {
 | 
	
		
			
				|  |  | +              item.parentData = {
 | 
	
		
			
				|  |  | +                ids: [...(parentData?.ids || []), point.id],
 | 
	
		
			
				|  |  | +                name: point.name
 | 
	
		
			
				|  |  | +              };
 | 
	
		
			
				|  |  | +              return item;
 | 
	
		
			
				|  |  | +            })
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /** 获取课件详情 */
 | 
	
		
			
				|  |  | +    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) => {
 | 
	
		
			
				|  |  | +      data.loading = true;
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        const res: any = await request.get(
 | 
	
		
			
				|  |  | +          state.platformApi +
 | 
	
		
			
				|  |  | +            '/lessonCourseware/getLessonCoursewareCourseList/' +
 | 
	
		
			
				|  |  | +            route.query.id,
 | 
	
		
			
				|  |  | +          {
 | 
	
		
			
				|  |  | +            requestType: 'form',
 | 
	
		
			
				|  |  | +            params: {
 | 
	
		
			
				|  |  | +              search
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        );
 | 
	
		
			
				|  |  | +        if (Array.isArray(res?.data)) {
 | 
	
		
			
				|  |  | +          data.search = search;
 | 
	
		
			
				|  |  | +          res.data.forEach((item: any) => {
 | 
	
		
			
				|  |  | +            item.children = item.knowledgePointList || [];
 | 
	
		
			
				|  |  | +            item.id = item.coursewareDetailId;
 | 
	
		
			
				|  |  | +            item.name = item.coursewareDetailName;
 | 
	
		
			
				|  |  | +            formatDataList(item.children);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          const firstItem = formatSelectFirstChild(res.data);
 | 
	
		
			
				|  |  | +          let list = filterPointList(res.data);
 | 
	
		
			
				|  |  | +          list = selectFirstChild(list, firstItem?.parentData?.ids || []);
 | 
	
		
			
				|  |  | +          data.list = list;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          list.forEach((item: any) => {
 | 
	
		
			
				|  |  | +            if (item.id === firstItem.parentData?.ids[0]) {
 | 
	
		
			
				|  |  | +              data.parentCollapse = item.id;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      } catch (error) {
 | 
	
		
			
				|  |  | +        //
 | 
	
		
			
				|  |  | +        console.log(error, 'error');
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      data.loading = false;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    getDetail();
 | 
	
		
			
				|  |  | +    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 () => (
 | 
	
		
			
				|  |  | +      <div class={styles.courseListSearch}>
 | 
	
		
			
				|  |  | +        <OSticky position="top">
 | 
	
		
			
				|  |  | +          <OHeader
 | 
	
		
			
				|  |  | +            background={`rgba(255,255,255, ${data.titleOpacity})`}
 | 
	
		
			
				|  |  | +            border={false}>
 | 
	
		
			
				|  |  | +            {{
 | 
	
		
			
				|  |  | +              title: () => (
 | 
	
		
			
				|  |  | +                <div class={styles.title}>
 | 
	
		
			
				|  |  | +                  <OSearch
 | 
	
		
			
				|  |  | +                    background="transparent"
 | 
	
		
			
				|  |  | +                    placeholder="请输入素材关键词"
 | 
	
		
			
				|  |  | +                    onSearch={(val: string) => {
 | 
	
		
			
				|  |  | +                      getList(val);
 | 
	
		
			
				|  |  | +                    }}
 | 
	
		
			
				|  |  | +                  />
 | 
	
		
			
				|  |  | +                </div>
 | 
	
		
			
				|  |  | +              )
 | 
	
		
			
				|  |  | +            }}
 | 
	
		
			
				|  |  | +          </OHeader>
 | 
	
		
			
				|  |  | +        </OSticky>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <div style="height: calc(100vh - var(--header-height)); overflow-x: hidden; overflow-y: auto;">
 | 
	
		
			
				|  |  | +          <TransitionGroup name="van-fade">
 | 
	
		
			
				|  |  | +            {!data.loading && (
 | 
	
		
			
				|  |  | +              <Collapse
 | 
	
		
			
				|  |  | +                key="courseListSearch"
 | 
	
		
			
				|  |  | +                modelValue={data.parentCollapse}
 | 
	
		
			
				|  |  | +                onUpdate:modelValue={(val: any) => {
 | 
	
		
			
				|  |  | +                  data.parentCollapse = val;
 | 
	
		
			
				|  |  | +                  // data.childrenCollapse = ''; // 重置子项选择
 | 
	
		
			
				|  |  | +                }}
 | 
	
		
			
				|  |  | +                class={styles.collapseParent}
 | 
	
		
			
				|  |  | +                border={false}
 | 
	
		
			
				|  |  | +                accordion>
 | 
	
		
			
				|  |  | +                {data.list.map((item: any) => (
 | 
	
		
			
				|  |  | +                  <CollapseItem
 | 
	
		
			
				|  |  | +                    center
 | 
	
		
			
				|  |  | +                    border={true}
 | 
	
		
			
				|  |  | +                    name={item.coursewareDetailId}
 | 
	
		
			
				|  |  | +                    clickable={false}
 | 
	
		
			
				|  |  | +                    class={['parentCollapse__item']}>
 | 
	
		
			
				|  |  | +                    {{
 | 
	
		
			
				|  |  | +                      title: () => (
 | 
	
		
			
				|  |  | +                        <div class={[styles.itemTitle]}>
 | 
	
		
			
				|  |  | +                          <img src={iconMenu} class={styles.iconMenu} />
 | 
	
		
			
				|  |  | +                          {item.coursewareDetailName}
 | 
	
		
			
				|  |  | +                        </div>
 | 
	
		
			
				|  |  | +                      ),
 | 
	
		
			
				|  |  | +                      default: () => (
 | 
	
		
			
				|  |  | +                        <>
 | 
	
		
			
				|  |  | +                          {Array.isArray(item?.materialList) &&
 | 
	
		
			
				|  |  | +                            item.materialList.map((n: any) => (
 | 
	
		
			
				|  |  | +                              <Cell center isLink clickable={false}>
 | 
	
		
			
				|  |  | +                                {{
 | 
	
		
			
				|  |  | +                                  title: () => (
 | 
	
		
			
				|  |  | +                                    <div class={styles.materialSection}>
 | 
	
		
			
				|  |  | +                                      <img
 | 
	
		
			
				|  |  | +                                        src={getImage(n)}
 | 
	
		
			
				|  |  | +                                        class={styles.iconMaterial}
 | 
	
		
			
				|  |  | +                                      />
 | 
	
		
			
				|  |  | +                                      {n.name}
 | 
	
		
			
				|  |  | +                                    </div>
 | 
	
		
			
				|  |  | +                                  )
 | 
	
		
			
				|  |  | +                                }}
 | 
	
		
			
				|  |  | +                              </Cell>
 | 
	
		
			
				|  |  | +                            ))}
 | 
	
		
			
				|  |  | +                          {Array.isArray(item?.children) && (
 | 
	
		
			
				|  |  | +                            <ChildNode
 | 
	
		
			
				|  |  | +                              id={route.query.id as any}
 | 
	
		
			
				|  |  | +                              search={data.search}
 | 
	
		
			
				|  |  | +                              isLock={isLock.value}
 | 
	
		
			
				|  |  | +                              list={item.children}
 | 
	
		
			
				|  |  | +                              collapse={item.collapse}
 | 
	
		
			
				|  |  | +                              onUpdate:collapse={(val: any) => {
 | 
	
		
			
				|  |  | +                                item.collapse = val;
 | 
	
		
			
				|  |  | +                              }}
 | 
	
		
			
				|  |  | +                            />
 | 
	
		
			
				|  |  | +                          )}
 | 
	
		
			
				|  |  | +                        </>
 | 
	
		
			
				|  |  | +                      ),
 | 
	
		
			
				|  |  | +                      'right-icon': () => (
 | 
	
		
			
				|  |  | +                        <i
 | 
	
		
			
				|  |  | +                          class={[
 | 
	
		
			
				|  |  | +                            styles.arrow,
 | 
	
		
			
				|  |  | +                            data.parentCollapse === item.coursewareDetailId
 | 
	
		
			
				|  |  | +                              ? styles.arrowActive
 | 
	
		
			
				|  |  | +                              : ''
 | 
	
		
			
				|  |  | +                          ]}></i>
 | 
	
		
			
				|  |  | +                      )
 | 
	
		
			
				|  |  | +                    }}
 | 
	
		
			
				|  |  | +                  </CollapseItem>
 | 
	
		
			
				|  |  | +                ))}
 | 
	
		
			
				|  |  | +              </Collapse>
 | 
	
		
			
				|  |  | +            )}
 | 
	
		
			
				|  |  | +          </TransitionGroup>
 | 
	
		
			
				|  |  | +          {data.loading && <OLoading />}
 | 
	
		
			
				|  |  | +          {!data.loading && !data.list.length && <OEmpty tips="暂无搜索结果" />}
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +});
 |