lex il y a 1 an
Parent
commit
d2ec2fa6eb

+ 1034 - 1026
src/views/prepare-lessons/components/lesson-main/courseware/addCourseware.tsx

@@ -1,1026 +1,1034 @@
-import {
-  defineComponent,
-  nextTick,
-  onMounted,
-  onUnmounted,
-  reactive,
-  ref,
-  watch
-} from 'vue';
-import styles from './addCourseware.module.less';
-import {
-  NButton,
-  NModal,
-  NScrollbar,
-  NSelect,
-  NSpace,
-  NSpin,
-  useMessage,
-  useDialog,
-  NSwitch,
-  NInput,
-  NTooltip,
-  NImage,
-  NIcon,
-  NForm,
-  NFormItem
-} from 'naive-ui';
-import CardType from '/src/components/card-type';
-// import AttendClass from '/src/views/prepare-lessons/model/attend-class';
-import { usePrepareStore } from '/src/store/modules/prepareLessons';
-// import { useCatchStore } from '/src/store/modules/catchData';
-// import TheEmpty from '/src/components/TheEmpty';
-import {
-  api_teacherChapterLessonCoursewareAdd,
-  api_teacherChapterLessonCoursewareUpdate,
-  api_teacherChapterLessonCoursewareDetail,
-  api_materialDetail
-  // courseScheduleStart,
-  // queryCourseware,
-  // saveCourseware
-} from '../../../api';
-import Draggable from 'vuedraggable';
-import iconDelete from '../../../images/icon-delete-default.png';
-import iconAddMusic from '../../../images/icon-add-music.png';
-// import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router';
-// import deepClone from '/src/helpers/deep-clone';
-import CardPreview from '/src/components/card-preview';
-import PreviewWindow from '/src/views/preview-window';
-// import { state } from '/src/state';
-// import SubjectSync from '../../../model/subject-sync';
-import { eventGlobal } from '/src/utils';
-// import iconTips from '../../../images/icon-tips.png';
-import TheMessageDialog from '/src/components/TheMessageDialog';
-import AddItemModel from '../../../model/add-item-model';
-import AddOtherSource from '../../../model/add-other-source';
-import deepClone from '/src/helpers/deep-clone';
-import AddCoursewareProtocol from '../../../model/add-courseware-protocol';
-import { useUserStore } from '/src/store/modules/users';
-export default defineComponent({
-  name: 'courseware-modal',
-  props: {
-    groupItem: {
-      type: Object,
-      default: () => ({})
-    }
-  },
-  emits: ['change'],
-  setup(props, { emit }) {
-    // const catchStore = useCatchStore();
-    const userStore = useUserStore();
-
-    const prepareStore = usePrepareStore();
-    // const route = useRoute();
-    // const router = useRouter();
-    // const dialog = useDialog();
-    const message = useMessage();
-
-    const forms = reactive({
-      subjects: [] as any,
-      openFlagEnable: true, // 是否支持修改公开状态
-      autoPlay: true,
-      name: '',
-      openFlag: false,
-      createId: null,
-      baseCoursewareList: [
-        {
-          name: '',
-          id: null,
-          list: [] as any
-        }
-      ] as any, // 基础数据
-      baseInfo: {
-        subjects: [] as any,
-        autoPlay: true,
-        name: '',
-        openFlag: false
-      }, // 基础数据
-      coursewareList: [
-        {
-          name: '',
-          id: null,
-          list: [] as any
-        }
-      ] as any,
-      loadingStatus: false,
-      showAttendClass: false,
-      attendClassType: 'change', //
-      removeIds: [] as any, // 临时删除的编号
-      editSubjectIds: '', // 声部编号
-      addCoursewareVisiable: false,
-      addCoursewareItem: {} as any,
-      messageCallBack: null as any,
-      messageOperation: {
-        visiable: false,
-        loading: false, // 是否显示加载
-        type: 'delete' as 'delete' | 'addItem' | 'save' | 'pageLive',
-        contentDirection: 'center' as 'left' | 'center' | 'right',
-        title: '删除知识点',
-        content: '请确认是否删除该知识点,删除知识点后将同步删除知识点下的资源',
-        cancelButtonText: '取消',
-        confirmButtonText: '确认',
-        index: 0
-      },
-      show: false,
-      item: {} as any,
-      previewModal: false,
-      previewParams: {
-        type: '',
-        subjectId: '',
-        detailId: ''
-      } as any,
-      addOtherSource: false,
-      addOtherIndex: 0 // 添加其它的索引
-    });
-    const coursewareListRef = ref();
-    const showModalMask = ref(false);
-
-    // 获取列表
-    const getList = async () => {
-      forms.loadingStatus = true;
-      try {
-        if (!props.groupItem.id) return (forms.loadingStatus = false);
-
-        const { data } = await api_teacherChapterLessonCoursewareDetail(
-          props.groupItem.id
-        );
-        const tempRows = data.chapterKnowledgeList || [];
-        forms.name = data.name;
-        forms.subjects = data.instrumentIds
-          ? data.instrumentIds.split(',').map((s: any) => {
-              return s;
-            })
-          : [];
-        forms.openFlag = data.openFlag;
-        forms.openFlagEnable = data.openFlagEnable;
-        forms.autoPlay = data.autoPlay;
-        const temp: any = [];
-        tempRows.forEach((row: any) => {
-          const child: any = row.chapterKnowledgeMaterialList;
-          const childList: any[] = [];
-          if (Array.isArray(child) && child.length > 0) {
-            child.forEach((sub: any) => {
-              childList.push({
-                id: sub.id,
-                materialId: sub.bizId,
-                coverImg: sub.bizInfo.coverImg,
-                type: sub.type,
-                title: sub.bizInfo.name,
-                dataJson: sub.dataJson,
-                // isCollect: !!sub.favoriteFlag,
-                isSelected: sub.source === 'PLATFORM' ? true : false,
-                content: sub.bizInfo.content,
-                removeFlag: sub.removeFlag
-              });
-            });
-          }
-          temp.push({
-            name: row.name,
-            id: row.id,
-            list: [...childList]
-          });
-        });
-        forms.coursewareList = temp;
-        forms.baseCoursewareList = deepClone(temp);
-
-        forms.baseInfo = deepClone({
-          subjects: forms.subjects,
-          autoPlay: forms.autoPlay,
-          name: forms.name,
-          openFlag: forms.openFlag
-        });
-
-        /** 给头部组件分发消息 */
-        eventGlobal.emit('updateCoursewareHeadInfo', {
-          name: forms.name,
-          subjects: forms.subjects,
-          openFlag: forms.openFlag,
-          openFlagEnable: forms.openFlagEnable,
-          autoPlay: forms.autoPlay
-        });
-      } catch (e) {
-        //
-        console.log(e);
-      }
-      forms.loadingStatus = false;
-    };
-
-    // 删除
-    const onDelete = (j: number, index: number) => {
-      const coursewareItem = forms.coursewareList[index];
-      if (!coursewareItem) return;
-      coursewareItem.list.splice(j, 1);
-    };
-
-    const isPointInsideElement = (element: any, x: number, y: number) => {
-      const rect = element.getBoundingClientRect();
-      return (
-        x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
-      );
-    };
-    const isPointOnLeft = (element: any, x: number) => {
-      const rect = element.getBoundingClientRect();
-      const elementCenterX = rect.left + rect.width / 2;
-      return x < elementCenterX;
-    };
-
-    // 操作
-    const onChangePoint = (type: string, index: number, item?: any) => {
-      if (type === 'up') {
-        // 向上移动
-        if (index === 0) return;
-        const temp = forms.coursewareList[index - 1];
-        forms.coursewareList[index - 1] = forms.coursewareList[index];
-        forms.coursewareList[index] = temp;
-      } else if (type === 'down') {
-        // 向下移动
-        if (index >= forms.coursewareList.length - 1) return;
-        const temp = forms.coursewareList[index + 1];
-        forms.coursewareList[index + 1] = forms.coursewareList[index];
-        forms.coursewareList[index] = temp;
-      } else if (type === 'remove') {
-        forms.messageOperation = {
-          visiable: true,
-          type: 'delete',
-          contentDirection: 'left',
-          title: '删除知识点',
-          loading: false,
-          content: `请确认是否删除${
-            item.name ? '【' + item.name + '】' : '该知识点'
-          },删除知识点后将同步删除知识点下的资源`,
-          cancelButtonText: '取消',
-          confirmButtonText: '确认',
-          index
-        };
-      }
-    };
-
-    //
-    const onMessageConfirm = async () => {
-      const type = forms.messageOperation.type;
-      if (type === 'delete') {
-        forms.coursewareList.splice(forms.messageOperation.index, 1);
-      } else if (type === 'addItem') {
-        forms.coursewareList.push({ name: '', list: [] });
-        addCoursewareItem(forms.addCoursewareItem);
-      } else if (type === 'save' || type === 'pageLive') {
-        if (forms.messageOperation.loading) return;
-        if (!forms.name) {
-          message.error('请输入课件标题');
-          forms.messageOperation.visiable = false;
-          return;
-        }
-        if (forms.subjects.length <= 0) {
-          message.error('请选择声部');
-          forms.messageOperation.visiable = false;
-          return;
-        }
-
-        if (forms.coursewareList.length <= 0) {
-          message.error('未配置知识点');
-          forms.messageOperation.visiable = false;
-          return;
-        }
-
-        let isNotAdd = false;
-        for (const item of forms.coursewareList) {
-          if (!item.name) {
-            message.error('请输入知识点名称');
-            forms.messageOperation.visiable = false;
-            return;
-          }
-          if (Array.isArray(item.list) && item.list.length <= 0) {
-            isNotAdd = true;
-          }
-        }
-
-        if (isNotAdd) {
-          message.error('请至少添加一个资源');
-          forms.messageOperation.visiable = false;
-          return;
-        }
-
-        forms.messageOperation.loading = true;
-        const resultStatus = await onSaveCourseWare();
-        forms.messageOperation.loading = false;
-        if (resultStatus) {
-          if (
-            type === 'pageLive' &&
-            typeof forms.messageCallBack === 'function'
-          ) {
-            forms.messageCallBack();
-          }
-          emit('change', {
-            status: false,
-            addParam: {
-              isAdd: !props.groupItem.id ? true : false,
-              name: forms.name,
-              id: forms.createId
-            }
-          });
-          eventGlobal.emit('teacher-slideshow', false);
-        }
-      }
-      forms.messageOperation.visiable = false;
-    };
-
-    const addCoursewareItem = async (item: any, point?: any) => {
-      const materialList: any[] = [];
-      try {
-        const { data } = await api_materialDetail(item.materialId);
-        if (Array.isArray(data.materialRefs)) {
-          data.materialRefs.forEach((item: any) => {
-            if (item.refType === 'STRONG') {
-              const relateMaterialInfo = item.relateMaterialInfo || {};
-              materialList.push({
-                content: relateMaterialInfo.content,
-                coverImg: relateMaterialInfo.coverImg,
-                // isCollect: relateMaterialInfo.,
-                isSelected:
-                  relateMaterialInfo.sourceFrom === 'PLATFORM' ? true : false,
-                materialId: relateMaterialInfo.id,
-                // removeFlag: relateMaterialInfo.,
-                title: relateMaterialInfo.name,
-                type: relateMaterialInfo.type
-              });
-            }
-          });
-        }
-      } catch {
-        //
-      }
-      nextTick(() => {
-        if (point) {
-          const rowGroupDom = document.querySelectorAll('.row-group');
-          const dom = rowGroupDom[item.index].querySelectorAll('.row-nav');
-          // const dom = document.querySelectorAll('.row-nav');
-          let isAdd = false;
-          dom.forEach((child: any, index: number) => {
-            // console.log(child);
-            const status = isPointInsideElement(child, point.x, point.y);
-            if (status) {
-              const array: any =
-                forms.coursewareList[item.index || 0].list || [];
-              const left = isPointOnLeft(child, point.x);
-              if (!left) {
-                array.splice(index + 1, 0, item);
-                materialList.forEach((m: any) => {
-                  array.splice(index + 1, 0, m);
-                });
-              } else {
-                materialList.forEach((m: any) => {
-                  array.splice(index, 0, m);
-                });
-                array.splice(index, 0, item);
-              }
-              isAdd = true;
-              forms.coursewareList[item.index || 0].list = array;
-            }
-          });
-          if (!isAdd) {
-            forms.coursewareList[item.index || 0].list.push(item);
-            materialList.forEach((m: any) => {
-              forms.coursewareList[item.index || 0].list.push(m);
-            });
-          }
-        } else {
-          forms.coursewareList[item.index || 0].list.push(item);
-          materialList.forEach((m: any) => {
-            forms.coursewareList[item.index || 0].list.push(m);
-          });
-          message.success('添加成功');
-        }
-      });
-    };
-
-    // 提交
-    const onSubmit = async () => {
-      try {
-        coursewareListRef.value.validate();
-        eventGlobal.emit('checkCoursewareForm');
-        if (!forms.name) {
-          message.error('请输入课件标题');
-          return;
-        }
-        if (forms.subjects.length <= 0) {
-          message.error('请选择声部');
-          return;
-        }
-        if (forms.coursewareList.length <= 0) {
-          message.error('请至少添加一个知识点');
-          return;
-        }
-
-        let isNotAdd = false;
-        for (const item of forms.coursewareList) {
-          if (!item.name) {
-            message.error('请输入知识点名称');
-            return;
-          }
-          if (Array.isArray(item.list) && item.list.length <= 0) {
-            isNotAdd = true;
-          }
-        }
-
-        if (isNotAdd) {
-          message.error('请至少添加一个资源');
-          return;
-        }
-
-        if (forms.openFlag && !userStore.getReadCoursewareOpenAgreement) {
-          showModalMask.value = true;
-          return;
-        }
-        const resultStatus = await onSaveCourseWare();
-
-        if (resultStatus) {
-          emit('change', {
-            status: false,
-            addParam: {
-              isAdd: !props.groupItem.id ? true : false,
-              name: forms.name,
-              id: forms.createId
-            }
-          });
-          eventGlobal.emit('teacher-slideshow', false);
-        }
-      } catch {
-        //
-      }
-    };
-    const onSaveCourseWare = async () => {
-      try {
-        const params = {
-          name: forms.name,
-          instrumentIds: forms.subjects.join(','),
-          openFlag: forms.openFlag,
-          autoPlay: forms.autoPlay,
-          coursewareDetailKnowledgeId: prepareStore.getSelectKey,
-          chapterKnowledgeList: [] as any
-        };
-
-        forms.coursewareList.forEach((item: any) => {
-          let tempItem: any = [];
-          if (Array.isArray(item.list) && item.list.length > 0) {
-            tempItem = item.list.map((child: any) => {
-              return {
-                bizId: child.materialId,
-                type: child.type,
-                dataJson: !['IMG', 'VIDEO', 'SONG', 'MUSIC', 'PPT'].includes(
-                  child.type
-                )
-                  ? JSON.stringify({
-                      setting: child.dataJson,
-                      coverImg: child.coverImg,
-                      bizId: child.bizId,
-                      content: child.content,
-                      name: child.title
-                    })
-                  : ''
-              };
-            });
-          }
-          params.chapterKnowledgeList.push({
-            name: item.name,
-            chapterKnowledgeMaterialList: tempItem
-          });
-        });
-        if (props.groupItem?.id) {
-          await api_teacherChapterLessonCoursewareUpdate({
-            id: props.groupItem.id,
-            ...params
-          });
-          message.success('保存成功');
-        } else {
-          const { data } = await api_teacherChapterLessonCoursewareAdd(params);
-          forms.createId = data.id;
-        }
-
-        return true;
-      } catch {
-        //
-        return false;
-      }
-    };
-
-    const addItem = (item: any, point?: any) => {
-      if (forms.coursewareList.length <= 0) {
-        // 添加到临时对象
-        forms.addCoursewareItem = item;
-        forms.messageOperation = {
-          visiable: true,
-          type: 'addItem',
-          contentDirection: 'center',
-          title: '添加到知识点',
-          loading: false,
-          content: '当前课件暂无知识点,请添加知识点后操作',
-          cancelButtonText: '取消',
-          confirmButtonText: '添加知识点',
-          index: 0
-        };
-      } else if (forms.coursewareList.length > 1 && item.addType !== 'drag') {
-        forms.addCoursewareVisiable = true;
-        forms.addCoursewareItem = item;
-      } else {
-        addCoursewareItem(item, point);
-      }
-    };
-
-    // 当页面离开时
-    const onPageBeforeLeave = (event: any) => {
-      const objA = JSON.stringify(forms.coursewareList);
-      const objB = JSON.stringify(forms.baseCoursewareList);
-      const baseA = JSON.stringify({
-        subjects: forms.subjects,
-        autoPlay: forms.autoPlay,
-        name: forms.name,
-        openFlag: forms.openFlag
-      });
-      const baseB = JSON.stringify(forms.baseInfo);
-      if (objA === objB && baseA === baseB) {
-        if (typeof event === 'function') {
-          event();
-
-          emit('change', {
-            status: false,
-            addParam: {
-              isAdd: false,
-              name: forms.name,
-              id: forms.createId
-            }
-          });
-          eventGlobal.emit('teacher-slideshow', false);
-        }
-      } else {
-        forms.messageCallBack = event;
-        forms.messageOperation = {
-          visiable: true,
-          type: 'pageLive',
-          loading: false,
-          contentDirection: 'center',
-          title: '保存课件',
-          content: '当前课件暂未保存,是否保存?',
-          cancelButtonText: '不保存',
-          confirmButtonText: '保存',
-          index: 0
-        };
-      }
-    };
-
-    const onCancelCourseware = (item: any) => {
-      forms.subjects = item.subjects;
-      forms.openFlagEnable = item.openFlagEnable;
-      forms.autoPlay = item.autoPlay;
-      forms.name = item.name;
-      forms.openFlag = item.openFlag;
-
-      const objA = JSON.stringify(forms.coursewareList);
-      const objB = JSON.stringify(forms.baseCoursewareList);
-      const baseA = JSON.stringify({
-        subjects: forms.subjects,
-        autoPlay: forms.autoPlay,
-        name: forms.name,
-        openFlag: forms.openFlag
-      });
-      const baseB = JSON.stringify(forms.baseInfo);
-
-      if (objA === objB && baseA === baseB) {
-        emit('change', {
-          status: false,
-          addParam: {
-            isAdd: false,
-            name: forms.name,
-            id: forms.createId
-          }
-        });
-
-        eventGlobal.emit('teacher-slideshow', false);
-      } else {
-        forms.messageOperation = {
-          visiable: true,
-          type: 'save',
-          loading: false,
-          contentDirection: 'center',
-          title: '保存课件',
-          content: '当前课件暂未保存,是否保存?',
-          cancelButtonText: '不保存',
-          confirmButtonText: '保存',
-          index: 0
-        };
-      }
-    };
-
-    const onSubmitCourseware = (item: any) => {
-      forms.subjects = item.subjects;
-      forms.openFlagEnable = item.openFlagEnable;
-      forms.autoPlay = item.autoPlay;
-      forms.name = item.name;
-      forms.openFlag = item.openFlag;
-
-      onSubmit();
-    };
-
-    onMounted(async () => {
-      // 修改时重置默认数据
-      if (props.groupItem?.id) {
-        forms.coursewareList = [];
-        forms.baseCoursewareList = [];
-      }
-
-      await getList();
-      // 动态添加数据
-      eventGlobal.on('onPrepareAddItem', addItem);
-      eventGlobal.on('pageBeforeLeave', onPageBeforeLeave);
-
-      // 取消
-      eventGlobal.on('coursewareClosed', onCancelCourseware);
-      // 保存
-      eventGlobal.on('coursewareSave', onSubmitCourseware);
-    });
-
-    onUnmounted(() => {
-      eventGlobal.off('onPrepareAddItem', addItem);
-      eventGlobal.off('pageBeforeLeave', onPageBeforeLeave);
-      eventGlobal.off('coursewareClosed', onCancelCourseware);
-      eventGlobal.off('coursewareSave', onSubmitCourseware);
-    });
-
-    // 当列表数据更新时同步缓存数据
-    watch(
-      () => forms.coursewareList,
-      () => {
-        prepareStore.setCoursewareList(forms.coursewareList);
-        // 内容有更新 - 相关资源会刷新
-        eventGlobal.emit('onCoursewareUpdate');
-      },
-      {
-        deep: true
-      }
-    );
-
-    return () => (
-      <NForm
-        class={styles.coursewareModal}
-        model={forms}
-        ref={coursewareListRef}>
-        <NScrollbar
-          class={[styles.listContainer, 'listContainerWrap']}
-          {...{ id: 'lessons-2' }}>
-          <NSpin show={forms.loadingStatus}>
-            <div class={[styles.listSection, 'listSectionWrap']}>
-              {forms.coursewareList.map((item: any, index: number) => (
-                <div
-                  class={[styles.listItems, 'row-group']}
-                  onDragenter={(e: any) => {
-                    e.preventDefault();
-                  }}
-                  onDragover={(e: any) => {
-                    e.preventDefault();
-                  }}
-                  onDrop={(e: any) => {
-                    let dropItem = e.dataTransfer.getData('text');
-                    dropItem =
-                      dropItem && e.dataTransfer.effectAllowed === 'all'
-                        ? JSON.parse(dropItem)
-                        : {};
-                    // 判断是否有数据
-                    if (dropItem.id) {
-                      // 获取拖拽的目标元素
-                      eventGlobal.emit(
-                        'onPrepareAddItem',
-                        {
-                          materialId: dropItem.id,
-                          coverImg: dropItem.coverImg,
-                          type: dropItem.type,
-                          title: dropItem.title,
-                          refFlag: dropItem.refFlag,
-                          isCollect: dropItem.isCollect,
-                          isSelected: dropItem.isSelected,
-                          content: dropItem.content,
-                          removeFlag: false,
-                          index,
-                          addType: 'drag'
-                        },
-                        {
-                          x: e.clientX,
-                          y: e.clientY
-                        }
-                      );
-                    }
-                  }}>
-                  <div class={styles.knowledgePoint}>
-                    {/* <div class={styles.btnItem}>
-                      <span class={styles.btnTitle}>
-                        <span>*</span>知识点名称:
-                      </span>
-
-                    </div> */}
-                    <NFormItem
-                      class={styles.btnItem}
-                      label="知识点名称"
-                      showFeedback={false}
-                      requireMarkPlacement="left"
-                      path={`coursewareList.${index}.name`}
-                      rule={[
-                        {
-                          required: true,
-                          trigger: ['input', 'blur']
-                        }
-                      ]}>
-                      <NInput
-                        placeholder="未命名知识点"
-                        v-model:value={item.name}
-                        maxlength={15}
-                        clearable
-                      />
-                    </NFormItem>
-                  </div>
-
-                  <NSpace class={styles.operationGroup}>
-                    {index > 0 && (
-                      <NTooltip showArrow={false}>
-                        {{
-                          trigger: () => (
-                            <i
-                              class={styles.iconCUp}
-                              onClick={() => onChangePoint('up', index)}></i>
-                          ),
-                          default: () => '上移知识点'
-                        }}
-                      </NTooltip>
-                    )}
-                    {index < forms.coursewareList.length - 1 && (
-                      <NTooltip showArrow={false}>
-                        {{
-                          trigger: () => (
-                            <i
-                              class={styles.iconCDown}
-                              onClick={() => onChangePoint('down', index)}></i>
-                          ),
-                          default: () => '下移知识点'
-                        }}
-                      </NTooltip>
-                    )}
-                    <NTooltip showArrow={false}>
-                      {{
-                        trigger: () => (
-                          <i
-                            class={styles.iconCRemove}
-                            onClick={() =>
-                              onChangePoint('remove', index, item)
-                            }></i>
-                        ),
-                        default: () => '删除知识点'
-                      }}
-                    </NTooltip>
-                  </NSpace>
-
-                  {item.list.length > 0 && (
-                    <Draggable
-                      v-model:modelValue={item.list}
-                      itemKey="id"
-                      componentData={{
-                        itemKey: 'id',
-                        tag: 'div',
-                        animation: 200,
-                        group: 'description',
-                        disabled: false
-                      }}
-                      class={styles.list}>
-                      {{
-                        item: (element: any) => {
-                          const item = element.element;
-                          return (
-                            <div
-                              data-id={item.id}
-                              class={[
-                                styles.itemWrap,
-                                styles.itemBlock,
-                                'row-nav'
-                              ]}>
-                              <div class={styles.itemWrapBox}>
-                                <CardType
-                                  class={[styles.itemContent]}
-                                  isShowCollect={false}
-                                  offShelf={item.removeFlag ? true : false}
-                                  // onOffShelf={() => onRemove(item)}
-                                  item={item}
-                                  disabledMouseHover={false}
-                                  onClick={() => {
-                                    if (item.type === 'IMG') return;
-                                    forms.show = true;
-                                    forms.item = item;
-                                  }}
-                                />
-                                <div class={styles.itemOperation}>
-                                  <img
-                                    src={iconDelete}
-                                    class={styles.iconDelete}
-                                    onClick={(e: MouseEvent) => {
-                                      e.stopPropagation();
-                                      onDelete(element.index, index);
-                                    }}
-                                  />
-                                </div>
-                              </div>
-                            </div>
-                          );
-                        },
-                        footer: () => (
-                          <div class={styles.itemWrap}>
-                            <div class={styles.itemWrapBox}>
-                              <div
-                                class={[
-                                  styles.itemContent,
-                                  styles.addMusicItem,
-                                  'handle'
-                                ]}
-                                onClick={() => {
-                                  forms.addOtherSource = true;
-                                  forms.addOtherIndex = index;
-                                }}>
-                                <img src={iconAddMusic} />
-
-                                <p class={styles.addMusicName}>添加资源</p>
-                              </div>
-                            </div>
-                          </div>
-                        )
-                      }}
-                    </Draggable>
-                  )}
-                  {item.list <= 0 && (
-                    <div class={styles.list}>
-                      <div class={styles.itemWrap}>
-                        <div class={styles.itemWrapBox}>
-                          <div
-                            class={[
-                              styles.itemContent,
-                              styles.addMusicItem,
-                              'handle'
-                            ]}
-                            onClick={() => {
-                              forms.addOtherSource = true;
-                              forms.addOtherIndex = index;
-                            }}>
-                            <img src={iconAddMusic} />
-
-                            <p class={styles.addMusicName}>添加资源</p>
-                          </div>
-                        </div>
-                      </div>
-                    </div>
-                  )}
-                </div>
-              ))}
-
-              {!forms.loadingStatus && (
-                <NButton
-                  block
-                  type="primary"
-                  secondary
-                  class={styles.addKnowledgePoint}
-                  onClick={() => {
-                    forms.coursewareList.push({
-                      name: '',
-                      list: []
-                    });
-                  }}>
-                  <i class={styles.iconCAdd}></i>
-                  添加知识点
-                </NButton>
-              )}
-            </div>
-          </NSpin>
-        </NScrollbar>
-
-        {/* 弹窗查看 */}
-        <CardPreview
-          size={
-            ['INSTRUMENT', 'THEORY', 'MUSIC_WIKI', 'MUSICIAN'].includes(
-              forms.item.type
-            )
-              ? 'large'
-              : ''
-          }
-          v-model:show={forms.show}
-          item={forms.item}
-        />
-
-        <NModal
-          v-model:show={forms.addCoursewareVisiable}
-          preset="card"
-          class={['modalTitle', styles.addCourseware]}
-          title={'添加到知识点'}>
-          <AddItemModel
-            coursewareList={forms.coursewareList}
-            onClose={() => (forms.addCoursewareVisiable = false)}
-            onConfirm={(selects: number[]) => {
-              if (Array.isArray(selects) && selects.length > 0) {
-                selects.forEach(select => {
-                  addCoursewareItem({
-                    ...forms.addCoursewareItem,
-                    index: select
-                  });
-                });
-
-                forms.addCoursewareVisiable = false;
-              } else {
-                message.error('请选择需要添加的知识点');
-              }
-            }}
-          />
-        </NModal>
-
-        <NModal
-          v-model:show={forms.messageOperation.visiable}
-          preset="card"
-          class={['modalTitle', styles.removeVisiable1]}
-          title={forms.messageOperation.title}>
-          <TheMessageDialog
-            content={forms.messageOperation.content}
-            contentDirection={forms.messageOperation.contentDirection}
-            cancelButtonText={forms.messageOperation.cancelButtonText}
-            confirmButtonText={forms.messageOperation.confirmButtonText}
-            loading={forms.messageOperation.loading}
-            onClose={() => {
-              forms.messageOperation.visiable = false;
-              if (
-                forms.messageOperation.type === 'save' ||
-                forms.messageOperation.type === 'pageLive'
-              ) {
-                emit('change', {
-                  status: false,
-                  addParam: {
-                    isAdd: false,
-                    name: forms.name,
-                    id: forms.createId
-                  }
-                });
-                eventGlobal.emit('teacher-slideshow', false);
-                if (
-                  forms.messageOperation.type === 'pageLive' &&
-                  typeof forms.messageCallBack === 'function'
-                ) {
-                  forms.messageCallBack();
-                }
-              }
-            }}
-            onConfirm={() => onMessageConfirm()}
-          />
-        </NModal>
-
-        <PreviewWindow
-          v-model:show={forms.previewModal}
-          type="attend"
-          params={forms.previewParams}
-        />
-
-        {/* 添加其它类型的资源 */}
-        <NModal
-          v-model:show={forms.addOtherSource}
-          preset="card"
-          class={['modalTitle background', styles.addOtherSource]}
-          title={'添加资源'}>
-          <AddOtherSource
-            onClose={() => (forms.addOtherSource = false)}
-            onComfirm={item => {
-              if (Array.isArray(item)) {
-                item.forEach((child: any) => {
-                  addCoursewareItem({ ...child, index: forms.addOtherIndex });
-                });
-              } else {
-                addCoursewareItem({ ...item, index: forms.addOtherIndex });
-              }
-            }}
-          />
-        </NModal>
-
-        <NModal v-model:show={showModalMask.value}>
-          <AddCoursewareProtocol
-            onClose={() => (showModalMask.value = false)}
-            onConfirm={async () => {
-              try {
-                const resultStatus = await onSaveCourseWare();
-                if (resultStatus) {
-                  userStore.setReadCoursewareOpenAgreement(true);
-                  emit('change', {
-                    status: false,
-                    addParam: {
-                      isAdd: !props.groupItem.id ? true : false,
-                      name: forms.name,
-                      id: forms.createId
-                    }
-                  });
-                  eventGlobal.emit('teacher-slideshow', false);
-                }
-              } catch {
-                //
-              }
-            }}
-          />
-        </NModal>
-      </NForm>
-    );
-  }
-});
+import {
+  defineComponent,
+  nextTick,
+  onMounted,
+  onUnmounted,
+  reactive,
+  ref,
+  watch
+} from 'vue';
+import styles from './addCourseware.module.less';
+import {
+  NButton,
+  NModal,
+  NScrollbar,
+  NSelect,
+  NSpace,
+  NSpin,
+  useMessage,
+  useDialog,
+  NSwitch,
+  NInput,
+  NTooltip,
+  NImage,
+  NIcon,
+  NForm,
+  NFormItem
+} from 'naive-ui';
+import CardType from '/src/components/card-type';
+// import AttendClass from '/src/views/prepare-lessons/model/attend-class';
+import { usePrepareStore } from '/src/store/modules/prepareLessons';
+// import { useCatchStore } from '/src/store/modules/catchData';
+// import TheEmpty from '/src/components/TheEmpty';
+import {
+  api_teacherChapterLessonCoursewareAdd,
+  api_teacherChapterLessonCoursewareUpdate,
+  api_teacherChapterLessonCoursewareDetail,
+  api_materialDetail
+  // courseScheduleStart,
+  // queryCourseware,
+  // saveCourseware
+} from '../../../api';
+import Draggable from 'vuedraggable';
+import iconDelete from '../../../images/icon-delete-default.png';
+import iconAddMusic from '../../../images/icon-add-music.png';
+// import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router';
+// import deepClone from '/src/helpers/deep-clone';
+import CardPreview from '/src/components/card-preview';
+import PreviewWindow from '/src/views/preview-window';
+// import { state } from '/src/state';
+// import SubjectSync from '../../../model/subject-sync';
+import { eventGlobal } from '/src/utils';
+// import iconTips from '../../../images/icon-tips.png';
+import TheMessageDialog from '/src/components/TheMessageDialog';
+import AddItemModel from '../../../model/add-item-model';
+import AddOtherSource from '../../../model/add-other-source';
+import deepClone from '/src/helpers/deep-clone';
+import AddCoursewareProtocol from '../../../model/add-courseware-protocol';
+import { useUserStore } from '/src/store/modules/users';
+export default defineComponent({
+  name: 'courseware-modal',
+  props: {
+    groupItem: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  emits: ['change'],
+  setup(props, { emit }) {
+    // const catchStore = useCatchStore();
+    const userStore = useUserStore();
+
+    const prepareStore = usePrepareStore();
+    // const route = useRoute();
+    // const router = useRouter();
+    // const dialog = useDialog();
+    const message = useMessage();
+
+    const forms = reactive({
+      subjects: [] as any,
+      openFlagEnable: true, // 是否支持修改公开状态
+      autoPlay: true,
+      name: '',
+      openFlag: false,
+      createId: null,
+      baseCoursewareList: [
+        {
+          name: '',
+          id: null,
+          list: [] as any
+        }
+      ] as any, // 基础数据
+      baseInfo: {
+        subjects: [] as any,
+        autoPlay: true,
+        name: '',
+        openFlag: false
+      }, // 基础数据
+      coursewareList: [
+        {
+          name: '',
+          id: null,
+          list: [] as any
+        }
+      ] as any,
+      loadingStatus: false,
+      showAttendClass: false,
+      attendClassType: 'change', //
+      removeIds: [] as any, // 临时删除的编号
+      editSubjectIds: '', // 声部编号
+      addCoursewareVisiable: false,
+      addCoursewareItem: {} as any,
+      messageCallBack: null as any,
+      messageOperation: {
+        visiable: false,
+        loading: false, // 是否显示加载
+        type: 'delete' as 'delete' | 'addItem' | 'save' | 'pageLive',
+        contentDirection: 'center' as 'left' | 'center' | 'right',
+        title: '删除知识点',
+        content: '请确认是否删除该知识点,删除知识点后将同步删除知识点下的资源',
+        cancelButtonText: '取消',
+        confirmButtonText: '确认',
+        index: 0
+      },
+      show: false,
+      item: {} as any,
+      previewModal: false,
+      previewParams: {
+        type: '',
+        subjectId: '',
+        detailId: ''
+      } as any,
+      addOtherSource: false,
+      addOtherIndex: 0 // 添加其它的索引
+    });
+    const coursewareListRef = ref();
+    const showModalMask = ref(false);
+
+    // 获取列表
+    const getList = async () => {
+      forms.loadingStatus = true;
+      try {
+        if (!props.groupItem.id) return (forms.loadingStatus = false);
+
+        const { data } = await api_teacherChapterLessonCoursewareDetail(
+          props.groupItem.id
+        );
+        const tempRows = data.chapterKnowledgeList || [];
+        forms.name = data.name;
+        forms.subjects = data.instrumentIds
+          ? data.instrumentIds.split(',').map((s: any) => {
+              return s;
+            })
+          : [];
+        forms.openFlag = data.openFlag;
+        forms.openFlagEnable = data.openFlagEnable;
+        forms.autoPlay = data.autoPlay;
+        const temp: any = [];
+        tempRows.forEach((row: any) => {
+          const child: any = row.chapterKnowledgeMaterialList;
+          const childList: any[] = [];
+          if (Array.isArray(child) && child.length > 0) {
+            child.forEach((sub: any) => {
+              childList.push({
+                id: sub.id,
+                materialId: sub.bizId,
+                coverImg: sub.bizInfo.coverImg,
+                type: sub.type,
+                title: sub.bizInfo.name,
+                dataJson: sub.dataJson,
+                // isCollect: !!sub.favoriteFlag,
+                isSelected: sub.source === 'PLATFORM' ? true : false,
+                content: sub.bizInfo.content,
+                removeFlag: sub.removeFlag
+              });
+            });
+          }
+          temp.push({
+            name: row.name,
+            id: row.id,
+            list: [...childList]
+          });
+        });
+        forms.coursewareList = temp;
+        forms.baseCoursewareList = deepClone(temp);
+
+        forms.baseInfo = deepClone({
+          subjects: forms.subjects,
+          autoPlay: forms.autoPlay,
+          name: forms.name,
+          openFlag: forms.openFlag
+        });
+
+        /** 给头部组件分发消息 */
+        eventGlobal.emit('updateCoursewareHeadInfo', {
+          name: forms.name,
+          subjects: forms.subjects,
+          openFlag: forms.openFlag,
+          openFlagEnable: forms.openFlagEnable,
+          autoPlay: forms.autoPlay
+        });
+      } catch (e) {
+        //
+        console.log(e);
+      }
+      forms.loadingStatus = false;
+    };
+
+    // 删除
+    const onDelete = (j: number, index: number) => {
+      const coursewareItem = forms.coursewareList[index];
+      if (!coursewareItem) return;
+      coursewareItem.list.splice(j, 1);
+
+      // 内容有更新 - 相关资源会刷新
+      eventGlobal.emit('onCoursewareUpdate');
+    };
+
+    const isPointInsideElement = (element: any, x: number, y: number) => {
+      const rect = element.getBoundingClientRect();
+      return (
+        x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
+      );
+    };
+    const isPointOnLeft = (element: any, x: number) => {
+      const rect = element.getBoundingClientRect();
+      const elementCenterX = rect.left + rect.width / 2;
+      return x < elementCenterX;
+    };
+
+    // 操作
+    const onChangePoint = (type: string, index: number, item?: any) => {
+      if (type === 'up') {
+        // 向上移动
+        if (index === 0) return;
+        const temp = forms.coursewareList[index - 1];
+        forms.coursewareList[index - 1] = forms.coursewareList[index];
+        forms.coursewareList[index] = temp;
+      } else if (type === 'down') {
+        // 向下移动
+        if (index >= forms.coursewareList.length - 1) return;
+        const temp = forms.coursewareList[index + 1];
+        forms.coursewareList[index + 1] = forms.coursewareList[index];
+        forms.coursewareList[index] = temp;
+      } else if (type === 'remove') {
+        forms.messageOperation = {
+          visiable: true,
+          type: 'delete',
+          contentDirection: 'left',
+          title: '删除知识点',
+          loading: false,
+          content: `请确认是否删除${
+            item.name ? '【' + item.name + '】' : '该知识点'
+          },删除知识点后将同步删除知识点下的资源`,
+          cancelButtonText: '取消',
+          confirmButtonText: '确认',
+          index
+        };
+      }
+    };
+
+    //
+    const onMessageConfirm = async () => {
+      const type = forms.messageOperation.type;
+      if (type === 'delete') {
+        forms.coursewareList.splice(forms.messageOperation.index, 1);
+      } else if (type === 'addItem') {
+        forms.coursewareList.push({ name: '', list: [] });
+        addCoursewareItem(forms.addCoursewareItem);
+      } else if (type === 'save' || type === 'pageLive') {
+        if (forms.messageOperation.loading) return;
+        if (!forms.name) {
+          message.error('请输入课件标题');
+          forms.messageOperation.visiable = false;
+          return;
+        }
+        if (forms.subjects.length <= 0) {
+          message.error('请选择声部');
+          forms.messageOperation.visiable = false;
+          return;
+        }
+
+        if (forms.coursewareList.length <= 0) {
+          message.error('未配置知识点');
+          forms.messageOperation.visiable = false;
+          return;
+        }
+
+        let isNotAdd = false;
+        for (const item of forms.coursewareList) {
+          if (!item.name) {
+            message.error('请输入知识点名称');
+            forms.messageOperation.visiable = false;
+            return;
+          }
+          if (Array.isArray(item.list) && item.list.length <= 0) {
+            isNotAdd = true;
+          }
+        }
+
+        if (isNotAdd) {
+          message.error('请至少添加一个资源');
+          forms.messageOperation.visiable = false;
+          return;
+        }
+
+        forms.messageOperation.loading = true;
+        const resultStatus = await onSaveCourseWare();
+        forms.messageOperation.loading = false;
+        if (resultStatus) {
+          if (
+            type === 'pageLive' &&
+            typeof forms.messageCallBack === 'function'
+          ) {
+            forms.messageCallBack();
+          }
+          emit('change', {
+            status: false,
+            addParam: {
+              isAdd: !props.groupItem.id ? true : false,
+              name: forms.name,
+              id: forms.createId
+            }
+          });
+          eventGlobal.emit('teacher-slideshow', false);
+        }
+      }
+      forms.messageOperation.visiable = false;
+    };
+
+    let timer: any = null;
+    const addCoursewareItem = async (item: any, point?: any) => {
+      clearTimeout(timer);
+      const materialList: any[] = [];
+      try {
+        const { data } = await api_materialDetail(item.materialId);
+        if (Array.isArray(data.materialRefs)) {
+          data.materialRefs.forEach((item: any) => {
+            if (item.refType === 'STRONG') {
+              const relateMaterialInfo = item.relateMaterialInfo || {};
+              materialList.push({
+                content: relateMaterialInfo.content,
+                coverImg: relateMaterialInfo.coverImg,
+                // isCollect: relateMaterialInfo.,
+                isSelected:
+                  relateMaterialInfo.sourceFrom === 'PLATFORM' ? true : false,
+                materialId: relateMaterialInfo.id,
+                // removeFlag: relateMaterialInfo.,
+                title: relateMaterialInfo.name,
+                type: relateMaterialInfo.type
+              });
+            }
+          });
+        }
+      } catch {
+        //
+      }
+      nextTick(() => {
+        if (point) {
+          const rowGroupDom = document.querySelectorAll('.row-group');
+          const dom = rowGroupDom[item.index].querySelectorAll('.row-nav');
+          // const dom = document.querySelectorAll('.row-nav');
+          let isAdd = false;
+          dom.forEach((child: any, index: number) => {
+            // console.log(child);
+            const status = isPointInsideElement(child, point.x, point.y);
+            if (status) {
+              const array: any =
+                forms.coursewareList[item.index || 0].list || [];
+              const left = isPointOnLeft(child, point.x);
+              if (!left) {
+                array.splice(index + 1, 0, item);
+                materialList.forEach((m: any) => {
+                  array.splice(index + 1, 0, m);
+                });
+              } else {
+                materialList.forEach((m: any) => {
+                  array.splice(index, 0, m);
+                });
+                array.splice(index, 0, item);
+              }
+              isAdd = true;
+              forms.coursewareList[item.index || 0].list = array;
+            }
+          });
+          if (!isAdd) {
+            forms.coursewareList[item.index || 0].list.push(item);
+            materialList.forEach((m: any) => {
+              forms.coursewareList[item.index || 0].list.push(m);
+            });
+          }
+        } else {
+          forms.coursewareList[item.index || 0].list.push(item);
+          materialList.forEach((m: any) => {
+            forms.coursewareList[item.index || 0].list.push(m);
+          });
+          message.success('添加成功');
+        }
+
+        timer = setTimeout(() => {
+          // 内容有更新 - 相关资源会刷新
+          eventGlobal.emit('onCoursewareUpdate');
+        }, 100);
+      });
+    };
+
+    // 提交
+    const onSubmit = async () => {
+      try {
+        coursewareListRef.value.validate();
+        eventGlobal.emit('checkCoursewareForm');
+        if (!forms.name) {
+          message.error('请输入课件标题');
+          return;
+        }
+        if (forms.subjects.length <= 0) {
+          message.error('请选择声部');
+          return;
+        }
+        if (forms.coursewareList.length <= 0) {
+          message.error('请至少添加一个知识点');
+          return;
+        }
+
+        let isNotAdd = false;
+        for (const item of forms.coursewareList) {
+          if (!item.name) {
+            message.error('请输入知识点名称');
+            return;
+          }
+          if (Array.isArray(item.list) && item.list.length <= 0) {
+            isNotAdd = true;
+          }
+        }
+
+        if (isNotAdd) {
+          message.error('请至少添加一个资源');
+          return;
+        }
+
+        if (forms.openFlag && !userStore.getReadCoursewareOpenAgreement) {
+          showModalMask.value = true;
+          return;
+        }
+        const resultStatus = await onSaveCourseWare();
+
+        if (resultStatus) {
+          emit('change', {
+            status: false,
+            addParam: {
+              isAdd: !props.groupItem.id ? true : false,
+              name: forms.name,
+              id: forms.createId
+            }
+          });
+          eventGlobal.emit('teacher-slideshow', false);
+        }
+      } catch {
+        //
+      }
+    };
+    const onSaveCourseWare = async () => {
+      try {
+        const params = {
+          name: forms.name,
+          instrumentIds: forms.subjects.join(','),
+          openFlag: forms.openFlag,
+          autoPlay: forms.autoPlay,
+          coursewareDetailKnowledgeId: prepareStore.getSelectKey,
+          chapterKnowledgeList: [] as any
+        };
+
+        forms.coursewareList.forEach((item: any) => {
+          let tempItem: any = [];
+          if (Array.isArray(item.list) && item.list.length > 0) {
+            tempItem = item.list.map((child: any) => {
+              return {
+                bizId: child.materialId,
+                type: child.type,
+                dataJson: !['IMG', 'VIDEO', 'SONG', 'MUSIC', 'PPT'].includes(
+                  child.type
+                )
+                  ? JSON.stringify({
+                      setting: child.dataJson,
+                      coverImg: child.coverImg,
+                      bizId: child.bizId,
+                      content: child.content,
+                      name: child.title
+                    })
+                  : ''
+              };
+            });
+          }
+          params.chapterKnowledgeList.push({
+            name: item.name,
+            chapterKnowledgeMaterialList: tempItem
+          });
+        });
+        if (props.groupItem?.id) {
+          await api_teacherChapterLessonCoursewareUpdate({
+            id: props.groupItem.id,
+            ...params
+          });
+          message.success('保存成功');
+        } else {
+          const { data } = await api_teacherChapterLessonCoursewareAdd(params);
+          forms.createId = data.id;
+        }
+
+        return true;
+      } catch {
+        //
+        return false;
+      }
+    };
+
+    const addItem = (item: any, point?: any) => {
+      if (forms.coursewareList.length <= 0) {
+        // 添加到临时对象
+        forms.addCoursewareItem = item;
+        forms.messageOperation = {
+          visiable: true,
+          type: 'addItem',
+          contentDirection: 'center',
+          title: '添加到知识点',
+          loading: false,
+          content: '当前课件暂无知识点,请添加知识点后操作',
+          cancelButtonText: '取消',
+          confirmButtonText: '添加知识点',
+          index: 0
+        };
+      } else if (forms.coursewareList.length > 1 && item.addType !== 'drag') {
+        forms.addCoursewareVisiable = true;
+        forms.addCoursewareItem = item;
+      } else {
+        addCoursewareItem(item, point);
+      }
+    };
+
+    // 当页面离开时
+    const onPageBeforeLeave = (event: any) => {
+      const objA = JSON.stringify(forms.coursewareList);
+      const objB = JSON.stringify(forms.baseCoursewareList);
+      const baseA = JSON.stringify({
+        subjects: forms.subjects,
+        autoPlay: forms.autoPlay,
+        name: forms.name,
+        openFlag: forms.openFlag
+      });
+      const baseB = JSON.stringify(forms.baseInfo);
+      if (objA === objB && baseA === baseB) {
+        if (typeof event === 'function') {
+          event();
+
+          emit('change', {
+            status: false,
+            addParam: {
+              isAdd: false,
+              name: forms.name,
+              id: forms.createId
+            }
+          });
+          eventGlobal.emit('teacher-slideshow', false);
+        }
+      } else {
+        forms.messageCallBack = event;
+        forms.messageOperation = {
+          visiable: true,
+          type: 'pageLive',
+          loading: false,
+          contentDirection: 'center',
+          title: '保存课件',
+          content: '当前课件暂未保存,是否保存?',
+          cancelButtonText: '不保存',
+          confirmButtonText: '保存',
+          index: 0
+        };
+      }
+    };
+
+    const onCancelCourseware = (item: any) => {
+      forms.subjects = item.subjects;
+      forms.openFlagEnable = item.openFlagEnable;
+      forms.autoPlay = item.autoPlay;
+      forms.name = item.name;
+      forms.openFlag = item.openFlag;
+
+      const objA = JSON.stringify(forms.coursewareList);
+      const objB = JSON.stringify(forms.baseCoursewareList);
+      const baseA = JSON.stringify({
+        subjects: forms.subjects,
+        autoPlay: forms.autoPlay,
+        name: forms.name,
+        openFlag: forms.openFlag
+      });
+      const baseB = JSON.stringify(forms.baseInfo);
+
+      if (objA === objB && baseA === baseB) {
+        emit('change', {
+          status: false,
+          addParam: {
+            isAdd: false,
+            name: forms.name,
+            id: forms.createId
+          }
+        });
+
+        eventGlobal.emit('teacher-slideshow', false);
+      } else {
+        forms.messageOperation = {
+          visiable: true,
+          type: 'save',
+          loading: false,
+          contentDirection: 'center',
+          title: '保存课件',
+          content: '当前课件暂未保存,是否保存?',
+          cancelButtonText: '不保存',
+          confirmButtonText: '保存',
+          index: 0
+        };
+      }
+    };
+
+    const onSubmitCourseware = (item: any) => {
+      forms.subjects = item.subjects;
+      forms.openFlagEnable = item.openFlagEnable;
+      forms.autoPlay = item.autoPlay;
+      forms.name = item.name;
+      forms.openFlag = item.openFlag;
+
+      onSubmit();
+    };
+
+    onMounted(async () => {
+      // 修改时重置默认数据
+      if (props.groupItem?.id) {
+        forms.coursewareList = [];
+        forms.baseCoursewareList = [];
+      }
+
+      await getList();
+      // 动态添加数据
+      eventGlobal.on('onPrepareAddItem', addItem);
+      eventGlobal.on('pageBeforeLeave', onPageBeforeLeave);
+
+      // 取消
+      eventGlobal.on('coursewareClosed', onCancelCourseware);
+      // 保存
+      eventGlobal.on('coursewareSave', onSubmitCourseware);
+    });
+
+    onUnmounted(() => {
+      eventGlobal.off('onPrepareAddItem', addItem);
+      eventGlobal.off('pageBeforeLeave', onPageBeforeLeave);
+      eventGlobal.off('coursewareClosed', onCancelCourseware);
+      eventGlobal.off('coursewareSave', onSubmitCourseware);
+    });
+
+    // 当列表数据更新时同步缓存数据
+    watch(
+      () => forms.coursewareList,
+      () => {
+        prepareStore.setCoursewareList(forms.coursewareList);
+      },
+      {
+        deep: true
+      }
+    );
+
+    return () => (
+      <NForm
+        class={styles.coursewareModal}
+        model={forms}
+        ref={coursewareListRef}>
+        <NScrollbar
+          class={[styles.listContainer, 'listContainerWrap']}
+          {...{ id: 'lessons-2' }}>
+          <NSpin show={forms.loadingStatus}>
+            <div class={[styles.listSection, 'listSectionWrap']}>
+              {forms.coursewareList.map((item: any, index: number) => (
+                <div
+                  class={[styles.listItems, 'row-group']}
+                  onDragenter={(e: any) => {
+                    e.preventDefault();
+                  }}
+                  onDragover={(e: any) => {
+                    e.preventDefault();
+                  }}
+                  onDrop={(e: any) => {
+                    let dropItem = e.dataTransfer.getData('text');
+                    dropItem =
+                      dropItem && e.dataTransfer.effectAllowed === 'all'
+                        ? JSON.parse(dropItem)
+                        : {};
+                    // 判断是否有数据
+                    if (dropItem.id) {
+                      // 获取拖拽的目标元素
+                      eventGlobal.emit(
+                        'onPrepareAddItem',
+                        {
+                          materialId: dropItem.id,
+                          coverImg: dropItem.coverImg,
+                          type: dropItem.type,
+                          title: dropItem.title,
+                          refFlag: dropItem.refFlag,
+                          isCollect: dropItem.isCollect,
+                          isSelected: dropItem.isSelected,
+                          content: dropItem.content,
+                          removeFlag: false,
+                          index,
+                          addType: 'drag'
+                        },
+                        {
+                          x: e.clientX,
+                          y: e.clientY
+                        }
+                      );
+                    }
+                  }}>
+                  <div class={styles.knowledgePoint}>
+                    {/* <div class={styles.btnItem}>
+                      <span class={styles.btnTitle}>
+                        <span>*</span>知识点名称:
+                      </span>
+
+                    </div> */}
+                    <NFormItem
+                      class={styles.btnItem}
+                      label="知识点名称"
+                      showFeedback={false}
+                      requireMarkPlacement="left"
+                      path={`coursewareList.${index}.name`}
+                      rule={[
+                        {
+                          required: true,
+                          trigger: ['input', 'blur']
+                        }
+                      ]}>
+                      <NInput
+                        placeholder="未命名知识点"
+                        v-model:value={item.name}
+                        maxlength={15}
+                        clearable
+                      />
+                    </NFormItem>
+                  </div>
+
+                  <NSpace class={styles.operationGroup}>
+                    {index > 0 && (
+                      <NTooltip showArrow={false}>
+                        {{
+                          trigger: () => (
+                            <i
+                              class={styles.iconCUp}
+                              onClick={() => onChangePoint('up', index)}></i>
+                          ),
+                          default: () => '上移知识点'
+                        }}
+                      </NTooltip>
+                    )}
+                    {index < forms.coursewareList.length - 1 && (
+                      <NTooltip showArrow={false}>
+                        {{
+                          trigger: () => (
+                            <i
+                              class={styles.iconCDown}
+                              onClick={() => onChangePoint('down', index)}></i>
+                          ),
+                          default: () => '下移知识点'
+                        }}
+                      </NTooltip>
+                    )}
+                    <NTooltip showArrow={false}>
+                      {{
+                        trigger: () => (
+                          <i
+                            class={styles.iconCRemove}
+                            onClick={() =>
+                              onChangePoint('remove', index, item)
+                            }></i>
+                        ),
+                        default: () => '删除知识点'
+                      }}
+                    </NTooltip>
+                  </NSpace>
+
+                  {item.list.length > 0 && (
+                    <Draggable
+                      v-model:modelValue={item.list}
+                      itemKey="id"
+                      componentData={{
+                        itemKey: 'id',
+                        tag: 'div',
+                        animation: 200,
+                        group: 'description',
+                        disabled: false
+                      }}
+                      class={styles.list}>
+                      {{
+                        item: (element: any) => {
+                          const item = element.element;
+                          return (
+                            <div
+                              data-id={item.id}
+                              class={[
+                                styles.itemWrap,
+                                styles.itemBlock,
+                                'row-nav'
+                              ]}>
+                              <div class={styles.itemWrapBox}>
+                                <CardType
+                                  class={[styles.itemContent]}
+                                  isShowCollect={false}
+                                  offShelf={item.removeFlag ? true : false}
+                                  // onOffShelf={() => onRemove(item)}
+                                  item={item}
+                                  disabledMouseHover={false}
+                                  onClick={() => {
+                                    if (item.type === 'IMG') return;
+                                    forms.show = true;
+                                    forms.item = item;
+                                  }}
+                                />
+                                <div class={styles.itemOperation}>
+                                  <img
+                                    src={iconDelete}
+                                    class={styles.iconDelete}
+                                    onClick={(e: MouseEvent) => {
+                                      e.stopPropagation();
+                                      onDelete(element.index, index);
+                                    }}
+                                  />
+                                </div>
+                              </div>
+                            </div>
+                          );
+                        },
+                        footer: () => (
+                          <div class={styles.itemWrap}>
+                            <div class={styles.itemWrapBox}>
+                              <div
+                                class={[
+                                  styles.itemContent,
+                                  styles.addMusicItem,
+                                  'handle'
+                                ]}
+                                onClick={() => {
+                                  forms.addOtherSource = true;
+                                  forms.addOtherIndex = index;
+                                }}>
+                                <img src={iconAddMusic} />
+
+                                <p class={styles.addMusicName}>添加资源</p>
+                              </div>
+                            </div>
+                          </div>
+                        )
+                      }}
+                    </Draggable>
+                  )}
+                  {item.list <= 0 && (
+                    <div class={styles.list}>
+                      <div class={styles.itemWrap}>
+                        <div class={styles.itemWrapBox}>
+                          <div
+                            class={[
+                              styles.itemContent,
+                              styles.addMusicItem,
+                              'handle'
+                            ]}
+                            onClick={() => {
+                              forms.addOtherSource = true;
+                              forms.addOtherIndex = index;
+                            }}>
+                            <img src={iconAddMusic} />
+
+                            <p class={styles.addMusicName}>添加资源</p>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  )}
+                </div>
+              ))}
+
+              {!forms.loadingStatus && (
+                <NButton
+                  block
+                  type="primary"
+                  secondary
+                  class={styles.addKnowledgePoint}
+                  onClick={() => {
+                    forms.coursewareList.push({
+                      name: '',
+                      list: []
+                    });
+                  }}>
+                  <i class={styles.iconCAdd}></i>
+                  添加知识点
+                </NButton>
+              )}
+            </div>
+          </NSpin>
+        </NScrollbar>
+
+        {/* 弹窗查看 */}
+        <CardPreview
+          size={
+            ['INSTRUMENT', 'THEORY', 'MUSIC_WIKI', 'MUSICIAN'].includes(
+              forms.item.type
+            )
+              ? 'large'
+              : ''
+          }
+          v-model:show={forms.show}
+          item={forms.item}
+        />
+
+        <NModal
+          v-model:show={forms.addCoursewareVisiable}
+          preset="card"
+          class={['modalTitle', styles.addCourseware]}
+          title={'添加到知识点'}>
+          <AddItemModel
+            coursewareList={forms.coursewareList}
+            onClose={() => (forms.addCoursewareVisiable = false)}
+            onConfirm={(selects: number[]) => {
+              if (Array.isArray(selects) && selects.length > 0) {
+                selects.forEach(select => {
+                  addCoursewareItem({
+                    ...forms.addCoursewareItem,
+                    index: select
+                  });
+                });
+
+                forms.addCoursewareVisiable = false;
+              } else {
+                message.error('请选择需要添加的知识点');
+              }
+            }}
+          />
+        </NModal>
+
+        <NModal
+          v-model:show={forms.messageOperation.visiable}
+          preset="card"
+          class={['modalTitle', styles.removeVisiable1]}
+          title={forms.messageOperation.title}>
+          <TheMessageDialog
+            content={forms.messageOperation.content}
+            contentDirection={forms.messageOperation.contentDirection}
+            cancelButtonText={forms.messageOperation.cancelButtonText}
+            confirmButtonText={forms.messageOperation.confirmButtonText}
+            loading={forms.messageOperation.loading}
+            onClose={() => {
+              forms.messageOperation.visiable = false;
+              if (
+                forms.messageOperation.type === 'save' ||
+                forms.messageOperation.type === 'pageLive'
+              ) {
+                emit('change', {
+                  status: false,
+                  addParam: {
+                    isAdd: false,
+                    name: forms.name,
+                    id: forms.createId
+                  }
+                });
+                eventGlobal.emit('teacher-slideshow', false);
+                if (
+                  forms.messageOperation.type === 'pageLive' &&
+                  typeof forms.messageCallBack === 'function'
+                ) {
+                  forms.messageCallBack();
+                }
+              }
+            }}
+            onConfirm={() => onMessageConfirm()}
+          />
+        </NModal>
+
+        <PreviewWindow
+          v-model:show={forms.previewModal}
+          type="attend"
+          params={forms.previewParams}
+        />
+
+        {/* 添加其它类型的资源 */}
+        <NModal
+          v-model:show={forms.addOtherSource}
+          preset="card"
+          class={['modalTitle background', styles.addOtherSource]}
+          title={'添加资源'}>
+          <AddOtherSource
+            onClose={() => (forms.addOtherSource = false)}
+            onComfirm={item => {
+              if (Array.isArray(item)) {
+                item.forEach((child: any) => {
+                  addCoursewareItem({ ...child, index: forms.addOtherIndex });
+                });
+              } else {
+                addCoursewareItem({ ...item, index: forms.addOtherIndex });
+              }
+            }}
+          />
+        </NModal>
+
+        <NModal v-model:show={showModalMask.value}>
+          <AddCoursewareProtocol
+            onClose={() => (showModalMask.value = false)}
+            onConfirm={async () => {
+              try {
+                const resultStatus = await onSaveCourseWare();
+                if (resultStatus) {
+                  userStore.setReadCoursewareOpenAgreement(true);
+                  emit('change', {
+                    status: false,
+                    addParam: {
+                      isAdd: !props.groupItem.id ? true : false,
+                      name: forms.name,
+                      id: forms.createId
+                    }
+                  });
+                  eventGlobal.emit('teacher-slideshow', false);
+                }
+              } catch {
+                //
+              }
+            }}
+          />
+        </NModal>
+      </NForm>
+    );
+  }
+});

+ 275 - 273
src/views/prepare-lessons/components/resource-main/components/resource-item/index.tsx

@@ -1,273 +1,275 @@
-import {
-  PropType,
-  defineComponent,
-  onMounted,
-  onUnmounted,
-  reactive,
-  watch
-} from 'vue';
-import ResourceSearchGroup from './resource-search-group';
-import { NScrollbar, NSpin, useDialog, useMessage } from 'naive-ui';
-import styles from './index.module.less';
-import CardType from '/src/components/card-type';
-import { favorite, materialQueryPage } from '/src/views/natural-resources/api';
-import TheEmpty from '/src/components/TheEmpty';
-import { usePrepareStore } from '/src/store/modules/prepareLessons';
-import { useDebounceFn, useThrottleFn, useThrottle } from '@vueuse/core';
-import { saveCourseware } from '/src/views/prepare-lessons/api';
-import CardPreview from '/src/components/card-preview';
-import { eventGlobal } from '/src/utils';
-
-const formatType = (type: string) => {
-  if (type === 'shareResources') {
-    return 2;
-  } else if (type === 'myResources') {
-    return 3;
-  } else if (type === 'myCollect') {
-    return 4;
-  } else if (type === 'relateResources') {
-    return 5;
-  }
-};
-export default defineComponent({
-  name: 'share-resources',
-  props: {
-    type: {
-      type: String as PropType<
-        'shareResources' | 'myResources' | 'myCollect' | 'relateResources'
-      >,
-      default: 'relateResources'
-    }
-  },
-  setup(props) {
-    const prepareStore = usePrepareStore();
-    const message = useMessage();
-    const dialog = useDialog();
-    const state = reactive({
-      loading: false,
-      finshed: false, // 是否加载完
-      pagination: {
-        page: 1,
-        rows: 20
-      },
-      searchGroup: {
-        type: 'MUSIC', //
-        name: '',
-        bookVersionId: null,
-        musicalInstrumentId: null,
-        subjectId: null,
-        sourceType: formatType(props.type),
-        enableFlag: true
-      },
-      tableList: [] as any,
-      show: false,
-      item: {} as any
-    });
-    const getList = async () => {
-      try {
-        // if (!prepareStore.getSubjectId) return;
-        if (state.pagination.page === 1) {
-          state.loading = true;
-        }
-        const { data } = await materialQueryPage({
-          ...state.searchGroup,
-          ...state.pagination,
-          lessonCoursewareKnowledgeId:
-            props.type === 'relateResources' || props.type === 'shareResources'
-              ? prepareStore.getSelectKey
-              : null,
-          relateLessonCoursewareKnowledgeMaterialIds: getIds()
-          // subjectId: prepareStore.getSubjectId
-        });
-        state.loading = false;
-        const tempRows = data.rows || [];
-        const temp: any = [];
-        tempRows.forEach((row: any) => {
-          const index = prepareStore.getCoursewareList.findIndex(
-            (course: any) => course.materialId === row.id
-          );
-          temp.push({
-            id: row.id,
-            coverImg: row.coverImg,
-            type: row.type,
-            title: row.name,
-            isCollect: !!row.favoriteFlag,
-            refFlag: row.refFlag,
-            isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
-            content: row.content
-            // exist: index !== -1 ? true : false // 是否存在
-          });
-        });
-        if (state.pagination.page === 1) {
-          state.tableList = temp;
-        } else {
-          state.tableList.push(...temp);
-        }
-
-        state.finshed = data.pages <= data.current ? true : false;
-      } catch {
-        state.loading = false;
-      }
-    };
-
-    const onSearch = async (item: any) => {
-      state.pagination.page = 1;
-      state.tableList = [];
-      state.searchGroup = Object.assign(state.searchGroup, item);
-      getList();
-    };
-
-    const throttledFnSearch = useDebounceFn(item => {
-      state.pagination.page = state.pagination.page + 1;
-      state.pagination.page = 1;
-      state.tableList = [];
-      state.searchGroup = Object.assign(state.searchGroup, item);
-      getList();
-    }, 500);
-
-    // 声部变化时
-    watch(
-      () => prepareStore.getInstrumentId,
-      () => {
-        onSearch(state.searchGroup);
-      }
-    );
-
-    const throttledFn = useThrottleFn(() => {
-      state.pagination.page = state.pagination.page + 1;
-      getList();
-    }, 500);
-
-    // 添加资源
-    const onAdd = async (item: any) => {
-      try {
-        eventGlobal.emit('onPrepareAddItem', {
-          materialId: item.id,
-          coverImg: item.coverImg,
-          refFlag: item.refFlag,
-          type: item.type,
-          title: item.title,
-          isCollect: item.isCollect,
-          isSelected: item.isSelected,
-          content: item.content,
-          removeFlag: false
-        });
-      } catch {
-        //
-      }
-    };
-
-    // 收藏
-    const onCollect = async (item: any) => {
-      try {
-        await favorite({
-          materialId: item.id,
-          favoriteFlag: item.isCollect ? 0 : 1,
-          type: item.type
-        });
-        item.isCollect = !item.isCollect;
-      } catch {
-        //
-      }
-    };
-    const getIds = () => {
-      let noRepeatIds: any = [];
-      if (props.type === 'relateResources') {
-        const materialIds: any = [];
-        prepareStore.getCoursewareList.forEach((course: any) => {
-          course.list?.forEach((item: any) => {
-            materialIds.push(item.materialId);
-          });
-        });
-        noRepeatIds = Array(...new Set(materialIds));
-      }
-      return noRepeatIds.join(',');
-    };
-
-    const onUpdate = () => {
-      state.pagination.page = 1;
-      state.tableList = [];
-      getList();
-    };
-
-    onMounted(() => {
-      // 加载的时候判断是否有资源数据
-      onUpdate();
-
-      eventGlobal.on('onCoursewareUpdate', onUpdate);
-    });
-    onUnmounted(() => {
-      eventGlobal.off('onCoursewareUpdate', onUpdate);
-    });
-    return () => (
-      <div>
-        <ResourceSearchGroup
-          type={props.type}
-          onSearch={(item: any) => {
-            state.searchGroup = Object.assign(state.searchGroup, item);
-            throttledFnSearch(item);
-          }}
-        />
-        <NScrollbar
-          class={[
-            styles.listContainer,
-            'listContainerResource',
-            state.searchGroup.type !== 'MUSIC' ||
-            ['myResources', 'myCollect', 'relateResources'].includes(props.type)
-              ? [styles.listNoMusic, 'listNoMusicResource']
-              : ''
-          ]}
-          onScroll={(e: any) => {
-            const clientHeight = e.target?.clientHeight;
-            const scrollTop = e.target?.scrollTop;
-            const scrollHeight = e.target?.scrollHeight;
-            // 是否到底,是否加载完
-            if (
-              clientHeight + scrollTop + 20 >= scrollHeight &&
-              !state.finshed &&
-              !state.loading
-            ) {
-              throttledFn();
-            }
-          }}>
-          <NSpin show={state.loading} size={'small'}>
-            <div
-              class={[
-                styles.listSection,
-                'listSectionResource',
-                !state.loading && state.tableList.length <= 0
-                  ? [styles.emptySection, 'emptySectionResource']
-                  : ''
-              ]}>
-              {state.tableList.length > 0 && (
-                <div class={styles.list}>
-                  {state.tableList.map((item: any) => (
-                    <CardType
-                      isShowAdd
-                      item={item}
-                      isShowCollect={true}
-                      draggable
-                      disabledMouseHover={false}
-                      onClick={() => {
-                        if (item.type === 'IMG') return;
-                        state.show = true;
-                        state.item = item;
-                      }}
-                      onCollect={(item: any) => onCollect(item)}
-                      // isShowAddDisabled={!prepareStore.getIsEditResource}
-                      onAdd={(item: any) => onAdd(item)}
-                    />
-                  ))}
-                </div>
-              )}
-              {!state.loading && state.tableList.length <= 0 && <TheEmpty />}
-            </div>
-          </NSpin>
-        </NScrollbar>
-
-        {/* 弹窗查看 */}
-        <CardPreview v-model:show={state.show} item={state.item} />
-      </div>
-    );
-  }
-});
+import {
+  PropType,
+  defineComponent,
+  onMounted,
+  onUnmounted,
+  reactive,
+  watch
+} from 'vue';
+import ResourceSearchGroup from './resource-search-group';
+import { NScrollbar, NSpin, useDialog, useMessage } from 'naive-ui';
+import styles from './index.module.less';
+import CardType from '/src/components/card-type';
+import { favorite, materialQueryPage } from '/src/views/natural-resources/api';
+import TheEmpty from '/src/components/TheEmpty';
+import { usePrepareStore } from '/src/store/modules/prepareLessons';
+import { useDebounceFn, useThrottleFn, useThrottle } from '@vueuse/core';
+import { saveCourseware } from '/src/views/prepare-lessons/api';
+import CardPreview from '/src/components/card-preview';
+import { eventGlobal } from '/src/utils';
+
+const formatType = (type: string) => {
+  if (type === 'shareResources') {
+    return 2;
+  } else if (type === 'myResources') {
+    return 3;
+  } else if (type === 'myCollect') {
+    return 4;
+  } else if (type === 'relateResources') {
+    return 5;
+  }
+};
+export default defineComponent({
+  name: 'share-resources',
+  props: {
+    type: {
+      type: String as PropType<
+        'shareResources' | 'myResources' | 'myCollect' | 'relateResources'
+      >,
+      default: 'relateResources'
+    }
+  },
+  setup(props) {
+    const prepareStore = usePrepareStore();
+    const message = useMessage();
+    const dialog = useDialog();
+    const state = reactive({
+      loading: false,
+      finshed: false, // 是否加载完
+      pagination: {
+        page: 1,
+        rows: 20
+      },
+      searchGroup: {
+        type: 'MUSIC', //
+        name: '',
+        bookVersionId: null,
+        musicalInstrumentId: null,
+        subjectId: null,
+        sourceType: formatType(props.type),
+        enableFlag: true
+      },
+      tableList: [] as any,
+      show: false,
+      item: {} as any
+    });
+    const getList = async () => {
+      try {
+        // if (!prepareStore.getSubjectId) return;
+        if (state.pagination.page === 1) {
+          state.loading = true;
+        }
+        const { data } = await materialQueryPage({
+          ...state.searchGroup,
+          ...state.pagination,
+          lessonCoursewareKnowledgeId:
+            props.type === 'relateResources' || props.type === 'shareResources'
+              ? prepareStore.getSelectKey
+              : null,
+          relateLessonCoursewareKnowledgeMaterialIds: getIds()
+          // subjectId: prepareStore.getSubjectId
+        });
+        state.loading = false;
+        const tempRows = data.rows || [];
+        const temp: any = [];
+        tempRows.forEach((row: any) => {
+          const index = prepareStore.getCoursewareList.findIndex(
+            (course: any) => course.materialId === row.id
+          );
+          temp.push({
+            id: row.id,
+            coverImg: row.coverImg,
+            type: row.type,
+            title: row.name,
+            isCollect: !!row.favoriteFlag,
+            refFlag: row.refFlag,
+            isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
+            content: row.content
+            // exist: index !== -1 ? true : false // 是否存在
+          });
+        });
+        if (state.pagination.page === 1) {
+          state.tableList = temp;
+        } else {
+          state.tableList.push(...temp);
+        }
+
+        state.finshed = data.pages <= data.current ? true : false;
+      } catch {
+        state.loading = false;
+      }
+    };
+
+    const onSearch = async (item: any) => {
+      state.pagination.page = 1;
+      state.tableList = [];
+      state.searchGroup = Object.assign(state.searchGroup, item);
+      getList();
+    };
+
+    const throttledFnSearch = useDebounceFn(item => {
+      state.pagination.page = state.pagination.page + 1;
+      state.pagination.page = 1;
+      state.tableList = [];
+      state.searchGroup = Object.assign(state.searchGroup, item);
+      getList();
+    }, 500);
+
+    // 声部变化时
+    watch(
+      () => prepareStore.getInstrumentId,
+      () => {
+        onSearch(state.searchGroup);
+      }
+    );
+
+    const throttledFn = useThrottleFn(() => {
+      state.pagination.page = state.pagination.page + 1;
+      getList();
+    }, 500);
+
+    // 添加资源
+    const onAdd = async (item: any) => {
+      try {
+        eventGlobal.emit('onPrepareAddItem', {
+          materialId: item.id,
+          coverImg: item.coverImg,
+          refFlag: item.refFlag,
+          type: item.type,
+          title: item.title,
+          isCollect: item.isCollect,
+          isSelected: item.isSelected,
+          content: item.content,
+          removeFlag: false
+        });
+      } catch {
+        //
+      }
+    };
+
+    // 收藏
+    const onCollect = async (item: any) => {
+      try {
+        await favorite({
+          materialId: item.id,
+          favoriteFlag: item.isCollect ? 0 : 1,
+          type: item.type
+        });
+        item.isCollect = !item.isCollect;
+      } catch {
+        //
+      }
+    };
+    const getIds = () => {
+      let noRepeatIds: any = [];
+      if (props.type === 'relateResources') {
+        const materialIds: any = [];
+        prepareStore.getCoursewareList.forEach((course: any) => {
+          course.list?.forEach((item: any) => {
+            materialIds.push(item.materialId);
+          });
+        });
+        noRepeatIds = Array(...new Set(materialIds));
+      }
+      return noRepeatIds.join(',');
+    };
+
+    const onUpdate = () => {
+      state.pagination.page = 1;
+      state.tableList = [];
+      getList();
+    };
+
+    onMounted(() => {
+      // 加载的时候判断是否有资源数据
+      onUpdate();
+
+      if (props.type === 'relateResources') {
+        eventGlobal.on('onCoursewareUpdate', onUpdate);
+      }
+    });
+    onUnmounted(() => {
+      eventGlobal.off('onCoursewareUpdate', onUpdate);
+    });
+    return () => (
+      <div>
+        <ResourceSearchGroup
+          type={props.type}
+          onSearch={(item: any) => {
+            state.searchGroup = Object.assign(state.searchGroup, item);
+            throttledFnSearch(item);
+          }}
+        />
+        <NScrollbar
+          class={[
+            styles.listContainer,
+            'listContainerResource',
+            state.searchGroup.type !== 'MUSIC' ||
+            ['myResources', 'myCollect', 'relateResources'].includes(props.type)
+              ? [styles.listNoMusic, 'listNoMusicResource']
+              : ''
+          ]}
+          onScroll={(e: any) => {
+            const clientHeight = e.target?.clientHeight;
+            const scrollTop = e.target?.scrollTop;
+            const scrollHeight = e.target?.scrollHeight;
+            // 是否到底,是否加载完
+            if (
+              clientHeight + scrollTop + 20 >= scrollHeight &&
+              !state.finshed &&
+              !state.loading
+            ) {
+              throttledFn();
+            }
+          }}>
+          <NSpin show={state.loading} size={'small'}>
+            <div
+              class={[
+                styles.listSection,
+                'listSectionResource',
+                !state.loading && state.tableList.length <= 0
+                  ? [styles.emptySection, 'emptySectionResource']
+                  : ''
+              ]}>
+              {state.tableList.length > 0 && (
+                <div class={styles.list}>
+                  {state.tableList.map((item: any) => (
+                    <CardType
+                      isShowAdd
+                      item={item}
+                      isShowCollect={true}
+                      draggable
+                      disabledMouseHover={false}
+                      onClick={() => {
+                        if (item.type === 'IMG') return;
+                        state.show = true;
+                        state.item = item;
+                      }}
+                      onCollect={(item: any) => onCollect(item)}
+                      // isShowAddDisabled={!prepareStore.getIsEditResource}
+                      onAdd={(item: any) => onAdd(item)}
+                    />
+                  ))}
+                </div>
+              )}
+              {!state.loading && state.tableList.length <= 0 && <TheEmpty />}
+            </div>
+          </NSpin>
+        </NScrollbar>
+
+        {/* 弹窗查看 */}
+        <CardPreview v-model:show={state.show} item={state.item} />
+      </div>
+    );
+  }
+});

+ 317 - 315
src/views/prepare-lessons/model/select-resources/select-item/index.tsx

@@ -1,315 +1,317 @@
-import {
-  PropType,
-  defineComponent,
-  onMounted,
-  onUnmounted,
-  reactive,
-  toRefs,
-  watch
-} from 'vue';
-import ResourceSearchGroup from './resource-search-group';
-import { NScrollbar, NSpin, useMessage } from 'naive-ui';
-import styles from './index.module.less';
-import CardType from '/src/components/card-type';
-import { favorite, materialQueryPage } from '/src/views/natural-resources/api';
-import TheEmpty from '/src/components/TheEmpty';
-import { usePrepareStore } from '/src/store/modules/prepareLessons';
-import { useDebounceFn, useResizeObserver } from '@vueuse/core';
-import CardPreview from '/src/components/card-preview';
-import { eventGlobal } from '/src/utils';
-import ClassSearchGroup from './class-search-group';
-import { useCatchStore } from '/src/store/modules/catchData';
-
-const formatType = (type: string) => {
-  if (type === 'shareResources') {
-    return 2;
-  } else if (type === 'myResources') {
-    return 3;
-  } else if (type === 'myCollect') {
-    return 4;
-  } else if (type === 'relateResources') {
-    return 5;
-  }
-};
-
-export default defineComponent({
-  name: 'share-resources',
-  props: {
-    type: {
-      type: String as PropType<
-        'relateResources' | 'shareResources' | 'myResources' | 'myCollect'
-      >,
-      default: 'shareResources'
-    },
-    /** 从哪里使用 */
-    from: {
-      type: String,
-      default: ''
-    }
-  },
-  setup(props) {
-    const prepareStore = usePrepareStore();
-    const catchStore = useCatchStore();
-    const message = useMessage();
-    const { type } = toRefs(props);
-    const className = 'resourceSearchGroup' + +new Date();
-    const state = reactive({
-      searchHeight: '0px',
-      loading: false,
-      finshed: false, // 是否加载完
-      pagination: {
-        page: 1,
-        rows: 20
-      },
-      searchGroup: {
-        type: 'MUSIC', //
-        name: '',
-        bookVersionId: null,
-        subjectId: null,
-        sourceType: formatType(type.value),
-        musicalInstrumentId: null as any,
-        enableFlag: true
-      },
-      tableList: [] as any,
-      show: false,
-      item: {} as any
-    });
-
-    // 查询列表
-    const getList = async () => {
-      try {
-        if (state.pagination.page === 1) {
-          state.loading = true;
-        }
-        const { data } = await materialQueryPage({
-          ...state.searchGroup,
-          ...state.pagination,
-          lessonCoursewareKnowledgeId:
-            props.type === 'relateResources' || props.type === 'shareResources'
-              ? prepareStore.getSelectKey
-              : null,
-          relateLessonCoursewareKnowledgeMaterialIds: getIds()
-        });
-        state.loading = false;
-        const tempRows = data.rows || [];
-        const temp: any = [];
-        tempRows.forEach((row: any) => {
-          temp.push({
-            id: row.id,
-            coverImg: row.coverImg,
-            type: row.type,
-            title: row.name,
-            isCollect: !!row.favoriteFlag,
-            isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
-            refFlag: row.refFlag,
-            content: row.content
-          });
-        });
-        state.tableList.push(...temp);
-
-        state.finshed = data.pages <= data.current ? true : false;
-      } catch {
-        state.loading = false;
-      }
-    };
-
-    const throttledFnSearch = useDebounceFn(item => {
-      state.pagination.page = 1;
-      state.tableList = [];
-      const { subjectId, ...res } = item;
-      state.searchGroup = Object.assign(state.searchGroup, {
-        ...res,
-        musicalInstrumentId: subjectId,
-        subjectId: null
-      });
-      getList();
-    }, 500);
-
-    // 添加资源
-    const onAdd = async (item: any) => {
-      try {
-        eventGlobal.emit('onPrepareAddItem', {
-          materialId: item.id,
-          coverImg: item.coverImg,
-          type: item.type,
-          title: item.title,
-          refFlag: item.refFlag,
-          isCollect: item.isCollect,
-          isSelected: item.isSelected,
-          content: item.content,
-          removeFlag: false
-        });
-      } catch {
-        //
-      }
-    };
-
-    // 收藏
-    const onCollect = async (item: any) => {
-      try {
-        await favorite({
-          materialId: item.id,
-          favoriteFlag: item.isCollect ? 0 : 1,
-          type: item.type
-        });
-        item.isCollect = !item.isCollect;
-      } catch {
-        //
-      }
-    };
-
-    const getIds = () => {
-      let noRepeatIds: any = [];
-      if (props.type === 'relateResources') {
-        const materialIds: any = [];
-        prepareStore.getCoursewareList.forEach((course: any) => {
-          course.list?.forEach((item: any) => {
-            materialIds.push(item.materialId);
-          });
-        });
-        noRepeatIds = Array(...new Set(materialIds));
-      }
-      return noRepeatIds.join(',');
-    };
-
-    const onUpdate = () => {
-      state.pagination.page = 1;
-      state.tableList = [];
-      getList();
-    };
-
-    onMounted(async () => {
-      // 加载的时候判断是否有资源数据
-      // 获取声部
-      await catchStore.getSubjects();
-
-      useResizeObserver(
-        document.querySelector('.' + className) as HTMLElement,
-        (entries: any) => {
-          const entry = entries[0];
-          const { height } = entry.contentRect;
-          state.searchHeight = height + 'px';
-        }
-      );
-      getList();
-
-      eventGlobal.on('onCoursewareUpdate', onUpdate);
-    });
-    onUnmounted(() => {
-      eventGlobal.off('onCoursewareUpdate', onUpdate);
-    });
-
-    // onMounted(async () => {
-    //   // 获取声部
-    //   await catchStore.getSubjects();
-
-    //   // 加载的时候判断是否有资源数据
-    //   let noRepeatIds: any = [];
-    //   if (props.type === 'relateResources') {
-    //     const materialIds: any = [];
-    //     prepareStore.getCoursewareList.forEach((course: any) => {
-    //       course.list?.forEach((item: any) => {
-    //         materialIds.push(item.materialId);
-    //       });
-    //     });
-    //     noRepeatIds = Array(...new Set(materialIds));
-    //   }
-    //   getList(noRepeatIds.join(','));
-
-    //   useResizeObserver(
-    //     document.querySelector('.' + className) as HTMLElement,
-    //     (entries: any) => {
-    //       const entry = entries[0];
-    //       const { height } = entry.contentRect;
-    //       state.searchHeight = height + 'px';
-    //     }
-    //   );
-    // });
-    return () => (
-      <div>
-        <div class={className}>
-          {props.from === 'class' ? (
-            <ClassSearchGroup
-              type={props.type}
-              subjectId={prepareStore.getSubjectId as any}
-              onSearch={(item: any) => throttledFnSearch(item)}
-            />
-          ) : (
-            <ResourceSearchGroup
-              type={props.type}
-              // subjectId={prepareStore.getSubjectId as any}
-              onSearch={(item: any) => throttledFnSearch(item)}
-            />
-          )}
-        </div>
-        <NScrollbar
-          class={[styles.listContainer, 'list_container']}
-          style={{
-            'max-height': `calc(var(--listContainerHeight) - var(--modal-lesson-tab-height) - ${state.searchHeight}) `
-          }}
-          onScroll={(e: any) => {
-            const clientHeight = e.target?.clientHeight;
-            const scrollTop = e.target?.scrollTop;
-            const scrollHeight = e.target?.scrollHeight;
-            // 是否到底,是否加载完
-            if (
-              clientHeight + scrollTop + 20 >= scrollHeight &&
-              !state.finshed &&
-              !state.loading
-            ) {
-              state.pagination.page = state.pagination.page + 1;
-              getList();
-            }
-          }}>
-          <NSpin show={state.loading} size={'small'}>
-            <div
-              style={{
-                'min-height': `calc(var(--listContainerHeight) - var(--modal-lesson-tab-height) - ${state.searchHeight})`
-              }}
-              class={[
-                styles.listSection,
-                !state.loading && state.tableList.length <= 0
-                  ? styles.emptySection
-                  : ''
-              ]}>
-              {state.tableList.length > 0 && (
-                <div class={styles.list}>
-                  {state.tableList.map((item: any) => (
-                    <div class={[styles.itemWrap, 'selresources_item_Wrap']}>
-                      <div class={styles.itemWrapBox}>
-                        <CardType
-                          isShowAdd={props.from === 'class' ? false : true}
-                          item={item}
-                          isShowCollect={true}
-                          // isShowAddDisabled={!prepareStore.getIsEditResource}
-                          onAdd={(item: any) => onAdd(item)}
-                          disabledMouseHover={false}
-                          onCollect={(item: any) => onCollect(item)}
-                          onClick={() => {
-                            if (item.type === 'IMG') return;
-                            state.show = true;
-                            state.item = item;
-                          }}
-                        />
-                      </div>
-                    </div>
-                  ))}
-                </div>
-              )}
-
-              {!state.loading && state.tableList.length <= 0 && <TheEmpty />}
-            </div>
-          </NSpin>
-        </NScrollbar>
-
-        {/* 弹窗查看 */}
-        <CardPreview
-          size={props.from === 'class' ? 'large' : 'default'}
-          v-model:show={state.show}
-          from={props.from}
-          item={state.item}
-        />
-      </div>
-    );
-  }
-});
+import {
+  PropType,
+  defineComponent,
+  onMounted,
+  onUnmounted,
+  reactive,
+  toRefs,
+  watch
+} from 'vue';
+import ResourceSearchGroup from './resource-search-group';
+import { NScrollbar, NSpin, useMessage } from 'naive-ui';
+import styles from './index.module.less';
+import CardType from '/src/components/card-type';
+import { favorite, materialQueryPage } from '/src/views/natural-resources/api';
+import TheEmpty from '/src/components/TheEmpty';
+import { usePrepareStore } from '/src/store/modules/prepareLessons';
+import { useDebounceFn, useResizeObserver } from '@vueuse/core';
+import CardPreview from '/src/components/card-preview';
+import { eventGlobal } from '/src/utils';
+import ClassSearchGroup from './class-search-group';
+import { useCatchStore } from '/src/store/modules/catchData';
+
+const formatType = (type: string) => {
+  if (type === 'shareResources') {
+    return 2;
+  } else if (type === 'myResources') {
+    return 3;
+  } else if (type === 'myCollect') {
+    return 4;
+  } else if (type === 'relateResources') {
+    return 5;
+  }
+};
+
+export default defineComponent({
+  name: 'share-resources',
+  props: {
+    type: {
+      type: String as PropType<
+        'relateResources' | 'shareResources' | 'myResources' | 'myCollect'
+      >,
+      default: 'shareResources'
+    },
+    /** 从哪里使用 */
+    from: {
+      type: String,
+      default: ''
+    }
+  },
+  setup(props) {
+    const prepareStore = usePrepareStore();
+    const catchStore = useCatchStore();
+    const message = useMessage();
+    const { type } = toRefs(props);
+    const className = 'resourceSearchGroup' + +new Date();
+    const state = reactive({
+      searchHeight: '0px',
+      loading: false,
+      finshed: false, // 是否加载完
+      pagination: {
+        page: 1,
+        rows: 20
+      },
+      searchGroup: {
+        type: 'MUSIC', //
+        name: '',
+        bookVersionId: null,
+        subjectId: null,
+        sourceType: formatType(type.value),
+        musicalInstrumentId: null as any,
+        enableFlag: true
+      },
+      tableList: [] as any,
+      show: false,
+      item: {} as any
+    });
+
+    // 查询列表
+    const getList = async () => {
+      try {
+        if (state.pagination.page === 1) {
+          state.loading = true;
+        }
+        const { data } = await materialQueryPage({
+          ...state.searchGroup,
+          ...state.pagination,
+          lessonCoursewareKnowledgeId:
+            props.type === 'relateResources' || props.type === 'shareResources'
+              ? prepareStore.getSelectKey
+              : null,
+          relateLessonCoursewareKnowledgeMaterialIds: getIds()
+        });
+        state.loading = false;
+        const tempRows = data.rows || [];
+        const temp: any = [];
+        tempRows.forEach((row: any) => {
+          temp.push({
+            id: row.id,
+            coverImg: row.coverImg,
+            type: row.type,
+            title: row.name,
+            isCollect: !!row.favoriteFlag,
+            isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
+            refFlag: row.refFlag,
+            content: row.content
+          });
+        });
+        state.tableList.push(...temp);
+
+        state.finshed = data.pages <= data.current ? true : false;
+      } catch {
+        state.loading = false;
+      }
+    };
+
+    const throttledFnSearch = useDebounceFn(item => {
+      state.pagination.page = 1;
+      state.tableList = [];
+      const { subjectId, ...res } = item;
+      state.searchGroup = Object.assign(state.searchGroup, {
+        ...res,
+        musicalInstrumentId: subjectId,
+        subjectId: null
+      });
+      getList();
+    }, 500);
+
+    // 添加资源
+    const onAdd = async (item: any) => {
+      try {
+        eventGlobal.emit('onPrepareAddItem', {
+          materialId: item.id,
+          coverImg: item.coverImg,
+          type: item.type,
+          title: item.title,
+          refFlag: item.refFlag,
+          isCollect: item.isCollect,
+          isSelected: item.isSelected,
+          content: item.content,
+          removeFlag: false
+        });
+      } catch {
+        //
+      }
+    };
+
+    // 收藏
+    const onCollect = async (item: any) => {
+      try {
+        await favorite({
+          materialId: item.id,
+          favoriteFlag: item.isCollect ? 0 : 1,
+          type: item.type
+        });
+        item.isCollect = !item.isCollect;
+      } catch {
+        //
+      }
+    };
+
+    const getIds = () => {
+      let noRepeatIds: any = [];
+      if (props.type === 'relateResources') {
+        const materialIds: any = [];
+        prepareStore.getCoursewareList.forEach((course: any) => {
+          course.list?.forEach((item: any) => {
+            materialIds.push(item.materialId);
+          });
+        });
+        noRepeatIds = Array(...new Set(materialIds));
+      }
+      return noRepeatIds.join(',');
+    };
+
+    const onUpdate = () => {
+      state.pagination.page = 1;
+      state.tableList = [];
+      getList();
+    };
+
+    onMounted(async () => {
+      // 加载的时候判断是否有资源数据
+      // 获取声部
+      await catchStore.getSubjects();
+
+      useResizeObserver(
+        document.querySelector('.' + className) as HTMLElement,
+        (entries: any) => {
+          const entry = entries[0];
+          const { height } = entry.contentRect;
+          state.searchHeight = height + 'px';
+        }
+      );
+      getList();
+
+      if (props.type === 'relateResources') {
+        eventGlobal.on('onCoursewareUpdate', onUpdate);
+      }
+    });
+    onUnmounted(() => {
+      eventGlobal.off('onCoursewareUpdate', onUpdate);
+    });
+
+    // onMounted(async () => {
+    //   // 获取声部
+    //   await catchStore.getSubjects();
+
+    //   // 加载的时候判断是否有资源数据
+    //   let noRepeatIds: any = [];
+    //   if (props.type === 'relateResources') {
+    //     const materialIds: any = [];
+    //     prepareStore.getCoursewareList.forEach((course: any) => {
+    //       course.list?.forEach((item: any) => {
+    //         materialIds.push(item.materialId);
+    //       });
+    //     });
+    //     noRepeatIds = Array(...new Set(materialIds));
+    //   }
+    //   getList(noRepeatIds.join(','));
+
+    //   useResizeObserver(
+    //     document.querySelector('.' + className) as HTMLElement,
+    //     (entries: any) => {
+    //       const entry = entries[0];
+    //       const { height } = entry.contentRect;
+    //       state.searchHeight = height + 'px';
+    //     }
+    //   );
+    // });
+    return () => (
+      <div>
+        <div class={className}>
+          {props.from === 'class' ? (
+            <ClassSearchGroup
+              type={props.type}
+              subjectId={prepareStore.getSubjectId as any}
+              onSearch={(item: any) => throttledFnSearch(item)}
+            />
+          ) : (
+            <ResourceSearchGroup
+              type={props.type}
+              // subjectId={prepareStore.getSubjectId as any}
+              onSearch={(item: any) => throttledFnSearch(item)}
+            />
+          )}
+        </div>
+        <NScrollbar
+          class={[styles.listContainer, 'list_container']}
+          style={{
+            'max-height': `calc(var(--listContainerHeight) - var(--modal-lesson-tab-height) - ${state.searchHeight}) `
+          }}
+          onScroll={(e: any) => {
+            const clientHeight = e.target?.clientHeight;
+            const scrollTop = e.target?.scrollTop;
+            const scrollHeight = e.target?.scrollHeight;
+            // 是否到底,是否加载完
+            if (
+              clientHeight + scrollTop + 20 >= scrollHeight &&
+              !state.finshed &&
+              !state.loading
+            ) {
+              state.pagination.page = state.pagination.page + 1;
+              getList();
+            }
+          }}>
+          <NSpin show={state.loading} size={'small'}>
+            <div
+              style={{
+                'min-height': `calc(var(--listContainerHeight) - var(--modal-lesson-tab-height) - ${state.searchHeight})`
+              }}
+              class={[
+                styles.listSection,
+                !state.loading && state.tableList.length <= 0
+                  ? styles.emptySection
+                  : ''
+              ]}>
+              {state.tableList.length > 0 && (
+                <div class={styles.list}>
+                  {state.tableList.map((item: any) => (
+                    <div class={[styles.itemWrap, 'selresources_item_Wrap']}>
+                      <div class={styles.itemWrapBox}>
+                        <CardType
+                          isShowAdd={props.from === 'class' ? false : true}
+                          item={item}
+                          isShowCollect={true}
+                          // isShowAddDisabled={!prepareStore.getIsEditResource}
+                          onAdd={(item: any) => onAdd(item)}
+                          disabledMouseHover={false}
+                          onCollect={(item: any) => onCollect(item)}
+                          onClick={() => {
+                            if (item.type === 'IMG') return;
+                            state.show = true;
+                            state.item = item;
+                          }}
+                        />
+                      </div>
+                    </div>
+                  ))}
+                </div>
+              )}
+
+              {!state.loading && state.tableList.length <= 0 && <TheEmpty />}
+            </div>
+          </NSpin>
+        </NScrollbar>
+
+        {/* 弹窗查看 */}
+        <CardPreview
+          size={props.from === 'class' ? 'large' : 'default'}
+          v-model:show={state.show}
+          from={props.from}
+          item={state.item}
+        />
+      </div>
+    );
+  }
+});