dev_review
yujialong 3 months ago
parent 5a21e78cac
commit 645e52a679
  1. 4
      src/App.vue
  2. 5
      src/components/Header.vue
  3. 2
      src/setting.js
  4. 2
      src/utils/api.js
  5. 1
      src/views/Login.vue
  6. 18
      src/views/match/add/index.vue
  7. 60
      src/views/match/add/step1.vue
  8. 4
      src/views/match/manage/matchRank.vue
  9. 16
      src/views/match/manage/theoryArchList.vue
  10. 91
      src/views/match/manage/theoryReport.vue
  11. 2
      src/views/serve/Configure.vue
  12. 18
      src/views/theoryExam/index.vue

@ -20,6 +20,10 @@ export default {
};
},
created () {
window.exitSystem = () => {
sessionStorage.removeItem('token')
location.reload()
}
//sessionStorage
if (sessionStorage.getItem("store")) {
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store"))))

@ -21,6 +21,7 @@ import Setting from '@/setting'
export default {
data () {
return {
timer: null,
Setting,
userName: '',
};
@ -81,8 +82,8 @@ export default {
},
//
heartbeatDetection () {
setInterval(async () => {
await this.$get(this.api.heartbeatDetection)
this.timer = setInterval(async () => {
sessionStorage.getItem('token') ? await this.$get(this.api.heartbeatDetection) : clearInterval(this.timer)
}, 58 * 1000)
},

@ -51,7 +51,7 @@ const Setting = {
isDev,
isPro,
// 是否使用动态路由
dynamicRoute: false,
dynamicRoute: true,
/**
* @description 默认密码
*/

@ -17,7 +17,7 @@ export default {
logout: `users/users/user/logout`,
// 阿里云文件/视频管理
getPlayAuth: `${uploadURL}oss/manage/getPlayAuth`, // 获取播放凭证
getPlayAuth: `nakadai/nakadai/oss/getPlayAuth`, // 获取播放凭证
encrypt: `nakadai/data/encrypt`,
staffTemplate: `https://occupationlab.com/template/%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E5%91%98%E5%B7%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 后台账号模板

@ -199,6 +199,7 @@ export default {
this.$refs[ref].validate(valid => {
if (valid) {
this.$post(this.api.logins, param).then(({ status, data, message }) => {
localStorage.removeItem('examPath')
if (status == 200) {
const accounts = data.userAccounts
//

@ -9,8 +9,8 @@
<div class="p-title">大赛发布类型</div>
<el-form label-width="100px" label-suffix=":" size="small" :disabled="!editing && id != ''">
<el-form-item label="请选择类型">
<el-radio v-model="releaseType" :label="0">仅发布信息</el-radio>
<el-radio v-model="releaseType" :label="1">设置完整比赛</el-radio>
<el-radio v-for="(item, i) in releaseTypes" :key="i" v-model="releaseType" :label="item.id">{{ item.name
}}</el-radio>
</el-form-item>
</el-form>
<el-button v-if="!editing && id" class="edit" type="primary" @click="editing = 1"
@ -83,6 +83,20 @@ export default {
updateTime: 0,
setupId: '',
releaseType: 0,
releaseTypes: [
{
id: 0,
name: '仅发布信息'
},
{
id: 1,
name: '设置完整比赛'
},
// {
// id: 2,
// name: ''
// },
],
editing: this.$route.query.id ? 0 : 1,
showBtns: true,
loadIns: null

@ -37,6 +37,8 @@
<el-input placeholder="请输入竞赛名称" v-model="form.name" clearable></el-input>
</div>
</el-form-item>
<template v-if="!isPractice">
<el-form-item class="req" label="主办方">
<div class="inline-input">
<div class="input-wrap" v-for="(item, index) in sponsorList" :key="index">
@ -72,6 +74,7 @@
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
:picker-options="pickerOptions"></el-date-picker>
</el-form-item>
</template>
<el-form-item class="req" label="竞赛时间">
<el-date-picker v-model="playTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
@ -92,6 +95,7 @@
</template>
</div>
</el-form-item>
<template v-if="!isPractice">
<el-form-item class="req" label="竞赛类型">
<el-radio v-model="form.completeCompetitionSetup.competitionType" :label="0">个人赛</el-radio>
<el-radio v-model="form.completeCompetitionSetup.competitionType" :label="1">团队赛</el-radio>
@ -128,6 +132,7 @@
<el-button v-if="form.completeCompetitionSetup.isNeedCode === 1" @click="randomInv">随机</el-button>
</div>
</el-form-item>
</template>
<el-form-item class="req" label="竞赛详情">
<quill v-if="quillShow" :border="true" v-model="form.description" :height="400"
:readonly="!editing && form.id !== ''" />
@ -136,6 +141,56 @@
<Upload :limit="5" :file-list.sync="fileList" :on-remove="handleAnnexRemove"
@onSuccess="uploadAnnexSuccess" />
</el-form-item>
<template v-if="isPractice">
<el-form-item label="比赛方式">
<el-radio-group v-model="form.type">
<el-radio :label="0">实训</el-radio>
<el-radio :label="1">理论</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="比赛内容">
<el-button style="margin-bottom: 10px;" size="small" type="primary">选择理论试卷</el-button>
<el-table :data="list" class="table" ref="table" stripe header-align="center" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" align="center" min-width="100"></el-table-column>
<el-table-column prop="questionCount" label="试题总数" align="center" width="70"></el-table-column>
<el-table-column prop="score" label="总分" align="center" width="60"></el-table-column>
<el-table-column prop="questionType" label="题型" align="center" min-width="90"
show-overflow-tooltip></el-table-column>
<el-table-column prop="difficult" label="试卷难度" align="center" width="100" sortable="custom">
<!-- <template slot-scope="scope">{{ difficults.find(e => e.id === scope.row.difficult) ? difficults.find(e
=>
e.id === scope.row.difficult).name : '' }}</template> -->
</el-table-column>
<el-table-column prop="suggestTime" label="建议用时" align="center" width="70">
<template slot-scope="scope">{{ scope.row.suggestTime }}min</template>
</el-table-column>
<el-table-column prop="classificationPath" label="试卷分类" align="center" width="90"
show-overflow-tooltip></el-table-column>
<el-table-column label="建议用途" align="center" width="70">
<!-- <template slot-scope="scope">{{ paperTypes.find(e => e.id === scope.row.paperType) ? paperTypes.find(e
=>
e.id === scope.row.paperType).name : '' }}</template> -->
</el-table-column>
<el-table-column prop="updateTime" label="最近编辑时间" align="center" width="160"
sortable="custom"></el-table-column>
<el-table-column prop="createUser" label="最近编辑人" align="center" width="90"></el-table-column>
<el-table-column label="操作" align="center" width="240">
<template slot-scope="scope">
<el-button type="text" @click="toDetail(scope.row, 1)">复制</el-button>
<!-- <el-button type="text" @click="edit(scope.row)">预览</el-button> -->
<el-button type="text" @click="toDetail(scope.row)">编辑</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button>
<el-switch v-if="!scope.row.status" v-model="scope.row.isDisable" :active-value="false"
:inactive-value="true" style="margin: 0 10px 0 5px" :active-text="scope.row.isDisable ? '关' : '开'"
@change="switchOff($event, scope.row, scope.$index)"></el-switch>
</template>
</el-table-column>
</el-table>
</el-form-item>
</template>
</el-form>
</div>
</div>
@ -293,6 +348,11 @@ export default {
quill,
Upload
},
computed: {
isPractice () {
return this.$parent.releaseType === 2
},
},
watch: {
editing: function (val) {
this.quillShow = false

@ -178,7 +178,7 @@ export default {
id: +this.$route.query.id,
stageId: +this.$route.query.stageId,
index: +this.$route.query.index,
method: this.$route.query.method,
method: +this.$route.query.method,
competitionType: +this.$route.query.competitionType,
rule: +this.$route.query.rule,
searchTimer: null,
@ -449,7 +449,7 @@ export default {
},
//
toReport (row) {
this.$router.push(`/matchReport?reportId=${row.reportId}`)
this.$router.push(`/${this.method !== 1 ? 'trialReport' : 'theoryReport'}?reportId=${row.reportId}`)
},
handleSelectionChange (val) { //
this.multipleSelection = val;

@ -47,8 +47,6 @@
</div>
<div v-if="!active">
<el-button v-if="method == 2" type="primary" @click="batchImport">上传成绩</el-button>
<el-button type="primary" :disabled="!!multipleSelection.find(e => method != 2 && !e.reportId)"
@click="delAllData">批量删除</el-button>
<el-button type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' : '批量导出'
}}</el-button>
</div>
@ -182,11 +180,11 @@ export default {
tabs: [
{
id: 1,
name: '成绩报告'
name: '已提交'
},
{
id: 0,
name: '未完成竞赛'
name: '未提交'
}
],
active: 1,
@ -322,7 +320,7 @@ export default {
},
handleCurrentChange (val) { //
this.$router.push({
path: '/matchArchList',
path: '/theoryArchList',
query: {
...this.$route.query,
page: val
@ -335,10 +333,6 @@ export default {
handleSelectionChange1 (val) { //
this.multipleSelection1 = val;
},
handleCurrentChange1 (val) { //
this.page1 = val;
this.getData();
},
getChart () { // 线
const { fractionalSegmentCounts: data } = this.statData
let myChart = echarts.init(document.getElementById("chart"));
@ -440,7 +434,7 @@ export default {
// tab
tabChange (i) {
this.active = i
this.getData()
this.initData()
},
//
preview (item) {
@ -539,7 +533,7 @@ export default {
}
.chart {
flex: 1;
width: calc(100% - 660px);
height: 300px;
}
}

@ -32,7 +32,7 @@
@click="filterStatus(item.id)">{{ item.name }}</li>
</ul>
</div>
<div class="right">
<div class="right" id="right">
<div class="text-right">
<el-button type="primary" @click="exportPage">导出报告</el-button>
</div>
@ -88,17 +88,24 @@
<img src="@/assets/img/report4.png" alt="">
得分情况
</h6>
<el-table :data="paper" class="table" border stripe header-align="center">
<el-table :data="outlines" class="table" border stripe header-align="center">
<el-table-column prop="outlineName" label="大题名称" align="center"></el-table-column>
<el-table-column prop="questionNum" label="小题总数" align="center"></el-table-column>
<el-table-column prop="targetScore" label="总分" align="center"></el-table-column>
<el-table-column prop="targetScore" label="总分" align="center">
<template slot-scope="scope">{{ scope.row.targetScore }}</template>
</el-table-column>
<el-table-column prop="userTotalScore" label="得分" align="center">
<template slot-scope="scope">
<p v-if="scope.row.questionType === 'essay'" class="text-red">待评分</p>
<p v-else>{{ scope.row.userTotalScore }}</p>
<p v-else-if="essayExist && !scope.row.paperId" class="text-red">{{ scope.row.userTotalScore
}}部分试题待判分成绩待定</p>
<p v-else>{{ scope.row.userTotalScore }}</p>
</template>
</el-table-column>
<el-table-column prop="scoreRatePercentage" label="得分率" align="center"></el-table-column>
<el-table-column prop="scoreRatePercentage" label="得分率" align="center">
<template slot-scope="scope">{{ scope.row.questionType === 'essay' ? '-' : scope.row.scoreRatePercentage
}}</template>
</el-table-column>
</el-table>
</div>
@ -146,9 +153,9 @@
</div>
</template>
<div class="m-b-10">
<div v-if="ques.knowledgePointList && ques.knowledgePointList.length" class="m-b-10">
<span>知识点</span>
<el-tag v-for="(kp, k) in ques.kpList" :key="k" class="m-r-5">{{ kp }}</el-tag>
<el-tag v-for="(kp, k) in ques.knowledgePointList" :key="k" class="m-r-5">{{ kp.name }}</el-tag>
</div>
<div class="flex m-b-10">
<span>解析</span>
@ -161,16 +168,16 @@
<div :class="['ques-info', { essay: item.questionType === 'essay' }]">
<template v-if="item.questionType === 'essay'">
<div class="line">
<span>参考答案</span>
<div v-html="ques.questionAnswerVersionsList[0].referenceAnswer"></div>
<span class="line-label">参考答案</span>
<div v-html="ques.questionAnswerVersionsList[0].referenceAnswer" class="html-parse"></div>
</div>
<div class="line">
<span>考生答案</span>
<div v-if="ques.answerContent" v-html="ques.answerContent"></div>
<span class="line-label">考生答案</span>
<div v-if="ques.answerContent" v-html="ques.answerContent" class="html-parse"></div>
<div v-else>未作答</div>
</div>
<div v-if="ques.attachmentUrl" class="line">
<span>考生上传附件</span>
<span class="line-label">考生上传附件</span>
<el-link class="m-r-10" type="primary">{{ ques.attachmentName }}</el-link>
<el-button type="primary" size="mini" round @click="download(ques)">下载</el-button>
</div>
@ -178,7 +185,7 @@
<template v-else>
<div class="line">正确答案{{ ques.quesAnswer }}</div>
<div class="line">
<span>考生答案</span>
<span class="line-label">考生答案</span>
<p v-if="item.questionType !== 'fill_blank'">{{ ques.userAnswerStr }}</p>
<div v-else-if="ques.userAnswerFill" class="fill-answers">
<p v-for="(ans, j) in ques.userAnswerFill" :key="j" class="fill-answer">
@ -192,7 +199,7 @@
<div class="line">题目分值{{ ques.questionScore }}</div>
<div class="line">考生得分<el-input class="score-input" size="small" :value="ques.userScore"
disabled />
readonly />
</div>
</div>
</div>
@ -218,6 +225,7 @@
import QuesConst from '@/const/ques'
import TestPaperConst from '@/const/testPaper'
import Util from '@/libs/util'
import _ from 'lodash'
export default {
data () {
return {
@ -256,6 +264,7 @@ export default {
name: '待判分'
},
],
outlines: [],
paper: [],
essayExist: 0,
};
@ -267,14 +276,14 @@ export default {
async getData () {
this.loading = true
try {
const { userAnswers: paper, report } = await this.$get(`${this.api.getDetailedExamScores}?reportId=${this.reportId}`)
const { userAnswers: outline, report, paper } = await this.$get(`${this.api.getDetailedExamScores}?reportId=${this.reportId}`)
this.form = report
//
const { questionTypes: types, difficults } = QuesConst
const { numToLetter } = Util
let essayExist = 0
paper.map(e => {
outline.map(e => {
if (e.questionType === 'essay') essayExist = 1
e.shrink = false
const type = e.questionType
@ -287,7 +296,6 @@ export default {
n.difficultTheme = curDiff.theme
}
}
n.kpList = n.knowledgePointName.split(',')
const opts = n.questionAnswerVersionsList
if (type !== 'fill_blank' && type !== 'essay') { //
@ -298,7 +306,7 @@ export default {
let { userAnswer } = n
if (userAnswer) {
userAnswer = JSON.parse(userAnswer)
n.userAnswerStr = userAnswer.length ? userAnswer.map(m => numToLetter(+m - 1)).join('') : '未作答'
n.userAnswerStr = userAnswer.length ? (type === 'judgement' ? opts[+userAnswer[0] - 1].optionText : userAnswer.map(m => numToLetter(+m - 1)).join('')) : '未作答'
} else {
userAnswer = []
}
@ -307,7 +315,7 @@ export default {
opts && opts.map((m, j) => {
const selected = userAnswer.includes(m.optionNumber)
m.optCorrect = m.answerIsCorrect ? (selected ? 1 : -1) : (selected ? 0 : -1) // (10-1)
m.answerIsCorrect && quesAnswer.push(numToLetter(j))
m.answerIsCorrect && quesAnswer.push(type === 'judgement' ? m.optionText : numToLetter(j))
})
n.quesAnswer = quesAnswer.join('')
@ -345,7 +353,17 @@ export default {
})
this.essayExist = essayExist //
this.paper = paper
this.paper = outline
this.outlines = [
...outline,
{
outlineName: '合计',
questionNum: paper.questionCount,
targetScore: paper.score,
userTotalScore: paper.userTotalScore,
scoreRatePercentage: paper.scoreRate
}
]
let { form } = this
this.info = {
workNumber: form.workNumber,
@ -368,7 +386,7 @@ export default {
function scroll () {
let now = Date.now()
let progress = Math.min(1, (now - startTime) / duration)
document.querySelector('#quesWrap').scrollTo(0, position * progress)
document.querySelector('#right').scrollTo(0, position * progress)
if (progress < 1) {
window.requestAnimationFrame(scroll)
@ -380,7 +398,7 @@ export default {
//
scrollToQues (e) {
const el = document.querySelector('#ques' + e.id)
el && this.scrollToSmooth(el.offsetTop - document.querySelector('#quesWrap').offsetTop, 200)
el && this.scrollToSmooth(el.offsetTop - document.querySelector('#quesWrap').offsetTop + 200, 200)
},
//
filterStatus (e) {
@ -799,6 +817,24 @@ samp {
}
}
.html-parse {
table {
display: table;
margin-bottom: 10px;
border-collapse: collapse;
th,
td {
padding: 5px 10px;
border: 1px solid #DDD;
}
}
}
img {
max-width: 100%;
}
.item:not(:last-child) {
padding-bottom: 15px;
margin-bottom: 15px;
@ -811,6 +847,7 @@ samp {
margin-bottom: 10px;
}
.tag {
margin-left: 10px;
cursor: pointer;
@ -863,7 +900,7 @@ samp {
.line {
display: flex;
align-items: center;
align-items: baseline;
margin-bottom: 8px;
font-size: 13px;
color: #333;
@ -871,6 +908,14 @@ samp {
&:last-child {
margin-bottom: 0;
}
img {
max-width: 100%;
}
}
.line-label {
white-space: nowrap;
}
.fill-answers {

@ -161,7 +161,7 @@ export default {
//
toBackstage (row) {
this.setReferrer()
if (row.systemId == 19) {
if (row.systemId == 19 || row.systemId == 30) {
location.href = `${Setting.sandPath}/#/config?token=${sessionStorage.getItem('token')}&admin=1&referrer=${encodeURIComponent(location.href)}`
} else {
this.$router.push(`/backstage?systemId=${row.systemId}&show=1&name=${row.systemName}`)

@ -10,11 +10,25 @@ import Setting from '@/setting'
export default {
data () {
return {
url: `http://${Setting.isDev ? '192.168.31.125:8098' : '121.37.12.51/examination'}/#/quesBankType?token=${sessionStorage.getItem('token')}`
url: ''
};
},
mounted () {
const path = localStorage.getItem('examPath')
let url = `${location.origin}/examination`
if (Setting.isDev) {
url = `http://192.168.31.125:8098/`
} else if (Setting.isPro) {
const { host } = location
url = `https://${host === 'dev.huorantech.cn' ? host : 'www.huorantech.cn'}/examination/`
}
if (path) {
url += `${path}${path.includes('?') ? `&` : '?'}token=${sessionStorage.getItem('token')}`
} else {
url += `#/quesBankType?token=${sessionStorage.getItem('token')}`
}
url += `&v=${Date.now()}`
this.url = url
},
methods: {

Loading…
Cancel
Save