yujialong 1 month ago
parent 46eaca3745
commit 37eb678280
  1. 7
      src/assets/css/main.css
  2. 4
      src/utils/api.js
  3. 21
      src/views/customer/AddCustomer.vue
  4. 51
      src/views/match/manage/matchArch.vue
  5. 364
      src/views/match/manage/matchArchList.vue
  6. 89
      src/views/match/manage/matchRank.vue
  7. 70
      src/views/match/manage/otherArchList.vue
  8. 3
      src/views/match/manage/theoryReport.vue
  9. 6
      src/views/order/AddOrder.vue

@ -520,3 +520,10 @@ li {
} }
} }
} }
.files-tip {
li {
line-height: 1.8;
cursor: pointer;
}
}

@ -414,9 +414,12 @@ export default {
batchDeleteContestGrade: `competition/competition/performance/batchDeleteContestGrade`, batchDeleteContestGrade: `competition/competition/performance/batchDeleteContestGrade`,
batchImportGrades: `${host}competition/competition/performance/batchImportGrades`, batchImportGrades: `${host}competition/competition/performance/batchImportGrades`,
exportExperimentalResultsInBatch: `${host}competition/competition/performance/exportExperimentalResultsInBatch`, exportExperimentalResultsInBatch: `${host}competition/competition/performance/exportExperimentalResultsInBatch`,
exportExamPaperReports: `${host}exam/exam/paper/exportExamPaperReports`,
batchExportReportsAsZip: `${host}occupationlab/occupationlab/achievement/batchExportReportsAsZip`,
performanceExportFailure: `${host}competition/competition/performance/exportFailure`, performanceExportFailure: `${host}competition/competition/performance/exportFailure`,
rankExportFailure: `${host}competition/competition/rank/exportFailure`, rankExportFailure: `${host}competition/competition/rank/exportFailure`,
batchImportRanking: `${host}competition/competition/rank/batchImportRanking`, batchImportRanking: `${host}competition/competition/rank/batchImportRanking`,
getPaperUploadFileZip: `${host}exam/exam/paper/question/userAnswer/getPaperUploadFileZip`,
stageGradeManagementList: `competition/competition/performance/stageGradeManagementList`, stageGradeManagementList: `competition/competition/performance/stageGradeManagementList`,
stageRaceRanking: `competition/competition/rank/stageRaceRanking`, stageRaceRanking: `competition/competition/rank/stageRaceRanking`,
overallStandingsInThePointsRace: `competition/competition/rank/overallStandingsInThePointsRace`, overallStandingsInThePointsRace: `competition/competition/rank/overallStandingsInThePointsRace`,
@ -442,6 +445,7 @@ export default {
getCompetitionStageRankingTime: `competition/competitionReleaseTime/getCompetitionStageRankingTime`, getCompetitionStageRankingTime: `competition/competitionReleaseTime/getCompetitionStageRankingTime`,
frontOfficeCompetitionRanking: `competition/competition/rank/frontOfficeCompetitionRanking`, frontOfficeCompetitionRanking: `competition/competition/rank/frontOfficeCompetitionRanking`,
cCompetitionStageFileList: `competition/cCompetitionStageFile/listByEntity`, cCompetitionStageFileList: `competition/cCompetitionStageFile/listByEntity`,
getPaperUploadFile: `exam/exam/paper/question/userAnswer/getPaperUploadFile`,
derive: `${host}competition/cCompetitionStageFile/deriveAll`, derive: `${host}competition/cCompetitionStageFile/deriveAll`,
allExperimentalResultsAreDerived: `${host}competition/competition/performance/allExperimentalResultsAreDerived`, allExperimentalResultsAreDerived: `${host}competition/competition/performance/allExperimentalResultsAreDerived`,
derivedRanking: `${host}competition/competition/rank/derivedRanking`, derivedRanking: `${host}competition/competition/rank/derivedRanking`,

@ -139,7 +139,7 @@
<el-table-column prop="productTypeName" label="产品分类" align="center"></el-table-column> <el-table-column prop="productTypeName" label="产品分类" align="center"></el-table-column>
<el-table-column label="起止日期" align="center"> <el-table-column label="起止日期" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.status === '已过期' ? '' : scope.row.startAndEndTime }} {{ scope.row.status === '已过期' ? '-' : scope.row.startAndEndTime }}
<el-tooltip v-if="scope.row.other" class="item" effect="dark" placement="top"> <el-tooltip v-if="scope.row.other" class="item" effect="dark" placement="top">
<div slot="content"> <div slot="content">
还有<span v-html="scope.row.other"></span><br>的订单还未生效 还有<span v-html="scope.row.other"></span><br>的订单还未生效
@ -200,7 +200,7 @@
<el-table-column prop="orderContent" label="订单内容" align="center"> <el-table-column prop="orderContent" label="订单内容" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-popover trigger="hover" placement="top" style='width: 500px' <el-popover trigger="hover" placement="top" style='width: 500px'
v-if='scope.row.orderContent.length > 14'> v-if='scope.row.orderContent && scope.row.orderContent.length > 14'>
<p> {{ scope.row.orderContent }}</p> <p> {{ scope.row.orderContent }}</p>
<div slot="reference" class="name-wrapper"> <div slot="reference" class="name-wrapper">
<el-tag size="medium" class='tags'>{{ scope.row.orderContent }}</el-tag> <el-tag size="medium" class='tags'>{{ scope.row.orderContent }}</el-tag>
@ -526,6 +526,7 @@ export default {
], ],
products: [], products: [],
productAll: [], productAll: [],
productAllOrigin: [],
pageProduct: this.$route.query.type === 'tab2' ? (+this.$route.query.page || 1) : 1, pageProduct: this.$route.query.type === 'tab2' ? (+this.$route.query.page || 1) : 1,
pageSizeProduct: 10, pageSizeProduct: 10,
totalProduct: 0, totalProduct: 0,
@ -775,6 +776,7 @@ export default {
} }
}) })
this.productAll = data this.productAll = data
this.productAllOrigin = data
this.totalProduct = data.length this.totalProduct = data.length
this.handlePage() this.handlePage()
}).catch(res => { }) }).catch(res => { })
@ -792,6 +794,15 @@ export default {
this.handlePage() this.handlePage()
this.$router.push(`addcustomer?id=${this.customerId}&type=tab2&page=${val}`) this.$router.push(`addcustomer?id=${this.customerId}&type=tab2&page=${val}`)
}, },
//
filterForm2 () {
const list = this.productAllOrigin
const { productType, status, keyword } = this.form2
this.productAll = list.filter(e => (productType === '' || productType === e.productType) && (e.status === status || status === '全部') && (!e.goodsName || (e.goodsName && e.goodsName.includes(keyword))))
this.pageProduct = 1
this.totalProduct = this.productAll.length
this.handlePage()
},
// //
setCustomer () { setCustomer () {
this.initCustomer() this.initCustomer()
@ -902,12 +913,6 @@ export default {
this.productTypeList = res.classificationList this.productTypeList = res.classificationList
}).catch(err => { }) }).catch(err => { })
}, },
//
filterForm2 () {
const list = this.productAll
const { productType, status, keyword } = this.form2
this.products = list.filter(e => (productType === '' || productType === e.productType) && (e.status === status || status === '全部') && (!e.goodsName || (e.goodsName && e.goodsName.includes(keyword))))
},
// //
exportList () { exportList () {
let list = this.productAll let list = this.productAll

@ -8,30 +8,46 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="stageName" label="阶段名称" align="center"></el-table-column> <el-table-column prop="stageName" label="阶段名称" align="center"></el-table-column>
<el-table-column prop="competitionContent" label="比赛内容" align="center"></el-table-column>
<el-table-column prop="methodName" label="比赛方式" align="center"></el-table-column> <el-table-column prop="methodName" label="比赛方式" align="center"></el-table-column>
<el-table-column prop="founderName" label="比赛形式" align="center"> <el-table-column label="竞赛类型" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.competitionType ? '团队赛' : '个人赛' }} {{ scope.row.competitionType ? '团队赛' : '个人赛' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="ruleName" label="赛制" align="center"></el-table-column> <el-table-column prop="ruleName" label="赛制" align="center"></el-table-column>
<el-table-column prop="status" label="状态" align="center"></el-table-column> <el-table-column prop="status" label="大赛状态" align="center"></el-table-column>
<el-table-column label="竞赛起止时间" width="290" align="center"> <el-table-column prop="reviewStatus" label="评阅情况" align="center"></el-table-column>
<el-table-column label="竞赛时间" width="290" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.startTime + ' ~ ' + scope.row.endTime }} {{ scope.row.startTime + ' ~ ' + scope.row.endTime }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="260"> <el-table-column label="操作" align="center" width="280">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="primary" @click="toRank(scope.row, scope.$index)">排名</el-button> <el-button type="text" @click="toRank(scope.row, scope.$index)">排名</el-button>
<el-button @click="toArch(scope.row, scope.$index)">成绩管理</el-button> <el-button type="text" @click="toArch(scope.row, scope.$index)">成绩统计</el-button>
<!-- <el-button @click="toArch(scope.row, scope.$index)">编辑试卷</el-button> -->
<el-button type="text" @click="showReview(scope.row, '/myReview/records')">我的评阅任务</el-button>
<el-button type="text" @click="showReview(scope.row, '/allocationReview/records')">分配评阅任务</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-drawer title="" :visible.sync="reviewVisible" size="100%" :close-on-click-modal="false" :withHeader="false"
custom-class="review-dia">
<div>
<button type="button" class="el-drawer__close-btn" @click="reviewVisible = false">
<i class="el-dialog__close el-icon el-icon-close"></i>
</button>
</div>
<iframe :src="reviewUrl" frameborder="0" width="100%"></iframe>
</el-drawer>
</div> </div>
</template> </template>
<script> <script>
import Setting from '@/setting'
import Const from '@/const/match' import Const from '@/const/match'
export default { export default {
name: "matchArch", name: "matchArch",
@ -42,6 +58,8 @@ export default {
form: {}, form: {},
timer: null, timer: null,
curStep: [], curStep: [],
reviewVisible: false,
reviewUrl: '',
}; };
}, },
mounted () { mounted () {
@ -102,6 +120,15 @@ export default {
const cur = this.form.competitionStage[i] const cur = this.form.competitionStage[i]
const showFile = !!(cur.method === 2 && cur.competitionStageContentSetting && cur.competitionStageContentSetting.whetherToUploadFiles) const showFile = !!(cur.method === 2 && cur.competitionStageContentSetting && cur.competitionStageContentSetting.whetherToUploadFiles)
this.$router.push(`/${cur.method === 2 ? 'otherArchList' : 'matchArchList'}?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}`)
},
//
showReview (row, path) {
let url = `${location.origin}/reviewCenter/`
if (Setting.isDev) url = `http://192.168.31.125:8099/`
url += `#${path}?token=${sessionStorage.getItem('token')}&v=${Date.now()}&competitionId=${this.id}&stageId=${row.stageId}`
localStorage.setItem('review_token', sessionStorage.getItem('token'))
this.reviewUrl = url
this.reviewVisible = true
} }
} }
}; };
@ -122,4 +149,16 @@ export default {
margin-right: 30px; margin-right: 30px;
} }
} }
/deep/.review-dia {
.el-drawer__close-btn {
position: absolute;
top: 20px;
right: 20px;
}
iframe {
height: 100%;
}
}
</style> </style>

@ -40,39 +40,88 @@
@click="tabChange(item.id)">{{ item.name }}</a> @click="tabChange(item.id)">{{ item.name }}</a>
</div> </div>
<div class="flex-between m-b-20"> <div class="tool flex-between">
<ul class="filter">
<li>
<label>省份</label>
<el-select v-model="filter.provinceId" filterable clearable placeholder="请选择省份" @change="provinceChange"
@clear="clearProvince">
<el-option v-for="(item, i) in provinces" :key="i" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select>
</li>
<li>
<label>城市</label>
<el-select v-model="filter.cityId" filterable clearable placeholder="请选择城市" :disabled="!filter.provinceId"
@change="initData">
<el-option v-for="(item, i) in cities" :key="i" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</li>
<li>
<label>学校</label>
<el-select v-model="filter.realSchoolId" clearable filterable placeholder="请选择学校" @change="initData">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</li>
<li v-if="active">
<label>评阅状态</label>
<el-select v-model="filter.reviewStatus" clearable placeholder="请选择评阅状态" @change="initData">
<el-option value="待评阅"></el-option>
<el-option value="已评阅"></el-option>
</el-select>
</li>
<li>
<el-input size="small" placeholder="请输入学生姓名、学生学号、团队名称" prefix-icon="el-icon-search" v-model="keyword"
clearable style="width: 300px"></el-input>
</li>
</ul>
<div> <div>
<el-input size="small" placeholder="请输入学校/学生姓名" prefix-icon="el-icon-search" v-model="keyword" clearable <template v-if="active">
style="width: 300px"></el-input> <el-button type="primary" size="mini" @click="showReview('/allocationReview/records')">分配评阅任务</el-button>
</div> <el-button type="primary" size="mini" @click="showReview('/myReview/records')">我的评阅任务</el-button>
<el-button type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' : '批量导出' <el-button type="primary" size="mini" @click="exportFiles">导出答题文件</el-button>
</template>
<el-button type="primary" size="mini" :loading="exportingList" @click="exportList">{{ exportingList ? '正在导出'
:
'导出成绩列表'
}}</el-button> }}</el-button>
<template v-if="active">
<el-button type="primary" size="mini" :loading="exportingReport" @click="exporReport">{{ exportingReport ?
'正在导出' :
'导出成绩报告'
}}</el-button>
<el-button type="primary" size="mini" @click="delAllData">批量删除</el-button>
</template>
</div>
</div> </div>
<el-table :data="list" class="table" :key="1" ref="table" stripe header-align="center" <el-table :data="list" class="table" :key="1" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange" row-key="id"> @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"> <el-table-column 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="provinceName" label="省份" min-width="100" align="center"></el-table-column>
<el-table-column prop="cityName" label="城市" min-width="100" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column> <el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column> <el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column>
<el-table-column v-if="competitionType" prop="teamName" label="团队名称" min-width="100" <el-table-column v-if="competitionType" prop="teamName" label="团队名称" min-width="100"
align="center"></el-table-column> align="center"></el-table-column>
<el-table-column prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column> <el-table-column prop="userName" 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="workNumber" label="学号" min-width="100" align="center"></el-table-column>
<el-table-column prop="score" label="分数" width="90" align="center"> <el-table-column prop="score" label="成绩" width="90" align="center" sortable="custom">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.submitTime ? scope.row.score : '--' }} {{ scope.row.submitTime ? scope.row.score : '--' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="timeSum" label="耗时" width="90" align="center"> <el-table-column prop="timeSum" label="时" width="90" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.timeSum ? scope.row.timeSum + 'min' : '--' }} {{ scope.row.timeSum ? scope.row.timeSum + 'min' : '--' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="submitTime" label="提交时间" min-width="150" align="center"> <el-table-column prop="submitTime" label="提交时间" min-width="150" align="center" sortable="custom">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.submitTime || '--' }} {{ scope.row.submitTime || '--' }}
</template> </template>
@ -82,11 +131,27 @@
{{ scope.row.reportId || method == 2 ? '已参加' : '未参加' }} {{ scope.row.reportId || method == 2 ? '已参加' : '未参加' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="160"> <el-table-column prop="evaluationStatus" label="评阅状态" align="center" width="90">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button v-if="method != 2 && scope.row.reportId" type="text" <span v-if="scope.row.reviewStatus === '-'">-</span>
@click="show(scope.row)">查看成绩报告</el-button> <el-tag v-else :type="scope.row.reviewStatus === '待评阅' ? 'danger' : 'success'">{{ scope.row.reviewStatus
<el-button v-if="scope.row.reportId" type="text" @click="handleDelete(scope.row)">删除</el-button> }}</el-tag>
</template>
</el-table-column>
<el-table-column v-if="active" label="操作" align="center" width="300">
<template v-if="scope.row.reportId" slot-scope="scope">
<el-popover placement="top" trigger="click" popper-class="files-tip">
<div>
<ul class="match-files">
<li v-for="(file, i) in scope.row.files" :key="i" @click="preview(file.attachmentUrl)">{{
file.attachmentName }}</li>
</ul>
</div>
<el-button slot="reference" type="text" @click="showFiles(scope.row)">查看答题文件</el-button>
</el-popover>
<el-button style="margin-left: 10px;" type="text" @click="downloadFile(scope.row)">下载答题文件</el-button>
<el-button v-if="method != 2" type="text" @click="toReport(scope.row)">查看成绩报告</el-button>
<el-button type="text" @click="handleDelete(scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -97,6 +162,7 @@
</div> </div>
</el-card> </el-card>
</div> </div>
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false" <el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false"
@close="cancelUpload"> @close="cancelUpload">
<div style="text-align: center"> <div style="text-align: center">
@ -127,22 +193,53 @@
<el-button @click="cancelUpload">停止导入</el-button> <el-button @click="cancelUpload">停止导入</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-drawer title="" :visible.sync="reviewVisible" size="100%" :close-on-click-modal="false" :withHeader="false"
custom-class="review-dia">
<div>
<button type="button" class="el-drawer__close-btn" @click="reviewVisible = false">
<i class="el-dialog__close el-icon el-icon-close"></i>
</button>
</div>
<iframe :src="reviewUrl" frameborder="0" width="100%"></iframe>
</el-drawer>
<el-dialog title="图片预览" :visible.sync="previewImgVisible" width="800px" :close-on-click-modal="false">
<el-image style="max-width: 100px; max-height: 100px" :src="previewImg" :preview-src-list="[previewImg]">
</el-image>
</el-dialog>
<PdfDia :key="pdfVisible" :visible.sync="pdfVisible" :src.sync="pdfSrc" />
</div> </div>
</template> </template>
<script> <script>
import util from "@/libs/util"; import Setting from '@/setting'
import PdfDia from '@/components/pdf'
import Util from '@/libs/util'
import * as echarts from "echarts"; import * as echarts from "echarts";
import axios from 'axios'; import axios from 'axios';
import Zip from '@/libs/zip'
export default { export default {
components: {
PdfDia
},
data () { data () {
return { return {
id: +this.$route.query.id, id: +this.$route.query.id,
stageId: +this.$route.query.stageId, stageId: +this.$route.query.stageId,
method: +this.$route.query.method, method: +this.$route.query.method,
competitionType: +this.$route.query.competitionType, competitionType: +this.$route.query.competitionType,
isCompress: util.isCompress, isCompress: Util.isCompress,
filter: {
provinceId: '',
cityId: '',
realSchoolId: '',
reviewStatus: '',
scoreSortOrder: '',
submitTimeSortOrder: '',
},
provinces: [],
cities: [],
schools: [],
keyword: this.$route.query.keyword || '', keyword: this.$route.query.keyword || '',
searchTimer: null, searchTimer: null,
list: [], list: [],
@ -182,8 +279,17 @@ export default {
], ],
active: 1, active: 1,
loading: false, loading: false,
exporting: false, exportingFiles: false,
exporting1: false, exportingList: false,
exportingReport: false,
previewImgVisible: false,
previewImg: '',
pdfVisible: false,
pdfSrc: '',
reviewVisible: false,
reviewUrl: '',
}; };
}, },
watch: { watch: {
@ -203,6 +309,8 @@ export default {
}, },
mounted () { mounted () {
this.getData() this.getData()
this.getProvince()
this.getSchool()
}, },
methods: { methods: {
async getData () { async getData () {
@ -215,6 +323,7 @@ export default {
stageId: this.stageId, stageId: this.stageId,
isNakadai: 1, isNakadai: 1,
participatingState: this.active, participatingState: this.active,
...this.filter
}) })
this.loading = false this.loading = false
this.total = page.total this.total = page.total
@ -226,22 +335,115 @@ export default {
this.page = 1 this.page = 1
this.getData() this.getData()
}, },
//
async getProvince () {
const { list } = await this.$get(this.api.queryProvince)
this.provinces = list
},
//
clearProvince () {
this.filter.cityId = ''
},
//
provinceChange () {
this.clearProvince()
this.getCity()
this.initData()
},
//
async getCity () {
const id = this.filter.provinceId
if (id) {
const { list } = await this.$get(this.api.queryCity, {
provinceId: id
})
this.cities = list
}
},
//
async getSchool () {
const { list } = await this.$get(this.api.querySchoolData)
this.schools = list
},
//
sortChange (column) {
if (column.prop === 'score') this.filter.scoreSortOrder = column.order ? column.order === 'ascending' ? 'ASC' : 'DESC' : ''
if (column.prop === 'submitTime') this.filter.scoreSortOrder = column.order ? column.order === 'ascending' ? 'ASC' : 'DESC' : ''
this.getData()
},
//
async showFiles (row) {
const { data } = await this.$get(this.api.getPaperUploadFile, {
reportId: row.reportId
})
this.$set(row, 'files', data)
},
//
async downloadFile (row) {
const res = await axios.post(this.api.getPaperUploadFileZip, {
reportIds: [row.reportId],
// reportIds: [3785],
stageId: this.stageId
}, {
headers: this.headers,
responseType: 'blob'
})
const name = res.headers['content-disposition']
Util.downloadFileDirect(name ? decodeURI(name) : '答题文件.zip', new Blob([res.data]))
},
// //
show (row) { toReport (row) {
this.$router.push(`/${this.method === 1 ? 'theoryReport' : 'trialReport'}?reportId=${row.reportId}`) this.$router.push(`/${this.method === 1 ? 'theoryReport' : 'trialReport'}?reportId=${row.reportId}`)
}, },
// ()
async exportData () {
//
showReview (path) {
let url = `${location.origin}/reviewCenter/`
if (Setting.isDev) url = `http://192.168.31.125:8099/`
url += `#${path}?token=${sessionStorage.getItem('token')}&v=${Date.now()}&competitionId=${this.id}&stageId=${this.stageId}`
localStorage.setItem('review_token', sessionStorage.getItem('token'))
this.reviewUrl = url
this.reviewVisible = true
},
//
async exportFiles () {
if (this.list.length) {
this.exportingFiles = true
const list = this.multipleSelection
const ids = []
if (list.length) {
list.forEach(e => {
e.reportId && ids.push(e.reportId)
})
}
const res = await axios.post(this.api.getPaperUploadFileZip, {
reportIds: ids,
// reportIds: [3785],
stageId: this.stageId
}, {
headers: this.headers,
responseType: 'blob'
})
const name = res.headers['content-disposition']
Util.downloadFileDirect(name ? decodeURI(name) : '答题文件.zip', new Blob([res.data]))
this.exportingFiles = false
}
},
// ()
async exportList () {
if (this.list.length) { if (this.list.length) {
this.exporting = true this.exportingList = true
// //
if (this.multipleSelection.length) { if (this.multipleSelection.length) {
const res = await axios.post(this.api.exportExperimentalResultsInBatch, this.multipleSelection, { const res = await axios.post(this.api.exportExperimentalResultsInBatch, this.multipleSelection, {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}) })
util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data])) Util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data]))
this.exporting = false this.exportingList = false
} else if (this.list.length) { } else if (this.list.length) {
const res = await axios.post(this.api.allExperimentalResultsAreDerived, { const res = await axios.post(this.api.allExperimentalResultsAreDerived, {
pageNum: 1, pageNum: 1,
@ -254,8 +456,45 @@ export default {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}) })
util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data])) Util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data]))
this.exporting = false this.exportingList = false
}
}
},
// ()
async exporReport () {
if (this.list.length) {
this.exportingReport = true
const list = this.multipleSelection
const ids = []
if (list.length) {
list.forEach(e => {
e.reportId && ids.push(e.reportId)
})
}
let res
//
if (this.method) {
res = await axios.post(this.api.exportExamPaperReports, {
ids,
stageId: list.length ? '' : this.stageId
}, {
headers: this.headers,
responseType: 'blob'
})
Util.downloadFileDirect('成绩报告.zip', new Blob([res.data]))
this.exportingReport = false
} else {
//
res = await axios.post(this.api.batchExportReportsAsZip, {
reportIds: ids,
stageId: this.stageId
}, {
headers: this.headers,
responseType: 'blob'
})
Util.downloadFileDirect('成绩报告.zip', new Blob([res.data]))
this.exportingReport = false
} }
} }
}, },
@ -273,7 +512,7 @@ export default {
competitionId: this.id, competitionId: this.id,
stageId: this.stageId stageId: this.stageId
}) })
util.successMsg("删除成功") Util.successMsg("删除成功")
this.getData() this.getData()
}, },
delAllData () { // delAllData () { //
@ -296,7 +535,7 @@ export default {
await this.$post(this.api.batchDeleteContestGrade, data) await this.$post(this.api.batchDeleteContestGrade, data)
this.multipleSelection = []; this.multipleSelection = [];
this.$refs.table.clearSelection(); this.$refs.table.clearSelection();
util.successMsg("删除成功"); Util.successMsg("删除成功");
this.getData(); this.getData();
}).catch(() => { }); }).catch(() => { });
}, },
@ -360,12 +599,12 @@ export default {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}).then((res) => { }).then((res) => {
util.downloadFileDirect('赛事成绩导入模板.xlsx', new Blob([res.data])) Util.downloadFileDirect('赛事成绩导入模板.xlsx', new Blob([res.data]))
}).catch(res => { }) }).catch(res => { })
}, },
// //
handleExceed (files, fileList) { handleExceed (files, fileList) {
util.warningMsg( Util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` `当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
) )
}, },
@ -375,7 +614,7 @@ export default {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}).then((res) => { }).then((res) => {
util.downloadFileDirect(`批量导入成绩管理失败数据导出.xls`, new Blob([res.data])) Util.downloadFileDirect(`批量导入成绩管理失败数据导出.xls`, new Blob([res.data]))
}).catch(res => { }) }).catch(res => { })
}, },
uploadSuccess (res) { uploadSuccess (res) {
@ -388,11 +627,11 @@ export default {
this.faildData = data this.faildData = data
this.uploadFaild = true this.uploadFaild = true
} else { } else {
util.successMsg(data.tip, 3000) Util.successMsg(data.tip, 3000)
this.importVisible = false this.importVisible = false
} }
} else { } else {
util.errorMsg(res.message || '上传失败,请检查数据') Util.errorMsg(res.message || '上传失败,请检查数据')
} }
}, },
uploadError (err, file, fileList) { uploadError (err, file, fileList) {
@ -428,25 +667,17 @@ export default {
this.initData() this.initData()
}, },
// //
preview (item) { preview (url) {
window.open((util.isDoc(item.fileFormat) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + item.filePath) const ext = url.split('.').pop()
}, if (Util.isDoc(ext)) {
// window.open('https://view.officeapps.live.com/op/view.aspx?src=' + url)
exportFile (item) { } else if (Util.isImg(ext)) {
item.loading = true this.previewImgVisible = true
const url = item.filePath this.previewImg = url
var x = new XMLHttpRequest() } else if (ext === 'pdf') {
x.open("GET", url, true) this.pdfVisible = true
x.responseType = "blob" this.pdfSrc = url
x.onload = function (e) { }
var url = window.URL.createObjectURL(x.response)
var a = document.createElement("a")
a.href = url
a.download = item.userName + '-' + item.fileName
a.click()
item.loading = false
}
x.send()
}, },
back () { back () {
this.$router.push(this.$store.state.innerReferrer) this.$router.push(this.$store.state.innerReferrer)
@ -474,6 +705,23 @@ export default {
} }
} }
.tool {
align-items: flex-start;
margin-bottom: 10px;
.filter {
flex-wrap: wrap;
}
li {
margin-bottom: 10px;
}
/deep/.el-select {
width: 140px;
}
}
.stat { .stat {
display: flex; display: flex;
@ -536,4 +784,16 @@ export default {
display: none !important; display: none !important;
} }
} }
/deep/.review-dia {
.el-drawer__close-btn {
position: absolute;
top: 20px;
right: 20px;
}
iframe {
height: 100%;
}
}
</style> </style>

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20 head-card"> <el-card shadow="hover" class="m-b-20 head-card">
<div class="flex-between m-b-20"> <div class="flex-between">
<el-page-header v-if="grades.length" @back="back" :content="grades[index].stageName + '/排名'"></el-page-header> <el-page-header v-if="grades.length" @back="back" :content="grades[index].stageName + '/排名'"></el-page-header>
</div> </div>
@ -14,15 +14,41 @@
@click="tabChange(item.stageId)">{{ item.stageName }}排名</a> @click="tabChange(item.stageId)">{{ item.stageName }}排名</a>
</template> </template>
</div> </div>
<div class="flex-between" style="margin: 20px 0">
<div class="tool flex-between" style="margin-top: 20px">
<div style="display: inline-flex;align-items: center"> <div style="display: inline-flex;align-items: center">
<el-radio v-model="type" :label="0" @change="typeChange">默认系统排序</el-radio> <el-radio v-model="type" :label="0" @change="typeChange">默认系统排序</el-radio>
<el-radio v-model="type" :label="1" @change="typeChange">手动上传</el-radio> <el-radio v-model="type" :label="1" @change="typeChange">手动上传</el-radio>
<el-button type="primary" :disabled="type === 0" class="ml20" @click="batchImport">上传文件</el-button> <el-button type="primary" :disabled="type === 0" class="ml20" @click="batchImport">上传文件</el-button>
</div> </div>
<div style="display: inline-flex;align-items: center"> <ul class="filter" style="flex: none;">
<li>
<label>省份</label>
<el-select v-model="filter.provinceId" clearable filterable placeholder="请选择省份" @change="provinceChange"
@clear="clearProvince">
<el-option v-for="(item, i) in provinces" :key="i" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select>
</li>
<li>
<label>城市</label>
<el-select v-model="filter.cityId" clearable filterable placeholder="请选择城市" :disabled="!filter.provinceId"
@change="initData">
<el-option v-for="(item, i) in cities" :key="i" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</li>
<li>
<label>学校</label>
<el-select v-model="filter.realSchoolId" clearable filterable placeholder="请选择学校" @change="initData">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</li>
<li>
<el-input style="margin-right: 15px" :placeholder="'请输入' + (competitionType ? '团队名称/队长' : '学生姓名') + '/学校'" <el-input style="margin-right: 15px" :placeholder="'请输入' + (competitionType ? '团队名称/队长' : '学生姓名') + '/学校'"
prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</li>
<el-button v-if="!published" type="primary" @click="cancelPublish(1)">发布排名</el-button> <el-button v-if="!published" type="primary" @click="cancelPublish(1)">发布排名</el-button>
<template v-else> <template v-else>
<span style="margin-right: 10px;white-space: nowrap;">{{ publishTime }}发布排名</span> <span style="margin-right: 10px;white-space: nowrap;">{{ publishTime }}发布排名</span>
@ -31,8 +57,9 @@
<el-button v-if="list.length" type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' : <el-button v-if="list.length" type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' :
'批量导出' '批量导出'
}}</el-button> }}</el-button>
</ul>
</div> </div>
</div>
<el-table :data="list" class="table" ref="table" stripe row-key="scoreId" <el-table :data="list" class="table" ref="table" stripe row-key="scoreId"
@selection-change="handleSelectionChange" header-align="center"> @selection-change="handleSelectionChange" header-align="center">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
@ -46,6 +73,8 @@
<el-table-column prop="leaderName" label="队长" min-width="150" align="center"></el-table-column> <el-table-column prop="leaderName" label="队长" min-width="150" align="center"></el-table-column>
</template> </template>
<el-table-column v-else prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column> <el-table-column v-else prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column>
<el-table-column prop="provinceName" label="省份" min-width="100" align="center"></el-table-column>
<el-table-column prop="cityName" label="城市" min-width="100" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column> <el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column> <el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column>
<el-table-column prop="timeSum" label="用时" width="90" align="center"> <el-table-column prop="timeSum" label="用时" width="90" align="center">
@ -182,6 +211,14 @@ export default {
competitionType: +this.$route.query.competitionType, competitionType: +this.$route.query.competitionType,
rule: +this.$route.query.rule, rule: +this.$route.query.rule,
searchTimer: null, searchTimer: null,
filter: {
provinceId: '',
cityId: '',
realSchoolId: '',
},
provinces: [],
cities: [],
schools: [],
keyword: this.$route.query.keyword || '', keyword: this.$route.query.keyword || '',
teamCalculationMethods: [ teamCalculationMethods: [
{ {
@ -262,6 +299,8 @@ export default {
} }
}, },
mounted () { mounted () {
this.getProvince()
this.getSchool()
this.getStage() this.getStage()
}, },
methods: { methods: {
@ -275,6 +314,7 @@ export default {
}, },
// //
getRank () { getRank () {
const { filter } = this
this.loading = true this.loading = true
// //
if (this.type) { if (this.type) {
@ -284,7 +324,8 @@ export default {
competitionId: this.id, competitionId: this.id,
isOverallRanking: this.active ? 0 : 1, isOverallRanking: this.active ? 0 : 1,
stageId: this.active || this.stageId, stageId: this.active || this.stageId,
keyword: this.keyword keyword: this.keyword,
...filter
}).then(({ message, publishStatus }) => { }).then(({ message, publishStatus }) => {
// isRelease 01 // isRelease 01
this.published = publishStatus this.published = publishStatus
@ -307,7 +348,8 @@ export default {
publicationType: this.type, publicationType: this.type,
locationStageId: this.stageId, locationStageId: this.stageId,
stageIds: ids.splice(0, ids.length - 1), stageIds: ids.splice(0, ids.length - 1),
keyword: this.keyword keyword: this.keyword,
...filter
}).then(({ page, publishStatus, total }) => { }).then(({ page, publishStatus, total }) => {
this.published = publishStatus this.published = publishStatus
this.list = page || [] this.list = page || []
@ -319,7 +361,7 @@ export default {
}) })
} else { } else {
// //
this.$post(`${this.api.stageRaceRanking}?competitionId=${this.id}&stageId=${this.active}&pageNum=${this.page}&pageSize=${this.pageSize}&publicationType=${this.type}&keyword=${this.keyword}`).then(({ page, total, publishStatus }) => { this.$post(`${this.api.stageRaceRanking}?competitionId=${this.id}&stageId=${this.active}&pageNum=${this.page}&pageSize=${this.pageSize}&publicationType=${this.type}&keyword=${this.keyword}&provinceId=${filter.provinceId}&cityId=${filter.cityId}&realSchoolId=${filter.realSchoolId}`).then(({ page, total, publishStatus }) => {
this.published = publishStatus this.published = publishStatus
this.list = page this.list = page
this.total = total this.total = total
@ -367,6 +409,39 @@ export default {
this.active = i this.active = i
this.initData() this.initData()
}, },
//
async getProvince () {
const { list } = await this.$get(this.api.queryProvince)
this.provinces = list
},
//
clearProvince () {
this.filter.cityId = ''
},
//
provinceChange () {
this.clearProvince()
this.getCity()
this.initData()
},
//
async getCity () {
const id = this.filter.provinceId
if (id) {
const { list } = await this.$get(this.api.queryCity, {
provinceId: id
})
this.cities = list
}
},
//
async getSchool () {
const { list } = await this.$get(this.api.querySchoolData)
this.schools = list
},
// //
show (row, i) { show (row, i) {
this.teams = [] this.teams = []

@ -31,11 +31,29 @@
item }}</a> item }}</a>
</div> </div>
<div class="flex-between m-b-20">
<div> <div class="tool flex-between">
<ul class="filter">
<li>
<label>省份</label>
<el-select v-model="filter.provinceId" filterable clearable placeholder="请选择省份" @change="provinceChange"
@clear="clearProvince">
<el-option v-for="(item, i) in provinces" :key="i" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select>
</li>
<li>
<label>城市</label>
<el-select v-model="filter.cityId" filterable clearable placeholder="请选择城市" :disabled="!filter.provinceId"
@change="initData">
<el-option v-for="(item, i) in cities" :key="i" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</li>
<li>
<el-input size="small" placeholder="请输入学校/学生姓名" prefix-icon="el-icon-search" v-model="keyword" clearable <el-input size="small" placeholder="请输入学校/学生姓名" prefix-icon="el-icon-search" v-model="keyword" clearable
style="width: 300px"></el-input> style="width: 300px"></el-input>
</div> </li>
</ul>
<div v-if="!active"> <div v-if="!active">
<el-button v-if="method == 2" type="primary" @click="batchImport">上传成绩</el-button> <el-button v-if="method == 2" type="primary" @click="batchImport">上传成绩</el-button>
<el-button type="primary" :disabled="!!multipleSelection.find(e => method != 2 && !e.reportId)" <el-button type="primary" :disabled="!!multipleSelection.find(e => method != 2 && !e.reportId)"
@ -57,6 +75,8 @@
{{ scope.$index + (page - 1) * pageSize + 1 }} {{ scope.$index + (page - 1) * pageSize + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="provinceName" label="省份" min-width="100" align="center"></el-table-column>
<el-table-column prop="cityName" label="城市" min-width="100" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column> <el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column> <el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column>
<el-table-column v-if="competitionType" prop="teamName" label="团队名称" min-width="100" <el-table-column v-if="competitionType" prop="teamName" label="团队名称" min-width="100"
@ -106,6 +126,8 @@
{{ scope.$index + (page1 - 1) * pageSize + 1 }} {{ scope.$index + (page1 - 1) * pageSize + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="provinceName" label="省份" align="center"></el-table-column>
<el-table-column prop="cityName" label="城市" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" align="center"></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 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 v-if="competitionType" prop="teamName" label="团队名称" align="center"></el-table-column>
@ -181,6 +203,16 @@ export default {
competitionType: +this.$route.query.competitionType, competitionType: +this.$route.query.competitionType,
showFile: this.$route.query.showFile === 'true', showFile: this.$route.query.showFile === 'true',
isCompress: util.isCompress, isCompress: util.isCompress,
filter: {
provinceId: '',
cityId: '',
realSchoolId: '',
reviewStatus: '',
scoreSortOrder: '',
submitTimeSortOrder: '',
},
provinces: [],
cities: [],
keyword: this.$route.query.keyword || '', keyword: this.$route.query.keyword || '',
searchTimer: null, searchTimer: null,
list: [], list: [],
@ -228,6 +260,7 @@ export default {
}, },
mounted () { mounted () {
this.getData() this.getData()
this.getProvince()
}, },
methods: { methods: {
async getData () { async getData () {
@ -240,6 +273,7 @@ export default {
competitionId: this.id, competitionId: this.id,
stageId: this.stageId, stageId: this.stageId,
keyWord: this.keyword, keyWord: this.keyword,
...this.filter
}) })
data.records.forEach(e => { data.records.forEach(e => {
e.loading = false e.loading = false
@ -268,7 +302,8 @@ export default {
competitionId: this.id, competitionId: this.id,
keyWord: this.keyword, keyWord: this.keyword,
stageId: this.stageId, stageId: this.stageId,
isNakadai: 1 isNakadai: 1,
...this.filter
}) })
this.loading = false this.loading = false
this.total = page.total this.total = page.total
@ -282,6 +317,33 @@ export default {
this.page = 1 this.page = 1
this.getData() this.getData()
}, },
//
async getProvince () {
const { list } = await this.$get(this.api.queryProvince)
this.provinces = list
},
//
clearProvince () {
this.filter.cityId = ''
},
//
provinceChange () {
this.clearProvince()
this.getCity()
this.initData()
},
//
async getCity () {
const id = this.filter.provinceId
if (id) {
const { list } = await this.$get(this.api.queryCity, {
provinceId: id
})
this.cities = list
}
},
// //
show (row) { show (row) {
this.$router.push(`/trialReport?reportId=${row.reportId}`) this.$router.push(`/trialReport?reportId=${row.reportId}`)

@ -96,8 +96,7 @@
</el-table-column> </el-table-column>
<el-table-column prop="userTotalScore" label="得分" align="center"> <el-table-column prop="userTotalScore" label="得分" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<p v-if="scope.row.questionType === 'essay' && scope.row.userTotalScore === undefined" <p v-if="scope.row.questionType === 'essay'" class="text-red">待评分
class="text-red">待评分
</p> </p>
<p v-else-if="essayExist && !scope.row.paperId" class="text-red">{{ scope.row.userTotalScore <p v-else-if="essayExist && !scope.row.paperId" class="text-red">{{ scope.row.userTotalScore
}}部分试题待判分成绩待定</p> }}部分试题待判分成绩待定</p>

@ -1936,6 +1936,12 @@ export default {
this.getSettlemennt() this.getSettlemennt()
}); });
this.$forceUpdate(); this.$forceUpdate();
//
this.productProps.map(e => {
this[e.name].map(n => {
this.deadLine(n.periodOfUse, n, n.options, 1)
})
})
} }
}, },
// //

Loading…
Cancel
Save