|
@@ -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>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|