|
|
|
@ -1,123 +1,75 @@ |
|
|
|
|
<template> |
|
|
|
|
<div :class="['panel', {active: pannelVisible}]" |
|
|
|
|
id="panel"> |
|
|
|
|
<el-container class="scrollbar" |
|
|
|
|
id="container" |
|
|
|
|
v-show="pannelVisible"> |
|
|
|
|
<el-header class="panel-header" |
|
|
|
|
id="panelHeader"> |
|
|
|
|
<div class="project"> |
|
|
|
|
<div class="inline-center"> |
|
|
|
|
<p class="whitespace-nowrap">实训项目</p> |
|
|
|
|
<el-tooltip effect="dark" |
|
|
|
|
content="点击右侧“下三角”按钮可切换实验项目" |
|
|
|
|
placement="bottom"> |
|
|
|
|
<i class="info el-icon-warning" |
|
|
|
|
style="margin-left: 10px"></i> |
|
|
|
|
</el-tooltip> |
|
|
|
|
</div> |
|
|
|
|
<el-select v-model="projectId" |
|
|
|
|
placeholder="请选择" |
|
|
|
|
class="select" |
|
|
|
|
:disabled="projectPermissions != 0" |
|
|
|
|
@change="selectProject" |
|
|
|
|
style="flex: 1"> |
|
|
|
|
<el-option v-for="(item, i) in projectList" |
|
|
|
|
:key="item.projectId" |
|
|
|
|
:label="i + 1 + '. ' + item.projectName" |
|
|
|
|
:value="item.projectId"></el-option> |
|
|
|
|
</el-select> |
|
|
|
|
</div> |
|
|
|
|
<div class="item"> |
|
|
|
|
<div class="count"> |
|
|
|
|
实训{{text}}时间 |
|
|
|
|
<span>{{day}}</span>天 |
|
|
|
|
<span>{{hour}}</span>小时 |
|
|
|
|
<span>{{minutes}}</span>分 |
|
|
|
|
<span>{{seconds}}</span>秒 |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div v-if="!competitionId" |
|
|
|
|
class="item"> |
|
|
|
|
<div> |
|
|
|
|
总得分: |
|
|
|
|
<span class="total-score">{{grade}}</span> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="actions"> |
|
|
|
|
<el-button @click="toggleReport" |
|
|
|
|
v-if="$parent.language && !isSubmit && !competitionId">填写实验报告</el-button> |
|
|
|
|
<el-button @click="toReport" |
|
|
|
|
v-if="isSubmit && !competitionId">查看实验报告</el-button> |
|
|
|
|
<el-button class="reload" |
|
|
|
|
@click="reloadConfirm" |
|
|
|
|
v-show="projectPermissions == 0">重新开始</el-button> |
|
|
|
|
<el-button type="primary" |
|
|
|
|
class="submit btn" |
|
|
|
|
@click="confirmSubmit" |
|
|
|
|
:disabled="isSubmit || !projectList.length">提交</el-button> |
|
|
|
|
</div> |
|
|
|
|
<div :class="['panel', { active: pannelVisible }]" id="panel"> |
|
|
|
|
<el-container class="scrollbar" id="container" v-show="pannelVisible"> |
|
|
|
|
<el-header class="panel-header" id="panelHeader"> |
|
|
|
|
<div class="project"> |
|
|
|
|
<div class="inline-center"> |
|
|
|
|
<p class="whitespace-nowrap">实训项目</p> |
|
|
|
|
<el-tooltip effect="dark" content="点击右侧“下三角”按钮可切换实验项目" placement="bottom"> |
|
|
|
|
<i class="info el-icon-warning" style="margin-left: 10px"></i> |
|
|
|
|
</el-tooltip> |
|
|
|
|
</div> |
|
|
|
|
<el-select v-model="projectId" placeholder="请选择" class="select" :disabled="projectPermissions != 0" |
|
|
|
|
@change="selectProject" style="flex: 1"> |
|
|
|
|
<el-option v-for="(item, i) in projectList" :key="item.projectId" :label="i + 1 + '. ' + item.projectName" |
|
|
|
|
:value="item.projectId"></el-option> |
|
|
|
|
</el-select> |
|
|
|
|
</div> |
|
|
|
|
<div class="item"> |
|
|
|
|
<div class="count"> |
|
|
|
|
实训{{ text }}时间 |
|
|
|
|
<span>{{ day }}</span>天 |
|
|
|
|
<span>{{ hour }}</span>小时 |
|
|
|
|
<span>{{ minutes }}</span>分 |
|
|
|
|
<span>{{ seconds }}</span>秒 |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div v-if="!competitionId" class="item"> |
|
|
|
|
<div> |
|
|
|
|
总得分: |
|
|
|
|
<span class="total-score">{{ grade }}</span> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="actions"> |
|
|
|
|
<el-button @click="toggleReport" v-if="$parent.language && !isSubmit && !competitionId">填写实验报告</el-button> |
|
|
|
|
<el-button @click="toReport" v-if="isSubmit && !competitionId">查看实验报告</el-button> |
|
|
|
|
<el-button class="reload" @click="reloadConfirm" v-show="projectPermissions == 0">重新开始</el-button> |
|
|
|
|
<el-button type="primary" class="submit btn" @click="confirmSubmit" |
|
|
|
|
:disabled="isSubmit || !projectList.length">提交</el-button> |
|
|
|
|
</div> |
|
|
|
|
</el-header> |
|
|
|
|
<div class="report-wrap" |
|
|
|
|
v-if="reportVisible"> |
|
|
|
|
<div class="report-wrap" v-if="reportVisible"> |
|
|
|
|
<i class="el-icon-caret-top close-report"></i> |
|
|
|
|
<el-table class="report-table" |
|
|
|
|
:data="taskList" |
|
|
|
|
:max-height="tableHeight"> |
|
|
|
|
<el-table-column prop="name" |
|
|
|
|
label="判分点" |
|
|
|
|
width="210" |
|
|
|
|
align="center"></el-table-column> |
|
|
|
|
<el-table-column prop="score" |
|
|
|
|
label="答案" |
|
|
|
|
align="center"> |
|
|
|
|
<el-table class="report-table" :data="taskList" :max-height="tableHeight"> |
|
|
|
|
<el-table-column prop="name" label="判分点" width="210" align="center"></el-table-column> |
|
|
|
|
<el-table-column prop="score" label="答案" align="center"> |
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
<codemirror v-model="scope.row.code" |
|
|
|
|
:options="cmOption" |
|
|
|
|
class="code-mirror" |
|
|
|
|
:ref="'codemirror' + scope.$index" |
|
|
|
|
@ready="() => ready(scope.$index)"></codemirror> |
|
|
|
|
<codemirror v-model="scope.row.code" :options="cmOption" class="code-mirror" |
|
|
|
|
:ref="'codemirror' + scope.$index" @ready="() => ready(scope.$index)"></codemirror> |
|
|
|
|
</template> |
|
|
|
|
</el-table-column> |
|
|
|
|
<el-table-column prop="score" |
|
|
|
|
label="运行结果" |
|
|
|
|
align="center"> |
|
|
|
|
<el-table-column prop="score" label="运行结果" align="center"> |
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
<quill class="quill" |
|
|
|
|
:tools="false" |
|
|
|
|
:border="true" |
|
|
|
|
v-model="scope.row.codeResult" |
|
|
|
|
:height="300" |
|
|
|
|
:index="1" /> |
|
|
|
|
<quill class="quill" :tools="false" :border="true" v-model="scope.row.codeResult" :height="300" |
|
|
|
|
:index="1" /> |
|
|
|
|
</template> |
|
|
|
|
</el-table-column> |
|
|
|
|
</el-table> |
|
|
|
|
</div> |
|
|
|
|
<el-container id="infoContainer" |
|
|
|
|
v-else> |
|
|
|
|
<el-aside id="aside" |
|
|
|
|
width="30%"> |
|
|
|
|
<el-container id="infoContainer" v-else> |
|
|
|
|
<el-aside id="aside" width="30%"> |
|
|
|
|
<div class="aside-header"> |
|
|
|
|
<div :class="['p-title color', 'system' + $themeId]"> |
|
|
|
|
<i class="el-icon-s-order"></i> |
|
|
|
|
<p>实验目标</p> |
|
|
|
|
</div> |
|
|
|
|
<div class="goal"> |
|
|
|
|
<div v-if="pd.experimentTargetType == 0 || !pd.experimentTargetType" |
|
|
|
|
class="ql-snow"> |
|
|
|
|
<div class="ql-editor" |
|
|
|
|
v-html="pd.experimentTarget"></div> |
|
|
|
|
<div v-if="pd.experimentTargetType == 0 || !pd.experimentTargetType" class="ql-snow"> |
|
|
|
|
<div class="ql-editor" v-html="pd.experimentTarget"></div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<mavon-editor v-else |
|
|
|
|
class="md" |
|
|
|
|
v-model="pd.experimentTarget" |
|
|
|
|
defaultOpen="preview" |
|
|
|
|
:ishljs="true" |
|
|
|
|
:subfield="false" |
|
|
|
|
:editable="false" |
|
|
|
|
:toolbarsFlag="false" |
|
|
|
|
boxShadowStyle="none" /> |
|
|
|
|
<mavon-editor v-else class="md" v-model="pd.experimentTarget" defaultOpen="preview" :ishljs="true" |
|
|
|
|
:subfield="false" :editable="false" :toolbarsFlag="false" boxShadowStyle="none" /> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="aside-footer"> |
|
|
|
@ -128,39 +80,24 @@ |
|
|
|
|
<div> |
|
|
|
|
<el-row> |
|
|
|
|
<el-col :span="24"> |
|
|
|
|
<el-card shadow="never" |
|
|
|
|
:border="false"> |
|
|
|
|
<el-table class="task-table" |
|
|
|
|
:data="taskList" |
|
|
|
|
:stripe="true"> |
|
|
|
|
<el-card shadow="never" :border="false"> |
|
|
|
|
<el-table class="task-table" :data="taskList" :stripe="true"> |
|
|
|
|
<el-table-column type="index"></el-table-column> |
|
|
|
|
<el-table-column prop="name" |
|
|
|
|
label="判分点" |
|
|
|
|
align="center"></el-table-column> |
|
|
|
|
<el-table-column prop="score" |
|
|
|
|
label="分值" |
|
|
|
|
width="60" |
|
|
|
|
align="center"></el-table-column> |
|
|
|
|
<el-table-column prop="name" label="判分点" align="center"></el-table-column> |
|
|
|
|
<el-table-column prop="score" label="分值" width="60" align="center"></el-table-column> |
|
|
|
|
<template v-if="!competitionId"> |
|
|
|
|
<el-table-column label="结果" |
|
|
|
|
width="60" |
|
|
|
|
align="center"> |
|
|
|
|
<el-table-column label="结果" width="60" align="center"> |
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
<template v-if="isSubmit"> |
|
|
|
|
<template v-if="!competitionId"> |
|
|
|
|
<i v-if="scope.row.finishedResult" |
|
|
|
|
class="el-icon-check right"></i> |
|
|
|
|
<i v-else |
|
|
|
|
class="el-icon-close wrong"></i> |
|
|
|
|
<i v-if="scope.row.finishedResult" class="el-icon-check right"></i> |
|
|
|
|
<i v-else class="el-icon-close wrong"></i> |
|
|
|
|
</template> |
|
|
|
|
<template v-else>-</template> |
|
|
|
|
</template> |
|
|
|
|
</template> |
|
|
|
|
</el-table-column> |
|
|
|
|
<el-table-column prop="score" |
|
|
|
|
label="得分" |
|
|
|
|
width="60" |
|
|
|
|
align="center"> |
|
|
|
|
<el-table-column prop="score" label="得分" width="60" align="center"> |
|
|
|
|
<template slot-scope="scope"> |
|
|
|
|
<template v-if="isSubmit">{{ competitionId ? '-' : scope.row.examScore }}</template> |
|
|
|
|
</template> |
|
|
|
@ -174,93 +111,52 @@ |
|
|
|
|
</div> |
|
|
|
|
</el-aside> |
|
|
|
|
<el-main id="main"> |
|
|
|
|
<el-tabs class="info-tab" |
|
|
|
|
v-model="pannelTab" |
|
|
|
|
type="card"> |
|
|
|
|
<el-tab-pane label="项目背景" |
|
|
|
|
name="first"> |
|
|
|
|
<div v-if="pd.experimentDescriptionType == 0 || !pd.experimentDescriptionType" |
|
|
|
|
class="ql-snow"> |
|
|
|
|
<div class="ql-editor" |
|
|
|
|
v-html="pd.experimentDescription"></div> |
|
|
|
|
<el-tabs class="info-tab" v-model="pannelTab" type="card"> |
|
|
|
|
<el-tab-pane label="项目背景" name="first"> |
|
|
|
|
<div v-if="pd.experimentDescriptionType == 0 || !pd.experimentDescriptionType" class="ql-snow"> |
|
|
|
|
<div class="ql-editor" v-html="pd.experimentDescription"></div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<mavon-editor v-else |
|
|
|
|
class="md" |
|
|
|
|
v-model="pd.experimentDescription" |
|
|
|
|
defaultOpen="preview" |
|
|
|
|
:subfield="false" |
|
|
|
|
:editable="false" |
|
|
|
|
:toolbarsFlag="false" |
|
|
|
|
boxShadowStyle="none" /> |
|
|
|
|
<mavon-editor v-else class="md" v-model="pd.experimentDescription" defaultOpen="preview" :subfield="false" |
|
|
|
|
:editable="false" :toolbarsFlag="false" boxShadowStyle="none" /> |
|
|
|
|
</el-tab-pane> |
|
|
|
|
<el-tab-pane label="实验要求" |
|
|
|
|
name="second"> |
|
|
|
|
<el-tab-pane label="实验要求" name="second"> |
|
|
|
|
<el-collapse v-model="curReq"> |
|
|
|
|
<el-collapse-item v-for="item in points" |
|
|
|
|
:name="item.judgmentId" |
|
|
|
|
:key="item.judgmentId"> |
|
|
|
|
<el-collapse-item v-for="item in points" :name="item.judgmentId" :key="item.judgmentId"> |
|
|
|
|
<template slot="title"> |
|
|
|
|
<i class="el-icon-s-ticket"></i> |
|
|
|
|
<div class="break-all des" |
|
|
|
|
v-html="item.name"></div> |
|
|
|
|
<div class="break-all des" v-html="item.name"></div> |
|
|
|
|
</template> |
|
|
|
|
<div v-if="item.experimentalRequirementsType == 0 || !item.experimentalRequirementsType" |
|
|
|
|
class="ql-snow"> |
|
|
|
|
<div class="ql-editor" |
|
|
|
|
v-html="item.experimentalRequirements"></div> |
|
|
|
|
class="ql-snow"> |
|
|
|
|
<div class="ql-editor" v-html="item.experimentalRequirements"></div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<mavon-editor v-else |
|
|
|
|
class="md" |
|
|
|
|
v-model="item.experimentalRequirements" |
|
|
|
|
defaultOpen="preview" |
|
|
|
|
:ishljs="true" |
|
|
|
|
:subfield="false" |
|
|
|
|
:editable="false" |
|
|
|
|
:toolbarsFlag="false" |
|
|
|
|
boxShadowStyle="none" /> |
|
|
|
|
<mavon-editor v-else class="md" v-model="item.experimentalRequirements" defaultOpen="preview" |
|
|
|
|
:ishljs="true" :subfield="false" :editable="false" :toolbarsFlag="false" boxShadowStyle="none" /> |
|
|
|
|
</el-collapse-item> |
|
|
|
|
</el-collapse> |
|
|
|
|
</el-tab-pane> |
|
|
|
|
<el-tab-pane label="实验提示" |
|
|
|
|
name="third" |
|
|
|
|
v-if="hintOpen"> |
|
|
|
|
<div v-if="pd.experimentHintType == 0 || !pd.experimentHintType" |
|
|
|
|
class="ql-snow"> |
|
|
|
|
<div class="ql-editor" |
|
|
|
|
v-html="pd.experimentHint"></div> |
|
|
|
|
<el-tab-pane label="实验提示" name="third" v-if="hintOpen"> |
|
|
|
|
<div v-if="pd.experimentHintType == 0 || !pd.experimentHintType" class="ql-snow"> |
|
|
|
|
<div class="ql-editor" v-html="pd.experimentHint"></div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<mavon-editor v-else |
|
|
|
|
class="md" |
|
|
|
|
v-model="pd.experimentHint" |
|
|
|
|
defaultOpen="preview" |
|
|
|
|
:ishljs="true" |
|
|
|
|
:subfield="false" |
|
|
|
|
:editable="false" |
|
|
|
|
:toolbarsFlag="false" |
|
|
|
|
boxShadowStyle="none" /> |
|
|
|
|
<mavon-editor v-else class="md" v-model="pd.experimentHint" defaultOpen="preview" :ishljs="true" |
|
|
|
|
:subfield="false" :editable="false" :toolbarsFlag="false" boxShadowStyle="none" /> |
|
|
|
|
</el-tab-pane> |
|
|
|
|
</el-tabs> |
|
|
|
|
</el-main> |
|
|
|
|
</el-container> |
|
|
|
|
</el-container> |
|
|
|
|
|
|
|
|
|
<div :class="['toggle-panel', {active: pannelVisible}]"> |
|
|
|
|
<div :class="['toggle-panel', { active: pannelVisible }]"> |
|
|
|
|
<!-- <div @click="togglePannel"> --> |
|
|
|
|
<i class="el-icon-rank drag-icon" |
|
|
|
|
id="drag"></i> |
|
|
|
|
<img :src="require(`@/assets/images/system/${$themeId}/left.png`)" |
|
|
|
|
alt |
|
|
|
|
class="c-p" |
|
|
|
|
@click="togglePannel" |
|
|
|
|
v-if="pannelVisible" /> |
|
|
|
|
<img :src="require(`@/assets/images/system/${$themeId}/right.png`)" |
|
|
|
|
alt |
|
|
|
|
class="c-p" |
|
|
|
|
@click="togglePannel" |
|
|
|
|
v-if="!pannelVisible" /> |
|
|
|
|
<i class="el-icon-rank drag-icon" id="drag"></i> |
|
|
|
|
<img :src="require(`@/assets/images/system/${$themeId}/left.png`)" alt class="c-p" @click="togglePannel" |
|
|
|
|
v-if="pannelVisible" /> |
|
|
|
|
<img :src="require(`@/assets/images/system/${$themeId}/right.png`)" alt class="c-p" @click="togglePannel" |
|
|
|
|
v-if="!pannelVisible" /> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
@ -440,13 +336,7 @@ export default { |
|
|
|
|
// 获取项目列表 |
|
|
|
|
this.getList().then(() => { |
|
|
|
|
if (!this.isSubmit) { |
|
|
|
|
let cache = localStorage.getItem('codeCache') // 获取本地缓存 |
|
|
|
|
// 如果有缓存,再调接口取上次运行的代码 |
|
|
|
|
if (cache) { |
|
|
|
|
this.getCache(JSON.parse(cache)) |
|
|
|
|
} else { |
|
|
|
|
this.getCache() |
|
|
|
|
} |
|
|
|
|
this.getCache() |
|
|
|
|
} else { |
|
|
|
|
this.closeLoad() |
|
|
|
|
} |
|
|
|
@ -620,120 +510,85 @@ export default { |
|
|
|
|
}).catch(res => { }) |
|
|
|
|
}, |
|
|
|
|
// 获取上次缓存记录 |
|
|
|
|
async getCache (cache) { |
|
|
|
|
async getCache () { |
|
|
|
|
if (this.isSubmit) { |
|
|
|
|
this.closeLoad() |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
const pId = cache ? cache.projectId : '' |
|
|
|
|
const projectId = Number(pId || this.projectId) |
|
|
|
|
const projectId = +this.projectId |
|
|
|
|
const cid = this.courseId |
|
|
|
|
const { assessmentId } = this |
|
|
|
|
const list = this.projectList |
|
|
|
|
let points = [] |
|
|
|
|
if (pId && cache.judgmentIdList && !Cookie.get('admin-projectId')) { |
|
|
|
|
cache.judgmentIdList.map(e => { |
|
|
|
|
points.push({ |
|
|
|
|
judgmentId: e |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
} else { |
|
|
|
|
// 深拷贝判分列表,下面接口获取到有缓存代码就直接存进去,如果用户选择了恢复代码,再用这个列表替换原来的判分列表 |
|
|
|
|
points = JSON.parse(JSON.stringify(this.points)) |
|
|
|
|
} |
|
|
|
|
const points = JSON.parse(JSON.stringify(this.points)) |
|
|
|
|
// 如果是没有代码的缓存,则只需要恢复项目,否则,就调接口查询缓存代码 |
|
|
|
|
if (cache && cache.empty && list.find(e => e.projectId === projectId) && !Cookie.get('admin-projectId')) { |
|
|
|
|
if (Cookie.get('admin-projectId') && !this.competitionId) { |
|
|
|
|
Cookie.remove('admin-projectId') |
|
|
|
|
} else { |
|
|
|
|
if (Cookie.get('admin-projectId') && this.projectPermissions == 0) { |
|
|
|
|
Cookie.remove('admin-projectId') |
|
|
|
|
} |
|
|
|
|
let newJudgmentId = '' // 要恢复到第一个有代码的判分规则,因为有代码的规则可能不是第一个,所以要判断如果这个为空,才把索引赋给该变量 |
|
|
|
|
const promiseList = [] // promise数组 |
|
|
|
|
let hasCache = 0 // 是否有缓存 |
|
|
|
|
points.map((e, i) => { |
|
|
|
|
const judgmentId = e.judgmentId |
|
|
|
|
promiseList.push(new Promise((resolve, reject) => { |
|
|
|
|
this.$post(this.api.getLastCache, { |
|
|
|
|
competitionId: this.competitionId, |
|
|
|
|
assessmentId: assessmentId ? Number(assessmentId) : '', |
|
|
|
|
bcId: judgmentId, |
|
|
|
|
projectId, // 项目id,同上 |
|
|
|
|
cid // 课程id |
|
|
|
|
}).then(res => { |
|
|
|
|
this.closeLoad() |
|
|
|
|
const result = res.runRecord |
|
|
|
|
// 如果有缓存代码 |
|
|
|
|
if (result) { |
|
|
|
|
hasCache = 1 |
|
|
|
|
if (newJudgmentId === '') newJudgmentId = i |
|
|
|
|
e.finalCode = result.code |
|
|
|
|
e.code = result.code |
|
|
|
|
e.codeId = result.id |
|
|
|
|
e.answer = result.runResult |
|
|
|
|
e.retResult = result.retResult |
|
|
|
|
e.photoUrl = result.runPhotoUrl |
|
|
|
|
} |
|
|
|
|
resolve() |
|
|
|
|
}).catch(res => { |
|
|
|
|
reject() |
|
|
|
|
this.closeLoad() |
|
|
|
|
}) |
|
|
|
|
})) |
|
|
|
|
}) |
|
|
|
|
// 如果有缓存代码,再提示用户是否要继续上次的实验 |
|
|
|
|
Promise.all(promiseList).then(_ => { |
|
|
|
|
hasCache && this.$confirm('是否要继续上次的操作记录?', '提示', { |
|
|
|
|
confirmButtonText: '是', |
|
|
|
|
cancelButtonText: '否', |
|
|
|
|
type: 'success', |
|
|
|
|
closeOnClickModal: false |
|
|
|
|
}).then(() => { |
|
|
|
|
this.projectId = projectId |
|
|
|
|
this.getProDetail() |
|
|
|
|
} |
|
|
|
|
this.closeLoad() |
|
|
|
|
localStorage.removeItem('codeCache') |
|
|
|
|
} else { |
|
|
|
|
if (Cookie.get('admin-projectId') && this.projectPermissions == 0) { |
|
|
|
|
Cookie.remove('admin-projectId') |
|
|
|
|
} |
|
|
|
|
let newJudgmentId = '' // 要恢复到第一个有代码的判分规则,因为有代码的规则可能不是第一个,所以要判断如果这个为空,才把索引赋给该变量 |
|
|
|
|
const promiseList = [] // promise数组 |
|
|
|
|
let hasCache = 0 // 是否有缓存 |
|
|
|
|
points.map((e, i) => { |
|
|
|
|
const judgmentId = e.judgmentId |
|
|
|
|
promiseList.push(new Promise((resolve, reject) => { |
|
|
|
|
this.$post(this.api.getLastCache, { |
|
|
|
|
// 恢复第一个判分点的代码 |
|
|
|
|
this.points.map(e => { |
|
|
|
|
const item = points.find(n => n.judgmentId === e.judgmentId) |
|
|
|
|
item.finalCode && this.$set(e, 'finalCode', item.finalCode) |
|
|
|
|
item.code && this.$set(e, 'code', item.code) |
|
|
|
|
item.codeId && this.$set(e, 'codeId', item.codeId) |
|
|
|
|
item.answer && this.$set(e, 'answer', item.answer) |
|
|
|
|
item.photoUrl && this.$set(e, 'photoUrl', item.photoUrl) |
|
|
|
|
this.$set(e, 'retResult', isNaN(item.retResult) ? '' : item.retResult) |
|
|
|
|
}) |
|
|
|
|
this.$emit('tell', projectId, this.curSystemId, this.points) |
|
|
|
|
this.$emit('recoveryCode') |
|
|
|
|
}).catch(() => { |
|
|
|
|
points.map(async (e) => { |
|
|
|
|
await this.$post(this.api.deleteTheLastUncommittedRecord, { |
|
|
|
|
competitionId: this.competitionId, |
|
|
|
|
assessmentId: assessmentId ? Number(assessmentId) : '', |
|
|
|
|
bcId: judgmentId, |
|
|
|
|
bcId: e.judgmentId, |
|
|
|
|
projectId, // 项目id,同上 |
|
|
|
|
cid // 课程id |
|
|
|
|
}).then(res => { |
|
|
|
|
this.closeLoad() |
|
|
|
|
const result = res.runRecord |
|
|
|
|
// 如果有缓存代码 |
|
|
|
|
if (result) { |
|
|
|
|
hasCache = 1 |
|
|
|
|
if (newJudgmentId === '') newJudgmentId = i |
|
|
|
|
e.finalCode = result.code |
|
|
|
|
e.code = result.code |
|
|
|
|
e.codeId = result.id |
|
|
|
|
e.answer = result.runResult |
|
|
|
|
e.retResult = result.retResult |
|
|
|
|
e.photoUrl = result.runPhotoUrl |
|
|
|
|
} |
|
|
|
|
resolve() |
|
|
|
|
}).catch(res => { |
|
|
|
|
reject() |
|
|
|
|
this.closeLoad() |
|
|
|
|
}) |
|
|
|
|
})) |
|
|
|
|
}) |
|
|
|
|
// 如果有缓存代码,再提示用户是否要继续上次的实验 |
|
|
|
|
Promise.all(promiseList).then(_ => { |
|
|
|
|
hasCache && this.$confirm('是否要继续上次的操作记录?', '提示', { |
|
|
|
|
confirmButtonText: '是', |
|
|
|
|
cancelButtonText: '否', |
|
|
|
|
type: 'success', |
|
|
|
|
closeOnClickModal: false |
|
|
|
|
}).then(() => { |
|
|
|
|
localStorage.removeItem('codeCache') // 恢复代码后清除本地缓存 |
|
|
|
|
this.projectId = projectId |
|
|
|
|
// 如果是本地缓存里有项目id,则要再次获取项目详情,取判分列表再次赋值;本地没有缓存则取只恢复第一个判分点的代码 |
|
|
|
|
if (pId) { |
|
|
|
|
this.getProDetail().then(() => { |
|
|
|
|
this.points.map(e => { |
|
|
|
|
const item = points.find(n => n.judgmentId === e.judgmentId) |
|
|
|
|
if (item) { |
|
|
|
|
item.finalCode && this.$set(e, 'finalCode', item.finalCode) |
|
|
|
|
item.code && this.$set(e, 'code', item.code) |
|
|
|
|
item.codeId && this.$set(e, 'codeId', item.codeId) |
|
|
|
|
item.answer && this.$set(e, 'answer', item.answer) |
|
|
|
|
item.photoUrl && this.$set(e, 'photoUrl', item.photoUrl) |
|
|
|
|
this.$set(e, 'retResult', isNaN(item.retResult) ? '' : item.retResult) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
this.$emit('tell', projectId, this.curSystemId, this.points) |
|
|
|
|
this.$emit('recoveryCode', newJudgmentId + '') // 切换为缓存的判分点,tab索引值要为字符串 |
|
|
|
|
}).catch(res => { }) |
|
|
|
|
} else { |
|
|
|
|
this.points.map(e => { |
|
|
|
|
const item = points.find(n => n.judgmentId === e.judgmentId) |
|
|
|
|
item.finalCode && this.$set(e, 'finalCode', item.finalCode) |
|
|
|
|
item.code && this.$set(e, 'code', item.code) |
|
|
|
|
item.codeId && this.$set(e, 'codeId', item.codeId) |
|
|
|
|
item.answer && this.$set(e, 'answer', item.answer) |
|
|
|
|
item.photoUrl && this.$set(e, 'photoUrl', item.photoUrl) |
|
|
|
|
this.$set(e, 'retResult', isNaN(item.retResult) ? '' : item.retResult) |
|
|
|
|
}) |
|
|
|
|
this.$emit('tell', projectId, this.curSystemId, this.points) |
|
|
|
|
this.$emit('recoveryCode') |
|
|
|
|
} |
|
|
|
|
}).catch(() => { |
|
|
|
|
// 选择了不继续上次的实验,则清除本地缓存,并删除服务器里缓存的代码 |
|
|
|
|
localStorage.removeItem('codeCache') |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}, |
|
|
|
|
// 查询考核状态(查到考核如果结束后,直接提交考核) |
|
|
|
|
getAssStatus () { |
|
|
|
@ -822,7 +677,6 @@ export default { |
|
|
|
|
async reload () { |
|
|
|
|
this.reloadCount() |
|
|
|
|
this.grade = '00' |
|
|
|
|
localStorage.removeItem('codeCache') |
|
|
|
|
this.setSubmit(false) |
|
|
|
|
const points = this.points |
|
|
|
|
// code和codeId,还有运行结果全部清空 |
|
|
|
@ -870,7 +724,6 @@ export default { |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
vscodeRunCode (data) { |
|
|
|
|
console.log("🚀 ~ vscodeRunCode ~ data:", data, this.$parent.workbench) |
|
|
|
|
const i = +data.sort |
|
|
|
|
this.$parent.workbench[i].codeId = data.codeId |
|
|
|
|
this.$parent.workbench[i].retResult = 1 |
|
|
|
@ -995,7 +848,6 @@ export default { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.$post(this.api.submit, data).then(({ retInfo, reportId }) => { |
|
|
|
|
localStorage.removeItem('codeCache') |
|
|
|
|
this.setSubmit(true) |
|
|
|
|
this.reportVisible = false |
|
|
|
|
let list = retInfo |
|
|
|
@ -1316,24 +1168,29 @@ export default { |
|
|
|
|
margin: 0px 20px 10px 10px; |
|
|
|
|
overflow: hidden; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.panel-header { |
|
|
|
|
display: flex; |
|
|
|
|
justify-content: space-between; |
|
|
|
|
align-items: center; |
|
|
|
|
flex-wrap: wrap; |
|
|
|
|
height: auto !important; |
|
|
|
|
flex-wrap: wrap; |
|
|
|
|
height: auto !important; |
|
|
|
|
|
|
|
|
|
.project { |
|
|
|
|
display: inline-flex; |
|
|
|
|
align-items: center; |
|
|
|
|
width: 28%; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.item { |
|
|
|
|
font-size: 16px; |
|
|
|
|
margin: 0 10px; |
|
|
|
|
padding: 20px 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.count { |
|
|
|
|
margin-left: -40px; |
|
|
|
|
|
|
|
|
|
span { |
|
|
|
|
padding: 5px 15px; |
|
|
|
|
margin: 0 5px; |
|
|
|
@ -1344,149 +1201,187 @@ export default { |
|
|
|
|
border-radius: 18px; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.total-score { |
|
|
|
|
padding: 10px; |
|
|
|
|
font-size: 14px; |
|
|
|
|
text-align: center; |
|
|
|
|
border-radius: 6px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.submit { |
|
|
|
|
width: 106px; |
|
|
|
|
font-size: 16px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.reload { |
|
|
|
|
color: #d0d0d0; |
|
|
|
|
font-size: 16px; |
|
|
|
|
background-color: #202020; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.whitespace-nowrap { |
|
|
|
|
white-space: nowrap; |
|
|
|
|
white-space: nowrap; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.des { |
|
|
|
|
font-size: 16px; |
|
|
|
|
font-family: 'Microsoft YaHei'; |
|
|
|
|
|
|
|
|
|
img { |
|
|
|
|
max-width: 100%; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.ql-editor { |
|
|
|
|
font-family: 'Microsoft Yahei'; |
|
|
|
|
font-size: 13px; |
|
|
|
|
|
|
|
|
|
.ql-syntax { |
|
|
|
|
font-family: 'Microsoft Yahei'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.el-collapse-item__wrap { |
|
|
|
|
border-bottom: none; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.el-collapse-item__header { |
|
|
|
|
border-bottom: none; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.el-icon-s-ticket:before { |
|
|
|
|
padding: 5px; |
|
|
|
|
font-size: 16px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.el-collapse-item__arrow { |
|
|
|
|
margin: 0 5px 0 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.info-tab.el-tabs--card { |
|
|
|
|
.el-tabs__item { |
|
|
|
|
font-size: 16px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.el-tabs__item.is-active { |
|
|
|
|
color: #fff; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.el-tabs__header .el-tabs__nav { |
|
|
|
|
border: none; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.el-tabs__header .el-tabs__item { |
|
|
|
|
border-left: none; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.el-tabs__header { |
|
|
|
|
padding: 5px 20px; |
|
|
|
|
border-bottom: none; |
|
|
|
|
} |
|
|
|
|
& > .el-tabs__content { |
|
|
|
|
|
|
|
|
|
&>.el-tabs__content { |
|
|
|
|
margin: 0 20px; |
|
|
|
|
max-height: calc(60vh - 70px); |
|
|
|
|
overflow: auto; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.el-collapse { |
|
|
|
|
border-bottom: none; |
|
|
|
|
border-top: none; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.el-aside { |
|
|
|
|
margin-bottom: 10px; |
|
|
|
|
color: #333; |
|
|
|
|
background-color: #fff; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.el-aside /deep/[class*=' el-icon-'], |
|
|
|
|
[class^='el-icon-'] { |
|
|
|
|
line-height: 40px; |
|
|
|
|
font-size: 16px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.aside-header { |
|
|
|
|
margin: 0px 10px 10px 10px; |
|
|
|
|
background-color: #fff; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.aside-footer { |
|
|
|
|
margin: 0px 10px 10px 10px; |
|
|
|
|
background-color: #fff; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.p-title { |
|
|
|
|
display: flex; |
|
|
|
|
justify-content: center; |
|
|
|
|
height: 40px; |
|
|
|
|
|
|
|
|
|
&.system4 { |
|
|
|
|
background-size: 100% 58px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
&.system7, |
|
|
|
|
&.system9 { |
|
|
|
|
background-size: 100% 40px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
&.system8, |
|
|
|
|
&.system6 { |
|
|
|
|
background-size: 100% 61px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
p { |
|
|
|
|
padding-left: 10px; |
|
|
|
|
line-height: 40px; |
|
|
|
|
font-size: 16px; |
|
|
|
|
color: #fff; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
i { |
|
|
|
|
color: #fff; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.el-card__body { |
|
|
|
|
padding: 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.task-table { |
|
|
|
|
font-size: 12px; |
|
|
|
|
|
|
|
|
|
thead { |
|
|
|
|
color: #fff; |
|
|
|
|
font-size: 10px; |
|
|
|
|
} |
|
|
|
|
th > .cell { |
|
|
|
|
|
|
|
|
|
th>.cell { |
|
|
|
|
font-weight: 100; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
td, |
|
|
|
|
th.is-leaf { |
|
|
|
|
border-bottom: 0 !important; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.el-table__cell { |
|
|
|
|
padding: 6px 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.goal { |
|
|
|
|
padding: 10px 0; |
|
|
|
|
margin: 0 10px; |
|
|
|
|
font-size: 14px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.select { |
|
|
|
|
min-width: 180px; |
|
|
|
|
min-width: 180px; |
|
|
|
|
|
|
|
|
|
.el-select__caret:before { |
|
|
|
|
content: '\e78f'; |
|
|
|
|
padding: 3px; |
|
|
|
@ -1494,12 +1389,15 @@ export default { |
|
|
|
|
color: #fff; |
|
|
|
|
border-radius: 50%; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.el-input__icon { |
|
|
|
|
line-height: 60px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.el-input { |
|
|
|
|
padding: 10px 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.el-input--suffix .el-input__inner { |
|
|
|
|
height: 40px !important; |
|
|
|
|
padding-right: 50px; |
|
|
|
@ -1514,6 +1412,7 @@ export default { |
|
|
|
|
white-space: nowrap; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.panel { |
|
|
|
|
z-index: 1000; |
|
|
|
|
position: relative; |
|
|
|
@ -1522,16 +1421,20 @@ export default { |
|
|
|
|
left: 0; |
|
|
|
|
width: 0; |
|
|
|
|
height: 0; |
|
|
|
|
|
|
|
|
|
.toggle-panel { |
|
|
|
|
position: absolute; |
|
|
|
|
top: 60%; |
|
|
|
|
text-align: center; |
|
|
|
|
|
|
|
|
|
&.active { |
|
|
|
|
left: 100%; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
img { |
|
|
|
|
height: 150px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.drag-icon { |
|
|
|
|
font-size: 20px; |
|
|
|
|
line-height: 1; |
|
|
|
@ -1539,45 +1442,56 @@ export default { |
|
|
|
|
cursor: pointer; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
&.active { |
|
|
|
|
position: fixed; |
|
|
|
|
width: 85%; |
|
|
|
|
height: 70%; |
|
|
|
|
|
|
|
|
|
.toggle-panel { |
|
|
|
|
top: 38%; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.el-container { |
|
|
|
|
height: 100%; |
|
|
|
|
|
|
|
|
|
&.is-vertical { |
|
|
|
|
background-color: #f5f5f5; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.right { |
|
|
|
|
color: #00af00; |
|
|
|
|
font-size: 20px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.wrong { |
|
|
|
|
color: #f00; |
|
|
|
|
font-size: 20px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.info { |
|
|
|
|
color: #bfbfbf; |
|
|
|
|
cursor: pointer; |
|
|
|
|
|
|
|
|
|
&:hover { |
|
|
|
|
opacity: 0.9; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.report-table.el-table { |
|
|
|
|
th { |
|
|
|
|
background-color: #c6daff !important; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.report-wrap { |
|
|
|
|
position: relative; |
|
|
|
|
padding-top: 5px; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.close-report { |
|
|
|
|
z-index: 2; |
|
|
|
|
position: absolute; |
|
|
|
@ -1587,41 +1501,47 @@ export default { |
|
|
|
|
color: #c6daff; |
|
|
|
|
cursor: pointer; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/deep/.v-note-wrapper { |
|
|
|
|
min-height: 0; |
|
|
|
|
height: auto; |
|
|
|
|
font-family: 'Microsoft Yahei'; |
|
|
|
|
|
|
|
|
|
.v-note-panel .v-note-show { |
|
|
|
|
font-family: 'Microsoft Yahei'; |
|
|
|
|
overflow: visible; |
|
|
|
|
|
|
|
|
|
.v-show-content { |
|
|
|
|
font-family: 'Microsoft Yahei'; |
|
|
|
|
overflow: visible; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pre, |
|
|
|
|
code { |
|
|
|
|
font-family: 'Microsoft Yahei'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
.text-danger { |
|
|
|
|
color: #f56c6c; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@media (max-width: 1550px) { |
|
|
|
|
.panel-header { |
|
|
|
|
.count { |
|
|
|
|
margin-left: 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.panel-header { |
|
|
|
|
.count { |
|
|
|
|
margin-left: 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@media (max-width: 1400px) { |
|
|
|
|
.panel-header { |
|
|
|
|
.actions { |
|
|
|
|
position: absolute; |
|
|
|
|
top: 70px; |
|
|
|
|
right: 30px; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.panel-header { |
|
|
|
|
.actions { |
|
|
|
|
position: absolute; |
|
|
|
|
top: 70px; |
|
|
|
|
right: 30px; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
</style> |