竞赛修复

master
yujialong 2 months ago
parent d0764a64a0
commit f3e795125d
  1. 8
      src/router/index.js
  2. 2
      src/views/match/manage/matchArch.vue
  3. 188
      src/views/match/manage/matchArchList.vue
  4. 4
      src/views/match/manage/matchInfo.vue
  5. 192
      src/views/match/manage/otherArchList.vue

@ -114,8 +114,8 @@ let router = new Router({
component: () => import('../views/match/manage/noticeDetail'),
},
{
path: '/matchArchList',
component: () => import('../views/match/manage/matchArchList'),
path: '/otherArchList',
component: () => import('../views/match/manage/otherArchList'),
},
{
path: '/matchRank',
@ -126,8 +126,8 @@ let router = new Router({
component: () => import('../views/match/manage/trialReport'),
},
{
path: '/theoryArchList',
component: () => import('../views/match/manage/theoryArchList'),
path: '/matchArchList',
component: () => import('../views/match/manage/matchArchList'),
},
{
path: '/theoryReport',

@ -101,7 +101,7 @@ export default {
this.$store.commit('setInnerReferrer', this.$route.fullPath)
const cur = this.form.competitionStage[i]
const showFile = !!(cur.method === 2 && cur.competitionStageContentSetting && cur.competitionStageContentSetting.whetherToUploadFiles)
this.$router.push(`/${cur.method === 2 ? 'matchArchList' : 'theoryArchList'}?id=${this.id}&stageId=${row.stageId}&method=${row.method}&competitionType=${row.competitionType}&showFile=${showFile}`)
this.$router.push(`/${cur.method === 2 ? 'otherArchList' : 'matchArchList'}?id=${this.id}&stageId=${row.stageId}&method=${row.method}&competitionType=${row.competitionType}&showFile=${showFile}`)
}
}
};

@ -17,8 +17,17 @@
</p>
</div>
<div class="item">
<p class="name">实验平均分</p>
<p class="val">{{ avgScore }}</p>
<p class="name">平均分</p>
<p class="val">{{ (+statData.avgScore).toFixed(2) }}</p>
</div>
<div class="item">
<p class="name">最高分</p>
<p class="val">{{ statData.maxScore }}
</p>
</div>
<div class="item">
<p class="name">最低分</p>
<p class="val">{{ statData.minScore }}</p>
</div>
</div>
<div class="chart" id="chart"></div>
@ -26,9 +35,9 @@
</el-card>
<el-card shadow="hover" class="m-b-20">
<div v-if="showFile" class="tabs m-b-20">
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: i === active }" @click="tabChange(i)">{{
item }}</a>
<div class="tabs m-b-20">
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: item.id === active }"
@click="tabChange(item.id)">{{ item.name }}</a>
</div>
<div class="flex-between m-b-20">
@ -36,19 +45,9 @@
<el-input size="small" placeholder="请输入学校/学生姓名" prefix-icon="el-icon-search" v-model="keyword" clearable
style="width: 300px"></el-input>
</div>
<div v-if="!active">
<el-button v-if="method == 2" type="primary" @click="batchImport">上传成绩</el-button>
<el-button type="primary" :disabled="!!multipleSelection.find(e => method != 2 && !e.reportId)"
@click="delAllData">批量删除</el-button>
<el-button type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' : '批量导出'
}}</el-button>
</div>
<div v-else>
<el-button type="primary" :loading="exporting1" @click="exportData1">{{ exporting1 ? '正在导出' : '批量导出'
}}</el-button>
</div>
</div>
<template v-if="!active">
<el-table :data="list" class="table" :key="1" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
@ -96,42 +95,6 @@
@current-change="handleCurrentChange" :current-page="page">
</el-pagination>
</div>
</template>
<template v-else>
<el-table :data="list1" class="table" :key="2" stripe header-align="center"
@selection-change="handleSelectionChange1" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center">
<template slot-scope="scope">
{{ scope.$index + (page1 - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" align="center"></el-table-column>
<el-table-column v-if="competitionType" prop="teamName" label="团队名称" align="center"></el-table-column>
<el-table-column prop="userName" label="学生姓名" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column>
<el-table-column prop="fileName" label="文件名" align="center"></el-table-column>
<el-table-column prop="fileSize" label="文件大小" align="center"></el-table-column>
<el-table-column prop="fileType" label="文件类型" align="center"></el-table-column>
<el-table-column prop="fileFormat" label="文件格式" align="center"></el-table-column>
<el-table-column prop="createTime" label="提交时间" width="150" align="center">
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button v-if="!isCompress(scope.row.fileFormat)" type="text"
@click="preview(scope.row)">预览文件</el-button>
<el-button type="primary" size="mini" :loading="scope.row.loading"
@click="exportFile(scope.row)">导出文件</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total1"
@current-change="handleCurrentChange1" :current-page="page1">
</el-pagination>
</div>
</template>
</el-card>
</div>
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false"
@ -179,7 +142,6 @@ export default {
stageId: +this.$route.query.stageId,
method: +this.$route.query.method,
competitionType: +this.$route.query.competitionType,
showFile: this.$route.query.showFile === 'true',
isCompress: util.isCompress,
keyword: this.$route.query.keyword || '',
searchTimer: null,
@ -203,9 +165,22 @@ export default {
headers: {
token: sessionStorage.getItem("token")
},
statData: {},
tabs: ['成绩列表', '文件列表'],
active: 0,
statData: {
avgScore: 0,
maxScore: 0,
minScore: 0,
},
tabs: [
{
id: 1,
name: '已提交'
},
{
id: 0,
name: '未提交'
}
],
active: 1,
loading: false,
exporting: false,
exporting1: false,
@ -232,51 +207,20 @@ export default {
methods: {
async getData () {
this.loading = true
//
if (this.active) {
const { data } = await this.$post(this.api.cCompetitionStageFileList, {
pageNum: this.page1,
pageSize: this.pageSize,
competitionId: this.id,
stageId: this.stageId,
keyWord: this.keyword,
})
data.records.forEach(e => {
e.loading = false
e.fileType = '其他'
if (util.isVideo(e.fileFormat)) {
e.fileType = '视频'
} else if (util.isAudio(e.fileFormat)) {
e.fileType = '音频'
} else if (util.isImg(e.fileFormat)) {
e.fileType = '图片'
} else if (util.isDoc(e.fileFormat)) {
e.fileType = '文档'
} else if (util.isCompress(e.fileFormat)) {
e.fileType = '压缩包'
} else if (e.fileType === 'pdf') {
e.fileType = 'pdf'
}
})
this.list1 = data.records
this.total1 = data.total
this.loading = false
} else { //
const { data, page } = await this.$post(this.api.stageGradeManagementList, {
pageNum: this.page,
pageSize: this.pageSize,
competitionId: this.id,
keyWord: this.keyword,
stageId: this.stageId,
isNakadai: 1
isNakadai: 1,
participatingState: this.active,
})
this.loading = false
this.total = page.total
this.list = page.records
this.statData = data
this.avgScore = (+data.avgScore).toFixed(2)
this.method != 2 && this.getChart()
}
this.getChart()
},
initData () {
this.page = 1
@ -284,7 +228,7 @@ export default {
},
//
show (row) {
this.$router.push(`/trialReport?reportId=${row.reportId}`)
this.$router.push(`/${this.method === 1 ? 'theoryReport' : 'trialReport'}?reportId=${row.reportId}`)
},
// ()
async exportData () {
@ -305,6 +249,7 @@ export default {
competitionId: this.id,
isNakadai: 1,
stageId: this.stageId,
participatingState: this.active,
}, {
headers: this.headers,
responseType: 'blob'
@ -314,31 +259,22 @@ export default {
}
}
},
// ()
exportData1 () {
this.exporting1 = true
let list = this.list1
if (this.multipleSelection1.length) {
list = this.multipleSelection1
}
Zip('批量导出', list, () => {
this.exporting1 = false
async handleDelete (row) { //
await this.$confirm(`<p>确认要删除【${row.userName}】的成绩记录吗?</p><p style="color: #f56c6c;">删除后成绩数据不可恢复,自动变为未提交</p>`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
})
},
handleDelete (row) { //
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$post(this.api.batchDeleteContestGrade, {
await this.$post(this.api.batchDeleteContestGrade, {
ids: [this.method == 2 ? row.scoreId : row.reportId],
competitionId: this.id,
stageId: this.stageId
}).then(res => {
util.successMsg("删除成功");
this.getData();
}).catch(res => {
});
}).catch(() => { });
})
util.successMsg("删除成功")
this.getData()
},
delAllData () { //
const list = this.multipleSelection
@ -382,16 +318,8 @@ export default {
handleSelectionChange1 (val) { //
this.multipleSelection1 = val;
},
handleCurrentChange1 (val) { //
this.page1 = val;
this.getData();
},
getChart () { // 线
const data = []
const { statData } = this
for (let i = 1; i <= 10; i++) {
data.push(statData['num' + i])
}
const { fractionalSegmentCounts: data } = this.statData
let myChart = echarts.init(document.getElementById("chart"));
myChart.setOption({
title: { text: "实验分数分布图" },
@ -401,7 +329,7 @@ export default {
type: "category",
boundaryGap: false,
interval: 10,
data: ["0-10", "10-20", "20-30", "30-40", "40-50", "50-60", "60-70", "70-80", "80-90", "90-100"]
data: data.map(e => e.range)
},
yAxis: {
name: "人数",
@ -409,7 +337,7 @@ export default {
minInterval: 10
},
series: [{
data,
data: data.map(e => e.count),
type: "line",
areaStyle: {},
color: ["#8191fd"]
@ -490,8 +418,10 @@ export default {
},
// tab
tabChange (i) {
this.multipleSelection = []
this.$refs.table.clearSelection()
this.active = i
this.getData()
this.initData()
},
//
preview (item) {
@ -545,7 +475,9 @@ export default {
.nums {
display: flex;
flex-wrap: wrap;
align-items: center;
width: 640px;
margin-right: 20px;
.item:nth-child(1) {
@ -556,6 +488,14 @@ export default {
background-image: url('../../../assets/img/avg.png');
}
.item:nth-child(3) {
background-image: url('../../../assets/img/ach1.png');
}
.item:nth-child(4) {
background-image: url('../../../assets/img/ach2.png');
}
.item {
width: 300px;
min-height: 145px;
@ -580,7 +520,7 @@ export default {
}
.chart {
flex: 1;
width: calc(100% - 660px);
height: 300px;
}
}

@ -570,9 +570,9 @@ export default {
},
//
show (row) {
this.curRow = row
//
if (this.form.completeCompetitionSetup.competitionType) { //
this.curRow = row
this.memberVisible = true
if (this.info.teamId) {
this.getMembers()
@ -589,7 +589,7 @@ export default {
},
//
toReport (row) {
this.$router.push(`/matchReport?reportId=${row.reportId}`)
this.$router.push(`/${this.curRow.method === 1 ? 'theoryReport' : 'trialReport'}?reportId=${row.reportId}`)
},
back () {
this.$router.push(this.$store.state.innerReferrer)

@ -17,17 +17,8 @@
</p>
</div>
<div class="item">
<p class="name">平均分</p>
<p class="val">{{ (+statData.avgScore).toFixed(2) }}</p>
</div>
<div class="item">
<p class="name">最高分</p>
<p class="val">{{ statData.maxScore }}
</p>
</div>
<div class="item">
<p class="name">最低分</p>
<p class="val">{{ statData.minScore }}</p>
<p class="name">实验平均分</p>
<p class="val">{{ avgScore }}</p>
</div>
</div>
<div class="chart" id="chart"></div>
@ -35,9 +26,9 @@
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="tabs m-b-20">
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: item.id === active }"
@click="tabChange(item.id)">{{ item.name }}</a>
<div v-if="showFile" class="tabs m-b-20">
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: i === active }" @click="tabChange(i)">{{
item }}</a>
</div>
<div class="flex-between m-b-20">
@ -45,9 +36,19 @@
<el-input size="small" placeholder="请输入学校/学生姓名" prefix-icon="el-icon-search" v-model="keyword" clearable
style="width: 300px"></el-input>
</div>
<div v-if="!active">
<el-button v-if="method == 2" type="primary" @click="batchImport">上传成绩</el-button>
<el-button type="primary" :disabled="!!multipleSelection.find(e => method != 2 && !e.reportId)"
@click="delAllData">批量删除</el-button>
<el-button type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' : '批量导出'
}}</el-button>
</div>
<div v-else>
<el-button type="primary" :loading="exporting1" @click="exportData1">{{ exporting1 ? '正在导出' : '批量导出'
}}</el-button>
</div>
</div>
<template v-if="!active">
<el-table :data="list" class="table" :key="1" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
@ -95,6 +96,42 @@
@current-change="handleCurrentChange" :current-page="page">
</el-pagination>
</div>
</template>
<template v-else>
<el-table :data="list1" class="table" :key="2" stripe header-align="center"
@selection-change="handleSelectionChange1" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center">
<template slot-scope="scope">
{{ scope.$index + (page1 - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" align="center"></el-table-column>
<el-table-column v-if="competitionType" prop="teamName" label="团队名称" align="center"></el-table-column>
<el-table-column prop="userName" label="学生姓名" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column>
<el-table-column prop="fileName" label="文件名" align="center"></el-table-column>
<el-table-column prop="fileSize" label="文件大小" align="center"></el-table-column>
<el-table-column prop="fileType" label="文件类型" align="center"></el-table-column>
<el-table-column prop="fileFormat" label="文件格式" align="center"></el-table-column>
<el-table-column prop="createTime" label="提交时间" width="150" align="center">
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button v-if="!isCompress(scope.row.fileFormat)" type="text"
@click="preview(scope.row)">预览文件</el-button>
<el-button type="primary" size="mini" :loading="scope.row.loading"
@click="exportFile(scope.row)">导出文件</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total1"
@current-change="handleCurrentChange1" :current-page="page1">
</el-pagination>
</div>
</template>
</el-card>
</div>
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false"
@ -142,6 +179,7 @@ export default {
stageId: +this.$route.query.stageId,
method: +this.$route.query.method,
competitionType: +this.$route.query.competitionType,
showFile: this.$route.query.showFile === 'true',
isCompress: util.isCompress,
keyword: this.$route.query.keyword || '',
searchTimer: null,
@ -165,22 +203,9 @@ export default {
headers: {
token: sessionStorage.getItem("token")
},
statData: {
avgScore: 0,
maxScore: 0,
minScore: 0,
},
tabs: [
{
id: 1,
name: '已提交'
},
{
id: 0,
name: '未提交'
}
],
active: 1,
statData: {},
tabs: ['成绩列表', '文件列表'],
active: 0,
loading: false,
exporting: false,
exporting1: false,
@ -191,7 +216,7 @@ export default {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.$router.push({
path: '/theoryArchList',
path: '/otherArchList',
query: {
...this.$route.query,
keyword: val
@ -207,20 +232,51 @@ export default {
methods: {
async getData () {
this.loading = true
//
if (this.active) {
const { data } = await this.$post(this.api.cCompetitionStageFileList, {
pageNum: this.page1,
pageSize: this.pageSize,
competitionId: this.id,
stageId: this.stageId,
keyWord: this.keyword,
})
data.records.forEach(e => {
e.loading = false
e.fileType = '其他'
if (util.isVideo(e.fileFormat)) {
e.fileType = '视频'
} else if (util.isAudio(e.fileFormat)) {
e.fileType = '音频'
} else if (util.isImg(e.fileFormat)) {
e.fileType = '图片'
} else if (util.isDoc(e.fileFormat)) {
e.fileType = '文档'
} else if (util.isCompress(e.fileFormat)) {
e.fileType = '压缩包'
} else if (e.fileType === 'pdf') {
e.fileType = 'pdf'
}
})
this.list1 = data.records
this.total1 = data.total
this.loading = false
} else { //
const { data, page } = await this.$post(this.api.stageGradeManagementList, {
pageNum: this.page,
pageSize: this.pageSize,
competitionId: this.id,
keyWord: this.keyword,
stageId: this.stageId,
isNakadai: 1,
participatingState: this.active,
isNakadai: 1
})
this.loading = false
this.total = page.total
this.list = page.records
this.statData = data
this.getChart()
this.avgScore = (+data.avgScore).toFixed(2)
this.method != 2 && this.getChart()
}
},
initData () {
this.page = 1
@ -228,7 +284,7 @@ export default {
},
//
show (row) {
this.$router.push(`/${this.method === 1 ? 'theoryReport' : 'trialReport'}?reportId=${row.reportId}`)
this.$router.push(`/trialReport?reportId=${row.reportId}`)
},
// ()
async exportData () {
@ -249,7 +305,6 @@ export default {
competitionId: this.id,
isNakadai: 1,
stageId: this.stageId,
participatingState: this.active,
}, {
headers: this.headers,
responseType: 'blob'
@ -259,22 +314,31 @@ export default {
}
}
},
async handleDelete (row) { //
await this.$confirm(`<p>确认要删除【${row.userName}】的成绩记录吗?</p><p style="color: #f56c6c;">删除后成绩数据不可恢复,自动变为未提交</p>`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
// ()
exportData1 () {
this.exporting1 = true
let list = this.list1
if (this.multipleSelection1.length) {
list = this.multipleSelection1
}
Zip('批量导出', list, () => {
this.exporting1 = false
})
await this.$post(this.api.batchDeleteContestGrade, {
},
handleDelete (row) { //
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$post(this.api.batchDeleteContestGrade, {
ids: [this.method == 2 ? row.scoreId : row.reportId],
competitionId: this.id,
stageId: this.stageId
})
util.successMsg("删除成功")
this.getData()
}).then(res => {
util.successMsg("删除成功");
this.getData();
}).catch(res => {
});
}).catch(() => { });
},
delAllData () { //
const list = this.multipleSelection
@ -305,7 +369,7 @@ export default {
},
handleCurrentChange (val) { //
this.$router.push({
path: '/theoryArchList',
path: '/otherArchList',
query: {
...this.$route.query,
page: val
@ -318,8 +382,16 @@ export default {
handleSelectionChange1 (val) { //
this.multipleSelection1 = val;
},
handleCurrentChange1 (val) { //
this.page1 = val;
this.getData();
},
getChart () { // 线
const { fractionalSegmentCounts: data } = this.statData
const data = []
const { statData } = this
for (let i = 1; i <= 10; i++) {
data.push(statData['num' + i])
}
let myChart = echarts.init(document.getElementById("chart"));
myChart.setOption({
title: { text: "实验分数分布图" },
@ -329,7 +401,7 @@ export default {
type: "category",
boundaryGap: false,
interval: 10,
data: data.map(e => e.range)
data: ["0-10", "10-20", "20-30", "30-40", "40-50", "50-60", "60-70", "70-80", "80-90", "90-100"]
},
yAxis: {
name: "人数",
@ -337,7 +409,7 @@ export default {
minInterval: 10
},
series: [{
data: data.map(e => e.count),
data,
type: "line",
areaStyle: {},
color: ["#8191fd"]
@ -418,10 +490,8 @@ export default {
},
// tab
tabChange (i) {
this.multipleSelection = []
this.$refs.table.clearSelection()
this.active = i
this.initData()
this.getData()
},
//
preview (item) {
@ -475,9 +545,7 @@ export default {
.nums {
display: flex;
flex-wrap: wrap;
align-items: center;
width: 640px;
margin-right: 20px;
.item:nth-child(1) {
@ -488,14 +556,6 @@ export default {
background-image: url('../../../assets/img/avg.png');
}
.item:nth-child(3) {
background-image: url('../../../assets/img/ach1.png');
}
.item:nth-child(4) {
background-image: url('../../../assets/img/ach2.png');
}
.item {
width: 300px;
min-height: 145px;
@ -520,7 +580,7 @@ export default {
}
.chart {
width: calc(100% - 660px);
flex: 1;
height: 300px;
}
}
Loading…
Cancel
Save