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: false, name: '', openFlag: false, createId: null, baseCoursewareList: [ { name: '', id: null, list: [] as any } ] as any, // 基础数据 baseInfo: { subjects: [] as any, autoPlay: false, 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); eventGlobal.emit('onCoursewareUpdate'); } 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, insert = false ) => { clearTimeout(timer); const materialList: any[] = []; if (!insert) { 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 () => (
{forms.coursewareList.map((item: any, index: number) => (
{ 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 } ); } }}>
{/*
*知识点名称:
*/}
{index > 0 && ( {{ trigger: () => ( onChangePoint('up', index)}> ), default: () => '上移知识点' }} )} {index < forms.coursewareList.length - 1 && ( {{ trigger: () => ( onChangePoint('down', index)}> ), default: () => '下移知识点' }} )} {{ trigger: () => ( onChangePoint('remove', index, item) }> ), default: () => '删除知识点' }} {/* {item.list.length > 0 && ( */} { // 修复滚动超出范围 const container: any = document.querySelector( '.listContainerWrap .n-scrollbar-container' ); const sensitivity = 150; // 自定义灵敏度 if (event.clientY < sensitivity) { container.scrollTop -= 8; } else if ( window.innerHeight - event.clientY < sensitivity ) { console.log('1111'); container.scrollTop += 8; } }} componentData={{ draggable: 'row-nav', // scroll: false, itemKey: 'id', tag: 'div', animation: 200, // pull: true, // put: true, group: 'description' // disabled: false }} class={styles.list}> {{ item: (element: any) => { const item = element.element; return (
onRemove(item)} item={item} disabledMouseHover={false} onClick={() => { if (item.type === 'IMG') return; forms.show = true; forms.item = item; }} />
{ e.stopPropagation(); onDelete(element.index, index); }} />
); }, footer: () => (
{ forms.addOtherSource = true; forms.addOtherIndex = index; }}>

添加资源

) }}
{/* )} {item.list <= 0 && (
{ forms.addOtherSource = true; forms.addOtherIndex = index; }}>

添加资源

)} */}
))} {!forms.loadingStatus && ( { forms.coursewareList.push({ name: '', list: [] }); }}> 添加知识点 )}
{/* 弹窗查看 */} (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('请选择需要添加的知识点'); } }} /> { 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()} /> {/* 添加其它类型的资源 */} (forms.addOtherSource = false)} onComfirm={item => { if (Array.isArray(item)) { console.log(item, 'item - item'); item.forEach(async (child: any) => { await addCoursewareItem( { ...child, index: forms.addOtherIndex }, null, true ); }); } else { addCoursewareItem( { ...item, index: forms.addOtherIndex }, null, true ); } }} /> (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 { // } }} />
); } });