| | |
| | | import { tokenKey } from "@/assets/js/config"; |
| | | import getPublicImage from "@/assets/js/middleGround/tool"; |
| | | // 获取题目列表 |
| | | const getQuestionList = async (page, questionList, activeBook) => { |
| | | const getQuestionList = async ( |
| | | page, |
| | | questionList, |
| | | activeBook, |
| | | bookQuestionsList |
| | | ) => { |
| | | if (!bookQuestionsList || !Array.isArray(bookQuestionsList) || bookQuestionsList.length === 0) { |
| | | console.warn("getQuestionList: 传入的 bookQuestionsList 为空或无效,将返回空列表。"); |
| | | return []; |
| | | } |
| | | const token = localStorage.getItem(tokenKey); |
| | | let collectList = []; |
| | | if (token) collectList = await getCollectList(activeBook); |
| | |
| | | catalogName: "简答题", |
| | | infoList: [], |
| | | }, |
| | | { |
| | | catalogName: "材料题", |
| | | infoList: [], |
| | | }, |
| | | ]; |
| | | let singleChoiceArr = []; // 单选 |
| | | let judgeArr = []; // 判断 |
| | | let shortArr = []; // 简答 |
| | | let multipleChoiceArr = []; // 多选 |
| | | let completionArr = []; // 填空 |
| | | let materialArr = []; // 材料 |
| | | // 11 |
| | | for (let qindex = 0; qindex < questionList.length; qindex++) { |
| | | const qitem = questionList[qindex]; |
| | | let query = { |
| | | storeInfo: activeBook.storeRefcode, |
| | | path: "*", |
| | | cmsPath: activeBook.rootCmsItemId, |
| | | cmsType: "*", |
| | | productId: activeBook.bookId, |
| | | queryType: "*", |
| | | itemIds: qitem + "", |
| | | itemFields: { |
| | | Embedded_QuestionBank_Stem: [], |
| | | Embedded_QuestionBank_AnalysisCon: [], |
| | | Embedded_QuestionBank_Answer: [], |
| | | Embedded_QuestionBank_Option: [], |
| | | Embedded_QuestionBank_QuestionType: [], |
| | | Embedded_QuestionBank_StemStyle: [], |
| | | Embedded_QuestionBank_OptionStyle: [], |
| | | Embedded_QuestionBank_KnowledgePoint: [], |
| | | Embedded_QuestionBank_Difficulty: [], |
| | | }, |
| | | for (let bindex = 0; bindex < questionList.length; bindex++) { |
| | | const qitem = questionList[bindex]; |
| | | let foundItems = bookQuestionsList.find((citem) => citem.id == qitem); |
| | | if ( |
| | | foundItems && |
| | | foundItems.Embedded_QuestionBank_QuestionType == "material" |
| | | ) { |
| | | foundItems.childList = bookQuestionsList.filter( |
| | | (ditem) => |
| | | ditem.productLinkInfo[0].LinkPath == foundItems.productLinkPath |
| | | ); |
| | | } |
| | | |
| | | let foundlist = []; |
| | | foundlist.push(foundItems); |
| | | if (foundlist.length > 0 && foundlist != undefined) { |
| | | foundlist.forEach((item, index) => { |
| | | const questionObj = handleQuestion(item, index + 1, oldList, collectList); |
| | | if (item.Embedded_QuestionBank_QuestionType == "judge") { |
| | | questionObj.type = "判断题"; |
| | | judgeArr.push(questionObj); |
| | | } else if (item.Embedded_QuestionBank_QuestionType == "singleChoice") { |
| | | questionObj.type = "单选题"; |
| | | singleChoiceArr.push(questionObj); |
| | | } else if ( |
| | | item.Embedded_QuestionBank_QuestionType == "multipleChoice" |
| | | ) { |
| | | questionObj.type = "多选题"; |
| | | multipleChoiceArr.push(questionObj); |
| | | } else if (item.Embedded_QuestionBank_QuestionType == "completion") { |
| | | questionObj.type = "填空题"; |
| | | completionArr.push(questionObj); |
| | | } else if (item.Embedded_QuestionBank_QuestionType == "shortAnswer") { |
| | | questionObj.type = "简答题"; |
| | | shortArr.push(questionObj); |
| | | } else if (item.Embedded_QuestionBank_QuestionType == "material") { |
| | | questionObj.type = "材料题"; |
| | | materialArr.push(questionObj); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | |
| | | // for (let qindex = 0; qindex < questionList.length; qindex++) { |
| | | // const qitem = questionList[qindex]; |
| | | // let query = { |
| | | // storeInfo: activeBook.storeRefcode, |
| | | // path: "*", |
| | | // cmsPath: activeBook.rootCmsItemId, |
| | | // cmsType: "*", |
| | | // productId: activeBook.bookId, |
| | | // queryType: "*", |
| | | // itemIds: qitem + "", |
| | | // itemFields: { |
| | | // Embedded_QuestionBank_Stem: [], |
| | | // Embedded_QuestionBank_AnalysisCon: [], |
| | | // Embedded_QuestionBank_Answer: [], |
| | | // Embedded_QuestionBank_Option: [], |
| | | // Embedded_QuestionBank_QuestionType: [], |
| | | // Embedded_QuestionBank_StemStyle: [], |
| | | // Embedded_QuestionBank_OptionStyle: [], |
| | | // Embedded_QuestionBank_KnowledgePoint: [], |
| | | // Embedded_QuestionBank_Difficulty: [], |
| | | // }, |
| | | // }; |
| | | // const res = await MG.store.getProductDetail(query); |
| | | // console.log(res.datas.cmsDatas[0].datas, "材料题"); |
| | | // if (!res.datas) return false; |
| | | // res.datas.cmsDatas[0].datas.forEach((item, index) => { |
| | | // let oldObj = {}; |
| | | // if (oldList) { |
| | | // oldObj = oldList.find((item) => item.id == qitem); |
| | | // } |
| | | // const questionObj = { |
| | | // number: index + 1, // 题号 |
| | | // id: item.id, |
| | | // stem: |
| | | // item.Embedded_QuestionBank_QuestionType == "completion" |
| | | // ? JSON.parse(item.Embedded_QuestionBank_Stem) |
| | | // .stemTxt.replaceAll("<vacancy>", ",input,") |
| | | // .split(",") |
| | | // : JSON.parse(item.Embedded_QuestionBank_Stem), // 题干 |
| | | // answer: item.Embedded_QuestionBank_Answer, // 答案 |
| | | // option: item.Embedded_QuestionBank_Option |
| | | // ? JSON.parse(item.Embedded_QuestionBank_Option) |
| | | // : "", // 选择题选项 |
| | | // analysisCon: item.Embedded_QuestionBank_AnalysisCon, // 解析 |
| | | // questionType: item.Embedded_QuestionBank_QuestionType, // 题型 |
| | | // optionStyle: item.Embedded_QuestionBank_OptionStyle, // 选项显示类型 |
| | | // stemStyle: item.Embedded_QuestionBank_StemStyle, // 题干显示类型 |
| | | // difficulty: item.Embedded_QuestionBank_Difficulty |
| | | // ? 4 - item.Embedded_QuestionBank_Difficulty |
| | | // : 0, // 难度等级 |
| | | // userAnswer: oldObj |
| | | // ? oldObj.userAnswer |
| | | // : item.Embedded_QuestionBank_QuestionType == "completion" || |
| | | // item.Embedded_QuestionBank_QuestionType == "multipleChoice" |
| | | // ? [] |
| | | // : "", |
| | | // isSubmit: false, // 查看解析 |
| | | // isRight: null, // 是否正确 |
| | | // isComplete: false, |
| | | // isCollect: collectList.indexOf(qitem) > -1 ? true : false, |
| | | // isUnfold: "", |
| | | // }; |
| | | |
| | | // console.log(item, "材料题"); |
| | | |
| | | // // 多选和填空答案肯为数组,要转换JSON格式 |
| | | // if ( |
| | | // questionObj.questionType == "completion" || |
| | | // questionObj.questionType == "multipleChoice" |
| | | // ) { |
| | | // try { |
| | | // questionObj.answer = JSON.parse(questionObj.answer); |
| | | // } catch (error) { |
| | | // questionObj.answer = item.Embedded_QuestionBank_Answer; |
| | | // } |
| | | // } |
| | | // // 填空题改造 |
| | | // if (questionObj.questionType == "completion") { |
| | | // let index = 0; |
| | | // for (let i = 0; i < questionObj.stem.length; i++) { |
| | | // const item = questionObj.stem[i]; |
| | | // if (item == "input") { |
| | | // questionObj.stem[i] = { |
| | | // num: index, |
| | | // data: "input", |
| | | // }; |
| | | // questionObj.userAnswer[index] = ""; |
| | | // index++; |
| | | // } |
| | | // } |
| | | // } |
| | | // // 获取图片 |
| | | // if ( |
| | | // questionObj.stemStyle == "Image" || |
| | | // questionObj.stemStyle == "TxtAndImage" |
| | | // ) { |
| | | // questionObj.stem.stemImage = getPublicImage( |
| | | // questionObj.stem.stemImage, |
| | | // 150 |
| | | // ); |
| | | // } |
| | | // if ( |
| | | // questionObj.optionStyle == "Image" || |
| | | // questionObj.optionStyle == "TxtAndImage" |
| | | // ) { |
| | | // questionObj.option.forEach((optionItem) => { |
| | | // if (optionItem.img) |
| | | // optionItem.img = getPublicImage(optionItem.img, 150); |
| | | // }); |
| | | // } |
| | | // // 题干富文本处理 |
| | | // if (questionObj.stemStyle == "RichText") { |
| | | // // questionObj.option.txt = '' |
| | | // questionObj.stem.stemTxt = questionObj.stem.stemTxt |
| | | // .replace( |
| | | // /\<img/gi, |
| | | // '<img style="max-width: 300rpx !important;object-fit: contain;" class="stem-rich-img" ' |
| | | // ) |
| | | // .replace(/\<p/gi, '<p class="stem-rich-p"') |
| | | // .replace("../file", process.env.VUE_APP_API_URL + "/file"); |
| | | // } |
| | | // // 选项富文本处理 |
| | | // if ( |
| | | // questionObj.optionStyle == "RichText" && |
| | | // (questionObj.questionType == "singleChoice" || |
| | | // questionObj.questionType == "judge" || |
| | | // questionObj.questionType == "multipleChoice") |
| | | // ) { |
| | | // questionObj.option.forEach((item) => { |
| | | // if (item.txt) |
| | | // item.txt = item.txt |
| | | // .replace(/\<img/gi, '<img class="option-rich-img"') |
| | | // .replace(/\<p/gi, '<p class="stem-rich-p"') |
| | | // .replace("../file", process.env.VUE_APP_API_URL + "/file"); |
| | | // }); |
| | | // } |
| | | // // 解析富文本处理 |
| | | // if ( |
| | | // questionObj.analysisCon && |
| | | // typeof questionObj.analysisCon == "string" |
| | | // ) { |
| | | // questionObj.analysisCon = questionObj.analysisCon.replace( |
| | | // /\<img/gi, |
| | | // '<img style="max-width: 300rpx !important;object-fit: contain;" class="stem-rich-img" ' |
| | | // ); |
| | | // } |
| | | // // 听力题修改 |
| | | // // if (questionObj.questionType == 'singleChoice') { |
| | | // // const src = this.extractSourceSrc(questionObj.stem.stemTxt) |
| | | // // if (src) { |
| | | // // questionObj.src = src |
| | | // // questionObj.stem.stemTxt = this.removeVideoAndAudioTags(questionObj.stem.stemTxt) |
| | | // // } |
| | | // // } |
| | | |
| | | // if (item.Embedded_QuestionBank_QuestionType == "judge") { |
| | | // questionObj.type = "判断题"; |
| | | // judgeArr.push(questionObj); |
| | | // } else if (item.Embedded_QuestionBank_QuestionType == "singleChoice") { |
| | | // questionObj.type = "单选题"; |
| | | // singleChoiceArr.push(questionObj); |
| | | // } else if (item.Embedded_QuestionBank_QuestionType == "multipleChoice") { |
| | | // questionObj.type = "多选题"; |
| | | // multipleChoiceArr.push(questionObj); |
| | | // } else if (item.Embedded_QuestionBank_QuestionType == "completion") { |
| | | // questionObj.type = "填空题"; |
| | | // completionArr.push(questionObj); |
| | | // } else if (item.Embedded_QuestionBank_QuestionType == "shortAnswer") { |
| | | // questionObj.type = "简答题"; |
| | | // shortArr.push(questionObj); |
| | | // } else if (item.Embedded_QuestionBank_QuestionType == "material") { |
| | | // questionObj.type = "材料题"; |
| | | // materialArr.push(questionObj); |
| | | // } |
| | | // }); |
| | | // } |
| | | // 22 |
| | | cardList[0].infoList = singleChoiceArr; |
| | | cardList[1].infoList = judgeArr; |
| | | cardList[2].infoList = multipleChoiceArr; |
| | | cardList[3].infoList = completionArr; |
| | | cardList[4].infoList = shortArr; |
| | | cardList[5].infoList = materialArr; |
| | | for (let index = 0; index < cardList.length; index++) { |
| | | const item = cardList[index]; |
| | | for (let cindex = 0; cindex < item.infoList.length; cindex++) { |
| | | const citem = item.infoList[cindex]; |
| | | citem.number = cindex + 1; |
| | | } |
| | | } |
| | | return cardList.filter((item) => item.infoList.length > 0); |
| | | }; |
| | | const res = await MG.store.getProductDetail(query); |
| | | if (!res.datas) return false; |
| | | res.datas.cmsDatas[0].datas.forEach((item, index) => { |
| | | |
| | | // 处理题目逻辑 |
| | | const handleQuestion = (item, index, oldList, collectList) => { |
| | | // 注意:这里的 qitem 应该是 item.id,我假设你原来的代码里 qitem 就是当前 item 的 id |
| | | const qitem = item.id; |
| | | let oldObj = {}; |
| | | if (oldList) { |
| | | oldObj = oldList.find((item) => item.id == qitem); |
| | | oldObj = oldList.find((oldItem) => oldItem.id == qitem); |
| | | } |
| | | // 1. 构建 questionObj 的基础结构 |
| | | const questionObj = { |
| | | number: index + 1, // 题号 |
| | | id: item.id, |
| | |
| | | isCollect: collectList.indexOf(qitem) > -1 ? true : false, |
| | | isUnfold: "", |
| | | }; |
| | | // 多选和填空答案肯为数组,要转换JSON格式 |
| | | |
| | | |
| | | |
| | | // 2. 处理多选和填空题的答案(JSON格式转换) |
| | | if ( |
| | | questionObj.questionType == "completion" || |
| | | questionObj.questionType == "multipleChoice" |
| | |
| | | try { |
| | | questionObj.answer = JSON.parse(questionObj.answer); |
| | | } catch (error) { |
| | | questionObj.answer = item.Embedded_QuestionBank_Answer; |
| | | console.error("解析答案失败:", error, item); |
| | | questionObj.answer = item.Embedded_QuestionBank_Answer; // 解析失败则保留原样 |
| | | } |
| | | } |
| | | // 填空题改造 |
| | | |
| | | // 3. 填空题改造 |
| | | if (questionObj.questionType == "completion") { |
| | | let index = 0; |
| | | let inputIndex = 0; // 使用更具描述性的变量名 |
| | | for (let i = 0; i < questionObj.stem.length; i++) { |
| | | const item = questionObj.stem[i]; |
| | | if (item == "input") { |
| | | const stemPart = questionObj.stem[i]; // 使用更具描述性的变量名 |
| | | if (stemPart == "input") { |
| | | questionObj.stem[i] = { |
| | | num: index, |
| | | num: inputIndex, |
| | | data: "input", |
| | | }; |
| | | questionObj.userAnswer[index] = ""; |
| | | index++; |
| | | // 确保 userAnswer 是数组且长度足够 |
| | | if (!Array.isArray(questionObj.userAnswer)) { |
| | | questionObj.userAnswer = []; |
| | | } |
| | | questionObj.userAnswer[inputIndex] = ""; |
| | | inputIndex++; |
| | | } |
| | | } |
| | | } |
| | | // 获取图片 |
| | | |
| | | // 4. 材料题处理 (核心递归点) |
| | | if (questionObj.questionType == "material" && Array.isArray(item.childList)) { |
| | | |
| | | // 遍历子题目列表,并对每一个子项递归调用 processQuestionItem |
| | | questionObj.childList = item.childList.map((childItem, childIndex) => { |
| | | // 子题目通常不需要 oldList 和 collectList,但为了逻辑统一,可以传入 |
| | | // 如果子题目也需要独立的作答状态和收藏状态,则需要调整 oldList 和 collectList 的结构 |
| | | // 这里假设它们不需要,或者由父级材料题统一管理 |
| | | return handleQuestion(childItem, childIndex + 1, null, []); |
| | | }); |
| | | } |
| | | |
| | | // 5. 获取图片 |
| | | if ( |
| | | questionObj.stemStyle == "Image" || |
| | | questionObj.stemStyle == "TxtAndImage" |
| | | ) { |
| | | // 确保 stem 是一个对象且有 stemImage 属性 |
| | | if (questionObj.stem && typeof questionObj.stem === 'object' && questionObj.stem.stemImage) { |
| | | questionObj.stem.stemImage = getPublicImage( |
| | | questionObj.stem.stemImage, |
| | | 150 |
| | | ); |
| | | } |
| | | } |
| | | if ( |
| | | questionObj.optionStyle == "Image" || |
| | |
| | | optionItem.img = getPublicImage(optionItem.img, 150); |
| | | }); |
| | | } |
| | | // 题干富文本处理 |
| | | |
| | | // 6. 题干富文本处理 |
| | | if (questionObj.stemStyle == "RichText") { |
| | | // questionObj.option.txt = '' |
| | | // 确保 stem 是一个对象且有 stemTxt 属性 |
| | | if (questionObj.stem && typeof questionObj.stem === 'object' && questionObj.stem.stemTxt) { |
| | | questionObj.stem.stemTxt = questionObj.stem.stemTxt |
| | | .replace( |
| | | /\<img/gi, |
| | |
| | | .replace(/\<p/gi, '<p class="stem-rich-p"') |
| | | .replace("../file", process.env.VUE_APP_API_URL + "/file"); |
| | | } |
| | | // 选项富文本处理 |
| | | } |
| | | |
| | | // 7. 选项富文本处理 |
| | | if ( |
| | | questionObj.optionStyle == "RichText" && |
| | | (questionObj.questionType == "singleChoice" || |
| | | questionObj.questionType == "judge" || |
| | | questionObj.questionType == "multipleChoice") |
| | | ) { |
| | | questionObj.option.forEach((item) => { |
| | | if (item.txt) |
| | | item.txt = item.txt |
| | | questionObj.option.forEach((optItem) => { // 使用更具描述性的变量名 |
| | | if (optItem.txt) |
| | | optItem.txt = optItem.txt |
| | | .replace(/\<img/gi, '<img class="option-rich-img"') |
| | | .replace(/\<p/gi, '<p class="stem-rich-p"') |
| | | .replace("../file", process.env.VUE_APP_API_URL + "/file"); |
| | | }); |
| | | } |
| | | // 解析富文本处理 |
| | | |
| | | // 8. 解析富文本处理 |
| | | if ( |
| | | questionObj.analysisCon && |
| | | typeof questionObj.analysisCon == "string" |
| | |
| | | '<img style="max-width: 300rpx !important;object-fit: contain;" class="stem-rich-img" ' |
| | | ); |
| | | } |
| | | // 听力题修改 |
| | | // if (questionObj.questionType == 'singleChoice') { |
| | | // const src = this.extractSourceSrc(questionObj.stem.stemTxt) |
| | | // if (src) { |
| | | // questionObj.src = src |
| | | // questionObj.stem.stemTxt = this.removeVideoAndAudioTags(questionObj.stem.stemTxt) |
| | | // } |
| | | // } |
| | | if (item.Embedded_QuestionBank_QuestionType == "judge") { |
| | | questionObj.type = "判断题"; |
| | | judgeArr.push(questionObj); |
| | | } else if (item.Embedded_QuestionBank_QuestionType == "singleChoice") { |
| | | questionObj.type = "单选题"; |
| | | singleChoiceArr.push(questionObj); |
| | | } else if (item.Embedded_QuestionBank_QuestionType == "multipleChoice") { |
| | | questionObj.type = "多选题"; |
| | | multipleChoiceArr.push(questionObj); |
| | | } else if (item.Embedded_QuestionBank_QuestionType == "completion") { |
| | | questionObj.type = "填空题"; |
| | | completionArr.push(questionObj); |
| | | } else if (item.Embedded_QuestionBank_QuestionType == "shortAnswer") { |
| | | questionObj.type = "简答题"; |
| | | shortArr.push(questionObj); |
| | | } |
| | | }); |
| | | } |
| | | // 22 |
| | | cardList[0].infoList = singleChoiceArr; |
| | | cardList[1].infoList = judgeArr; |
| | | cardList[2].infoList = multipleChoiceArr; |
| | | cardList[3].infoList = completionArr; |
| | | cardList[4].infoList = shortArr; |
| | | for (let index = 0; index < cardList.length; index++) { |
| | | const item = cardList[index]; |
| | | for (let cindex = 0; cindex < item.infoList.length; cindex++) { |
| | | const citem = item.infoList[cindex]; |
| | | citem.number = cindex + 1; |
| | | } |
| | | } |
| | | return cardList.filter((item) => item.infoList.length > 0); |
| | | |
| | | return questionObj; |
| | | }; |
| | | |
| | | // 获取收藏列表 |
| | | const getCollectList = async (activeBook) => { |
| | | const allCollect = [ |