dev_202412
yujialong 8 months ago
parent c84ccc6ce0
commit d11e9ed59b
  1. 355
      src/pages/achievement/info/course.vue
  2. 379
      src/pages/achievement/info/project.vue
  3. 1
      src/pages/achievement/show/index.vue
  4. 390
      src/pages/match/manage/matchReport.vue
  5. 311
      src/pages/project/add/index.vue
  6. 4
      src/pages/station/preview/index.vue
  7. 202
      src/plugins/requests/index.js
  8. 2
      src/setting.js

@ -1,32 +1,20 @@
<template> <template>
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20 head-card">
class="m-b-20 head-card">
<div class="flex-between m-b-20"> <div class="flex-between m-b-20">
<el-page-header @back="back" <el-page-header @back="back" :content="goodsName"></el-page-header>
:content="goodsName"></el-page-header>
</div> </div>
</el-card> </el-card>
<div v-loading="loading"> <div v-loading="loading">
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20"> <el-tabs v-model="classId" @tab-click="classChange">
<el-tabs v-model="classId" <el-tab-pane v-for="(item, i) in classList" :key="i" :name="item.id" :label="item.className"></el-tab-pane>
@tab-click="classChange">
<el-tab-pane v-for="(item, i) in classList"
:key="i"
:name="item.id"
:label="item.className"></el-tab-pane>
</el-tabs> </el-tabs>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20"> <el-tabs v-model="curTab" @tab-click="tabChange">
<el-tabs v-model="curTab" <el-tab-pane v-for="(item) in tabs" :label="item.name" :name="item.id" :key="item.id"></el-tab-pane>
@tab-click="tabChange">
<el-tab-pane v-for="(item) in tabs"
:label="item.name"
:name="item.id"
:key="item.id"></el-tab-pane>
</el-tabs> </el-tabs>
<div class="stat"> <div class="stat">
<div class="nums"> <div class="nums">
@ -47,224 +35,138 @@
<p class="val">{{ minScore || 0 }}</p> <p class="val">{{ minScore || 0 }}</p>
</div> </div>
</div> </div>
<div class="chart" <div class="chart" id="chart"></div>
id="chart"></div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<h6 style="font-size: 16px">错误率分析</h6> <h6 style="font-size: 16px">错误率分析</h6>
<div class="wrong"> <div class="wrong">
<div class="line"> <div class="line">
<span class="jud-name">错误率最高{{ max.projectName }}</span> <span class="jud-name">错误率最高{{ max.projectName }}</span>
<span>参加考试{{ permissions ? (max.numberOfParticipants || 0) : (max.quantityAfterWeightRemoval || 0) }}&emsp;&emsp;{{ curTab == 1 ? `${max.itemErrorCount || 0}人做错,` : '' }}错误率{{ max.errorRate || 0 }}%</span> <span>参加考试{{ permissions ? (max.numberOfParticipants || 0) : (max.quantityAfterWeightRemoval || 0)
}}&emsp;&emsp;{{ curTab == 1 ? `${max.itemErrorCount || 0}人做错,` : '' }}错误率{{ max.errorRate || 0
}}%</span>
</div> </div>
<div class="line"> <div class="line">
<span class="jud-name">错误率最低{{ min.projectName }}</span> <span class="jud-name">错误率最低{{ min.projectName }}</span>
<span>参加考试{{ permissions ? (min.numberOfParticipants || 0) : (min.quantityAfterWeightRemoval || 0) }}&emsp;&emsp;{{ curTab == 1 ? `${min.itemErrorCount || 0}人做错,` : '' }}错误率{{ min.errorRate || 0 }}%</span> <span>参加考试{{ permissions ? (min.numberOfParticipants || 0) : (min.quantityAfterWeightRemoval || 0)
}}&emsp;&emsp;{{ curTab == 1 ? `${min.itemErrorCount || 0}人做错,` : '' }}错误率{{ min.errorRate || 0
}}%</span>
</div> </div>
</div> </div>
<div class="chart" <div class="chart" id="chart1"></div>
id="chart1"></div>
</el-card> </el-card>
<el-card shadow="hover"> <el-card shadow="hover">
<div class="flex-between m-b-20"> <div class="flex-between m-b-20">
<div> <div>
<el-input placeholder="请输入姓名/学号" <el-input placeholder="请输入姓名/学号" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
prefix-icon="el-icon-search"
v-model="keyword"
clearable></el-input>
</div> </div>
<div> <div>
<el-button type="primary" <el-button type="primary" @click="exportData">导出成绩列表</el-button>
@click="exportData">导出成绩列表</el-button>
<!-- <el-button type="primary" <!-- <el-button type="primary"
@click="exportReport">导出成绩详情</el-button> --> @click="exportReport">导出成绩详情</el-button> -->
</div> </div>
</div> </div>
<el-table :data="listData" <el-table :data="listData" class="table" ref="table" :key="curTab" stripe header-align="center"
class="table" @selection-change="handleSelectionChange" row-key="reportId">
ref="table" <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
:key="curTab" <el-table-column type="index" width="60" label="序号" align="center">
stripe
header-align="center"
@selection-change="handleSelectionChange"
row-key="reportId">
<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">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + (page - 1) * pageSize + 1 }} {{ scope.$index + (page - 1) * pageSize + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="userName" <el-table-column prop="userName" label="姓名" align="center"></el-table-column>
label="姓名" <el-table-column prop="workNumber" label="学号" align="center"></el-table-column>
align="center"></el-table-column>
<el-table-column prop="workNumber"
label="学号"
align="center"></el-table-column>
<template v-if="curTab == 0"> <template v-if="curTab == 0">
<el-table-column label="练习项目数" <el-table-column label="练习项目数" align="center">
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.totalNumberOfPractices }} {{ scope.row.totalNumberOfPractices }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="numberOfExercises" <el-table-column prop="numberOfExercises" label="练习次数" width="90" align="center"></el-table-column>
label="练习次数" <el-table-column label="累计练习时长" align="center">
width="90"
align="center"></el-table-column>
<el-table-column label="累计练习时长"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.cumulativePracticeTime }}min {{ scope.row.cumulativePracticeTime }}min
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
<template v-else> <template v-else>
<el-table-column prop="totalNumberOfParticipants" <el-table-column prop="totalNumberOfParticipants" label="参加考核次数" align="center">
label="参加考核次数"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="averageTimeSpent" <el-table-column prop="averageTimeSpent" label="平均用时" align="center">
label="平均用时"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.averageTimeSpent }}min {{ scope.row.averageTimeSpent }}min
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
<el-table-column prop="avgScore" <el-table-column prop="avgScore" label="平均分" align="center">
label="平均分"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ curTab == 0 ? scope.row.avgScore : scope.row.averageScore }} {{ curTab == 0 ? scope.row.avgScore : scope.row.averageScore }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="maxScore" <el-table-column prop="maxScore" label="最高分" align="center"></el-table-column>
label="最高分" <el-table-column prop="minScore" label="最低分" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column label="操作" align="center" width="140">
<el-table-column prop="minScore"
label="最低分"
align="center"></el-table-column>
<el-table-column label="操作"
align="center"
width="140">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" <el-button type="text" @click="show(scope.row)">查看成绩详情</el-button>
@click="show(scope.row)">查看成绩详情</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background layout="total, prev, pager, next" :total="total"
layout="total, prev, pager, next" @current-change="handleCurrentChange" :current-page="page">
:total="total"
@current-change="handleCurrentChange"
:current-page="page">
</el-pagination> </el-pagination>
</div> </div>
</el-card> </el-card>
</el-card> </el-card>
<el-dialog title="成绩详情" <el-dialog title="成绩详情" :visible.sync="detailVisible" width="900px" :key="curTab" :close-on-click-modal="false">
:visible.sync="detailVisible"
width="900px"
:key="curTab"
:close-on-click-modal="false">
<div class="m-b-10 text-right"> <div class="m-b-10 text-right">
<el-button type="primary" <el-button type="primary" @click="exportDetail">导出</el-button>
@click="exportDetail">导出</el-button>
</div> </div>
<el-table :data="details" <el-table :data="details" stripe :key="curTab" header-align="center" row-key="id">
stripe <el-table-column type="index" width="60" label="序号" align="center">
:key="curTab"
header-align="center"
row-key="id">
<el-table-column type="index"
width="60"
label="序号"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + (pageDetail - 1) * pageSizeDetail + 1 }} {{ scope.$index + (pageDetail - 1) * pageSizeDetail + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="userName" <el-table-column prop="userName" label="姓名" width="100" align="center">
label="姓名"
width="100"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="workNumber" <el-table-column prop="workNumber" label="学号" width="100" align="center"></el-table-column>
label="学号"
width="100"
align="center"></el-table-column>
<template v-if="curTab == 0"> <template v-if="curTab == 0">
<el-table-column prop="projectName" <el-table-column prop="projectName" label="项目名称" min-width="200" align="center"></el-table-column>
label="项目名称" <el-table-column prop="averageDuration" label="平均练习时长" width="110" align="center">
min-width="200"
align="center"></el-table-column>
<el-table-column prop="averageDuration"
label="平均练习时长"
width="110"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.averageDuration }}min {{ scope.row.averageDuration }}min
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="averageScore" <el-table-column prop="averageScore" label="平均分" min-width="100" align="center"></el-table-column>
label="平均分"
min-width="100"
align="center"></el-table-column>
</template> </template>
<template v-else> <template v-else>
<el-table-column prop="experimentalName" <el-table-column prop="experimentalName" label="考核名称" min-width="200" align="center"></el-table-column>
label="考核名称" <el-table-column prop="averageDuration" label="用时" width="100" align="center">
min-width="200"
align="center"></el-table-column>
<el-table-column prop="averageDuration"
label="用时"
width="100"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.timeSum }}min {{ scope.row.timeSum }}min
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="score" <el-table-column prop="score" label="分数" min-width="100" align="center"></el-table-column>
label="分数"
min-width="100"
align="center"></el-table-column>
</template> </template>
<el-table-column label="成绩报告" <el-table-column label="成绩报告" align="center" width="90">
align="center"
width="90">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" <el-button type="text" @click="toReport(scope.row)">查看</el-button>
@click="toReport(scope.row)">查看</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background layout="total, prev, pager, next" :total="totalDetail" :page-size="pageSizeDetail"
layout="total, prev, pager, next" @current-change="handleCurrentDetailChange" :current-page="pageDetail">
:total="totalDetail"
:page-size="pageSizeDetail"
@current-change="handleCurrentDetailChange"
:current-page="pageDetail">
</el-pagination> </el-pagination>
</div> </div>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer"> <el-button size="small" type="primary" @click="detailVisible = false">确定</el-button>
<el-button size="small"
type="primary"
@click="detailVisible = false">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -448,20 +350,23 @@ export default {
// //
const list = this.multipleSelection.length ? this.multipleSelection : this.listDataAll const list = this.multipleSelection.length ? this.multipleSelection : this.listDataAll
list.forEach(async e => { list.forEach(async e => {
const { report, userScores } = await this.$get(`${this.api.reportDetail}?reportId=${e.reportId}`) if (e.reportId) {
userScores.map((e, i) => { try {
if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;') const { report, userScores } = await this.$get(`${this.api.reportDetail}?reportId=${e.reportId}`)
}) userScores.map((e, i) => {
for (const i in report) { if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
if (report[i] && typeof report[i] === 'string') report[i] = report[i].replace(/<[^>]+>/g, '') })
for (const i in report) {
if (report[i] && typeof report[i] === 'string') report[i] = report[i].replace(/<[^>]+>/g, '')
}
report.purpose = report.purpose.replace(/<[^>]+>/g, '')
const res = await this.$post(this.api[userScores.find(e => e.lcRuleRecords) ? 'exportBankExperimentReport' : 'exportLabReport'], {
...report,
experimentalData: userScores
})
util.downloadFileDirect(`${e.userName}的实验报告.docx`, new Blob([res]))
} catch (e) { }
} }
report.purpose = report.purpose.replace(/<[^>]+>/g, '')
this.$post(this.api[userScores.find(e => e.lcRuleRecords) ? 'exportBankExperimentReport' : 'exportLabReport'], {
...report,
experimentalData: userScores
}).then(res => {
util.downloadFileDirect(`${e.userName}的实验报告.docx`, new Blob([res]))
}).catch(res => { })
}) })
}, },
handleDelete (row) { // handleDelete (row) { //
@ -714,75 +619,85 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/ .head-card { /deep/ .head-card {
.el-card__body { .el-card__body {
padding-bottom: 0px; padding-bottom: 0px;
.el-tabs__header { .el-tabs__header {
margin-bottom: 1px; margin-bottom: 1px;
.el-tabs__nav-wrap::after { .el-tabs__nav-wrap::after {
display: none; display: none;
} }
.el-tabs__item { .el-tabs__item {
font-size: 18px; font-size: 18px;
} }
}
} }
}
} }
.chart { .chart {
height: 300px; height: 300px;
} }
.stat { .stat {
display: flex;
.nums {
display: flex; display: flex;
.nums { align-items: center;
display: flex; flex-wrap: wrap;
align-items: center; width: 640px;
flex-wrap: wrap; margin-right: 20px;
width: 640px;
margin-right: 20px;
.item { .item {
width: 300px; width: 300px;
padding: 30px 30px; padding: 30px 30px;
margin: 0 10px; margin: 0 10px;
box-sizing: border-box; box-sizing: border-box;
border-radius: 8px; border-radius: 8px;
background: url('../../../assets/img/total.png') 0 0/100% 100% no-repeat; background: url('../../../assets/img/total.png') 0 0/100% 100% no-repeat;
p {
font-size: 18px; p {
color: #ffffff; font-size: 18px;
} color: #ffffff;
.val { }
margin-top: 10px;
color: #ffffff; .val {
font-size: 36px; margin-top: 10px;
} color: #ffffff;
} font-size: 36px;
.item:nth-child(2) { }
background-image: url('../../../assets/img/avg.png'); }
}
.item:nth-child(3) { .item:nth-child(2) {
background-image: url('../../../assets/img/ach1.png'); background-image: url('../../../assets/img/avg.png');
} }
.item:nth-child(4) {
background-image: url('../../../assets/img/ach2.png'); .item:nth-child(3) {
} background-image: url('../../../assets/img/ach1.png');
} }
.chart {
width: calc(100% - 660px); .item:nth-child(4) {
background-image: url('../../../assets/img/ach2.png');
} }
}
.chart {
width: calc(100% - 660px);
}
} }
.wrong { .wrong {
.line { .line {
display: flex; display: flex;
width: 920px; width: 920px;
margin: 0 auto 10px; margin: 0 auto 10px;
.jud-name {
width: 500px; .jud-name {
margin-right: 100px; width: 500px;
} margin-right: 100px;
} }
}
} }
</style> </style>

@ -1,36 +1,26 @@
<template> <template>
<div> <div>
<div class="back-wrap"> <div class="back-wrap">
<span class="back" <span class="back" @click="back">返回 ></span>
@click="back">返回 ></span>
<span class="name">{{ experimentalName }}</span> <span class="name">{{ experimentalName }}</span>
</div> </div>
<div v-loading="loading"> <div v-loading="loading">
<el-card v-if="classes.length" <el-card v-if="classes.length" shadow="hover" class="m-b-20 head-card">
shadow="hover"
class="m-b-20 head-card">
<div class="flex-between m-b-20"> <div class="flex-between m-b-20">
<div> <div>
<span class="m-r-10">班级</span> <span class="m-r-10">班级</span>
<el-select v-model="classId" <el-select v-model="classId" clearable @change="initData">
clearable <el-option label="不限" value="">
@change="initData">
<el-option label="不限"
value="">
</el-option> </el-option>
<el-option v-for="item in classes" <el-option v-for="item in classes" :key="item.id" :label="item.className" :value="item.id">
:key="item.id"
:label="item.className"
:value="item.id">
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div class="stat"> <div class="stat">
<div class="nums"> <div class="nums">
<div class="item"> <div class="item">
@ -50,224 +40,124 @@
<p class="val">{{ minScore }}</p> <p class="val">{{ minScore }}</p>
</div> </div>
</div> </div>
<div class="chart" <div class="chart" id="chart"></div>
id="chart"></div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<h6 style="font-size: 16px">错误率分析</h6> <h6 style="font-size: 16px">错误率分析</h6>
<div class="wrong"> <div class="wrong">
<div class="line"> <div class="line">
<span class="jud-name">错误率最高{{ max.judgmentName }}</span> <span class="jud-name">错误率最高{{ max.judgmentName }}</span>
<span>参加考试{{ peopleNum }}&emsp;&emsp;{{ permissions ? `${max.errorTotal || 0}人做错,` : '' }}错误率{{ max.errorRate }}%</span> <span>参加考试{{ peopleNum }}&emsp;&emsp;{{ permissions ? `${max.errorTotal || 0}人做错,` : '' }}错误率{{
max.errorRate }}%</span>
</div> </div>
<div class="line"> <div class="line">
<span class="jud-name">错误率最低{{ min.judgmentName }}</span> <span class="jud-name">错误率最低{{ min.judgmentName }}</span>
<span>参加考试{{ peopleNum }}&emsp;&emsp;{{ permissions ? `${min.errorTotal || 0}人做错,` : '' }}错误率{{ min.errorRate }}%</span> <span>参加考试{{ peopleNum }}&emsp;&emsp;{{ permissions ? `${min.errorTotal || 0}人做错,` : '' }}错误率{{
min.errorRate }}%</span>
</div> </div>
</div> </div>
<div class="chart" <div class="chart" id="chart1"></div>
id="chart1"></div>
</el-card> </el-card>
<el-card shadow="hover"> <el-card shadow="hover">
<div class="flex-between m-b-10"> <div class="flex-between m-b-10">
<div> <div>
<el-tabs v-model="curTab" <el-tabs v-model="curTab" @tab-click="tabChange">
@tab-click="tabChange"> <el-tab-pane v-for="(item) in tabs" :label="item.name" :name="item.id" :key="item.id"></el-tab-pane>
<el-tab-pane v-for="(item) in tabs"
:label="item.name"
:name="item.id"
:key="item.id"></el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</div> </div>
<div class="flex-between m-b-20"> <div class="flex-between m-b-20">
<div> <div>
<el-input placeholder="请输入姓名/学号" <el-input placeholder="请输入姓名/学号" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
prefix-icon="el-icon-search"
v-model="keyword"
clearable></el-input>
</div> </div>
<div v-if="curTab == 0"> <div v-if="curTab == 0">
<el-button type="primary" <el-button type="primary" @click="delAllData">批量删除</el-button>
@click="delAllData">批量删除</el-button> <el-button type="primary" @click="exportData">导出成绩列表</el-button>
<el-button type="primary" <el-button type="primary" @click="exportReport">导出成绩报告</el-button>
@click="exportData">导出成绩列表</el-button>
<el-button type="primary"
@click="exportReport">导出成绩报告</el-button>
</div> </div>
<div v-else> <div v-else>
<el-button type="primary" <el-button type="primary" @click="exportDataActivation">导出</el-button>
@click="exportDataActivation">导出</el-button>
</div> </div>
</div> </div>
<template v-if="curTab == 0"> <template v-if="curTab == 0">
<el-table :data="listData" <el-table :data="listData" :key="1" class="table" ref="table" stripe header-align="center"
:key="1" @selection-change="handleSelectionChange" row-key="reportId">
class="table" <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
ref="table" <el-table-column type="index" width="60" label="序号" align="center">
stripe
header-align="center"
@selection-change="handleSelectionChange"
row-key="reportId">
<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">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + (page - 1) * pageSize + 1 }} {{ scope.$index + (page - 1) * pageSize + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="className" <el-table-column prop="className" label="班级" min-width="150" align="center">
label="班级"
min-width="150"
align="center">
</el-table-column> </el-table-column>
<el-table-column v-if="permissions" <el-table-column v-if="permissions" prop="experimentalName" label="考核名称" min-width="250"
prop="experimentalName" align="center"></el-table-column>
label="考核名称" <el-table-column prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column>
min-width="250" <el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="score" label="分数" width="90" align="center"></el-table-column>
<el-table-column prop="userName" <el-table-column prop="timeSum" label="耗时" width="90" align="center">
label="学生姓名"
min-width="100"
align="center"></el-table-column>
<el-table-column prop="workNumber"
label="学号"
min-width="100"
align="center"></el-table-column>
<el-table-column prop="score"
label="分数"
width="90"
align="center"></el-table-column>
<el-table-column prop="timeSum"
label="耗时"
width="90"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.timeSum + (scope.row.reportId ? 'min' : '') }} {{ scope.row.timeSum + (scope.row.reportId ? 'min' : '') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="submitTime" <el-table-column prop="submitTime" label="提交时间" min-width="150" align="center">
label="提交时间"
min-width="150"
align="center">
</el-table-column> </el-table-column>
<el-table-column v-if="permissions" <el-table-column v-if="permissions" prop="submitTime" label="状态" min-width="150" align="center">
prop="submitTime"
label="状态"
min-width="150"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.reportId ? '已参加' : '未参加' }} {{ scope.row.reportId ? '已参加' : '未参加' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="160">
align="center"
width="160">
<template slot-scope="scope"> <template slot-scope="scope">
<tempalte v-if="scope.row.reportId"> <tempalte v-if="scope.row.reportId">
<el-button type="text" <el-button type="text" @click="show(scope.row)">查看成绩报告</el-button>
@click="show(scope.row)">查看成绩报告</el-button> <el-button type="text" @click="handleDelete(scope.row)">删除</el-button>
<el-button type="text"
@click="handleDelete(scope.row)">删除</el-button>
</tempalte> </tempalte>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background layout="total, prev, pager, next" :total="total"
layout="total, prev, pager, next" @current-change="handleCurrentChange" :current-page="page">
:total="total"
@current-change="handleCurrentChange"
:current-page="page">
</el-pagination> </el-pagination>
</div> </div>
</template> </template>
<template v-else> <template v-else>
<el-table :data="activations" <el-table :data="activations" :key="2" ref="table" stripe header-align="center"
:key="2" @selection-change="handleSelectionActivationChange" row-key="reportId">
ref="table" <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
stripe <el-table-column type="index" width="60" label="序号" align="center">
header-align="center"
@selection-change="handleSelectionActivationChange"
row-key="reportId">
<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">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + (pageActivation - 1) * pageSizeActivation + 1 }} {{ scope.$index + (pageActivation - 1) * pageSizeActivation + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="className" <el-table-column prop="className" label="班级" min-width="150" align="center">
label="班级"
min-width="150"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="userName" <el-table-column prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column>
label="学生姓名" <el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column>
min-width="100" <el-table-column prop="practiceNum" label="练习次数" min-width="90" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="avgScore" label="实验平均分" min-width="90" align="center"></el-table-column>
<el-table-column prop="workNumber" <el-table-column prop="highestScore" label="实验最高分" min-width="90" align="center"></el-table-column>
label="学号" <el-table-column prop="lowestMark" label="实验最低分" min-width="90" align="center"></el-table-column>
min-width="100" <el-table-column prop="timeSum" label="耗时最多" min-width="90" align="center">
align="center"></el-table-column>
<el-table-column prop="practiceNum"
label="练习次数"
min-width="90"
align="center"></el-table-column>
<el-table-column prop="avgScore"
label="实验平均分"
min-width="90"
align="center"></el-table-column>
<el-table-column prop="highestScore"
label="实验最高分"
min-width="90"
align="center"></el-table-column>
<el-table-column prop="lowestMark"
label="实验最低分"
min-width="90"
align="center"></el-table-column>
<el-table-column prop="timeSum"
label="耗时最多"
min-width="90"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.theLongestTime }}min {{ scope.row.theLongestTime }}min
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="timeSum" <el-table-column prop="timeSum" label="耗时最少" min-width="90" align="center">
label="耗时最少"
min-width="90"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.shortestTime }}min {{ scope.row.shortestTime }}min
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="lastSubmissionTime" <el-table-column prop="lastSubmissionTime" label="最近提交时间" min-width="150" align="center">
label="最近提交时间"
min-width="150"
align="center">
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background layout="total, prev, pager, next" :total="totalActivation"
layout="total, prev, pager, next" @current-change="handleCurrentActivationChange" :current-page="pageActivation">
:total="totalActivation"
@current-change="handleCurrentActivationChange"
:current-page="pageActivation">
</el-pagination> </el-pagination>
</div> </div>
</template> </template>
@ -450,20 +340,23 @@ export default {
} }
list.forEach(async e => { list.forEach(async e => {
const { report, userScores } = await this.$get(`${this.api.reportDetail}?reportId=${e.reportId}`) if (e.reportId) {
userScores.map((e, i) => { try {
if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;') const { report, userScores } = await this.$get(`${this.api.reportDetail}?reportId=${e.reportId}`)
}) userScores.map((e, i) => {
for (const i in report) { if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
if (report[i] && typeof report[i] === 'string') report[i] = report[i].replace(/<[^>]+>/g, '') })
for (const i in report) {
if (report[i] && typeof report[i] === 'string') report[i] = report[i].replace(/<[^>]+>/g, '')
}
report.purpose = report.purpose.replace(/<[^>]+>/g, '')
const res = await this.$post(this.api[userScores.find(e => e.lcRuleRecords) ? 'exportBankExperimentReport' : 'exportLabReport'], {
...report,
experimentalData: userScores
})
util.downloadFileDirect(`${e.userName}的实验报告.docx`, new Blob([res]))
} catch (e) { }
} }
report.purpose = report.purpose.replace(/<[^>]+>/g, '')
this.$post(this.api[userScores.find(e => e.lcRuleRecords) ? 'exportBankExperimentReport' : 'exportLabReport'], {
...report,
experimentalData: userScores
}).then(res => {
util.downloadFileDirect(`${e.userName}的实验报告.docx`, new Blob([res]))
}).catch(res => { })
}) })
}, },
handleDelete (row) { // handleDelete (row) { //
@ -707,83 +600,95 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.back-wrap { .back-wrap {
margin-bottom: 20px; margin-bottom: 20px;
.back {
margin-right: 20px; .back {
color: #9278ff; margin-right: 20px;
cursor: pointer; color: #9278ff;
} cursor: pointer;
}
} }
/deep/ .head-card { /deep/ .head-card {
.el-card__body { .el-card__body {
padding-bottom: 0px; padding-bottom: 0px;
.el-tabs__header { .el-tabs__header {
margin-bottom: 1px; margin-bottom: 1px;
.el-tabs__nav-wrap::after { .el-tabs__nav-wrap::after {
display: none; display: none;
} }
.el-tabs__item { .el-tabs__item {
font-size: 18px; font-size: 18px;
} }
}
} }
}
} }
.chart { .chart {
height: 300px; height: 300px;
} }
.stat { .stat {
display: flex;
.nums {
display: flex; display: flex;
.nums { align-items: center;
display: flex; flex-wrap: wrap;
align-items: center; width: 640px;
flex-wrap: wrap; margin-right: 20px;
width: 640px;
margin-right: 20px;
.item { .item {
width: 300px; width: 300px;
padding: 30px 30px; padding: 30px 30px;
margin: 0 10px; margin: 0 10px;
box-sizing: border-box; box-sizing: border-box;
border-radius: 8px; border-radius: 8px;
background: url('../../../assets/img/total.png') 0 0/100% 100% no-repeat; background: url('../../../assets/img/total.png') 0 0/100% 100% no-repeat;
p {
font-size: 18px; p {
color: #ffffff; font-size: 18px;
} color: #ffffff;
.val { }
margin-top: 10px;
color: #ffffff; .val {
font-size: 36px; margin-top: 10px;
} color: #ffffff;
} font-size: 36px;
.item:nth-child(2) { }
background-image: url('../../../assets/img/avg.png'); }
}
.item:nth-child(3) { .item:nth-child(2) {
background-image: url('../../../assets/img/ach1.png'); background-image: url('../../../assets/img/avg.png');
} }
.item:nth-child(4) {
background-image: url('../../../assets/img/ach2.png'); .item:nth-child(3) {
} background-image: url('../../../assets/img/ach1.png');
} }
.chart {
width: calc(100% - 660px); .item:nth-child(4) {
background-image: url('../../../assets/img/ach2.png');
} }
}
.chart {
width: calc(100% - 660px);
}
} }
.wrong { .wrong {
.line { .line {
display: flex; display: flex;
width: 920px; width: 920px;
margin: 0 auto 10px; margin: 0 auto 10px;
.jud-name {
width: 500px; .jud-name {
margin-right: 100px; width: 500px;
} margin-right: 100px;
} }
}
} }
</style> </style>

@ -411,6 +411,7 @@ samp {
} }
.result-pic { .result-pic {
max-width: 100%;
margin: 10px 0; margin: 10px 0;
} }

@ -1,204 +1,137 @@
<template> <template>
<div class="wrap"> <div class="wrap">
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20"> <el-page-header @back="$router.back()" content="查看报告"></el-page-header>
<el-page-header @back="$router.back()"
content="查看报告"></el-page-header>
</el-card> </el-card>
<div class="content" <div class="content" v-loading="loading">
v-loading="loading">
<div class="text-right"> <div class="text-right">
<el-button type="primary" <el-button type="primary" @click="exportPage">导出报告</el-button>
@click="exportPage">导出报告</el-button>
</div> </div>
<h6 class="r-title">标准实验报告</h6> <h6 class="r-title">标准实验报告</h6>
<div class="info"> <div class="info">
<h6 class="l-title"> <h6 class="l-title">
<img src="@/assets/img/info1.png" <img src="@/assets/img/info1.png" alt="">
alt="">
基本信息 基本信息
</h6> </h6>
<ul :class="['info-list', {edit: editing}]"> <ul :class="['info-list', { edit: editing }]">
<li> <li>
<label>学生姓名</label> <label>学生姓名</label>
<el-input v-if="editing" <el-input v-if="editing" v-model="infoData.userName" disabled></el-input>
v-model="infoData.userName"
disabled></el-input>
<span v-else>{{ infoData.userName }}</span> <span v-else>{{ infoData.userName }}</span>
</li> </li>
<li> <li>
<label>学生学号</label> <label>学生学号</label>
<el-input v-if="editing" <el-input v-if="editing" v-model="infoData.workNumber" disabled></el-input>
v-model="infoData.workNumber"
disabled></el-input>
<span v-else>{{ infoData.workNumber }}</span> <span v-else>{{ infoData.workNumber }}</span>
</li> </li>
<li> <li>
<label>实验时间</label> <label>实验时间</label>
<el-input v-if="editing" <el-input v-if="editing" v-model="infoData.submitTime" disabled></el-input>
v-model="infoData.submitTime"
disabled></el-input>
<span v-else>{{ infoData.submitTime }}</span> <span v-else>{{ infoData.submitTime }}</span>
</li> </li>
<li> <li>
<label>实验成绩</label> <label>实验成绩</label>
<el-input v-if="editing" <el-input v-if="editing" v-model="infoData.score" disabled></el-input>
v-model="infoData.score" <div v-else class="score-wrap">
disabled></el-input>
<div v-else
class="score-wrap">
<em>{{ infoData.score }}</em> <em>{{ infoData.score }}</em>
<img src="@/assets/img/point.png" <img src="@/assets/img/point.png" alt="">
alt="">
</div> </div>
</li> </li>
<li> <li>
<label>学生班级</label> <label>学生班级</label>
<el-input v-if="editing" <el-input v-if="editing" v-model="infoData.className"></el-input>
v-model="infoData.className"></el-input>
<span v-else>{{ infoData.className }}</span> <span v-else>{{ infoData.className }}</span>
</li> </li>
<li> <li>
<label>指导老师</label> <label>指导老师</label>
<el-input v-if="editing" <el-input v-if="editing" v-model="infoData.instructor"></el-input>
v-model="infoData.instructor"></el-input>
<span v-else>{{ infoData.instructor }}</span> <span v-else>{{ infoData.instructor }}</span>
</li> </li>
<li> <li>
<label>实验学时</label> <label>实验学时</label>
<el-input v-if="editing" <el-input v-if="editing" v-model="infoData.period"></el-input>
v-model="infoData.period"></el-input>
<span v-else>{{ infoData.period }}</span> <span v-else>{{ infoData.period }}</span>
</li> </li>
</ul> </ul>
<div class="m-b-20"> <div class="m-b-20">
<h6 class="l-title"> <h6 class="l-title">
<img src="@/assets/img/report2.png" <img src="@/assets/img/report2.png" alt="">
alt="">
实验项目名称 实验项目名称
</h6> </h6>
<el-input v-if="editing" <el-input v-if="editing" v-model="form.projectName" type="textarea"></el-input>
v-model="form.projectName" <div v-else class="pre-wrap" v-html="form.projectName"></div>
type="textarea"></el-input>
<div v-else
class="pre-wrap"
v-html="form.projectName"></div>
</div> </div>
<div class="m-b-20"> <div class="m-b-20">
<h6 class="l-title"> <h6 class="l-title">
<img src="@/assets/img/report3.png" <img src="@/assets/img/report3.png" alt="">
alt="">
实验目的 实验目的
</h6> </h6>
<div :class="['pre-wrap', {edit: editing}]" <div :class="['pre-wrap', { edit: editing }]" v-html="form.purpose"></div>
v-html="form.purpose"></div>
</div> </div>
<div class="m-b-20"> <div class="m-b-20">
<h6 class="l-title"> <h6 class="l-title">
<img src="@/assets/img/report4.png" <img src="@/assets/img/report4.png" alt="">
alt="">
实验数据 实验数据
</h6> </h6>
<el-table :data="expData" <el-table :data="expData" class="table" border stripe header-align="center">
class="table" <el-table-column type="index" label="序号" align="center" width="60">
border
stripe
header-align="center">
<el-table-column type="index"
label="序号"
align="center"
width="60">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + 1 }} {{ scope.$index + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="judgmentName" <el-table-column prop="judgmentName" label="判分点" width="270" align="center"></el-table-column>
label="判分点" <el-table-column v-if='project' prop="judgmentName" label="考核点" align="center" width="150">
width="270"
align="center"></el-table-column>
<el-table-column v-if='project'
prop="judgmentName"
label="考核点"
align="center"
width="150">
<template slot-scope="scope"> <template slot-scope="scope">
<div v-for="(item, index) in scope.row.lcRuleRecords" <div v-for="(item, index) in scope.row.lcRuleRecords" :key="index">
:key="index">
<span> <span>
<span>{{index+1}}. </span>{{item.name}} <span>{{ index + 1 }}. </span>{{ item.name }}
</span> </span>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="ruleAnswer" <el-table-column prop="ruleAnswer" label="参考答案" style='word-wrap: break-word'>
label="参考答案"
style='word-wrap: break-word'>
<template slot-scope="scope"> <template slot-scope="scope">
<div v-if='scope.row.lcRuleRecords'> <div v-if='scope.row.lcRuleRecords'>
<div v-for="(item, index) in scope.row.lcRuleRecords" <div v-for="(item, index) in scope.row.lcRuleRecords" :key="index">
:key="index">
<span> <span>
<span>{{index+1}}. </span>{{item.ruleAnswer}} <span>{{ index + 1 }}. </span>{{ item.ruleAnswer }}
</span> </span>
</div> </div>
</div> </div>
<div v-else <div v-else v-html="scope.row.referenceAnswer"></div>
v-html="scope.row.referenceAnswer"></div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="userAnswer" <el-table-column prop="userAnswer" label="学生答案">
label="学生答案">
<template slot-scope="scope"> <template slot-scope="scope">
<div v-if='scope.row.lcRuleRecords'> <div v-if='scope.row.lcRuleRecords'>
<div v-for="(item, index) in scope.row.lcRuleRecords" <div v-for="(item, index) in scope.row.lcRuleRecords" :key="index">
:key="index">
<span v-if='item.userAnswer'> <span v-if='item.userAnswer'>
<span>{{index+1}}. </span>{{item.userAnswer}} <span>{{ index + 1 }}. </span>{{ item.userAnswer }}
</span> </span>
<span v-else> <span v-else>
<span>{{index+1}}. </span>未填写 <span>{{ index + 1 }}. </span>未填写
</span> </span>
</div> </div>
</div> </div>
<div v-else <div v-else v-html='scope.row.answer' style='white-space: pre-wrap'></div>
v-html='scope.row.answer'
style='white-space: pre-wrap'></div>
<template v-if="scope.row.runThePictureList"> <template v-if="scope.row.runThePictureList">
<img v-for="(img, i) in scope.row.runThePictureList" <img v-for="(img, i) in scope.row.runThePictureList" :key="i" width="200" class="result-pic"
:key="i" :src="img" alt="">
width="200"
class="result-pic"
:src="img"
alt="">
</template> </template>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="quesScore" <el-table-column prop="quesScore" label="分值" :key="6" width="80" align="center"></el-table-column>
label="分值" <el-table-column prop="score" label="得分" width="80" align="center"></el-table-column>
:key="6"
width="80"
align="center"></el-table-column>
<el-table-column prop="score"
label="得分"
width="80"
align="center"></el-table-column>
</el-table> </el-table>
</div> </div>
<div class="m-b-20"> <div class="m-b-20">
<h6 class="l-title"> <h6 class="l-title">
<img src="@/assets/img/report5.png" <img src="@/assets/img/report5.png" alt="">
alt="">
实验总结与体会 实验总结与体会
</h6> </h6>
<quill v-if="editing" <quill v-if="editing" :border="true" v-model="form.summarize" :minHeight="150" :height="150" />
:border="true" <div v-else class="pre-wrap" v-html="form.summarize"></div>
v-model="form.summarize"
:minHeight="150"
:height="150" />
<div v-else
class="pre-wrap"
v-html="form.summarize"></div>
</div> </div>
</div> </div>
</div> </div>
@ -313,132 +246,161 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.wrap { .wrap {
padding: 12px 300px 20px; padding: 12px 300px 20px;
} }
.text-right { .text-right {
text-align: right; text-align: right;
} }
code, code,
kbd, kbd,
samp { samp {
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif; font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
word-wrap: break-word; word-wrap: break-word;
white-space: pre-wrap; white-space: pre-wrap;
} }
/deep/ pre { /deep/ pre {
white-space: pre-wrap; /* css-3 */ white-space: pre-wrap;
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ /* css-3 */
white-space: pre-wrap; /* Opera 4-6 */ white-space: -moz-pre-wrap;
white-space: -o-pre-wrap; /* Opera 7 */ /* Mozilla, since 1999 */
word-wrap: break-word; /* Internet Explorer 5.5+ */ white-space: pre-wrap;
word-break: break-all; /* Opera 4-6 */
overflow: hidden; white-space: -o-pre-wrap;
font-size: 12px; /* Opera 7 */
font-weight: 400; word-wrap: break-word;
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif; /* Internet Explorer 5.5+ */
word-break: break-all;
overflow: hidden;
font-size: 12px;
font-weight: 400;
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
} }
.content { .content {
padding: 16px 40px; padding: 16px 40px;
background: #fff; background: #fff;
.r-title {
margin-bottom: 40px; .r-title {
font-size: 24px; margin-bottom: 40px;
text-align: center; font-size: 24px;
color: #333; text-align: center;
} color: #333;
.info { }
padding: 20px 16px;
border: 1px solid #e1e6f2; .info {
padding: 20px 16px;
border: 1px solid #e1e6f2;
}
.l-title {
display: flex;
align-items: center;
padding: 5px 8px;
margin-bottom: 12px;
font-size: 14px;
color: #333;
background-color: #f7f5ff;
}
.info-list {
display: flex;
flex-wrap: wrap;
padding: 10px 0 0 20px;
li {
display: inline-flex;
width: 23%;
padding: 0 10px;
margin-bottom: 34px;
} }
.l-title {
display: flex; &.edit {
li {
align-items: center; align-items: center;
padding: 5px 8px; }
margin-bottom: 12px;
font-size: 14px;
color: #333;
background-color: #f7f5ff;
} }
.info-list {
display: flex; label {
flex-wrap: wrap; font-size: 14px;
padding: 10px 0 0 20px; color: #333;
li { white-space: nowrap;
display: inline-flex;
width: 23%;
padding: 0 10px;
margin-bottom: 34px;
}
&.edit {
li {
align-items: center;
}
}
label {
font-size: 14px;
color: #333;
white-space: nowrap;
}
span {
min-width: 150px;
padding: 0 10px 3px;
border-bottom: 1px solid #e1e6f2;
}
/deep/.el-input {
width: 174px;
}
} }
.score-wrap {
position: relative; span {
min-width: 150px; min-width: 150px;
border-bottom: 1px solid #e1e6f2; padding: 0 10px 3px;
em { border-bottom: 1px solid #e1e6f2;
position: absolute;
top: -12px;
left: 30px;
font-family: din;
font-size: 30px;
font-weight: 600;
color: #0b1d30;
}
img {
position: absolute;
bottom: -15px;
left: 0;
}
} }
/deep/.el-textarea .el-textarea__inner,
.pre-wrap { /deep/.el-input {
min-height: 72px; width: 174px;
padding: 10px 16px;
font-size: 14px;
color: #333;
&.edit {
color: #abb3c6;
border: 1px solid #cacfdb;
border-radius: 4px;
background-color: #f6f7f9;
}
} }
/deep/ .table th { }
background-color: #e5dfff !important;
.cell { .score-wrap {
line-height: 35px; position: relative;
color: #fff; min-width: 150px;
} border-bottom: 1px solid #e1e6f2;
em {
position: absolute;
top: -12px;
left: 30px;
font-family: din;
font-size: 30px;
font-weight: 600;
color: #0b1d30;
}
img {
position: absolute;
bottom: -15px;
left: 0;
}
}
/deep/.el-textarea .el-textarea__inner,
.pre-wrap {
min-height: 72px;
padding: 10px 16px;
font-size: 14px;
color: #333;
&.edit {
color: #abb3c6;
border: 1px solid #cacfdb;
border-radius: 4px;
background-color: #f6f7f9;
} }
}
/deep/ .table th {
background-color: #e5dfff !important;
.cell {
line-height: 35px;
color: #fff;
}
}
} }
.result-pic { .result-pic {
margin: 10px 0; max-width: 100%;
margin: 10px 0;
} }
@media (max-width: 1650px) { @media (max-width: 1650px) {
.wrap { .wrap {
padding: 12px 200px 20px; padding: 12px 200px 20px;
} }
} }
@media (max-width: 1430px) { @media (max-width: 1430px) {
.wrap { .wrap {
padding: 12px 100px 20px; padding: 12px 100px 20px;
} }
} }
</style> </style>

@ -1,65 +1,39 @@
<template> <template>
<div ref="main" <div ref="main" class="main" v-loading="loading">
class="main"
v-loading="loading">
<el-form :disabled="isDetail"> <el-form :disabled="isDetail">
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div class="flex-between"> <div class="flex-between">
<el-page-header @back="back" <el-page-header @back="back" content="项目配置"></el-page-header>
content="项目配置"></el-page-header>
<div v-if="!isDetail"> <div v-if="!isDetail">
<el-button type="success" <el-button type="success" :loading="submiting === 0" @click="save(0)">保存为草稿</el-button>
:loading="submiting === 0" <el-button type="primary" :loading="submiting === 1" @click="save(1)">确定并发布</el-button>
@click="save(0)">保存为草稿</el-button>
<el-button type="primary"
:loading="submiting === 1"
@click="save(1)">确定并发布</el-button>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<h6 class="p-title">基本信息</h6> <h6 class="p-title">基本信息</h6>
<div> <div>
<el-form label-width="80px" <el-form label-width="80px" :disabled="isDetail">
:disabled="isDetail">
<div class="flex"> <div class="flex">
<el-form-item label="课程"> <el-form-item label="课程">
<el-cascader v-if="projectManage.founder" <el-cascader v-if="projectManage.founder" v-model="mallIds" :options="curs"
v-model="mallIds" :props="{ checkStrictly: true, value: 'id' }" popper-class="course-cas" @expand-change="curChange"
:options="curs" @change="curChange"></el-cascader>
:props="{ checkStrictly: true, value: 'id' }"
popper-class="course-cas"
@expand-change="curChange"
@change="curChange"></el-cascader>
<el-select v-else <el-select v-else v-model="projectManage.systemId" placeholder="请选择" @change="systemChange">
v-model="projectManage.systemId" <el-option v-for="item in systemList" :key="item.id" :label="item.label" :value="item.id"></el-option>
placeholder="请选择"
@change="systemChange">
<el-option v-for="item in systemList"
:key="item.id"
:label="item.label"
:value="item.id"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="项目名称"> <el-form-item label="项目名称">
<el-input v-model.trim="projectManage.projectName" <el-input v-model.trim="projectManage.projectName" placeholder="20个字符以内"
placeholder="20个字符以内" @blur="projectNameExistis"></el-input>
@blur="projectNameExistis"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="项目用途"> <el-form-item label="项目用途">
<el-select v-model="projectManage.permissions" <el-select v-model="projectManage.permissions" placeholder="请选择" @change="permissionChange">
placeholder="请选择" <el-option label="练习" :value="0"></el-option>
@change="permissionChange"> <el-option label="考核" :value="1"></el-option>
<el-option label="练习" <el-option label="竞赛" :value="2"></el-option>
:value="0"></el-option>
<el-option label="考核"
:value="1"></el-option>
<el-option label="竞赛"
:value="2"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</div> </div>
@ -67,172 +41,101 @@
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<h6 class="p-title">实验目标</h6> <h6 class="p-title">实验目标</h6>
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item> <el-form-item>
<quill :border="true" <quill :border="true" :readonly="isDetail" v-model="projectManage.experimentTarget"
:readonly="isDetail" :type.sync="projectManage.experimentTargetType" radio :minHeight="150" :height="150" />
v-model="projectManage.experimentTarget"
:type.sync="projectManage.experimentTargetType"
radio
:minHeight="150"
:height="150" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<h6 class="p-title">项目背景</h6> <h6 class="p-title">项目背景</h6>
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item> <el-form-item>
<quill :border="true" <quill :border="true" :readonly="isDetail" v-model="projectManage.experimentDescription"
:readonly="isDetail" :type.sync="projectManage.experimentDescriptionType" radio :minHeight="150" :height="150" :index="1" />
v-model="projectManage.experimentDescription"
:type.sync="projectManage.experimentDescriptionType"
radio
:minHeight="150"
:height="150"
:index="1" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div class="m-b-20 flex-between"> <div class="m-b-20 flex-between">
<h6 class="p-title" <h6 class="p-title" style="margin-bottom: 0">实验任务</h6>
style="margin-bottom: 0">实验任务</h6>
<div> <div>
<!--<el-button :disabled="isDetail" type="primary" @click="toJudgePoint('home')">进入判分点</el-button>--> <!--<el-button :disabled="isDetail" type="primary" @click="toJudgePoint('home')">进入判分点</el-button>-->
</div> </div>
</div> </div>
<div class="m-b-20 flex-between"> <div class="m-b-20 flex-between">
<div class="flex-center"> <div class="flex-center">
<div class="m-r-20" <div class="m-r-20" style="color: #f00">项目总分值100</div>
style="color: #f00">项目总分值100</div>
<!-- <div>权重&emsp;<div class="dib"><el-input></el-input></div></div> --> <!-- <div>权重&emsp;<div class="dib"><el-input></el-input></div></div> -->
</div> </div>
<div> <div>
<el-button class="m-r-20" <el-button class="m-r-20" type="text" @click="avgDistributionScore">平均分配分值</el-button>
type="text" <el-button class="m-r-20" type="text" @click="manualDistributionScore">手动分配分值</el-button>
@click="avgDistributionScore">平均分配分值</el-button>
<el-button class="m-r-20"
type="text"
@click="manualDistributionScore">手动分配分值</el-button>
<span>(待分配分值: {{ handDistributionScore }}/100)</span> <span>(待分配分值: {{ handDistributionScore }}/100)</span>
</div> </div>
</div> </div>
<el-button type="primary" <el-button type="primary" icon="el-icon-plus" round @click="handleQueryJudgment"
icon="el-icon-plus" style="margin-bottom: 10px">判分点</el-button>
round <el-button type="primary" icon="el-icon-delete" round @click="batchDeleteProjectJudgment"
@click="handleQueryJudgment" style="margin-bottom: 10px">批量删除</el-button>
style="margin-bottom: 10px">判分点</el-button>
<el-button type="primary"
icon="el-icon-delete"
round
@click="batchDeleteProjectJudgment"
style="margin-bottom: 10px">批量删除</el-button>
<div class="draggable"> <div class="draggable">
<u-table ref="projectJudgementTable" <u-table ref="projectJudgementTable" :data="projectJudgmentData" class="table" stripe header-align="center"
:data="projectJudgmentData" :use-virtual="isLc" :max-height="600" :row-height="60" :border="false"
class="table" @selection-change="handleSelectionProjectJudgment" row-key="judgmentId" v-loading="listLoading">
stripe <u-table-column type="selection" width="55" align="center"></u-table-column>
header-align="center" <u-table-column prop="sort" label="序号" width="80" align="center">
:use-virtual="isLc"
:max-height="600"
:row-height="60"
:border="false"
@selection-change="handleSelectionProjectJudgment"
row-key="judgmentId"
v-loading="listLoading">
<u-table-column type="selection"
width="55"
align="center"></u-table-column>
<u-table-column prop="sort"
label="序号"
width="80"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.sort }} {{ scope.row.sort }}
</template> </template>
</u-table-column> </u-table-column>
<u-table-column prop="name" <u-table-column prop="name" label="判分指标" align="center" show-overflow-tooltip
label="判分指标" min-width="140"></u-table-column>
align="center" <u-table-column prop="name" label="判分点名称" align="center" show-overflow-tooltip
show-overflow-tooltip min-width="140"></u-table-column>
min-width="140"></u-table-column> <u-table-column label="实验要求" align="center" width="600">
<u-table-column prop="name"
label="判分点名称"
align="center"
show-overflow-tooltip
min-width="140"></u-table-column>
<u-table-column label="实验要求"
align="center"
width="600">
<template slot-scope="scope"> <template slot-scope="scope">
<quill :readonly="true" <quill :readonly="true" elseRead="true" v-model="scope.row.experimentalRequirements" :index="2" />
elseRead="true"
v-model="scope.row.experimentalRequirements"
:index="2" />
</template> </template>
</u-table-column> </u-table-column>
<u-table-column prop="score" <u-table-column prop="score" label="分数" align="center" width="120">
label="分数"
align="center"
width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input :key="scope.$index" <el-input :key="scope.$index" type="number" step="0.1" v-model.trim="scope.row.score"></el-input>
type="number"
step="0.1"
v-model.trim="scope.row.score"></el-input>
<!-- <!--
@input="scoreChange(scope.row, scope.$index)" --> @input="scoreChange(scope.row, scope.$index)" -->
</template> </template>
</u-table-column> </u-table-column>
<u-table-column label="操作" <u-table-column label="操作" width="100" align="center">
width="100"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<!--<el-button :disabled="isDetail" type="text" style="margin-right: 10px" @click="toJudgePoint('edit', scope.row)">自定义</el-button>--> <!--<el-button :disabled="isDetail" type="text" style="margin-right: 10px" @click="toJudgePoint('edit', scope.row)">自定义</el-button>-->
<el-button type="text" <el-button type="text" @click="delJudgePoint(scope.$index)">删除</el-button>
@click="delJudgePoint(scope.$index)">删除</el-button>
</template> </template>
</u-table-column> </u-table-column>
</u-table> </u-table>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div class="m-b-20 flex-between"> <div class="m-b-20 flex-between">
<h6 class="p-title" <h6 class="p-title" style="margin-bottom: 0">实验提示</h6>
style="margin-bottom: 0">实验提示</h6>
<div> <div>
启用 启用
<el-switch :active-value="0" <el-switch :active-value="0" :inactive-value="1" v-model="projectManage.hintOpen"></el-switch>
:inactive-value="1"
v-model="projectManage.hintOpen"></el-switch>
</div> </div>
</div> </div>
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item prop="tips" <el-form-item prop="tips" label="">
label=""> <quill :border="true" :readonly="isDetail" v-model="projectManage.experimentHint"
<quill :border="true" :type.sync="projectManage.experimentHintType" radio :minHeight="150" :height="400" :index="3" />
:readonly="isDetail"
v-model="projectManage.experimentHint"
:type.sync="projectManage.experimentHintType"
radio
:minHeight="150"
:height="400"
:index="3" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -240,59 +143,32 @@
</el-form> </el-form>
<!--选择判分点对话框--> <!--选择判分点对话框-->
<el-dialog title="添加判分点" <el-dialog title="添加判分点" :visible.sync="dialogVisible" width="40%" :close-on-click-modal="false">
:visible.sync="dialogVisible"
width="40%"
:close-on-click-modal="false">
<div class="text-right m-b-10"> <div class="text-right m-b-10">
<div> <div>
<el-input placeholder="请输入需要查找的判分点" <el-input placeholder="请输入需要查找的判分点" prefix-icon="el-icon-search" v-model.trim="judgementpointsquery"
prefix-icon="el-icon-search" clearable></el-input>
v-model.trim="judgementpointsquery"
clearable></el-input>
</div> </div>
</div> </div>
<u-table v-loading="visibleLoading" <u-table v-loading="visibleLoading" :data="judgementData" ref="judgementTable" class="table" stripe
:data="judgementData" header-align="center" use-virtual :row-height="45" :max-height="400" :border="false"
ref="judgementTable" @selection-change="handleSelectionJudgment" :row-key="rowKey">
class="table" <u-table-column type="selection" width="55" align="center" :reserve-selection="true"></u-table-column>
stripe <u-table-column prop="id" label="序号" align="center" width="100">
header-align="center"
use-virtual
:row-height="45"
:max-height="400"
:border="false"
@selection-change="handleSelectionJudgment"
:row-key="rowKey">
<u-table-column type="selection"
width="55"
align="center"
:reserve-selection="true"></u-table-column>
<u-table-column prop="id"
label="序号"
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + 1 }} {{ scope.$index + 1 }}
</template> </template>
</u-table-column> </u-table-column>
<u-table-column prop="name" <u-table-column prop="name" label="判分点名称" align="center"></u-table-column>
label="判分点名称" <u-table-column label="操作" align="center" width="100">
align="center"></u-table-column>
<u-table-column label="操作"
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" <el-button size="mini" @click="toJudgePoint('view', scope.row)">查看</el-button>
@click="toJudgePoint('view', scope.row)">查看</el-button>
</template> </template>
</u-table-column> </u-table-column>
</u-table> </u-table>
<div slot="footer" <div slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" <el-button type="primary" @click="addJudgment"> </el-button>
@click="addJudgment"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
@ -685,25 +561,29 @@ export default {
} }
}, },
handleQueryJudgment () { // handleQueryJudgment () { //
let { systemId } = this.projectManage; let { systemId } = this.projectManage
this.dialogVisible = true; if (systemId) {
this.$nextTick(() => { this.dialogVisible = true;
this.$refs.judgementTable.clearSelection(); this.$nextTick(() => {
}); this.$refs.judgementTable.clearSelection();
let params = { });
systemId, let params = {
name: this.judgementpointsquery systemId,
}; name: this.judgementpointsquery
if (systemId == 2 || systemId == 3) { };
console.log("系统id:", systemId); if (systemId == 2 || systemId == 3) {
} else if (this.isLc) { console.log("系统id:", systemId);
// () } else if (this.isLc) {
this.rowKey = "lcId"; // ()
this.getProcessClassData(params); this.rowKey = "lcId";
this.getProcessClassData(params);
} else {
//
this.rowKey = "bcId";
this.getProgrammingClassData(params);
}
} else { } else {
// util.errorMsg('请选择课程')
this.rowKey = "bcId";
this.getProgrammingClassData(params);
} }
}, },
getProcessClassData (params) { // getProcessClassData (params) { //
@ -888,13 +768,14 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/ .readonly .ql-toolbar { /deep/ .readonly .ql-toolbar {
height: 0; height: 0;
padding: 0; padding: 0;
border-bottom: 0; border-bottom: 0;
} }
.main { .main {
overflow: auto; overflow: auto;
overflow-x: hidden; overflow-x: hidden;
height: calc(100vh - 152px); height: calc(100vh - 152px);
} }
</style> </style>

@ -15,7 +15,7 @@
<template v-if="showMask"> <template v-if="showMask">
<div class="mask" style="top: 0;width:100%;height: 48px;"></div> <div class="mask" style="top: 0;width:100%;height: 48px;"></div>
<div class="mask" style="top: 53px;width:100%;height: 30px;"></div> <div class="mask" style="top: 53px;width:100%;height: 30px;"></div>
<div class="mask" style="bottom: 0;right: 0;width:280px;height: 22px;background-color: #444;"></div> <div class="mask" style="bottom: 0;right: 40px;width:195px;height: 22px;background-color: #444;"></div>
</template> </template>
<template v-if="showMask1"> <template v-if="showMask1">
<div class="word-mask" style="height: 40px;"></div> <div class="word-mask" style="height: 40px;"></div>
@ -978,7 +978,7 @@ $height: 700px;
.entry { .entry {
width: 100%; width: 100%;
height: 34px; height: 40px;
font-size: 17px; font-size: 17px;
} }

@ -5,132 +5,132 @@ import Setting from "@/setting";
import store from '@/store' import store from '@/store'
const service = axios.create({ const service = axios.create({
baseURL: Setting.apiBaseURL, baseURL: Setting.apiBaseURL,
timeout: 10000000 timeout: 10000000
}); });
// post请求头 // post请求头
service.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8"; service.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";
// 请求拦截器 // 请求拦截器
service.interceptors.request.use(config => { service.interceptors.request.use(config => {
let token = util.local.get(Setting.tokenKey); let token = util.local.get(Setting.tokenKey);
if (token) config.headers.token = token; if (token) config.headers.token = token;
return config; return config;
}, err => { }, err => {
util.errorMsg({ util.errorMsg({
message: "退出登陆", message: "退出登陆",
onClose: function() { onClose: function () {
store.dispatch('user/logout') store.dispatch('user/logout')
} }
}); });
return Promise.reject(err); return Promise.reject(err);
}); });
let logouted = 0; let logouted = 0;
// 响应拦截器 // 响应拦截器
service.interceptors.response.use( service.interceptors.response.use(
response => { response => {
const res = response.data; const res = response.data;
if (res.status == 200 || res.status == 10000 || res.status == 30001) { if (res.status == 200 || res.status == 10000 || res.status == 30001) {
return Promise.resolve(res).catch(e => {}); return Promise.resolve(res).catch(e => { });
} else if (!res.status) { } else if (!res.status) {
return Promise.resolve(res).catch(e => {}); return Promise.resolve(res).catch(e => { });
} else { } else {
util.errorMsg(res.message); util.errorMsg(res.message);
return Promise.reject(res) return Promise.reject(res)
// return Promise.resolve(res).catch(e => {}); // return Promise.resolve(res).catch(e => {});
} }
}, },
// 服务器状态码不是200的情况 // 服务器状态码不是200的情况
error => { error => {
if (error.response.status) { if (error.response.status) {
switch (error.response.status) { switch (error.response.status) {
// 401: 未登录 // 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径 // 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。 // 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401: case 401:
if (!logouted) { if (!logouted) {
util.local.remove(Setting.storeKey); util.local.remove(Setting.storeKey);
util.local.remove(Setting.tokenKey); util.local.remove(Setting.tokenKey);
util.errorMsg("登录过期,请重新登录"); util.errorMsg("登录过期,请重新登录");
setTimeout(() => { setTimeout(() => {
store.dispatch('user/logout') store.dispatch('user/logout')
}, 1000); }, 1000);
logouted = 1 logouted = 1
} }
break; break;
case 500: case 500:
util.errorMsg("网络错误"); util.errorMsg("网络错误");
break; break;
// 403 token过期 // 403 token过期
// 登录过期对用户进行提示 // 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象 // 清除本地token和清空vuex中token对象
// 跳转登录页面 // 跳转登录页面
case 403: case 403:
util.local.remove(Setting.storeKey); util.local.remove(Setting.storeKey);
util.local.remove(Setting.tokenKey); util.local.remove(Setting.tokenKey);
util.errorMsg("登录过期,请重新登录"); util.errorMsg("登录过期,请重新登录");
// 清除token // 清除token
// store.commit('loginSuccess', null); // store.commit('loginSuccess', null);
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面 // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() => { setTimeout(() => {
store.dispatch('user/logout') store.dispatch('user/logout')
}, 1000); }, 1000);
break; break;
// 404请求不存在 // 404请求不存在
case 404: case 404:
util.errorMsg("网络请求不存在!"); util.errorMsg("网络请求不存在!");
break; break;
// 其他错误,直接抛出错误提示 // 其他错误,直接抛出错误提示
default: default:
util.errorMsg(error.response.data.message); util.errorMsg(error.response.data.message);
Promise.reject(res); Promise.reject(res);
} }
return Promise.reject(error.response); return Promise.reject(error.response);
}
} }
}
); );
function get(url, params) { function get (url, params) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
service.get(url, { params: params }).then(res => { service.get(url, { params: params }).then(res => {
resolve(res); resolve(res);
}).catch(err => { }).catch(err => {
reject(err); reject(err);
});
}); });
});
} }
function post(url, params) { function post (url, params) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
service.post(url, params).then(res => { service.post(url, params).then(res => {
resolve(res); resolve(res);
}).catch(err => { }).catch(err => {
reject(err.data); reject(err.data);
});
}); });
});
} }
function del(url, params) { function del (url, params) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
service.delete(url, { service.delete(url, {
params params
}).then(res => { }).then(res => {
resolve(res); resolve(res);
}).catch(err => { }).catch(err => {
reject(err.data); reject(err.data);
});
}); });
});
} }
function put(url, params) { function put (url, params) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
service.put(url, params).then(res => { service.put(url, params).then(res => {
resolve(res); resolve(res);
}).catch(err => { }).catch(err => {
reject(err.data); reject(err.data);
});
}); });
});
} }
export { get, post, del, put }; export { get, post, del, put };

@ -30,7 +30,7 @@ if (isPro) {
uploadURL = `http://121.37.12.51/` uploadURL = `http://121.37.12.51/`
host = "http://121.37.12.51/"; // 中台测试服 host = "http://121.37.12.51/"; // 中台测试服
host = 'https://www.occupationlab.com/' // 正式服 host = 'https://www.occupationlab.com/' // 正式服
host = "http://192.168.31.51:9000/"; // host = "http://192.168.31.51:9000/";
host = localStorage.getItem('localIp') == 1 ? 'http://192.168.31.51:9000/' : 'http://192.168.31.217:9000/' host = localStorage.getItem('localIp') == 1 ? 'http://192.168.31.51:9000/' : 'http://192.168.31.217:9000/'
} else if (isSq) { } else if (isSq) {
zcPath = `10.20.100.204:8883` zcPath = `10.20.100.204:8883`

Loading…
Cancel
Save