pptist: canvasTool 里面 新增插入试题
This commit is contained in:
parent
23795f2419
commit
be9d33fcd3
|
@ -57,6 +57,7 @@
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"hfmath": "^0.0.2",
|
"hfmath": "^0.0.2",
|
||||||
"html-to-image": "^1.11.11",
|
"html-to-image": "^1.11.11",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"im_electron_sdk": "^8.0.5904",
|
"im_electron_sdk": "^8.0.5904",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
</template>
|
</template>
|
||||||
<IconVideoTwo class="handler-item" v-tooltip="'插入音视频'" />
|
<IconVideoTwo class="handler-item" v-tooltip="'插入音视频'" />
|
||||||
</Popover>
|
</Popover>
|
||||||
<IconFormula class="handler-item" v-tooltip="'插入试题'" @click="classWorkTaskVisible = true" />
|
<IconPreviewOpen class="handler-item" v-tooltip="'插入试题'" @click="classWorkTaskVisible = true" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="right-handler">
|
<div class="right-handler">
|
||||||
|
@ -116,9 +116,10 @@
|
||||||
v-model:visible="classWorkTaskVisible"
|
v-model:visible="classWorkTaskVisible"
|
||||||
:width="880"
|
:width="880"
|
||||||
>
|
>
|
||||||
<LaTeXEditor
|
<QuestToPPTist
|
||||||
|
class="class-work-task-modal"
|
||||||
@close="classWorkTaskVisible = false"
|
@close="classWorkTaskVisible = false"
|
||||||
@update="data => { createLatexElement(data); classWorkTaskVisible = false }"
|
@update="data => { onhtml2canvas(data); classWorkTaskVisible = false }"
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
@ -147,7 +148,7 @@ import Modal from '../../../components/Modal.vue'
|
||||||
import Divider from '../../../components/Divider.vue'
|
import Divider from '../../../components/Divider.vue'
|
||||||
import Popover from '../../../components/Popover.vue'
|
import Popover from '../../../components/Popover.vue'
|
||||||
import PopoverMenuItem from '../../../components/PopoverMenuItem.vue'
|
import PopoverMenuItem from '../../../components/PopoverMenuItem.vue'
|
||||||
import SearchQuestion from '@/views/classTask/newClassTaskAssign/searchQuestion/index.vue'
|
import QuestToPPTist from '@/views/classTask/newClassTaskAssign/questToPPTist/index.vue'
|
||||||
|
|
||||||
const mainStore = useMainStore()
|
const mainStore = useMainStore()
|
||||||
const { creatingElement, creatingCustomShape, showSelectPanel, showSearchPanel, showNotesPanel } = storeToRefs(mainStore)
|
const { creatingElement, creatingCustomShape, showSelectPanel, showSearchPanel, showNotesPanel } = storeToRefs(mainStore)
|
||||||
|
@ -185,6 +186,10 @@ const insertImageElement = (files: FileList) => {
|
||||||
getImageDataURL(imageFile).then(dataURL => createImageElement(dataURL))
|
getImageDataURL(imageFile).then(dataURL => createImageElement(dataURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onhtml2canvas = (imgbs64: string) => {
|
||||||
|
createImageElement(imgbs64)
|
||||||
|
}
|
||||||
|
|
||||||
const shapePoolVisible = ref(false)
|
const shapePoolVisible = ref(false)
|
||||||
const linePoolVisible = ref(false)
|
const linePoolVisible = ref(false)
|
||||||
const chartPoolVisible = ref(false)
|
const chartPoolVisible = ref(false)
|
||||||
|
@ -357,6 +362,9 @@ const toggleNotesPanel = () => {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.class-work-task-modal{
|
||||||
|
height: 80vh;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (width <= 1200px) {
|
@media screen and (width <= 1200px) {
|
||||||
.right-handler .text {
|
.right-handler .text {
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<el-button @click="handleQueryParamFromEntpCourseWork(1)"><el-icon><Search /></el-icon> 查找</el-button>
|
<el-button @click="handleQueryParamFromEntpCourseWork(1)"><el-icon><Search /></el-icon> 查找</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="5">
|
<el-col :span="5">
|
||||||
<el-button type="primary" @click="goToQuestUpload()">添加习题</el-button>
|
<el-button v-if="!props.isHtml2canvas" type="primary" @click="goToQuestUpload()">添加习题</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<!-- 习题表格 -->
|
<!-- 习题表格 -->
|
||||||
|
@ -58,9 +58,9 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div @click="showExamAnalyseDrawer(scope.row)">
|
<div @click="showExamAnalyseDrawer(scope.row)" :id=" `screenshot-target-${scope.row.id}` " style="padding: 5px;">
|
||||||
<div style="overflow: hidden; text-overflow: ellipsis" v-html="scope.row.titleFormat"></div>
|
<div style="overflow: hidden; text-overflow: ellipsis; padding: 2px;" v-html="scope.row.titleFormat"></div>
|
||||||
<div style="overflow: hidden; text-overflow: ellipsis; font-size: 0.9em; margin-top: 6px;" v-html="scope.row.workdescFormat"></div>
|
<div style="overflow: hidden; text-overflow: ellipsis; font-size: 0.9em; margin-top: 6px; padding: 2px;" v-html="scope.row.workdescFormat"></div>
|
||||||
<el-col :span="24" style="display: flex">
|
<el-col :span="24" style="display: flex">
|
||||||
<div style="font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.entpname }} {{ scope.row.editusername }}</div>
|
<div style="font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.entpname }} {{ scope.row.editusername }}</div>
|
||||||
<div style="margin-left: 30px; font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.worktag }}</div>
|
<div style="margin-left: 30px; font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.worktag }}</div>
|
||||||
|
@ -70,7 +70,8 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column width="100">
|
<el-table-column width="100">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div>
|
<el-button v-if="props.isHtml2canvas" type="primary" @click="captureScreenshot(scope.row.id)">选取该题</el-button>
|
||||||
|
<div v-else>
|
||||||
<el-button type="primary" @click="handleClassWorkQuizAdd('entpcourseworklist', scope.row.id)">添加</el-button>
|
<el-button type="primary" @click="handleClassWorkQuizAdd('entpcourseworklist', scope.row.id)">添加</el-button>
|
||||||
<div style="padding: 2px;"></div>
|
<div style="padding: 2px;"></div>
|
||||||
<el-button type="warning" @click="handleImportSingleDlg(scope.row)">纠错</el-button>
|
<el-button type="warning" @click="handleImportSingleDlg(scope.row)">纠错</el-button>
|
||||||
|
@ -117,6 +118,7 @@
|
||||||
import { Search } from '@element-plus/icons-vue'
|
import { Search } from '@element-plus/icons-vue'
|
||||||
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
|
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import html2canvas from 'html2canvas';
|
||||||
|
|
||||||
import { listEntpcoursework, listEntpcourseworkLocal } from '@/api/education/entpCourseWork'
|
import { listEntpcoursework, listEntpcourseworkLocal } from '@/api/education/entpCourseWork'
|
||||||
import { listEvaluationclue } from '@/api/classTask'
|
import { listEvaluationclue } from '@/api/classTask'
|
||||||
|
@ -136,7 +138,7 @@ const router = useRouter()
|
||||||
|
|
||||||
|
|
||||||
// 定义要发送的emit事件
|
// 定义要发送的emit事件
|
||||||
const emit = defineEmits(['addQuiz'])
|
let emit = defineEmits(['addQuiz', 'addQuizImgBs64'])
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const userStore = useUserStore().user
|
const userStore = useUserStore().user
|
||||||
const {
|
const {
|
||||||
|
@ -150,6 +152,10 @@ const props = defineProps({
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
|
isHtml2canvas: {// 是否截屏
|
||||||
|
type: Boolean,
|
||||||
|
default: () => false
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const knowledgePointProps = ref({value: 'thirdId', label: 'title'});
|
const knowledgePointProps = ref({value: 'thirdId', label: 'title'});
|
||||||
|
@ -440,6 +446,22 @@ const handleDelete = async(item, index) => {
|
||||||
// ElMessage('试题已经存在')
|
// ElMessage('试题已经存在')
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 把该题区域id 获取为截屏区域
|
||||||
|
* @param id 试题id
|
||||||
|
*/
|
||||||
|
const captureScreenshot = (id) => {
|
||||||
|
const targetElement = document.getElementById('screenshot-target-' + id);
|
||||||
|
html2canvas(targetElement).then(canvas => {
|
||||||
|
// 将canvas转换为图像URL
|
||||||
|
const screenshotUrl = canvas.toDataURL('image/png');
|
||||||
|
// 在这里可以将截图保存到本地或上传到服务器
|
||||||
|
// console.log(screenshotUrl);
|
||||||
|
emit('addQuizImgBs64', screenshotUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 防抖
|
// 防抖
|
||||||
const debounceQueryData = debounce(() => {
|
const debounceQueryData = debounce(() => {
|
||||||
console.log("防抖 加载数据中...")
|
console.log("防抖 加载数据中...")
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
<template>
|
||||||
|
<div class="page">
|
||||||
|
<div class="page-resource">
|
||||||
|
<div class="page-center">
|
||||||
|
<el-tabs v-model="activeAptTab" style="height: 100%;">
|
||||||
|
<el-tab-pane label="自主搜题" name="自主搜题" class="prepare-center-zzst">
|
||||||
|
<SearchQuestion :bookobj="courseObj" :isHtml2canvas="true" @addQuizImgBs64="handleaddQuizImgBs64" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="校本题库" name="校本题库" class="prepare-center-xbtk">
|
||||||
|
<SchoolQuestion />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="个人题库" name="个人题库" class="prepare-center-grst">
|
||||||
|
<MyQuestion :bookobj="courseObj" :isHtml2canvas="true" @addQuizImgBs64="handleaddQuizImgBs64"/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, ref, watch, reactive, getCurrentInstance, nextTick } from 'vue'
|
||||||
|
|
||||||
|
import MyQuestion from '@/views/classTask/newClassTaskAssign/myQuestion/index.vue'
|
||||||
|
import SchoolQuestion from '@/views/classTask/newClassTaskAssign/schoolQuestion/index.vue'
|
||||||
|
import SearchQuestion from '@/views/classTask/newClassTaskAssign/searchQuestion/index.vue'
|
||||||
|
|
||||||
|
import { sessionStore } from '@/utils/store'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import useUserStore from '@/store/modules/user'
|
||||||
|
const userStore = useUserStore().user
|
||||||
|
|
||||||
|
|
||||||
|
const emit = defineEmits(['update']);
|
||||||
|
const courseObj = reactive({
|
||||||
|
// 课程相关参数: 教材id,单元id,章节id,课程名称
|
||||||
|
textbookId: '',
|
||||||
|
levelFirstId: '',
|
||||||
|
levelSecondId: '',
|
||||||
|
coursetitle:'',
|
||||||
|
node: null, // 选择的课程节点
|
||||||
|
//
|
||||||
|
})
|
||||||
|
|
||||||
|
const activeAptTab = ref("自主搜题");
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const curNode = sessionStore.get('subject.curNode')
|
||||||
|
courseObj.textbookId = curNode.rootid
|
||||||
|
courseObj.levelFirstId = curNode.parentNode.id
|
||||||
|
courseObj.levelSecondId = curNode.id
|
||||||
|
courseObj.coursetitle = curNode.itemtitle,
|
||||||
|
courseObj.node = curNode
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const handleaddQuizImgBs64 = (quizbs64) => {
|
||||||
|
emit('update', quizbs64)
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.page {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.page-resource {
|
||||||
|
user-select: none;
|
||||||
|
height: calc(100% - 55px);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
flex: 1;
|
||||||
|
:deep(.el-tabs__nav) {
|
||||||
|
.el-tabs__item{
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.page-center{
|
||||||
|
flex: 1;
|
||||||
|
//min-width: calc(100% - 675px);
|
||||||
|
height: 100%;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin: 0 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
.prepare-center-zzst{
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
.prepare-center-xbtk{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.prepare-center-grst{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.upload-homework{
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -71,9 +71,9 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div @click="showExamAnalyseDrawer(scope.row)">
|
<div @click="showExamAnalyseDrawer(scope.row)" :id=" `screenshot-target-${scope.row.id}` " style="padding: 5px;">
|
||||||
<div style="overflow: hidden; text-overflow: ellipsis" v-html="scope.row.titleFormat"></div>
|
<div style="overflow: hidden; text-overflow: ellipsis; padding: 2px;" v-html="scope.row.titleFormat"></div>
|
||||||
<div style="overflow: hidden; text-overflow: ellipsis; font-size: 0.9em; margin-top: 6px;" v-html="scope.row.workdescFormat"></div>
|
<div style="overflow: hidden; text-overflow: ellipsis; font-size: 0.9em; margin-top: 6px; padding: 2px;" v-html="scope.row.workdescFormat"></div>
|
||||||
<el-col :span="24" style="display: flex">
|
<el-col :span="24" style="display: flex">
|
||||||
<div style="font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.entpname }} {{ scope.row.editusername }}</div>
|
<div style="font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.entpname }} {{ scope.row.editusername }}</div>
|
||||||
<div style="margin-left: 30px; font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.worktag }}</div>
|
<div style="margin-left: 30px; font-size: 1em; color: silver; padding-top: 5px">{{ scope.row.worktag }}</div>
|
||||||
|
@ -83,7 +83,8 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="left" width="100">
|
<el-table-column align="left" width="100">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button type="primary" @click="handleClassWorkQuizAdd('entpcourseworklist', scope.row.id)">添加</el-button>
|
<el-button v-if="props.isHtml2canvas" type="primary" @click="captureScreenshot(scope.row.id)">选取该题</el-button>
|
||||||
|
<el-button v-else type="primary" @click="handleClassWorkQuizAdd('entpcourseworklist', scope.row.id)">添加</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
@ -104,7 +105,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Search } from '@element-plus/icons-vue'
|
import { Search } from '@element-plus/icons-vue'
|
||||||
|
import html2canvas from 'html2canvas';
|
||||||
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
|
import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
|
||||||
|
|
||||||
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
|
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
|
||||||
|
@ -122,7 +123,7 @@ import useUserStore from '@/store/modules/user'
|
||||||
import useClassTaskStore from '@/store/modules/classTask'
|
import useClassTaskStore from '@/store/modules/classTask'
|
||||||
|
|
||||||
// 定义要发送的emit事件
|
// 定义要发送的emit事件
|
||||||
const emit = defineEmits(['addQuiz'])
|
let emit = defineEmits(['addQuiz', 'addQuizImgBs64'])
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const userStore = useUserStore().user
|
const userStore = useUserStore().user
|
||||||
const {
|
const {
|
||||||
|
@ -136,6 +137,10 @@ const props = defineProps({
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
|
isHtml2canvas: {// 是否截屏
|
||||||
|
type: Boolean,
|
||||||
|
default: () => false
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const entpCourseWorkPointList = ref([
|
const entpCourseWorkPointList = ref([
|
||||||
|
@ -427,6 +432,20 @@ const getPaginationList = ( page, limit ) => {
|
||||||
// ElMessage('试题已经存在')
|
// ElMessage('试题已经存在')
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 把该题区域id 获取为截屏区域
|
||||||
|
* @param id 试题id
|
||||||
|
*/
|
||||||
|
const captureScreenshot = (id) => {
|
||||||
|
const targetElement = document.getElementById('screenshot-target-' + id);
|
||||||
|
html2canvas(targetElement).then(canvas => {
|
||||||
|
// 将canvas转换为图像URL
|
||||||
|
const screenshotUrl = canvas.toDataURL('image/png');
|
||||||
|
// 在这里可以将截图保存到本地或上传到服务器
|
||||||
|
// console.log(screenshotUrl);
|
||||||
|
emit('addQuizImgBs64', screenshotUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 防抖
|
// 防抖
|
||||||
|
|
Loading…
Reference in New Issue