试卷相关

master
yujialong 4 months ago
parent 88781b9d98
commit 891c9b19a1
  1. 10
      package-lock.json
  2. 2
      package.json
  3. 8
      public/index.html
  4. 1
      src/api/index.js
  5. 46
      src/components/upload/config.js
  6. 14
      src/components/upload/index.vue
  7. 11
      src/components/upload/upload.js
  8. 39
      src/pages/testPaper/detail/auto.vue
  9. 27
      src/pages/testPaper/detail/index.vue
  10. 2
      src/pages/testPaper/detail/manual.vue
  11. 6
      src/pages/testPaperLibrary/index.vue

10
package-lock.json generated

@ -3885,6 +3885,11 @@
"randomfill": "^1.0.3" "randomfill": "^1.0.3"
} }
}, },
"crypto-js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"css": { "css": {
"version": "2.2.4", "version": "2.2.4",
"resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
@ -9561,6 +9566,11 @@
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
}, },
"jsencrypt": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.3.2.tgz",
"integrity": "sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A=="
},
"jsesc": { "jsesc": {
"version": "2.5.2", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",

@ -12,6 +12,7 @@
"ali-oss": "^6.20.0", "ali-oss": "^6.20.0",
"axios": "^0.18.0", "axios": "^0.18.0",
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.12", "dayjs": "^1.11.12",
"decimal.js": "^10.4.3", "decimal.js": "^10.4.3",
"echarts": "^4.8.0", "echarts": "^4.8.0",
@ -19,6 +20,7 @@
"element-ui": "^2.13.0", "element-ui": "^2.13.0",
"image-conversion": "^2.1.1", "image-conversion": "^2.1.1",
"js-cookie": "^2.2.1", "js-cookie": "^2.2.1",
"jsencrypt": "^3.3.2",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mavon-editor": "^2.6.17", "mavon-editor": "^2.6.17",
"postcss-px2rem": "^0.3.0", "postcss-px2rem": "^0.3.0",

@ -13,9 +13,13 @@
</noscript> </noscript>
<div id="app"></div> <div id="app"></div>
<script src='./static/ueditor/ueditor.config.js?v=3'></script> <!-- <script src='./static/ueditor/ueditor.config.js?v=3'></script>
<script src='./static/ueditor/ueditor.all.js?v=3'></script> <script src='./static/ueditor/ueditor.all.js?v=3'></script>
<script src='./static/ueditor/lang/zh-cn/zh-cn.js'></script> <script src='./static/ueditor/lang/zh-cn/zh-cn.js'></script> -->
<script src='./static/dist/ueditor.config.js?v=3'></script>
<script src='./static/dist/ueditor.all.js?v=3'></script>
<!-- <script src='./static/ueditor1/kityformula-plugin/addKityFormulaDialog.js'></script> <!-- <script src='./static/ueditor1/kityformula-plugin/addKityFormulaDialog.js'></script>
<script src='./static/ueditor1/kityformula-plugin/getKfContent.js'></script> <script src='./static/ueditor1/kityformula-plugin/getKfContent.js'></script>
<script src='./static/ueditor1/kityformula-plugin/defaultFilterFix.js'></script> --> <script src='./static/ueditor1/kityformula-plugin/defaultFilterFix.js'></script> -->

@ -2,6 +2,7 @@ import Setting from '@/setting'
const { apiBaseURL: host } = Setting const { apiBaseURL: host } = Setting
export default { export default {
encrypt: `/nakadai/data/encrypt`,
queryProfessional: `/exam/exam/professional/queryProfessional`, queryProfessional: `/exam/exam/professional/queryProfessional`,
categoriesDel: `/exam/question/bank/categories/batchDeletion`, categoriesDel: `/exam/question/bank/categories/batchDeletion`,

@ -1,15 +1,41 @@
/** /**
* 阿里云oss配置 * 阿里云oss配置
* */ * */
import { get } from '@/plugins/requests/index.js'
import api from '@/api'
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
export default { const A = (key, encryptedData) => {
// oss账号信息 const keyHex = CryptoJS.enc.Base64.parse(key)
config: { const decrypted = CryptoJS.AES.decrypt(encryptedData, keyHex, {
region: 'oss-cn-shenzhen', mode: CryptoJS.mode.ECB,
accessKeyId: 'LTAI4FzqQHnk4rozqLZ8jCNj', padding: CryptoJS.pad.Pkcs7
accessKeySecret: 'mveW7B1OyFoKUkHm8WsxmrjHmkJWHq', })
bucket: 'huoran' return decrypted.toString(CryptoJS.enc.Utf8)
}, }
// 上传成功url前置部分(成功回调没有返回url)
preUrl: 'https://huoran.oss-cn-shenzhen.aliyuncs.com/' const R = (encryptedKey, privateKey) => {
const decrypt = new JSEncrypt()
decrypt.setPrivateKey(privateKey)
const decryptedKey = decrypt.decrypt(encryptedKey)
return decryptedKey
}
export default async function () {
try {
const res = await get(api.encrypt)
const RE = A(R(res.encryptedKey, res.privateKey), res.encryptedData).split('/')
return {
// oss账号信息
config: {
region: 'oss-cn-shenzhen',
accessKeyId: RE[0],
accessKeySecret: RE[1],
bucket: 'huoran'
},
// 上传成功url前置部分(成功回调没有返回url)
preUrl: 'https://huoran.oss-cn-shenzhen.aliyuncs.com/'
}
} catch (e) { }
} }

@ -1,5 +1,5 @@
<template> <template>
<el-upload :disabled="uploading" :accept="accept" :before-upload="beforeUpload" :on-remove="onRemove" <el-upload :disabled="uploading"  :accept="accept" :before-upload="beforeUpload" :on-remove="onRemove"
:on-error="uploadError" :limit="limit" action="" :on-exceed="handleExceed" :show-file-list="showFiles" :on-error="uploadError" :limit="limit" action="" :on-exceed="handleExceed" :show-file-list="showFiles"
:file-list="fileList" :http-request="handleRequest" name="file"> :file-list="fileList" :http-request="handleRequest" name="file">
<slot name="trigger"> <slot name="trigger">
@ -62,7 +62,8 @@ export default {
client: null, client: null,
uploading: false, uploading: false,
uploadProgress: 0, uploadProgress: 0,
showFiles: this.showFileList showFiles: this.showFileList,
Oss: {},
}; };
}, },
mounted () { mounted () {
@ -70,8 +71,9 @@ export default {
}, },
methods: { methods: {
// oss // oss
initOss () { async initOss () {
this.client = new OSS(OssConfig.config) this.Oss = await OssConfig()
this.client = new OSS(this.Oss.config)
}, },
// //
beforeUpload (file) { beforeUpload (file) {
@ -94,14 +96,13 @@ export default {
this.uploadProgress = 0 this.uploadProgress = 0
this.uploading = true this.uploading = true
this.showFiles = false this.showFiles = false
// oss // oss
const { name } = await this.client.multipartUpload(Date.now() + '.' + Util.getFileExt(file.name), file, { const { name } = await this.client.multipartUpload(Date.now() + '.' + Util.getFileExt(file.name), file, {
progress: this.handleProgress progress: this.handleProgress
}); });
this.uploading = false this.uploading = false
const url = OssConfig.preUrl + name const url = this.Oss.preUrl + name
this.changeFileList && this.$emit('update:fileList', [ this.changeFileList && this.$emit('update:fileList', [
...this.fileList, ...this.fileList,
{ {
@ -109,6 +110,7 @@ export default {
url url
} }
]) ])
this.showFiles = true this.showFiles = true
this.$emit('onSuccess', { this.$emit('onSuccess', {
format: Util.getFileExt(file.name), format: Util.getFileExt(file.name),

@ -5,10 +5,13 @@ import OssConfig from './config'
import Util from '@/libs/util' import Util from '@/libs/util'
let client = null let client = null
let Oss
// 初始化oss // 初始化oss
const initOss = () => { const initOss = async () => {
if (!client) client = new OSS(OssConfig.config) Oss = await OssConfig()
if (!client) client = new OSS(Oss.config)
} }
initOss()
export default { export default {
// 上传文件 // 上传文件
@ -21,7 +24,7 @@ export default {
resolve({ resolve({
format: Util.getFileExt(file.name), format: Util.getFileExt(file.name),
name: file.name, name: file.name,
url: OssConfig.preUrl + res.name, url: Oss.preUrl + res.name,
size: file.size, size: file.size,
}) })
} catch (error) { } catch (error) {
@ -32,6 +35,6 @@ export default {
// 删除文件(传完整url,不是没有https的name,因为很多接口没有存name,只存url,所以统一使用url) // 删除文件(传完整url,不是没有https的name,因为很多接口没有存name,只存url,所以统一使用url)
async del (url) { async del (url) {
initOss() initOss()
await client.delete(url.replace(OssConfig.preUrl, '')); await client.delete(url.replace(Oss.preUrl, ''));
} }
} }

@ -186,6 +186,7 @@ export default {
const { list } = await this.$post(this.api.questionBankStructureLevel, { const { list } = await this.$post(this.api.questionBankStructureLevel, {
keyword: this.quesBankKeyword, keyword: this.quesBankKeyword,
createSource: 1, createSource: 1,
status: 1,
}) })
this.quesBanks = list this.quesBanks = list
} catch (e) { } } catch (e) { }
@ -291,20 +292,33 @@ export default {
list.forEach(e => { list.forEach(e => {
const total = e.questionNum const total = e.questionNum
// if (target === 1) {
let totalWeight = Decimal(total).mul(Decimal(target)).toNumber() let already = 0
const maxCount = Math.ceil(total / 4) this.$set(e, 'basicDifficulty', Math.floor(total * 0.6))
for (let i = 0; i < 4; i++) { this.$set(e, 'normalDifficulty', Math.floor(total * 0.3))
if (totalWeight > 0) { this.$set(e, 'hardDifficulty', Math.floor(total * 0.1))
const random = Math.floor(Math.random() * maxCount) + 1 this.$set(e, 'veryHardDifficulty', 0)
const weight = difficultyWeights[i] already = Decimal(already).add(e.basicDifficulty).add(e.normalDifficulty).add(e.hardDifficulty).add(e.veryHardDifficulty).toNumber()
totalWeight = Decimal(totalWeight).sub(Decimal(weight * random)).toNumber()
this.$set(e, names[i], totalWeight > 0 ? random : 0) while (total > already) {
// e[names[i]] = totalWeight > 0 ? random : 0 e.basicDifficulty++
already++
} }
console.log(33, already)
} }
console.log("🚀 ~ calculateQuestionNumbers ~ totalWeight:", totalWeight) //
// let totalWeight = Decimal(total).mul(Decimal(target)).toNumber()
// const maxCount = Math.ceil(total / 4)
// for (let i = 0; i < 4; i++) {
// if (totalWeight > 0) {
// const random = Math.floor(Math.random() * maxCount) + 1
// const weight = difficultyWeights[i]
// totalWeight = Decimal(totalWeight).sub(Decimal(weight * random)).toNumber()
// this.$set(e, names[i], totalWeight > 0 ? random : 0)
// // e[names[i]] = totalWeight > 0 ? random : 0
// }
// }
}) })
@ -313,7 +327,7 @@ export default {
// //
difficultData (val) { difficultData (val) {
// debugger // debugger
console.log(111, this.calculateQuestionNumbers(this.list, 0.3)) console.log(111, this.calculateQuestionNumbers(this.list, val))
}, },
// //
yearAllChange (val) { yearAllChange (val) {
@ -365,6 +379,7 @@ export default {
list.map((e, i) => { list.map((e, i) => {
if (e.questionNum !== res.list[i].questions.length) invalid = 1 if (e.questionNum !== res.list[i].questions.length) invalid = 1
if (e.examQuestions.length) hasQues = 1 if (e.examQuestions.length) hasQues = 1
e.score = 0
}) })
// 3 // 3

@ -131,7 +131,10 @@
</template> </template>
<div class="bottom-line"> <div class="bottom-line">
<div class="correct">正确答案A</div> <div class="correct">
{{ ques.questionType === 'essay' ? '参考答案' : '正确答案' }}
<div v-html="getCorrectAnswer(ques)"></div>
</div>
<div class="actions"> <div class="actions">
<div class="sort"> <div class="sort">
<span>排序</span> <span>排序</span>
@ -312,6 +315,12 @@ export default {
}) })
const r = res.examPaper const r = res.examPaper
const paper = r.paperOutline const paper = r.paperOutline
paper.map(e => {
e.examQuestions.map(n => {
Object.assign(n, n.question)
})
})
if (r.particularYear) r.particularYear = r.particularYear + '' if (r.particularYear) r.particularYear = r.particularYear + ''
this.form = r this.form = r
// this.answerAnalysis = opts[0].answerAnalysis // this.answerAnalysis = opts[0].answerAnalysis
@ -395,7 +404,7 @@ export default {
data.avgValueList.map((e, i) => { data.avgValueList.map((e, i) => {
// scores-1 // scores-1
e.scores.includes(-1) || e.scores.map((n, j) => { e.scores.includes(-1) || e.scores.map((n, j) => {
paper[i].examQuestions[j].score = n this.$set(paper[i].examQuestions[j], 'score', n)
}) })
}) })
@ -405,6 +414,17 @@ export default {
showAuto () { showAuto () {
this.autoVisible = true this.autoVisible = true
}, },
//
getCorrectAnswer (e) {
if (e.questionType === 'fill_blank') { //
// return e.questionAnswerVersionsList.filter(e => e.answerIsCorrect)
} else if (e.questionType === 'essay') { //
return e.questionAnswerVersionsList[0].referenceAnswer
} else {
const correct = e.questionAnswerVersionsList.filter(e => e.answerIsCorrect)
return correct ? (e.questionType === 'judgement' ? correct[0].optionText : correct.map(e => Util.numToLetter(e.optionNumber - 1)).join('')) : ''
}
},
// //
showManualDia (item, i, ques) { showManualDia (item, i, ques) {
this.curType = item this.curType = item
@ -497,6 +517,7 @@ export default {
break break
} }
} }
debugger
if (invalid) return false if (invalid) return false
this.submiting = true this.submiting = true
@ -516,7 +537,6 @@ export default {
} }
}) })
}) })
debugger
if (typeof form.classificationId === 'object') form.classificationId = form.classificationId[form.classificationId.length - 1] if (typeof form.classificationId === 'object') form.classificationId = form.classificationId[form.classificationId.length - 1]
form.questionType = [...new Set(paper.map(e => e.questionType))].join('、') form.questionType = [...new Set(paper.map(e => e.questionType))].join('、')
form.createSource = 1 form.createSource = 1
@ -638,6 +658,7 @@ export default {
} }
.correct { .correct {
display: flex;
font-size: 13px; font-size: 13px;
color: #333; color: #333;
} }

@ -159,6 +159,7 @@ export default {
const { list } = await this.$post(this.api.questionBankStructureLevel, { const { list } = await this.$post(this.api.questionBankStructureLevel, {
keyword: this.quesBankKeyword, keyword: this.quesBankKeyword,
createSource: 1, createSource: 1,
status: 1,
}) })
this.quesBanks = list this.quesBanks = list
} catch (e) { } } catch (e) { }
@ -309,7 +310,6 @@ export default {
this.$set(e, 'score', '') this.$set(e, 'score', '')
this.$set(e, 'questionVersionId', e.questionId) this.$set(e, 'questionVersionId', e.questionId)
}) })
// debugger
if (curQues) { if (curQues) {
// curQues // curQues

@ -26,7 +26,7 @@
<div class="right"> <div class="right">
<h6 class="page-name">筛选</h6> <h6 class="page-name">筛选</h6>
<!-- <UeditorPlus /> --> <UeditorPlus />
<div class="tool"> <div class="tool">
<ul class="filter"> <ul class="filter">
<li> <li>
@ -104,10 +104,10 @@
<script> <script>
import Util from '@/libs/util' import Util from '@/libs/util'
import Setting from '@/setting' import Setting from '@/setting'
// import UeditorPlus from '@/components/ueditorPlus' import UeditorPlus from '@/components/ueditorPlus'
import _ from 'lodash' import _ from 'lodash'
export default { export default {
// components: { UeditorPlus }, components: { UeditorPlus },
data () { data () {
return { return {
loading: false, loading: false,

Loading…
Cancel
Save