Compare commits

...

17 Commits

Author SHA1 Message Date
lyc 97f55ca333 Merge pull request 'lyc-dev' (#93) from lyc-dev into main 2024-12-06 16:40:40 +08:00
lyc cb5445f9a9 Merge branch 'main' into lyc-dev 2024-12-06 16:40:03 +08:00
lyc 560e6f0e70 插入素材-pptlist 2024-12-06 16:39:47 +08:00
baigl 4010411c9f Merge pull request 'baigl' (#92) from baigl into main
Reviewed-on: #92
2024-12-06 15:30:38 +08:00
白了个白 da1c80406f Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk_WS into baigl 2024-12-06 15:29:35 +08:00
白了个白 e3199b43de 1 2024-12-06 15:26:22 +08:00
zhengdegang e5be55f12e Merge pull request '弹窗进度条' (#91) from zdg_dev into main
Reviewed-on: #91
2024-12-06 14:15:42 +08:00
zdg 209ab7fafc 弹窗进度条 2024-12-06 14:15:01 +08:00
zouyf 1f96b9b09e Merge pull request 'zouyf_dev' (#90) from zouyf_dev into main
Reviewed-on: #90
2024-12-05 14:55:32 +08:00
“zouyf” 35c088c25a Merge branch 'main' into zouyf_dev 2024-12-05 14:37:13 +08:00
“zouyf” 028eb0f752 [考试分析] - 增加分页及优化题型获取 2024-12-05 14:36:50 +08:00
zhengdegang 9a68661fb0 Merge pull request 'zdg_dev' (#89) from zdg_dev into main
Reviewed-on: #89
2024-12-05 14:22:13 +08:00
zdg b28abdff50 Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk_WS into zdg_dev 2024-12-05 14:21:43 +08:00
zdg b428260703 类型异常 2024-12-05 14:21:36 +08:00
lyc b5f824ceea Merge pull request 'edit' (#88) from lyc-dev into main 2024-12-05 10:36:59 +08:00
lyc d3b3e3bcb5 edit 2024-12-05 10:36:34 +08:00
“zouyf” 7b59d78ce3 1 2024-12-02 17:30:24 +08:00
15 changed files with 384 additions and 39 deletions

View File

@ -4,7 +4,7 @@
* @date 2024-11-26 * @date 2024-11-26
*/ */
import { toRaw } from 'vue' import { toRaw } from 'vue'
import { Result } from '@/types' // 接口类型 import type { Result } from './types' // 接口类型
import msgUtils from '@/plugins/modal' // 消息工具 import msgUtils from '@/plugins/modal' // 消息工具
import * as API_entpcoursefile from '@/api/education/entpcoursefile' // 相关api import * as API_entpcoursefile from '@/api/education/entpcoursefile' // 相关api
import * as API_smarttalk from '@/api/file' // 相关api import * as API_smarttalk from '@/api/file' // 相关api

View File

@ -2,7 +2,7 @@
* @description api store循环引用 * @description api store循环引用
* @author zdg * @author zdg
*/ */
import { Result } from '@/types' // 接口类型 import type { Result } from './types' // 接口类型
import msgUtils from '@/plugins/modal' // 消息工具 import msgUtils from '@/plugins/modal' // 消息工具
import * as API_entpcoursefile from '@/api/education/entpcoursefile' // 相关api import * as API_entpcoursefile from '@/api/education/entpcoursefile' // 相关api

View File

@ -125,6 +125,7 @@ import {
User, User,
Switch, Switch,
More, More,
Material
} from '@icon-park/vue-next' } from '@icon-park/vue-next'
export interface Icons { export interface Icons {
@ -255,6 +256,7 @@ export const icons: Icons = {
IconUser: User, IconUser: User,
IconSwitch: Switch, IconSwitch: Switch,
IconMore: More, IconMore: More,
IconMaterial: Material
} }
export default { export default {

View File

@ -0,0 +1,173 @@
<template>
<header class="flex material-header">
<span>选择素材</span>
<i class="iconfont icon-guanbi" @click="onClose"></i>
</header>
<div class="flex material-list" v-loading="loading">
<div class="flex material-item" v-for="item in list" :key="item.id" >
<div class="flex">
<el-image :src="fileUrl(item)" class="img" />
<el-text truncated>{{ item.fileShowName }}</el-text>
</div>
<el-button type="primary" @click="onInsert(item)">插入</el-button>
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, computed } from 'vue';
import { sessionStore } from '@/utils/store'
import { getSmarttalkPage } from '@/api/file'
import { getFileSuffix, urlToBase64 } from '@/utils/ruoyi.js'
const emit = defineEmits(['insertMaterial', 'close'])
const curNode = reactive({})
let params = {
textbookId: '',
levelFirstId: '',
levelSecondId: null,
fileSource: '个人',
fileRoot: '备课',
orderByColumn: 'uploadTime',
isAsc: 'desc',
pageSize: 500
}
const suffixAry = [ 'jpeg','jpg','png','gif','mp3','mp4','avi','mov']
const videoSuffix = ['mp3','mp4','avi','mov']
const list = ref([])
const loading = ref(false)
const init = () => {
loading.value = true
getSmarttalkPage(params).then(res => {
loading.value = false
if(res.rows && res.rows.length){
//
list.value = res.rows.filter( item => suffixAry.indexOf(getFileSuffix(item.fileShowName)) != -1)
}
})
}
const fileUrl = computed(() => (item) =>{
if(videoSuffix.indexOf(getFileSuffix(item.fileShowName)) != -1){
return item.coverPic
}
else{
return item.fileFullPath
}
})
//
const onInsert = async (item) =>{
if(videoSuffix.indexOf(getFileSuffix(item.fileShowName)) != -1){
emit('insertMaterial',{ type: 'video', data: item.fileFullPath })
}
else{
const base64 = await urlToBase64(item.fileFullPath)
emit('insertMaterial',{ type: 'img', data: base64 })
}
}
const GetUrlParameters = (parameters) => {
let resData = "";
let url = document.location.toString();
let arrUrl = url.split("?");
//
if (arrUrl.length > 1) {
//
let parametersArr = arrUrl[1].split("&");
//
for (let i = 0; i <= parametersArr.length; i++) {
if (parametersArr[i]) {
//
let parameterStr = parametersArr[i].split("=");
if (parameters == parameterStr[0]) {
resData = parameterStr[1];
break;
}
}
}
}
return resData;
}
const proxyToBase64 = (url)=> {
const dourl = GetUrlParameters(url)
console.log(dourl,'dourl')
return
axios({
url: "/api/logo.png",
method: "get",
responseType: "blob",
}).then((res) => {
const reader = new FileReader();
reader.readAsDataURL(res.data);
reader.onload = () => {
console.log(reader.result);
};
});
}
//
const onClose = () =>{
emit('close')
}
onMounted(() => {
let data = sessionStore.get('subject.curNode')
Object.assign(curNode, data);
params.textbookId = curNode.rootid
if (curNode.parentNode) {
params.levelFirstId = curNode.parentNode.id
params.levelSecondId = curNode.id
}
else {
params.levelFirstId = curNode.id
}
init()
})
</script>
<style lang="scss" scoped>
.material-header {
font-size: 17px;
font-weight: bold;
margin-bottom: 20px;
justify-content: space-between;
align-items: center;
.icon-guanbi{
font-size: 20px;
cursor: pointer;
}
}
.material-list{
flex-direction: column;
min-height: 150px;
max-height: 500px;
overflow-y: auto
}
.material-item {
align-items: center;
margin-bottom: 10px;
font-size: 14px;
justify-content: space-between;
.img{
width: 100px;
height: 100px;
margin-right: 20px;
}
}
</style>

View File

@ -82,6 +82,7 @@
<IconVideoTwo class="handler-item" v-tooltip="'插入音视频'" /> <IconVideoTwo class="handler-item" v-tooltip="'插入音视频'" />
</Popover> </Popover>
<IconPreviewOpen class="handler-item" v-tooltip="'插入试题'" @click="classWorkTaskVisible = true" /> <IconPreviewOpen class="handler-item" v-tooltip="'插入试题'" @click="classWorkTaskVisible = true" />
<IconMaterial class="handler-item" v-tooltip="'插入素材'" @click="materiaVisible = true"/>
</div> </div>
<div class="right-handler"> <div class="right-handler">
@ -112,17 +113,22 @@
/> />
</Modal> </Modal>
<Modal
v-model:visible="classWorkTaskVisible" <el-dialog v-model="classWorkTaskVisible" append-to-body :show-close="false" width="70%">
:width="880"
>
<QuestToPPTist <QuestToPPTist
class="class-work-task-modal" class="class-work-task-modal"
@close="classWorkTaskVisible = false" @close="classWorkTaskVisible = false"
@update="data => { onhtml2canvas(data); classWorkTaskVisible = false }" @update="data => { onhtml2canvas(data); classWorkTaskVisible = false }"
/> />
</el-dialog>
<Modal
v-model:visible="materiaVisible"
:width="880">
<MaterialDialog @close="materiaVisible = false" @insertMaterial="insertMaterial"/>
</Modal> </Modal>
</div> </div>
</template> </template>
@ -149,6 +155,7 @@ 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 QuestToPPTist from '@/views/classTask/newClassTaskAssign/questToPPTist/index.vue' import QuestToPPTist from '@/views/classTask/newClassTaskAssign/questToPPTist/index.vue'
import MaterialDialog from './MaterialDialog.vue'
const mainStore = useMainStore() const mainStore = useMainStore()
const { creatingElement, creatingCustomShape, showSelectPanel, showSearchPanel, showNotesPanel } = storeToRefs(mainStore) const { creatingElement, creatingCustomShape, showSelectPanel, showSearchPanel, showNotesPanel } = storeToRefs(mainStore)
@ -200,6 +207,7 @@ const classWorkTaskVisible = ref(false)
const textTypeSelectVisible = ref(false) const textTypeSelectVisible = ref(false)
const shapeMenuVisible = ref(false) const shapeMenuVisible = ref(false)
const moreVisible = ref(false) const moreVisible = ref(false)
const materiaVisible = ref(false)
// //
const drawText = (vertical = false) => { const drawText = (vertical = false) => {
@ -246,6 +254,23 @@ const toggleSraechPanel = () => {
const toggleNotesPanel = () => { const toggleNotesPanel = () => {
mainStore.setNotesPanelState(!showNotesPanel.value) mainStore.setNotesPanelState(!showNotesPanel.value)
} }
//
interface MaterialParams {
type: string,
data: string
}
const insertMaterial = (item: MaterialParams) =>{
const { type, data } = item
if(type == 'video'){
createVideoElement(data)
}
else{
createImageElement(data)
}
materiaVisible.value = false
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -363,7 +388,7 @@ const toggleNotesPanel = () => {
} }
} }
.class-work-task-modal{ .class-work-task-modal{
height: 80vh; height: 70vh;
} }
@media screen and (width <= 1200px) { @media screen and (width <= 1200px) {

View File

@ -154,13 +154,15 @@ const topImgWrapperPositionStyle = computed(() => {
const topImgPositionStyle = computed(() => { const topImgPositionStyle = computed(() => {
const bottomWidth = imgPosition.value.width const bottomWidth = imgPosition.value.width
const bottomHeight = imgPosition.value.height const bottomHeight = imgPosition.value.height
console.log("底层图片位置大小(遮罩区域图片)", imgPosition.value)
const { top, left, width, height } = topImgWrapperPosition.value const { top, left, width, height } = topImgWrapperPosition.value
console.log("width", ((bottomWidth / width * 100) - (left * (100 / width))) + '%')
console.log("height", bottomHeight / height * 100 + '%')
return { return {
left: -left * (100 / width) + '%', left: -left * (100 / width) + '%',
top: -top * (100 / height) + '%', top: -top * (100 / height) + '%',
width: bottomWidth / width * 100 + '%', width: ((bottomWidth / width * 100) - (left * (100 / width))) + '%' ,
height: bottomHeight / height * 100 + '%', height: bottomHeight / height * 100 + '%',
} }
}) })
@ -228,6 +230,7 @@ const updateRange = () => {
width: parseInt(topImgPositionStyle.value.width), width: parseInt(topImgPositionStyle.value.width),
height: parseInt(topImgPositionStyle.value.height), height: parseInt(topImgPositionStyle.value.height),
} }
console.log('retPosition', retPosition)
const widthScale = 100 / retPosition.width const widthScale = 100 / retPosition.width
const heightScale = 100 / retPosition.height const heightScale = 100 / retPosition.height
@ -475,7 +478,7 @@ const scaleClipRange = (e: MouseEvent, type: OperateResizeHandlers) => {
isMouseDown = false isMouseDown = false
document.onmousemove = null document.onmousemove = null
document.onmouseup = null document.onmouseup = null
console.log('----------------------------------')
updateRange() updateRange()
setTimeout(() => isSettingClipRange.value = false, 0) setTimeout(() => isSettingClipRange.value = false, 0)

View File

@ -36,13 +36,13 @@ export const processList = (row, aloneOption=false) => {
row[i].method = jjj.method row[i].method = jjj.method
row[i].discuss = jjj.discuss row[i].discuss = jjj.discuss
//row[i].discusscollapse = false; //row[i].discusscollapse = false;
if (row[i].examdate !== null && row[i].examdate !== undefined) { if (row[i].examdate && row[i].examdate != "") {
row[i].examdate = row[i].examdate.substring(0, 10) row[i].examdate = row[i].examdate.substring(0, 10)
} }
// 具体题型数据结构处理 // 具体题型数据结构处理
if (row[i].worktype == '复合题') { if (row[i].worktype == '复合题') {
// 旧类型 // 复合题 - 旧格式
if (row[i].title.indexOf('!@#$%') !== -1) { if (row[i].title.indexOf('!@#$%') !== -1) {
// 1.选项解析替换 // 1.选项解析替换
const options = JSON.parse(row[i].workdesc) const options = JSON.parse(row[i].workdesc)
@ -129,7 +129,9 @@ export const processList = (row, aloneOption=false) => {
row[i].workanswerFormat = answer row[i].workanswerFormat = answer
} else { } else {
// 处理[题干显示] - 不再需要处理 // 复合题 - 现格式
// 处理[题干显示] - 不再需要处理(头部已处理)
// row[i].titleFormat = row[i].title; // 仅占位提示 // row[i].titleFormat = row[i].title; // 仅占位提示
/** /**
@ -222,6 +224,7 @@ export const processList = (row, aloneOption=false) => {
row[i].workanswerFormat = workAnswerHtml row[i].workanswerFormat = workAnswerHtml
} }
} else if ( } else if (
/** 主观题/非基础题(其中主要为第三方的各类解答题) */
row[i].worktype == '主观题' || row[i].worktype == '主观题' ||
(row[i].worktype !== '单选题' && (row[i].worktype !== '单选题' &&
row[i].worktype !== '多选题' && row[i].worktype !== '多选题' &&
@ -236,7 +239,7 @@ export const processList = (row, aloneOption=false) => {
row[i].workanswerFormat = JSON.parse(row[i].workanswer) row[i].workanswerFormat = JSON.parse(row[i].workanswer)
} }
} else { } else {
// 单选题|多选题|填空题|判断题|主观题?(待确认是否归在这里) // 基础题: 单选题|多选题|填空题|判断题|主观题?(待确认是否归在这里)
// 通用选项结构 ['ABC123','ABC123'] | ['ABC123','ABC123'] | [](填空题无选项) | [](判断题无选项) // 通用选项结构 ['ABC123','ABC123'] | ['ABC123','ABC123'] | [](填空题无选项) | [](判断题无选项)
let workDescArr = [] let workDescArr = []
if ( if (

View File

@ -258,16 +258,45 @@ export const getFileName = (filename) => {
return filename.replace(/\.[^/.]+$/, ""); return filename.replace(/\.[^/.]+$/, "");
} }
// 清除当前选中的教材 章节 相关信息
export const clearBookInfo = () =>{ /**
//当前选中的教材 * 根据图片的url转换对应的base64值
localStorage.removeItem('curBook') * @param { String } url http://xxxx/xxx.png
// 当前选中的节点 * @returns base64取值
localStorage.removeItem('curNode') */
// 所有章节单元数据 export const urlToBase64 = (url) => {
localStorage.removeItem('unitList')
// 所有教材数据 return new Promise((resolve, reject) => {
localStorage.removeItem('subjectList') if (!url) {
// 展开的节点 reject('请传入url内容')
localStorage.removeItem('defaultExpandedKeys') }
if (/\.(png|jpe?g|gif|svg)(\?.*)?$/.test(url)) {
// 图片地址
let image = new Image()
// 设置跨域问题
image.setAttribute('crossOrigin', 'anonymous')
// 图片地址
image.src = url +"?v=" + Math.random(); // 处理缓存,fix缓存bug,有缓存,浏览器会报错;
image.onload = () => {
let canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = image.width
canvas.height = image.height
ctx.drawImage(image, 0, 0, image.width, image.height)
// 获取图片后缀
const ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase()
// 转base64
const dataUrl = canvas.toDataURL(`image/${ext}`)
resolve(dataUrl || '')
canvas = null // 清除canvas元素
image = null // 清除img元素
}
} else {
// 非图片地址
reject('非(png/jpe?g/gif/svg等)图片地址');
}
})
} }

View File

@ -68,7 +68,7 @@ defineExpose({
.page-resource { .page-resource {
user-select: none; user-select: none;
height: calc(100% - 55px); height: 100%;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: nowrap; flex-wrap: nowrap;

View File

@ -16,6 +16,16 @@
<el-table-column align="center" prop="worktype" width="100"></el-table-column> <el-table-column align="center" prop="worktype" width="100"></el-table-column>
<el-table-column align="center" prop="worktag" width="120"></el-table-column> <el-table-column align="center" prop="worktag" width="120"></el-table-column>
</el-table> </el-table>
<!-- 分页-->
<div style="height: 48px;">
<el-pagination
v-show="paginationParams.total > 0"
v-model:page="paginationParams.pageNum"
v-model:limit="paginationParams.pageSize"
:total="paginationParams.total"
:style="{ position: 'relative', 'padding': '8px 20px 0 0' }"
@change="changePageNum" />
</div>
<!-- 试题详细信息 --> <!-- 试题详细信息 -->
<examDetailsDrawer ref="examDetailsDrawerRef"></examDetailsDrawer> <examDetailsDrawer ref="examDetailsDrawerRef"></examDetailsDrawer>
@ -54,11 +64,13 @@ const { proxy } = getCurrentInstance()
const props = defineProps({ const props = defineProps({
listExamQuestion: {type: Array}, listExamQuestion: {type: Array},
loading: {type: Boolean} loading: {type: Boolean},
paginationParams: {type: Object},
}) })
const activeExamInfoDrawer = ref(false); const activeExamInfoDrawer = ref(false);
const activeExam = ref({}); const activeExam = ref({});
const emit = defineEmits(['updatePageNum'])
const showExamAnalyseDrawer = (row) => { const showExamAnalyseDrawer = (row) => {
nextTick(() => { nextTick(() => {
@ -69,13 +81,17 @@ const showExamAnalyseDrawer = (row) => {
}) })
} }
const changePageNum = (pageNum) => {
emit('updatePageNum', pageNum);
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.table-main { .table-main {
width: 100%; width: 100%;
height: 100%; height: calc(100% - 48px);
text-align: left; text-align: left;
.main-title { .main-title {

View File

@ -47,10 +47,13 @@
</el-select> </el-select>
</div> </div>
<div :style="{'width': (viewportWidth - 400) + 'px','height': (viewportHeight-38) + 'px','overflow-y': 'auto'}"> <!-- <div :style="{'width': (viewportWidth - 400) + 'px','height': (viewportHeight-38) + 'px','overflow-y': 'auto'}"> -->
<div style="width: 100%; height: 100%; overflow-y: auto; border-radius: 10px;">
<examReview <examReview
:loading="loading" :loading="loading"
:listExamQuestion="listExamQuestion" :listExamQuestion="listExamQuestion"
:paginationParams="paginationParams"
@updatePageNum="updatePageNum"
v-if="curTask.viewkey=='真题回顾' " v-if="curTask.viewkey=='真题回顾' "
/> />
@ -77,12 +80,15 @@ import ChooseTextbook from '@/components/choose-textbook/index.vue'
import {listEntpcoursework, listEntpcourseworkNew} from '@/api/education/entpCourseWork' import {listEntpcoursework, listEntpcourseworkNew} from '@/api/education/entpCourseWork'
import { processList } from '@/hooks/useProcessList' import { processList } from '@/hooks/useProcessList'
import { JYApiListCT} from "@/utils/examQuestion/jyeoo" import { JYApiListCT} from "@/utils/examQuestion/jyeoo"
import useClassTaskStore from '@/store/modules/classTask'
import examReview from './container/examReview.vue' import examReview from './container/examReview.vue'
import pointAnalysis from './container/pointAnalysis.vue' import pointAnalysis from './container/pointAnalysis.vue'
import examMocks from './container/examMocks.vue' import examMocks from './container/examMocks.vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
const classTaskStore = useClassTaskStore();
const {proxy} = getCurrentInstance(); const {proxy} = getCurrentInstance();
const sourceStore = useResoureStore(); const sourceStore = useResoureStore();
const viewportHeight = ref(0); const viewportHeight = ref(0);
@ -91,6 +97,11 @@ const viewportWidth = ref(0);
const curNode = ref({}); const curNode = ref({});
// //
const listExamQuestion = ref([]); const listExamQuestion = ref([]);
const paginationParams = reactive({
pageNum: 1,
pageSize: 10,
total: 0,
});
const loading = ref(false); const loading = ref(false);
const curTask = reactive({ const curTask = reactive({
viewkey: '真题回顾', viewkey: '真题回顾',
@ -107,6 +118,22 @@ const listWorkType = ref([{
value: 0, value: 0,
}]); }]);
/**
* @desc: 翻页
* @return: {*}
* @param {*} pageNum
*/
const updatePageNum = (pageNum) => {
paginationParams.pageNum = pageNum;
queryExamQuestionByParams();
}
/**
* @desc: 具体获取试题及格式化
* @return: {*}
* @param {*} params
*/
const getCourseWorkList = async (params) => { const getCourseWorkList = async (params) => {
const res = await listEntpcourseworkNew(params); const res = await listEntpcourseworkNew(params);
if(res.data == null) { if(res.data == null) {
@ -115,7 +142,14 @@ const getCourseWorkList = async (params) => {
return; return;
} }
listExamQuestion.value = res.data; listExamQuestion.value = res.data;
// queryParams.total = res.total; //
const total = parseInt(res.msg)
if (!isNaN(total)) {
paginationParams.total = total;
} else {
console.error('无法将 res.msg 转换为数字');
paginationParams.total = 0; //
}
// //
processList(listExamQuestion.value); processList(listExamQuestion.value);
} }
@ -132,7 +166,8 @@ const getData = async (data) => {
loading.value = true; loading.value = true;
// 1. // 1.
getWorkType(data.node); //getWorkType(data.node);
listWorkType.value = classTaskStore.entpCourseWorkTypeList;
// 2. // 2.
curNode.value = data.node; curNode.value = data.node;
@ -166,6 +201,8 @@ const getData = async (data) => {
edusubject: curNode.value.edusubject, edusubject: curNode.value.edusubject,
edustage: curNode.value.edustage, edustage: curNode.value.edustage,
sectionName: curNode.value.itemtitle, sectionName: curNode.value.itemtitle,
currentPage: paginationParams.pageNum,
pageSize: paginationParams.pageSize,
} }
await getCourseWorkList(params); await getCourseWorkList(params);
loading.value = false; loading.value = false;
@ -181,6 +218,7 @@ const changeTaskView = (item, key) => {
curTask.viewkey = item; curTask.viewkey = item;
} }
// 使, classTaskStore
const getWorkType = async (data) => { const getWorkType = async (data) => {
const selName = `${data.edustage}${data.edusubject}` const selName = `${data.edustage}${data.edusubject}`
const curName = `${curNode.value.edustage}${curNode.value.edusubject}` const curName = `${curNode.value.edustage}${curNode.value.edusubject}`
@ -231,6 +269,8 @@ const queryExamQuestionByParams = async () => {
edusubject: curNode.value.edusubject, edusubject: curNode.value.edusubject,
edustage: curNode.value.edustage, edustage: curNode.value.edustage,
sectionName: curNode.value.itemtitle, sectionName: curNode.value.itemtitle,
currentPage: paginationParams.pageNum,
pageSize: paginationParams.pageSize,
} }
await getCourseWorkList(params); await getCourseWorkList(params);
loading.value = false; loading.value = false;

View File

@ -129,7 +129,6 @@ const dataset_id = ref('')
// //
const onSuccess = async (response) => { const onSuccess = async (response) => {
console.log(response, 'response')
let data = { let data = {
url: response.url, url: response.url,
dataset_id: dataset_id.value dataset_id: dataset_id.value
@ -174,13 +173,10 @@ const clickItem = (index, item) => {
const prevItem = reactive({}) const prevItem = reactive({})
const onPrevItem = (item) => { const onPrevItem = (item) => {
console.log(item)
Object.assign(prevItem, item) Object.assign(prevItem, item)
prevVisible.value = true prevVisible.value = true
} }
onMounted(() => { onMounted(() => {
let data = sessionStore.get('subject.curNode') let data = sessionStore.get('subject.curNode')
Object.assign(curNode, data); Object.assign(curNode, data);

View File

@ -0,0 +1,33 @@
<template>
<el-dialog v-model="open" v-bind="dAttrs">
<el-progress type="dashboard" v-bind="$attrs.pg" />
</el-dialog>
</template>
<script setup>
//
import { computed, useAttrs } from 'vue'
const attrs = useAttrs()
const props = defineProps({
visible: { //
type: Boolean,
default: false
},
})
//
const emit = defineEmits(['update:visible'])
// -
const open = computed({
get: () => props.visible,
set: val => emit('update:visible', val)
})
//
const dAttrs = computed(() => {
const attrsNew = { ...attrs }
delete attrsNew.pg
return attrsNew
})
</script>
<style lang="scss" scoped>
</style>

View File

@ -50,6 +50,7 @@
<EditDialog v-model="isEdit" :item="curItem" /> <EditDialog v-model="isEdit" :item="curItem" />
<AdjustDialog v-model="isAdjust" :item="curItem" /> <AdjustDialog v-model="isAdjust" :item="curItem" />
<PptDialog @add-success="addAiPPT" :dataList="resultList" v-model="pptDialog"/> <PptDialog @add-success="addAiPPT" :dataList="resultList" v-model="pptDialog"/>
<progress-dialog v-model:visible="pgDialog.visible" v-bind="pgDialog" />
</template> </template>
<script setup> <script setup>
@ -58,6 +59,7 @@ import { sessionStore } from '@/utils/store'
import emitter from '@/utils/mitt' import emitter from '@/utils/mitt'
import EditDialog from './edit-dialog.vue' import EditDialog from './edit-dialog.vue'
import AdjustDialog from './adjust-dialog.vue' import AdjustDialog from './adjust-dialog.vue'
import progressDialog from './progress-dialog.vue'
import { completion, tempResult } from '@/api/mode/index.js' import { completion, tempResult } from '@/api/mode/index.js'
// import { dataSetJson } from '@/utils/comm.js' // import { dataSetJson } from '@/utils/comm.js'
import * as commUtils from '@/utils/comm.js' import * as commUtils from '@/utils/comm.js'
@ -77,7 +79,22 @@ const resultList = ref([])
const courseObj = reactive({ const courseObj = reactive({
node: null, // node: null, //
}) })
const pgDialog = reactive({ // -
visible: false,
title: 'PPT解析中...',
width: 300,
showClose: false,
draggable: true,
beforeClose: done => {}, // -
pg: { // -
percentage: 0, //
color: [
{ color: '#1989fa', percentage: 50 }, //
{ color: '#e6a23c', percentage: 80 }, //
{ color: '#5cb87a', percentage: 100 }, // 绿
]
}
})
emitter.on('changeMode', (item) => { emitter.on('changeMode', (item) => {
console.log(item, 'item') console.log(item, 'item')
resultList.value = item.child resultList.value = item.child
@ -115,6 +132,8 @@ const params = reactive(
const addAiPPT = async(res) => { const addAiPPT = async(res) => {
let node = courseObj.node let node = courseObj.node
if (!node) return msgUtils.msgWarning('请选择章节?') if (!node) return msgUtils.msgWarning('请选择章节?')
pgDialog.visible = true
pgDialog.pg.percentage = 0
//TODO resPPT //TODO resPPT
const params = { evalid: node.id, edituserid: userStore.id, pageSize: 1 } const params = { evalid: node.id, edituserid: userStore.id, pageSize: 1 }
const resEnpt = await HTTP_SERVER_API('getCourseList', params) const resEnpt = await HTTP_SERVER_API('getCourseList', params)
@ -129,10 +148,16 @@ const addAiPPT = async(res) => {
const resPptJson = await PPTXFileToJson(buffer) const resPptJson = await PPTXFileToJson(buffer)
const { def, slides, ...content } = resPptJson const { def, slides, ...content } = resPptJson
// || 线 // || 线
let completed = 0
const total = slides.length
for( let o of slides ) { for( let o of slides ) {
completed++
await toRousrceUrl(o) await toRousrceUrl(o)
//
pgDialog.pg.percentage = Math.floor(completed / total * 100)
} }
// return pgDialog.pg.percentage = 0
pgDialog.visible = false
// ppt- // ppt-
const p_params = {parentContent: JSON.stringify(content)} const p_params = {parentContent: JSON.stringify(content)}
const parentid = await HTTP_SERVER_API('addEntpcoursefile', p_params) const parentid = await HTTP_SERVER_API('addEntpcoursefile', p_params)