Pārlūkot izejas kodu

课堂播放添加搜索功能

lex-xin 3 mēneši atpakaļ
vecāks
revīzija
a488bed221

BIN
src/components/o-search/images/icon_search.png


+ 94 - 0
src/components/o-search/index.module.less

@@ -0,0 +1,94 @@
+.m-search {
+  --van-cell-background-color: transparent;
+
+  input::placeholder {
+    color: var(--k-gray-4);
+    font-size: 13px;
+  }
+
+  :global {
+    .van-field__control {
+      -webkit-user-select: text !important;
+      user-select: text !important;
+      font-size: 13px;
+    }
+
+    .van-search__field {
+      background: transparent !important;
+      padding: 0 var(--van-padding-xs) 0 0;
+    }
+
+    .van-field__right-icon {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      padding-right: 4px;
+    }
+  }
+
+  // &.default {
+  //   :global {
+  //     .van-search__content {
+  //       background: #f8f9fc !important;
+  //     }
+  //   }
+  // }
+
+  // &.white {
+  //   :global {
+  //     .van-search__content {
+  //       background: #fff !important;
+  //     }
+  //   }
+  // }
+
+  // &.transparent {
+  //   :global {
+  //     .van-search__content {
+  //       background: rgba(255, 255, 255, 0.16);
+
+  //       input::placeholder {
+  //         color: #fff;
+  //       }
+
+  //       input {
+  //         color: #fff;
+  //       }
+
+  //       .van-field__clear {
+  //         color: #fff;
+  //       }
+  //     }
+  //   }
+  // }
+
+  .searchBtn {
+    width: 52px;
+    height: 25px;
+    padding: 0;
+    font-size: 13px;
+    font-weight: 500;
+    --van-button-mini-height: 28px;
+    --van-font-size-xs: 12px;
+    background: linear-gradient(to right, #55D8C4, #0BC4B7);
+    border: none;
+    font-weight: 600;
+
+    :global {
+      .van-button__text {
+        margin-top: 1px;
+      }
+    }
+  }
+
+  .leftIcon {
+    width: 14px;
+    height: 14px;
+    margin-top: -2px;
+
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+}

+ 109 - 0
src/components/o-search/index.tsx

@@ -0,0 +1,109 @@
+import { Button, Icon, Search } from 'vant';
+import { PropType, defineComponent, reactive, ref, watch } from 'vue';
+import styles from './index.module.less';
+import iconSearch from './images/icon_search.png';
+
+export default defineComponent({
+  name: 'm-search',
+  props: {
+    modelValue: {
+      type: String,
+      default: ''
+    },
+    shape: {
+      type: String as PropType<'round' | 'square'>,
+      default: 'round'
+    },
+    disabled: {
+      type: Boolean,
+      default: false
+    },
+    clearable: {
+      type: Boolean,
+      default: true
+    },
+    autofocus: {
+      // ios系统不支持
+      type: Boolean,
+      default: false
+    },
+    placeholder: {
+      type: String,
+      default: '请输入搜索关键词'
+    },
+    background: {
+      type: String,
+      default: '#fff'
+    },
+    searchIcon: {
+      type: String,
+      default: iconSearch
+    },
+    inputBackground: {
+      type: String,
+      default: '#f8f9fc'
+    }
+  },
+  emits: ['search', 'focus', 'blur'],
+  setup(props, { slots, emit, expose }) {
+    const forms = reactive({
+      search: props.modelValue || '',
+    });
+    const searchRef = ref()
+    watch(
+      () => props.modelValue,
+      () => {
+        forms.search = props.modelValue;
+      }
+    );
+
+    const searchBlur = () => {
+      searchRef.value?.blur()
+    }
+
+    expose({
+      searchBlur
+    })
+    return () => (
+      <Search
+        class={[styles['m-search'], styles[props.inputBackground]]}
+        style={{"--van-search-content-background": props.inputBackground}}
+        ref={searchRef}
+        shape={props.shape}
+        background={props.background}
+        placeholder={props.placeholder}
+        disabled={props.disabled}
+        autofocus={props.autofocus}
+        autocomplete="off"
+        clearable={props.clearable}
+        v-model={forms.search}
+        clearTrigger="always"
+        onClear={() => {
+          console.log('clear');
+          forms.search = '';
+          emit('search', forms.search);
+        }}
+        onFocus={() => emit('focus')}
+        onBlur={() => emit('blur', forms.search)}
+        onSearch={() => emit('search', forms.search)}>
+        {{
+          left: () => slots.left && slots.left(),
+          'left-icon': () => (
+            <Icon name={props.searchIcon} class={styles.leftIcon} />
+          ),
+          'right-icon': () => (
+            <Button
+              disabled={props.disabled}
+              class={styles.searchBtn}
+              round
+              type="primary"
+              size="mini"
+              onClick={() => emit('search', forms.search)}>
+              搜索
+            </Button>
+          )
+        }}
+      </Search>
+    );
+  }
+});

+ 8 - 0
src/router/index.ts

@@ -24,6 +24,14 @@ const router: Router = createRouter({
           }
           }
         },
         },
         {
         {
+          path: '/courseListSearch',
+          name: 'courseListSearch',
+          component: () => import('@/views/courseListSearch/index'),
+          meta: {
+            title: '搜索'
+          }
+        },
+        {
           path: '/coursewarePlay',
           path: '/coursewarePlay',
           name: 'coursewarePlay',
           name: 'coursewarePlay',
           component: () => import('@/views/coursewarePlay'),
           component: () => import('@/views/coursewarePlay'),

BIN
src/views/courseList/image/icon_search.png


+ 27 - 1
src/views/courseList/index.module.less

@@ -71,11 +71,37 @@
   }
   }
 }
 }
 
 
+.periodHeader {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 20px 20px 0;
+  .searchGroup {
+    padding: 3px 10px 3px 7px;
+    border-radius: 19px;
+    border: 1px solid rgba(1,193,181,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;
+      height: 20px;
+      /deep/.van-icon__image {
+        margin: auto;
+        vertical-align: middle;
+      }
+    }
+  }
+}
+
 
 
 .periodTitle {
 .periodTitle {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
-  padding: 20px 20px 0;
+  
 
 
   .pIcon {
   .pIcon {
     width: 20px;
     width: 20px;

+ 18 - 4
src/views/courseList/index.tsx

@@ -28,6 +28,7 @@ import {
 import iconCourse from './image/icon-course.png';
 import iconCourse from './image/icon-course.png';
 import iconCachePoint from './image/icon-cache-point.png';
 import iconCachePoint from './image/icon-cache-point.png';
 import iconCourseLock from './image/icon-course-lock.png';
 import iconCourseLock from './image/icon-course-lock.png';
+import iconSearch from './image/icon_search.png'
 // import iconTip from './image/iconTip.png';
 // import iconTip from './image/iconTip.png';
 import { browser } from '@/helpers/utils';
 import { browser } from '@/helpers/utils';
 import OEmpty from '@/components/o-empty';
 import OEmpty from '@/components/o-empty';
@@ -328,10 +329,23 @@ export default defineComponent({
         <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 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>
 
 
               <div key="list" class={styles.periodList}>
               <div key="list" class={styles.periodList}>

+ 151 - 0
src/views/courseListSearch/child-node.tsx

@@ -0,0 +1,151 @@
+import { defineComponent } from "vue";
+import styles from './index.module.less'
+import { Cell, Collapse, CollapseItem } from "vant";
+import iconVideo from './image/icon-video.png'
+import iconSong from './image/icon-song.png'
+import iconImage from './image/icon-image.png'
+import { handleShowVip } from "@/state";
+import { browser } from "@/helpers/utils";
+import { useRouter } from "vue-router";
+
+// 获取对应图片
+export const getImage = (item: any) => {
+  if (item.typeCode === 'VIDEO') {
+    return iconVideo;
+  } else if (['IMAGE', 'IMG'].includes(item.typeCode)) {
+    return iconImage;
+  } else if (item.typeCode === 'SONG') {
+    return iconSong;
+  } else {
+    return iconVideo;
+  }
+};
+
+const ChildNode = defineComponent({
+  name: 'child-node',
+  props: {
+    id: {
+      type: String,
+      default: ''
+    },
+    search: {
+      type: String,
+      default: ''
+    },
+    isLock: {
+      type: Boolean,
+      default: false,
+    },
+    list: {
+      type: Array,
+      default: () => []
+    },
+    collapse: {
+      type: String,
+      default: ''
+    }
+  },
+  emits: ['update:collapse'],
+  setup(props, { emit }) {
+    const router = useRouter()
+    const toDetail = (item: any) => {
+      // 
+      if(props.isLock) {
+        handleShowVip(props.id, "LESSON")
+        return
+      }
+
+      if (browser().isApp) {
+        postMessage({
+          api: 'openWebView',
+          content: {
+            url: `${location.origin}${location.pathname}#/coursewarePlay?lessonId=${props.id}&source=search&kId=${item.id}&search=${props.search}`,
+            orientation: 0,
+            isHideTitle: true,
+            statusBarTextColor: false,
+            isOpenLight: true,
+            showLoadingAnim: true
+          }
+        });
+      } else {
+        router.push({
+          path: '/coursewarePlay',
+          query: {
+            lessonId: props.id,
+            kId: item.id,
+            search: props.search,
+            source: 'search'
+          }
+        });
+      }
+    }
+
+    const formatName = (name: string) => {
+      if(!name || !props.search) return name
+      const search: any = props.search
+      return name.replace(search, `<span style="color: #01C1B5;">${search}</span>`)
+    }
+    return () => (
+      <Collapse
+        modelValue={props.collapse}
+        onUpdate:modelValue={(val: any) => {
+          emit('update:collapse', val);
+        }}
+        border={false}
+        accordion>
+        {props.list?.map((point: any) => (
+          <CollapseItem
+            clickable={false}
+            center
+            border={false}
+            class={styles.collapseChild}
+            name={point.id}>
+            {{
+              title: () => (
+                <div
+                  class={[
+                    styles.itemTitle,
+                    Array.isArray(point?.materialList) && point?.materialList.length > 0 ? styles.materialTitle : ''
+                  ]}>
+                  {point.name}
+                </div>
+              ),
+              default: () => (
+                <>
+                  {Array.isArray(point?.materialList) &&
+                    point.materialList.map((n: any) => (
+                      <Cell center isLink clickable={false} onClick={() => toDetail(n)}>
+                        {{
+                          title: () => <div class={styles.materialSection}>
+                            <img src={getImage(n)} class={styles.iconMaterial} />
+                            <div v-html={formatName(n.name)}></div>
+                          </div>
+                        }}
+                      </Cell>
+                    ))}
+                  {Array.isArray(point?.children) && (
+                    <ChildNode
+                      isLock={props.isLock}
+                      search={props.search}
+                      id={props.id}
+                      list={point.children}
+                      collapse={point.collapse}
+                      onUpdate:collapse={val => {
+                        point.collapse = val;
+                      }}
+                    />
+                  )}
+                </>
+              ),
+              'right-icon': () => (
+                  <i class={[styles.arrow, props.collapse === point.id ? styles.arrowActive : '']}></i>
+              )
+            }}
+          </CollapseItem>
+        ))}
+      </Collapse>
+    );
+  }
+});
+
+export default ChildNode;

BIN
src/views/courseListSearch/image/icon-arrow-down.png


BIN
src/views/courseListSearch/image/icon-arrow-up.png


BIN
src/views/courseListSearch/image/icon-image.png


BIN
src/views/courseListSearch/image/icon-menu.png


BIN
src/views/courseListSearch/image/icon-song.png


BIN
src/views/courseListSearch/image/icon-video.png


+ 138 - 0
src/views/courseListSearch/index.module.less

@@ -0,0 +1,138 @@
+.courseListSearch {
+  min-height: 100vh;
+  background-color: #fff;
+  background: linear-gradient(180deg, #7defe6 0%, rgba(255, 255, 255, 0) 170px);
+  box-sizing: border-box;
+
+  :global {
+    .van-nav-bar__title {
+      width: 100%;
+      max-width: 100%;
+      margin-left: 46px;
+    }
+    .van-nav-bar__right {
+      display: none;
+    }
+    .van-search {
+      padding-left: 0;
+    }
+
+    .o-result-container {
+      height: 90vh;
+    }
+  }
+}
+
+.collapseParent {
+  padding-top: 12px;
+
+  
+  :global {
+    .parentCollapse__item {
+      margin: 0 14px 12px;
+  
+      & >  .van-collapse-item__wrapper {
+        margin: 0 14px 12px;
+      }
+    }
+    .van-cell {
+      padding: 14px;
+      font-weight: 600;
+    }
+
+    .van-collapse-item {
+      background-color: #fff;
+      border-radius: 12px;
+      overflow: hidden;
+      
+    }
+
+    .van-collapse-item--border:after {
+      left: 0;
+      right: 0;
+    }
+
+    .van-collapse-item__content {
+      padding-top: 0;
+      padding-bottom: 0;
+      padding-right: 0;
+      padding-left: 0;
+    }
+  }
+}
+
+.collapseChild {
+  // margin: 0 !important;
+  :global {
+    .van-cell {
+      padding: 12px 0;
+      font-weight: 400;
+      font-size: 15px;
+      color: #333333;
+      line-height: 21px;  
+    }
+    .van-collapse-item__content {
+      // padding-left: 22px;
+
+      .van-cell {
+        padding: 12px 0;
+      }
+
+      .van-cell__title {
+        flex: 1 auto;
+      }
+
+      .van-cell__value {
+        flex-shrink: 0;
+        flex: 1 auto;
+      }
+    }
+  }
+}
+.materialSection {
+  display: flex;
+  align-items: center;
+  color: #333333;
+  padding-left: 10px;
+  .iconMaterial {
+    width: 32px;
+    height: 32px;
+    margin-right: 10px;
+  }
+}
+
+
+.itemTitle {
+  display: flex;
+  align-items: center;
+  font-size: 15px;
+  color: #333333;
+  line-height: 21px;
+  .iconMenu {
+    width: 36px;
+    height: 40px;
+    margin-right: 8px;
+  }
+
+  &.materialTitle::before {
+    content: '';
+    width: 4px;
+    height: 4px;
+    background: #01C1B5;
+    border-radius: 50%;
+    display: inline-block;
+    margin-right: 6px;
+  }
+}
+.arrow {
+  width: 16px;
+  height: 17px;
+  display: inline-block;
+  background: url('./image/icon-arrow-down.png');
+  background-size: contain;
+
+  &.arrowActive {
+    background: url('./image/icon-arrow-up.png');
+    background-size: contain;
+  }
+}

+ 216 - 0
src/views/courseListSearch/index.tsx

@@ -0,0 +1,216 @@
+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 { useEventListener, usePageVisibility } from '@vant/use';
+import iconMenu from './image/icon-menu.png';
+
+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 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);
+          });
+
+          data.list = res.data;
+
+          data.parentCollapse = data.list[0].id
+        }
+      } catch (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 > 100 ? 1 : height / 100;
+    });
+    return () => (
+      <div class={styles.courseListSearch}>
+        <OHeader
+          isBack
+          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>
+
+        <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
+                  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>
+    );
+  }
+});

+ 14 - 0
src/views/coursewarePlay/component/point.module.less

@@ -24,6 +24,20 @@
   }
   }
 }
 }
 
 
+.pointHeadSearch {
+  :global {
+    .van-search {
+      padding-top: 17px;
+      padding-left: 20px;
+      padding-right: 20px;
+
+      input {
+        color: rgba(255,255,255,0.9);
+      }
+    }
+  }
+}
+
 .content {
 .content {
   flex: 1;
   flex: 1;
   overflow-y: auto;
   overflow-y: auto;

+ 311 - 0
src/views/coursewarePlay/component/points-search.tsx

@@ -0,0 +1,311 @@
+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, Icon, Image } from 'vant';
+import PlayLoading from './play-loading';
+import OSearch from '@/components/o-search';
+import OLoading from '@/components/o-loading';
+import OEmpty from '@/components/o-empty';
+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;
+      }
+    };
+    return () => (
+      <div class={styles.container}>
+        <div class={styles.pointHeadSearch}>
+          <OSearch placeholder='请输入素材关键词' modelValue={pointData.search} background='transparent' inputBackground='rgba(255, 255, 255, 0.15)' onSearch={(val: any) => {
+            // 
+            if(props.loading) return
+            pointData.isSearch = true
+            pointData.search = val
+            emit('handleSearch', {
+              search: val
+            })
+          }} />
+        </div>
+        <div class={styles.content}>
+          {props.loading && <OLoading />}
+          {!props.loading && !props.data.length && <OEmpty tips="暂无搜索结果" />}
+          <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">
+                                                  {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">
+                                                                    {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>
+    );
+  }
+});

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
src/views/coursewarePlay/image/icons.json


+ 315 - 37
src/views/coursewarePlay/index.tsx

@@ -8,7 +8,8 @@ import {
   ref,
   ref,
   watch,
   watch,
   Transition,
   Transition,
-  computed
+  computed,
+  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';
@@ -25,7 +26,7 @@ import MusicScore from './component/musicScore';
 // import iconDian from './image/icon-dian.svg';
 // import iconDian from './image/icon-dian.svg';
 // import iconPoint from './image/icon-point.svg';
 // import iconPoint from './image/icon-point.svg';
 // import qs from 'query-string';
 // import qs from 'query-string';
-import { iconUp, iconDown, iconTouping, iconMenu, iconCourseType } from './image/icons.json';
+import { iconUp, iconDown, iconTouping, iconMenu, iconCourseType, iconSearch } from './image/icons.json';
 import Points from './component/points';
 import Points from './component/points';
 import { browser } from '@/helpers/utils';
 import { browser } from '@/helpers/utils';
 import { Vue3Lottie } from 'vue3-lottie';
 import { Vue3Lottie } from 'vue3-lottie';
@@ -42,6 +43,7 @@ import CoursewareTips from './component/courseware-tips';
 import GlobalTools from '@/components/globalTools';
 import GlobalTools from '@/components/globalTools';
 import { isHidden, isPlay, penShow, toolOpen, whitePenShow } from '@/components/globalTools/globalTools';
 import { isHidden, isPlay, penShow, toolOpen, whitePenShow } from '@/components/globalTools/globalTools';
 import { vaildCurrentUrl } from '@/helpers/validate';
 import { vaildCurrentUrl } from '@/helpers/validate';
+import PointsSearch from './component/points-search';
 
 
 export default defineComponent({
 export default defineComponent({
   name: 'CoursewarePlay',
   name: 'CoursewarePlay',
@@ -56,8 +58,17 @@ export default defineComponent({
           handleStop();
           handleStop();
         }
         }
         if (value === "visible") {
         if (value === "visible") {
-          getDetail('visible', data.currentId)
-          getRefLevel(data.currentId)
+          if(data.source === 'search') {
+            getSearchDetail({
+              type: 'visible',
+              id: data.currentId,
+              search: data.search
+            })
+          } else {
+            getDetail('visible', data.currentId)
+            getRefLevel(data.currentId)
+          }
+          
         }
         }
       }
       }
     );
     );
@@ -121,9 +132,16 @@ 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({
-      currentId: route.query.id as any,
+      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 || route.query.lessonId as any,
       lessonCoursewareId: "",
       lessonCoursewareId: "",
+      // detailList: [], // 搜索来的所有数据
       detail: null as any,
       detail: null as any,
       refLevelList: [] as any, // 课堂类型
       refLevelList: [] as any, // 课堂类型
       knowledgePointList: [] as any,
       knowledgePointList: [] as any,
@@ -132,7 +150,6 @@ export default defineComponent({
       // isCourse: false,
       // isCourse: false,
       isRecordPlay: false,
       isRecordPlay: false,
       videoRefs: {},
       videoRefs: {},
-
       videoState: 'init' as 'init' | 'play',
       videoState: 'init' as 'init' | 'play',
       videoItemRef: null as any,
       videoItemRef: null as any,
       animationState: 'start' as 'start' | 'end',
       animationState: 'start' as 'start' | 'end',
@@ -313,7 +330,7 @@ export default defineComponent({
             title: '温馨提示',
             title: '温馨提示',
             message: '课件已锁定'
             message: '课件已锁定'
           }).then(() => {
           }).then(() => {
-            goback();
+            goBack();
           });
           });
           return;
           return;
         }
         }
@@ -383,6 +400,217 @@ export default defineComponent({
       }
       }
     };
     };
 
 
+
+
+    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 checkRecursionCoursewareId = (list: [], id: string) => {
+      list.forEach((parent: any) => {
+        if(Array.isArray(parent.materialList)) {
+          const parentMaterial = parent.materialList || []
+          parentMaterial.forEach((item: any) => {
+            console.log(item.materialId, id, '------------------------------')
+            if(item.materialId == id) {
+              console.log(item, '---------------')
+              return true
+            }
+          })
+        }
+        if(Array.isArray(parent.child)) {
+          const parentItem = parent.child || []
+          checkRecursionCoursewareId(parentItem, id)
+        }
+      })
+    }
+    const getSearchParentCoursewareId = (list: [], id: string) => {
+      if(!id || list.length <= 0) return
+
+      // list.knowledgePointList.forEach(element => {
+        
+      // });
+      // let coursewareDetailId = ''
+      console.log(list, '12121--------')
+      list.forEach((parent: any) => {
+        if(Array.isArray(parent.knowledgePointList)) {
+          const parentItem = parent.knowledgePointList || []
+          console.log(checkRecursionCoursewareId(parentItem, id))
+        }
+      })
+    }
+
+    /** 从搜索页面来的 */
+    const getSearchDetail = async (params: { type?: string, id?: any, search?: string }) => {
+      try {
+        const res = await request.get(
+          state.platformApi +
+            `/lessonCourseware/getLessonCoursewareCourseList/${params.id || route.query.lessonId}`,
+          {
+            hideLoading: true,
+            params: {
+              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;
+                    const useStatus = materialRefs.length > 0
+                    ? materialRefs[0]?.extend?.useStatus : null
+                    const isLock = useStatus === 'LOCK' && state.platformType === "STUDENT" ? true : false
+                    return {
+                      ...item,
+                      isLock,
+                      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;
+                      const useStatus = materialRefs.length > 0
+                      ? materialRefs[0]?.extend?.useStatus : null
+                      const isLock = useStatus === 'LOCK' && state.platformType === "STUDENT" ? true : false
+                      return {
+                        ...item,
+                        isLock,
+                        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
+          return
+        }
+        detailList.value = result
+        detailTempSearchList.value = result
+
+        // getSearchParentCoursewareId(result, route.query.kId as any)  
+
+        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) => {
     const onTitleTip = (type: "phaseGoals" | "checkItem", text: string) => {
       handleStop()
       handleStop()
       popupData.pointOpen = true
       popupData.pointOpen = true
@@ -500,8 +728,12 @@ export default defineComponent({
     onMounted(async () => {
     onMounted(async () => {
       isHidden.value = true;
       isHidden.value = true;
       await sysParamConfig();
       await sysParamConfig();
-      await getRefLevel()
-      await getDetail();
+      if(data.source === 'search') {
+        await getSearchDetail({search: data.search})
+      } else {
+        await getRefLevel()
+        await getDetail();
+      }
       isHidden.value = false;
       isHidden.value = false;
       // getCourseSchedule();
       // getCourseSchedule();
       window.addEventListener('message', iframeHandle);
       window.addEventListener('message', iframeHandle);
@@ -525,7 +757,7 @@ export default defineComponent({
 
 
     const playRef = ref();
     const playRef = ref();
     // 返回
     // 返回
-    const goback = () => {
+    const goBack = () => {
       try {
       try {
         playRef.value?.handleOut();
         playRef.value?.handleOut();
       } catch (error) {
       } catch (error) {
@@ -677,6 +909,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();
@@ -1102,20 +1338,29 @@ export default defineComponent({
             {activeData.model && (
             {activeData.model && (
               <div class={styles.leftFixedBtns} onClick={(e: Event) => e.stopPropagation()}>
               <div class={styles.leftFixedBtns} onClick={(e: Event) => e.stopPropagation()}>
                 <div class={[styles.btnsWrap, styles.prePoint]}>
                 <div class={[styles.btnsWrap, styles.prePoint]}>
-                  <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>
-                  
+                  {data.source === 'search' ? 
+                    <div class={styles.fullBtn} onClick={() => {
+                      handleStop()
+                      detailTempSearchList.value = detailList.value
+                      // data.searchTemp = JSON.parse(JSON.stringify(data.search))
+                      popupData.open = true
+                    }}>
+                      <img src={iconSearch} />
+                    </div> : <>
+                    <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} />
+                    </div>
+                  </>}
+
                     <div
                     <div
                       class={[styles.fullBtn, !(popupData.activeIndex != 0) && styles.disabled]}
                       class={[styles.fullBtn, !(popupData.activeIndex != 0) && styles.disabled]}
                       onClick={() => {
                       onClick={() => {
@@ -1147,11 +1392,11 @@ export default defineComponent({
             ref={headeRef}
             ref={headeRef}
           >
           >
             <div class={styles.backBtn}>
             <div class={styles.backBtn}>
-              <Icon name={iconBack} onClick={goback} />
+              <Icon name={iconBack} onClick={goBack} />
               <div class={styles.titleSection}>
               <div class={styles.titleSection}>
-                <div class={styles.title} onClick={goback}>{popupData.tabName}</div>
+                <div class={styles.title} onClick={goBack}>{popupData.tabName}</div>
                 <div class={styles.titleContent}>
                 <div class={styles.titleContent}>
-                  <p onClick={goback}>{data.itemList[popupData.activeIndex]?.name}</p>
+                  <p onClick={goBack}>{data.itemList[popupData.activeIndex]?.name}</p>
                   {data.detail?.lessonTargetDesc ? <span onClick={() => onTitleTip('phaseGoals', data.detail?.lessonTargetDesc)}>阶段目标</span>: ""}
                   {data.detail?.lessonTargetDesc ? <span onClick={() => onTitleTip('phaseGoals', data.detail?.lessonTargetDesc)}>阶段目标</span>: ""}
                   {data.itemList[popupData.activeIndex]?.checkItem ? <span onClick={() => onTitleTip('checkItem', data.itemList[popupData.activeIndex]?.checkItem)}>检查事项</span> : ""}
                   {data.itemList[popupData.activeIndex]?.checkItem ? <span onClick={() => onTitleTip('checkItem', data.itemList[popupData.activeIndex]?.checkItem)}>检查事项</span> : ""}
                 </div>
                 </div>
@@ -1183,16 +1428,49 @@ export default defineComponent({
           round
           round
           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.search}
+                loading={data.searchLoading}
+                tabActive={popupData.tabActive}
+                itemActive={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) => {
+                  popupData.open = false;
+                  toggleMaterial(res.itemActive);
+                }}
+              />}
+          
         </Popup>
         </Popup>
 
 
         <Popup
         <Popup

+ 1 - 1
vite.config.ts

@@ -14,7 +14,7 @@ function resolve(dir: string) {
 }
 }
 // https://vitejs.dev/config/
 // https://vitejs.dev/config/
 // https://github.com/vitejs/vite/issues/1930 .env
 // https://github.com/vitejs/vite/issues/1930 .env
-const proxyUrl = 'https://test.gym.lexiaoya.cn';
+const proxyUrl = 'https://dev.gym.lexiaoya.cn';
 export default defineConfig({
 export default defineConfig({
   base: './',
   base: './',
   plugins: [
   plugins: [

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels