parent
2f18b9e99c
commit
2ab291e7bd
11 changed files with 1606 additions and 507 deletions
@ -0,0 +1,737 @@ |
||||
<template> |
||||
<div> |
||||
<el-card shadow="hover" |
||||
class="m-b-20 head-card"> |
||||
<div class="flex-between m-b-20"> |
||||
<el-page-header @back="$router.back()" |
||||
:content="goodsName"></el-page-header> |
||||
</div> |
||||
|
||||
</el-card> |
||||
|
||||
<el-card shadow="hover" |
||||
class="m-b-20"> |
||||
<el-tabs v-model="curTab" |
||||
@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> |
||||
<div class="stat"> |
||||
<div class="nums"> |
||||
<div class="item"> |
||||
<p class="name">实验总人数</p> |
||||
<p class="val">{{ peopleNum }}</p> |
||||
</div> |
||||
<div class="item item2"> |
||||
<p class="name">实验平均分</p> |
||||
<p class="val">{{ avgScore }}</p> |
||||
</div> |
||||
<div class="item item3"> |
||||
<p class="name">实验最高分</p> |
||||
<p class="val">{{ maxScore }}</p> |
||||
</div> |
||||
<div class="item item4"> |
||||
<p class="name">实验最低分</p> |
||||
<p class="val">{{ minScore }}</p> |
||||
</div> |
||||
</div> |
||||
<div class="chart" |
||||
id="chart"></div> |
||||
</div> |
||||
</el-card> |
||||
|
||||
<el-card shadow="hover" |
||||
class="m-b-20"> |
||||
<h6 style="font-size: 16px">错误率分析</h6> |
||||
<div class="wrong"> |
||||
<div class="line"> |
||||
<span class="jud-name">错误率最高:{{ max.projectName }}</span> |
||||
<span>参加考试{{ max.itemErrorCount }}人 | {{ permissions ? `共${max.errorTotal}人做错,` : '' }}错误率{{ max.errorRate }}%</span> |
||||
</div> |
||||
<div class="line"> |
||||
<span class="jud-name">错误率最低:{{ min.projectName }}</span> |
||||
<span>参加考试{{ min.itemErrorCount }}人 | {{ permissions ? `共${min.errorTotal}人做错,` : '' }}错误率{{ min.errorRate }}%</span> |
||||
</div> |
||||
</div> |
||||
<div class="chart" |
||||
id="chart1"></div> |
||||
</el-card> |
||||
|
||||
<el-card shadow="hover"> |
||||
<div class="flex-between m-b-20"> |
||||
<div> |
||||
<el-input placeholder="请输入姓名/学号" |
||||
prefix-icon="el-icon-search" |
||||
v-model="keyword" |
||||
clearable></el-input> |
||||
</div> |
||||
<div> |
||||
<el-button type="primary" |
||||
@click="exportData">导出成绩列表</el-button> |
||||
<!-- <el-button type="primary" |
||||
@click="exportReport">导出成绩详情</el-button> --> |
||||
</div> |
||||
</div> |
||||
<el-table :data="listData" |
||||
class="table" |
||||
ref="table" |
||||
:key="curTab" |
||||
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"> |
||||
{{ scope.$index + (page - 1) * pageSize + 1 }} |
||||
</template> |
||||
</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> |
||||
<template v-if="curTab == 0"> |
||||
<el-table-column label="练习项目数" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.row.totalNumberOfPractices }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="numberOfExercises" |
||||
label="练习次数" |
||||
width="90" |
||||
align="center"></el-table-column> |
||||
<el-table-column label="累计练习时长" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.row.timeSum }}min |
||||
</template> |
||||
</el-table-column> |
||||
</template> |
||||
<template v-else> |
||||
<el-table-column prop="totalNumberOfParticipants" |
||||
label="参加考核次数" |
||||
align="center"> |
||||
</el-table-column> |
||||
<el-table-column prop="averageTimeSpent" |
||||
label="平均用时" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.row.averageTimeSpent }}min |
||||
</template> |
||||
</el-table-column> |
||||
</template> |
||||
<el-table-column prop="avgScore" |
||||
label="平均分" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ curTab == 0 ? scope.row.avgScore : scope.row.averageScore }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="maxScore" |
||||
label="最高分" |
||||
align="center"></el-table-column> |
||||
<el-table-column prop="minScore" |
||||
label="最低分" |
||||
align="center"></el-table-column> |
||||
<el-table-column label="操作" |
||||
align="center" |
||||
width="140"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" |
||||
@click="show(scope.row)">查看成绩详情</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination background |
||||
layout="total, prev, pager, next" |
||||
:total="total" |
||||
@current-change="handleCurrentChange" |
||||
:current-page="page"> |
||||
</el-pagination> |
||||
</div> |
||||
</el-card> |
||||
|
||||
<el-dialog title="成绩详情" |
||||
:visible.sync="detailVisible" |
||||
width="900px" |
||||
:key="curTab" |
||||
:close-on-click-modal="false"> |
||||
<div class="m-b-10 text-right"> |
||||
<el-button type="primary" |
||||
@click="exportDetail">导出</el-button> |
||||
</div> |
||||
<el-table :data="details" |
||||
stripe |
||||
:key="curTab" |
||||
header-align="center" |
||||
row-key="id"> |
||||
<el-table-column type="index" |
||||
width="60" |
||||
label="序号" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.$index + (pageDetail - 1) * pageSizeDetail + 1 }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="userName" |
||||
label="姓名" |
||||
width="100" |
||||
align="center"> |
||||
</el-table-column> |
||||
<el-table-column prop="workNumber" |
||||
label="学号" |
||||
width="100" |
||||
align="center"></el-table-column> |
||||
<template v-if="curTab == 0"> |
||||
<el-table-column prop="projectName" |
||||
label="项目名称" |
||||
min-width="200" |
||||
align="center"></el-table-column> |
||||
<el-table-column prop="averageDuration" |
||||
label="平均练习时长" |
||||
width="110" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.row.averageDuration }}min |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="averageScore" |
||||
label="平均分" |
||||
min-width="100" |
||||
align="center"></el-table-column> |
||||
</template> |
||||
<template v-else> |
||||
<el-table-column prop="experimentalName" |
||||
label="考核名称" |
||||
min-width="200" |
||||
align="center"></el-table-column> |
||||
<el-table-column prop="averageDuration" |
||||
label="用时" |
||||
width="100" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.row.timeSum }}min |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="score" |
||||
label="分数" |
||||
min-width="100" |
||||
align="center"></el-table-column> |
||||
</template> |
||||
<el-table-column label="成绩报告" |
||||
align="center" |
||||
width="90"> |
||||
<template slot-scope="scope"> |
||||
<el-button type="text" |
||||
@click="toReport(scope.row)">查看</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination background |
||||
layout="total, prev, pager, next" |
||||
:total="totalDetail" |
||||
:page-size="pageSizeDetail" |
||||
@current-change="handleCurrentDetailChange" |
||||
:current-page="pageDetail"> |
||||
</el-pagination> |
||||
</div> |
||||
<span slot="footer" |
||||
class="dialog-footer"> |
||||
<el-button size="small" |
||||
type="primary" |
||||
@click="detailVisible = false">确定</el-button> |
||||
</span> |
||||
</el-dialog> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import Setting from "@/setting"; |
||||
import util from "@/libs/util"; |
||||
import echarts from "echarts"; |
||||
import axios from 'axios'; |
||||
export default { |
||||
data () { |
||||
return { |
||||
tabs: [ |
||||
{ |
||||
id: '0', |
||||
name: '练习成绩' |
||||
}, |
||||
{ |
||||
id: '1', |
||||
name: '考核成绩' |
||||
} |
||||
], |
||||
curTab: this.$route.query.permissions || '0', |
||||
permissions: +this.$route.query.permissions, |
||||
goodsName: this.$route.query.curriculumName, |
||||
accountId: this.$route.query.accountId, |
||||
id: +this.$route.query.id, |
||||
cid: +this.$route.query.cid, |
||||
keyword: "", |
||||
searchTimer: null, |
||||
listDataAll: [], |
||||
listData: [], |
||||
multipleSelection: [], |
||||
page: 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
peopleNum: 0, // 总人数 |
||||
avgScore: 0, // 平均分 |
||||
maxScore: 0, |
||||
minScore: 0, |
||||
errorAnalysis: {}, |
||||
max: {}, |
||||
min: {}, |
||||
token: util.local.get(Setting.tokenKey), |
||||
detailVisible: false, |
||||
details: [], |
||||
multipleSelectionActivation: [], |
||||
pageDetail: 1, |
||||
pageSizeDetail: 5, |
||||
totalDetail: 0, |
||||
curRow: {}, |
||||
stageNumber: [] |
||||
}; |
||||
}, |
||||
watch: { |
||||
keyword: function (val) { |
||||
clearTimeout(this.searchTimer); |
||||
this.searchTimer = setTimeout(() => { |
||||
this.initData(); |
||||
}, 500); |
||||
} |
||||
}, |
||||
mounted () { |
||||
// this.getClass() |
||||
this.getData() |
||||
}, |
||||
methods: { |
||||
// 成绩 |
||||
async getData () { |
||||
const per = +this.curTab |
||||
const res = await this.$post(this.api.productReadScore, { |
||||
pageNum: this.page, |
||||
pageSize: 10000, |
||||
keyWord: this.keyword, |
||||
mallId: this.id, |
||||
cid: this.cid, |
||||
permissions: per |
||||
}) |
||||
this.listDataAll = per ? res.listOfAssessmentResults.records : res.userScoreList.records |
||||
this.total = per ? res.listOfAssessmentResults.total : res.userScoreList.total |
||||
const stat = res.experimentalStatistics |
||||
this.avgScore = stat.averageScore |
||||
this.peopleNum = stat.experimentalPopulation |
||||
this.maxScore = stat.maxScore |
||||
this.minScore = stat.minScore |
||||
const err = per ? res.testErrorRateUnderProduct : res.projectErrorRateAnalysisUnderProduct |
||||
err.forEach(e => { |
||||
e.errorRate = (+e.errorRate).toFixed(2) |
||||
}) |
||||
this.errorAnalysis = err |
||||
this.max = err[0] |
||||
this.min = err[err.length - 1] |
||||
const { row } = this.$store.state.achievement |
||||
row && this.$nextTick(() => { |
||||
window.scrollTo(0, document.documentElement.scrollHeight) |
||||
this.show(row) |
||||
this.$store.commit('achievement/setRow', null) |
||||
}) |
||||
this.handlePage() |
||||
this.getChart() |
||||
this.errorChart() |
||||
}, |
||||
initData () { |
||||
this.page = 1 |
||||
this.getData() |
||||
}, |
||||
// 分页 |
||||
handlePage () { |
||||
const list = this.listDataAll |
||||
this.listData = list.slice((this.page - 1) * this.pageSize, this.page * this.pageSize) |
||||
}, |
||||
// 练习考核切换 |
||||
tabChange () { |
||||
this.$router.push({ |
||||
path: 'course', |
||||
query: { |
||||
...this.$route.query, |
||||
permissions: this.curTab |
||||
} |
||||
}) |
||||
this.initData() |
||||
}, |
||||
// 导出(有勾选:就导勾选中的;没有勾选:就导全部) |
||||
async exportData () { |
||||
let list = this.multipleSelection |
||||
const practice = this.curTab == 0 // 练习 |
||||
// 没勾选,则查询所有成绩 |
||||
if (!list.length) { |
||||
const res = await this.$post(this.api.productReadScore, { |
||||
pageNum: 1, |
||||
pageSize: 10000, |
||||
mallId: this.id, |
||||
cid: this.cid, |
||||
permissions: +this.curTab, |
||||
}) |
||||
list = practice ? res.userScoreList.records : res.listOfAssessmentResults.records |
||||
} |
||||
list.forEach(e => { |
||||
e.goodsName = this.goodsName |
||||
e.cid = this.cid |
||||
}) |
||||
axios.post(this.api[practice ? 'exportProductPracticeResults' : 'exportProductAssessResults'], list, { |
||||
headers: { |
||||
token: this.token |
||||
}, |
||||
responseType: 'blob' |
||||
}).then((res) => { |
||||
util.downloadFileDirect(`${practice ? '练习' : '考核'}成绩列表.xlsx`, new Blob([res.data])) |
||||
}).catch(res => { }) |
||||
}, |
||||
// 导出实验报告 |
||||
exportReport () { |
||||
// 没选择数据,则导出全部 |
||||
const list = this.multipleSelection.length ? this.multipleSelection : this.listDataAll |
||||
list.forEach(async e => { |
||||
const { report, userScores } = await this.$get(`${this.api.reportDetail}?reportId=${e.reportId}`) |
||||
userScores.map((e, i) => { |
||||
if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/( |&|%s)/g, '').replace(/>/g, '>').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, '') |
||||
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) { // 删除 |
||||
this.$confirm("确定要删除吗?", "提示", { |
||||
type: "warning" |
||||
}).then(() => { |
||||
this.$post(this.api.deleteExperimentalReport, [row.reportId]).then(res => { |
||||
util.successMsg("删除成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
}).catch(() => { |
||||
}); |
||||
}, |
||||
delAllData () { // 批量删除 |
||||
if (this.multipleSelection.length) { |
||||
this.$confirm("该项目下的所有成绩报告将会删除,是否继续?", "提示", { |
||||
type: "warning" |
||||
}).then(() => { |
||||
let ids = this.multipleSelection.map(item => { |
||||
return item.reportId; |
||||
}); |
||||
this.$post(this.api.deleteExperimentalReport, ids).then(res => { |
||||
this.multipleSelection = []; |
||||
this.$refs.table.clearSelection(); |
||||
util.successMsg("删除成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
}).catch(() => { |
||||
}); |
||||
} else { |
||||
util.errorMsg("请先选择数据 !"); |
||||
} |
||||
}, |
||||
handleSelectionChange (val) { // 多选 |
||||
this.multipleSelection = val; |
||||
}, |
||||
handleCurrentChange (val) { // 切换分页 |
||||
this.page = val |
||||
this.handlePage() |
||||
}, |
||||
|
||||
// 打开成绩详情 |
||||
async show (row) { |
||||
this.curRow = row |
||||
this.detailVisible = true |
||||
this.initDetailData() |
||||
}, |
||||
// 查询成绩详情 |
||||
async getDetail () { |
||||
const { data } = await this.$post(this.api.productReadGradeDetails, { |
||||
pageNum: this.pageDetail, |
||||
pageSize: this.pageSizeDetail, |
||||
mallId: this.id, |
||||
permissions: +this.curTab, |
||||
studentAccountId: this.curRow.accountId |
||||
}) |
||||
this.details = data.records |
||||
this.totalDetail = data.total |
||||
}, |
||||
initDetailData () { |
||||
this.pageDetail = 1 |
||||
this.getDetail() |
||||
}, |
||||
// 详情分页 |
||||
handleCurrentDetailChange (val) { |
||||
this.pageDetail = val |
||||
this.getDetail() |
||||
}, |
||||
// 导出 |
||||
async exportDetail () { |
||||
const practice = this.curTab == 0 // 练习 |
||||
if (this.details.length) { |
||||
const res = await axios.post(this.api[practice ? 'exportDetailsOfStudentPracticeScores' : 'exportDetailsOfStudentAssessmentResults'], { |
||||
pageNum: 1, |
||||
pageSize: 1000, |
||||
mallId: this.id, |
||||
permissions: +this.curTab, |
||||
studentAccountId: this.curRow.accountId, |
||||
goodsName: this.curriculumgoodsNameName |
||||
}, { |
||||
headers: { |
||||
token: this.token |
||||
}, |
||||
responseType: 'blob' |
||||
}) |
||||
util.downloadFileDirect(`${this.curRow.userName}_${practice ? '练习' : '考核'}成绩详情.xlsx`, new Blob([res.data])) |
||||
} |
||||
}, |
||||
// 查看成绩报告 |
||||
toReport (row) { |
||||
this.$store.commit('achievement/setRow', this.curRow) |
||||
// 考核跳实验报告,练习跳项目维度的成绩详情 |
||||
this.$router.push(this.curTab == 1 ? `show?reportId=${row.reportId}` : `project?id=${row.projectId}&projectName=${row.goodsName}&classId=${this.curRow.classId || ''}&workNumber=${row.workNumber || row.userName}`) |
||||
}, |
||||
getChart () { // 初始化折线图 |
||||
const xData = Array.from({ length: 101 }, (v, k) => k) |
||||
const yData = Array.from({ length: 101 }, (v, k) => 0) |
||||
const list = this.listDataAll |
||||
const prop = this.curTab == 0 ? 'avgScore' : 'averageScore' |
||||
list.map(n => { |
||||
yData[n[prop]]++ |
||||
}) |
||||
return console.log(333, xData, yData) |
||||
const nums = this.stageNumber |
||||
for (const i in this.stageNumber) { |
||||
data.push(nums[i]) |
||||
} |
||||
let myChart = echarts.init(document.getElementById("chart")); |
||||
myChart.setOption({ |
||||
title: { text: "实验分数分布图" }, |
||||
tooltip: {}, |
||||
xAxis: { |
||||
name: "分数", |
||||
type: "category", |
||||
boundaryGap: false, |
||||
interval: 10, |
||||
data: ["0", "10", "20", "30", "40", "50", "60", "70", "80", "90", '100'] |
||||
}, |
||||
yAxis: { |
||||
name: this.permissions ? "人数" : '成绩报告数量', |
||||
type: "value", |
||||
interval: 1 |
||||
}, |
||||
series: [{ |
||||
data, |
||||
type: "line", |
||||
areaStyle: {}, |
||||
color: ["#8191fd"] |
||||
}] |
||||
}); |
||||
}, |
||||
// 错误率统计图 |
||||
errorChart () { |
||||
const data = this.errorAnalysis |
||||
const maxFontLength = data.length > 13 ? 6 : 10 |
||||
const option = { |
||||
tooltip: { |
||||
trigger: 'axis', |
||||
}, |
||||
grid: { |
||||
left: '5%', |
||||
right: '5%', |
||||
top: '10%', |
||||
bottom: '30%' |
||||
}, |
||||
dataZoom: [//滑动条 |
||||
{ |
||||
// xAxisIndex: 0,//这里是从X轴的0刻度开始 |
||||
show: true, |
||||
type: 'slider', |
||||
start: 0, |
||||
end: 150, |
||||
xAxisIndex: [0], |
||||
bottom: -10, |
||||
} |
||||
], |
||||
xAxis: [{ |
||||
type: 'category', |
||||
axisLine: { |
||||
lineStyle: { |
||||
color: '#57617B' |
||||
} |
||||
}, |
||||
axisLabel: { |
||||
interval: 0, |
||||
textStyle: { |
||||
color: '#333', |
||||
}, |
||||
formatter: function (value, index) { |
||||
value = value.substring(0, maxFontLength) + (value.length > maxFontLength ? '...' : '') |
||||
// if (index % 2 != 0) { |
||||
// return '\n\n' + value; |
||||
// } else { |
||||
// return value; |
||||
// } |
||||
return value |
||||
} |
||||
// rotate: 45 |
||||
}, |
||||
data: data.map(e => e.projectName) |
||||
}], |
||||
yAxis: [ |
||||
{ |
||||
type: 'value', |
||||
name: '错误率', |
||||
nameGap: 10, |
||||
axisLine: { |
||||
lineStyle: { |
||||
color: '#333' |
||||
} |
||||
}, |
||||
axisLabel: { |
||||
margin: 10, |
||||
textStyle: { |
||||
fontSize: 12, |
||||
color: '#333' |
||||
}, |
||||
formatter: '{value}%' |
||||
}, |
||||
} |
||||
], |
||||
series: [{ |
||||
name: '错误率', |
||||
type: 'bar', |
||||
barWidth: 25, |
||||
axisLabel: { |
||||
margin: 10, |
||||
textStyle: { |
||||
fontSize: 12, |
||||
color: '#333' |
||||
}, |
||||
formatter: '{value}%' |
||||
}, |
||||
itemStyle: { |
||||
normal: { |
||||
barBorderRadius: [10, 10, 0, 0], |
||||
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [{ |
||||
offset: 0, |
||||
color: "#009AFD" |
||||
}, { |
||||
offset: 0.8, |
||||
color: "#33DAFF" |
||||
}], false), |
||||
shadowColor: 'rgba(0, 0, 0, 0.1)', |
||||
} |
||||
}, |
||||
data: data.map(e => e.errorRate) |
||||
} |
||||
] |
||||
} |
||||
echarts.init(document.querySelector(`#chart1`)).setOption(option) |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
/deep/ .head-card { |
||||
.el-card__body { |
||||
padding-bottom: 0px; |
||||
|
||||
.el-tabs__header { |
||||
margin-bottom: 1px; |
||||
|
||||
.el-tabs__nav-wrap::after { |
||||
display: none; |
||||
} |
||||
|
||||
.el-tabs__item { |
||||
font-size: 18px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.chart { |
||||
height: 300px; |
||||
} |
||||
.stat { |
||||
display: flex; |
||||
.nums { |
||||
display: flex; |
||||
align-items: center; |
||||
flex-wrap: wrap; |
||||
width: 640px; |
||||
margin-right: 20px; |
||||
|
||||
.item { |
||||
width: 300px; |
||||
padding: 30px 30px; |
||||
margin: 0 10px; |
||||
box-sizing: border-box; |
||||
border-radius: 8px; |
||||
background: url('../../../assets/img/total.png') 0 0/100% 100% no-repeat; |
||||
p { |
||||
font-size: 18px; |
||||
color: #ffffff; |
||||
} |
||||
.val { |
||||
margin-top: 10px; |
||||
color: #ffffff; |
||||
font-size: 36px; |
||||
} |
||||
} |
||||
.item:nth-child(2) { |
||||
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'); |
||||
} |
||||
} |
||||
.chart { |
||||
width: calc(100% - 660px); |
||||
} |
||||
} |
||||
.wrong { |
||||
.line { |
||||
display: flex; |
||||
width: 920px; |
||||
margin: 0 auto 10px; |
||||
.jud-name { |
||||
width: 500px; |
||||
margin-right: 100px; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,275 @@ |
||||
<template> |
||||
<div class="page"> |
||||
<h6 class="p-title">筛选</h6> |
||||
<div class="tool mul"> |
||||
<ul class="filter"> |
||||
<li> |
||||
<label>课程</label> |
||||
<el-select v-model="mallId" |
||||
@change="initData"> |
||||
<el-option label="不限" |
||||
value=""></el-option> |
||||
<el-option v-for="(item, i) in curs" |
||||
:key="i" |
||||
:label="item.curriculumName" |
||||
:value="item.mallId" |
||||
@change="curChange"></el-option> |
||||
</el-select> |
||||
</li> |
||||
<li> |
||||
<label>班级</label> |
||||
<el-select v-model="classId" |
||||
@change="classChange"> |
||||
<el-option label="不限" |
||||
value=""></el-option> |
||||
<el-option v-for="item in classList" |
||||
:key="item.id" |
||||
:label="item.className" |
||||
:value="item.id"> |
||||
</el-option> |
||||
</el-select> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
<el-table :data="list" |
||||
class="table" |
||||
ref="table" |
||||
stripe |
||||
header-align="center" |
||||
row-key="id"> |
||||
<el-table-column type="index" |
||||
width="60" |
||||
label="序号" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.$index + (page - 1) * pageSize + 1 }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="curriculumName" |
||||
label="课程" |
||||
align="center" |
||||
min-width="200"></el-table-column> |
||||
<el-table-column prop="className" |
||||
label="班级" |
||||
align="center" |
||||
min-width="130"></el-table-column> |
||||
<el-table-column prop="numberOfPracticeItems" |
||||
label="练习项目数" |
||||
align="center" |
||||
min-width="100"></el-table-column> |
||||
<el-table-column prop="numberOfAssessmentItems" |
||||
label="考核项目数" |
||||
align="center" |
||||
min-width="100"></el-table-column> |
||||
<el-table-column prop="classSize" |
||||
label="班级人数" |
||||
align="center" |
||||
min-width="100"></el-table-column> |
||||
<el-table-column label="操作" |
||||
align="center" |
||||
width="100"> |
||||
<template slot-scope="scope"> |
||||
<el-button v-auth="'练习成绩管理'" |
||||
type="text" |
||||
@click="entry(scope.row)">成绩管理</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination background |
||||
layout="total, prev, pager, next" |
||||
:total="total" |
||||
@current-change="handleCurrentChange" |
||||
:current-page="page"></el-pagination> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { Loading } from "element-ui"; |
||||
import util from "@/libs/util"; |
||||
export default { |
||||
data () { |
||||
return { |
||||
classId: this.$route.query.class ? +this.$route.query.class : '', |
||||
classList: [], |
||||
mallId: this.$route.query.mallId ? +this.$route.query.mallId : '', |
||||
curriculumList: [], |
||||
projectPermissions: this.$route.query.per ? +this.$route.query.per : 0, |
||||
mallIds: [], |
||||
curs: [], |
||||
keyword: "", |
||||
searchTimer: null, |
||||
startingtime: "", |
||||
endTime: "", |
||||
month: "", |
||||
list: [], |
||||
multipleSelection: [], |
||||
dateList: [ |
||||
{ |
||||
id: "", |
||||
name: "不限" |
||||
}, { |
||||
id: 1, |
||||
name: "近一个月" |
||||
}, { |
||||
id: 6, |
||||
name: "近六个月" |
||||
} |
||||
], |
||||
projectType: [ |
||||
{ |
||||
id: 0, |
||||
name: "练习" |
||||
}, { |
||||
id: 1, |
||||
name: "考核" |
||||
} |
||||
], |
||||
date: "", |
||||
page: +this.$route.query.page || 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
loadIns: null |
||||
}; |
||||
}, |
||||
watch: { |
||||
month: function (val) { |
||||
if (val) { |
||||
let unit = 24 * 60 * 60 * 1000; |
||||
this.date = [util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() - unit * 30 * val)), util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() + unit))]; |
||||
} else { |
||||
this.date = []; |
||||
} |
||||
}, |
||||
date: function (val) { |
||||
if (val) { |
||||
this.startingtime = val[0]; |
||||
this.endTime = val[1]; |
||||
} else { |
||||
this.startingtime = ""; |
||||
this.endTime = ""; |
||||
this.month = ''; |
||||
} |
||||
this.initData(); |
||||
}, |
||||
keyword: function (val) { |
||||
clearTimeout(this.searchTimer); |
||||
this.searchTimer = setTimeout(() => { |
||||
this.initData(); |
||||
}, 500); |
||||
} |
||||
}, |
||||
mounted () { |
||||
this.getClassData() |
||||
this.getCourse() |
||||
}, |
||||
methods: { |
||||
// 获取课程 |
||||
async getCourse () { |
||||
const { data } = await this.$get(this.api.getSchoolEffectiveCourse) |
||||
this.curs = data |
||||
this.initData(); |
||||
}, |
||||
// 课程选择回调 |
||||
curChange (id) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
mallId: id |
||||
} |
||||
}) |
||||
this.initData() |
||||
}, |
||||
|
||||
getClassData () { // 获取班级下拉框数据 |
||||
this.$post(this.api.allClassesInOurSchool).then(res => { |
||||
this.classList = res.data |
||||
}).catch(res => { }) |
||||
}, |
||||
getData () { |
||||
this.loadIns = Loading.service({ |
||||
background: "rgba(255,255,255,.6)" |
||||
}); |
||||
this.$post(this.api.practiceByProduct, { |
||||
classId: this.classId, |
||||
mallId: this.mallId, |
||||
keyWord: this.keyword, |
||||
pageNum: this.page, |
||||
pageSize: this.pageSize, |
||||
}).then(res => { |
||||
this.list = res.data |
||||
this.total = res.total |
||||
this.$nextTick(() => { |
||||
this.loadIns.close() |
||||
}); |
||||
}).catch(res => { |
||||
this.loadIns.close() |
||||
}); |
||||
}, |
||||
// 项目分类回调 |
||||
perChange (val) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
per: val |
||||
} |
||||
}) |
||||
this.getData() |
||||
}, |
||||
// 班级回调 |
||||
classChange (val) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
class: val |
||||
} |
||||
}) |
||||
this.getData() |
||||
}, |
||||
// 课程回调 |
||||
curriculumChange (val) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
curriculum: val |
||||
} |
||||
}) |
||||
this.getData() |
||||
}, |
||||
initData () { |
||||
this.$refs.table.clearSelection(); |
||||
this.page = 1; |
||||
this.getData(); |
||||
}, |
||||
// 进入实验记录 |
||||
entry (row) { |
||||
this.$router.push(`course?id=${row.mallId}&curriculumName=${row.curriculumName}&cid=${row.cid}`) |
||||
}, |
||||
handleCurrentChange (val) { // 切换页码 |
||||
this.page = val |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
page: val |
||||
} |
||||
}) |
||||
this.getData(); |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.el-radio.is-bordered + .el-radio.is-bordered { |
||||
margin-left: 0; |
||||
} |
||||
.el-radio-group { |
||||
white-space: nowrap; |
||||
} |
||||
</style> |
@ -1,431 +1,69 @@ |
||||
<template> |
||||
<div class="page"> |
||||
<h6 class="p-title">筛选</h6> |
||||
<div class="tool mul"> |
||||
<ul class="filter"> |
||||
<li v-if="projectPermissions"> |
||||
<label>时间</label> |
||||
<el-radio-group v-model="month" |
||||
@change="initData"> |
||||
<el-radio v-for="(item,index) in dateList" |
||||
:key="index" |
||||
:label="item.id" |
||||
border>{{ item.name }}</el-radio> |
||||
</el-radio-group> |
||||
<el-date-picker v-model="date" |
||||
@blur='pickerInput' |
||||
align="right" |
||||
unlink-panels |
||||
type="daterange" |
||||
start-placeholder="开始日期" |
||||
end-placeholder="结束日期" |
||||
format="yyyy-MM-dd" |
||||
value-format="yyyy-MM-dd" |
||||
clearable |
||||
style="width: 300px"> |
||||
</el-date-picker> |
||||
</li> |
||||
<li> |
||||
<label>实验项目分类</label> |
||||
<el-radio-group v-model="projectPermissions" |
||||
@change="perChange"> |
||||
<el-radio v-for="(item,index) in projectType" |
||||
:key="index" |
||||
:label="item.id" |
||||
border>{{ item.name }}</el-radio> |
||||
</el-radio-group> |
||||
</li> |
||||
<li v-show="projectPermissions === 1"> |
||||
<label>班级</label> |
||||
<el-select v-model="classId" |
||||
@change="classChange"> |
||||
<el-option v-for="item in classList" |
||||
:key="item.id" |
||||
:label="item.className" |
||||
:value="item.id"> |
||||
</el-option> |
||||
</el-select> |
||||
</li> |
||||
<li> |
||||
<label>课程</label> |
||||
<el-select v-model="mallId" |
||||
@change="initData"> |
||||
<el-option v-for="(item, i) in curs" |
||||
:key="i" |
||||
:label="item.curriculumName" |
||||
:value="item.mallId" |
||||
@change="curChange"></el-option> |
||||
</el-select> |
||||
</li> |
||||
<li> |
||||
<el-input placeholder="请输入考核或项目名称" |
||||
prefix-icon="el-icon-search" |
||||
v-model="keyword" |
||||
clearable></el-input> |
||||
</li> |
||||
</ul> |
||||
<div class="tabs"> |
||||
<a class="item" |
||||
v-for="(item,index) in tabs" |
||||
:key="index" |
||||
:class="{active: index == active}" |
||||
@click="tabChange(index)">{{ item }}</a> |
||||
</div> |
||||
<div class="tool mul"> |
||||
<ul class="filter"></ul> |
||||
<div style="margin-bottom: 24px"> |
||||
<el-button v-auth |
||||
type="primary" |
||||
@click="delAllData">批量删除</el-button> |
||||
</div> |
||||
</div> |
||||
<el-table :data="listData" |
||||
class="table" |
||||
ref="table" |
||||
stripe |
||||
header-align="center" |
||||
@selection-change="handleSelectionChange" |
||||
row-key="id"> |
||||
<el-table-column type="selection" |
||||
width="55" |
||||
align="center" |
||||
:reserve-selection="true" |
||||
:selectable="disabledSelection"></el-table-column> |
||||
<el-table-column type="index" |
||||
width="60" |
||||
label="序号" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.$index + (page - 1) * pageSize + 1 }} |
||||
</template> |
||||
</el-table-column> |
||||
<template v-if="projectPermissions == 1"> |
||||
<el-table-column prop="className" |
||||
label="班级" |
||||
align="center" |
||||
width="140"></el-table-column> |
||||
<el-table-column prop="experimentalName" |
||||
label="考核名称" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
<span class="mul-ellipsis2">{{ scope.row.experimentalName }}</span> |
||||
</template> |
||||
</el-table-column> |
||||
</template> |
||||
<el-table-column prop="projectName" |
||||
label="项目名称" |
||||
align="center"></el-table-column> |
||||
<el-table-column prop="projectPermissions" |
||||
label="分类" |
||||
align="center" |
||||
width="100"> |
||||
<template slot-scope="scope"> |
||||
{{ projectPermissions ? '考核' : '练习' }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="experimentalNumber" |
||||
label="成绩报告数量" |
||||
align="center" |
||||
:width="projectPermissions ? 120 : 230"></el-table-column> |
||||
<el-table-column prop="createTime" |
||||
label="创建时间" |
||||
align="center" |
||||
:width="projectPermissions ? 160 : 230"> |
||||
</el-table-column> |
||||
<el-table-column label="操作" |
||||
align="center" |
||||
:width="projectPermissions ? 150 : 230"> |
||||
<template slot-scope="scope"> |
||||
<el-button v-auth="'练习成绩管理'" |
||||
type="text" |
||||
@click="entry(scope.row)">成绩管理</el-button> |
||||
<el-button v-auth |
||||
type="text" |
||||
v-if="scope.row.canDel" |
||||
@click="handleDelete(scope.row)">删除</el-button> |
||||
<el-button v-auth |
||||
type="text" |
||||
v-else |
||||
style='color:#999'>删除</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination background |
||||
layout="total, prev, pager, next" |
||||
:total="total" |
||||
@current-change="handleCurrentChange" |
||||
:current-page="page"></el-pagination> |
||||
<div class="page-content"> |
||||
<Course v-if="active == 'tab1'" /> |
||||
<Project v-if="active == 'tab2'" /> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { Loading } from "element-ui"; |
||||
import util from "@/libs/util"; |
||||
import Setting from "@/setting"; |
||||
import { mapState } from "vuex"; |
||||
import Course from "./course"; |
||||
import Project from "./project"; |
||||
|
||||
export default { |
||||
name: "achievement", |
||||
name: "course", |
||||
components: { |
||||
Course, |
||||
Project |
||||
}, |
||||
data () { |
||||
return { |
||||
classId: this.$route.query.class ? +this.$route.query.class : '', |
||||
classList: [], |
||||
mallId: this.$route.query.mallId ? +this.$route.query.mallId : '', |
||||
curriculumList: [], |
||||
projectPermissions: this.$route.query.per ? +this.$route.query.per : 0, |
||||
mallIds: [], |
||||
curs: [], |
||||
keyword: "", |
||||
searchTimer: null, |
||||
startingtime: "", |
||||
endTime: "", |
||||
month: "", |
||||
listData: [], |
||||
multipleSelection: [], |
||||
dateList: [ |
||||
{ |
||||
id: "", |
||||
name: "不限" |
||||
}, { |
||||
id: 1, |
||||
name: "近一个月" |
||||
}, { |
||||
id: 6, |
||||
name: "近六个月" |
||||
} |
||||
], |
||||
projectType: [ |
||||
{ |
||||
id: 0, |
||||
name: "练习" |
||||
}, { |
||||
id: 1, |
||||
name: "考核" |
||||
} |
||||
], |
||||
date: "", |
||||
page: +this.$route.query.page || 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
loadIns: null |
||||
active: this.$route.query.tab || "tab1", // 当前标签页 |
||||
tabs: { |
||||
tab1: '课程维度', |
||||
tab2: '项目维度', |
||||
// tab3: '多维评分', |
||||
}, |
||||
}; |
||||
}, |
||||
watch: { |
||||
month: function (val) { |
||||
if (val) { |
||||
let unit = 24 * 60 * 60 * 1000; |
||||
this.date = [util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() - unit * 30 * val)), util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() + unit))]; |
||||
} else { |
||||
this.date = []; |
||||
} |
||||
}, |
||||
date: function (val) { |
||||
if (val) { |
||||
this.startingtime = val[0]; |
||||
this.endTime = val[1]; |
||||
} else { |
||||
this.startingtime = ""; |
||||
this.endTime = ""; |
||||
this.month = ''; |
||||
} |
||||
this.initData(); |
||||
}, |
||||
keyword: function (val) { |
||||
clearTimeout(this.searchTimer); |
||||
this.searchTimer = setTimeout(() => { |
||||
this.initData(); |
||||
}, 500); |
||||
} |
||||
computed: { |
||||
...mapState("auth", [ |
||||
"btns" |
||||
]) |
||||
}, |
||||
mounted () { |
||||
this.getClassData() |
||||
this.getCourse() |
||||
// Setting.dynamicRoute && this.initTabs(); |
||||
}, |
||||
methods: { |
||||
pickerInput () { |
||||
this.month = '6' |
||||
}, |
||||
|
||||
// 获取课程 |
||||
async getCourse () { |
||||
const { data } = await this.$get(this.api.getSchoolEffectiveCourse) |
||||
this.curs = data |
||||
this.mallId = this.mallId || data[0].mallId |
||||
this.initData(); |
||||
}, |
||||
// 课程选择回调 |
||||
curChange (id) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
mallId: id |
||||
} |
||||
}) |
||||
this.initData() |
||||
}, |
||||
|
||||
getClassData () { // 获取班级下拉框数据 |
||||
this.$post(this.api.myClass).then(res => { |
||||
this.classList = res.list; |
||||
}).catch(res => { |
||||
}); |
||||
}, |
||||
getData () { |
||||
this.loadIns = Loading.service({ |
||||
background: "rgba(255,255,255,.6)" |
||||
}); |
||||
const per = this.projectPermissions |
||||
const { mallId } = this |
||||
const cur = this.curs.find(e => e.mallId == mallId) || {} |
||||
let data = { |
||||
classId: this.classId, |
||||
permissions: per, |
||||
curriculumId: cur.cid, |
||||
mallId, |
||||
keyWord: this.keyword, |
||||
startTime: this.startingtime, |
||||
endTime: this.endTime, |
||||
month: this.month, |
||||
pageNum: this.page, |
||||
pageSize: this.pageSize, |
||||
systemId: cur.systemId |
||||
}; |
||||
this.$post(this.api.getAchievementInfo, data).then(res => { |
||||
let list = [] |
||||
if (per == 0) { |
||||
list = res.page |
||||
this.total = res.total |
||||
} else { |
||||
list = res.page.records |
||||
this.total = res.page.total |
||||
} |
||||
console.log(33, per) |
||||
list.map(e => { |
||||
// isAdmin表示这个项目是不是内置的项目,如果为1 表示内置的项目,删除的前提条件就是这个项目删除了isdel=1以及courseDel=1 同时课程管理也移除了这个项目才能删除, 所以要系统内置的项目要满足这三个条件(1.为内置 2.中台删除了、3、课程里面也移除了)才能删除。是isAdmin为0就说明不是内置项目,为当前用户自己创建的项目,所以条件就是isDel为1直接删 |
||||
e.canDel = per ? |
||||
e.isDel : |
||||
(e.isAdmin === 0 && e.isDel === 1) || (e.isAdmin === 1 && e.isDel === 1 && e.courseDel === 1) |
||||
}) |
||||
this.listData = list |
||||
this.$nextTick(() => { |
||||
this.loadIns.close() |
||||
}); |
||||
}).catch(res => { |
||||
this.loadIns.close() |
||||
}); |
||||
}, |
||||
// 项目分类回调 |
||||
perChange (val) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
per: val |
||||
} |
||||
}) |
||||
this.getData() |
||||
}, |
||||
// 班级回调 |
||||
classChange (val) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
class: val |
||||
} |
||||
}) |
||||
this.getData() |
||||
}, |
||||
// 课程回调 |
||||
curriculumChange (val) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
curriculum: val |
||||
} |
||||
}) |
||||
this.getData() |
||||
}, |
||||
initData () { |
||||
this.$refs.table.clearSelection(); |
||||
this.page = 1; |
||||
this.getData(); |
||||
}, |
||||
disabledSelection (row, index) { // 禁用勾选 |
||||
if (row.canDel) return true |
||||
return false |
||||
}, |
||||
// 进入实验记录 |
||||
entry (row) { |
||||
this.$router.push(`teach?id=${row.assessmentId || row.projectId}&projectName=${row.projectName}&permissions=${row.permissions || 0}`) |
||||
}, |
||||
handleDelete (row) { // 删除 |
||||
this.$confirm("该项目下的所有成绩报告将会删除,是否继续?", "提示", { |
||||
type: "warning" |
||||
}).then(() => { |
||||
let url = ""; |
||||
if (this.projectPermissions === 0) { |
||||
url = `${this.api.deleteReportById}?ids=&projectIds=${row.projectId}&projectPermissions=${this.projectPermissions}`; |
||||
} else { |
||||
url = `${this.api.deleteReportById}?ids=${row.assessmentId}&projectIds=${row.projectId}&projectPermissions=${this.projectPermissions}`; |
||||
} |
||||
this.$get(url).then(res => { |
||||
util.successMsg("删除成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
}).catch(() => { |
||||
}); |
||||
}, |
||||
delAllData () { // 批量删除 |
||||
if (this.multipleSelection.length) { |
||||
this.$confirm("该项目下的所有成绩报告将会删除,是否继续?", "提示", { |
||||
type: "warning" |
||||
}).then(() => { |
||||
let url = ""; |
||||
let ids = []; |
||||
ids = this.multipleSelection.map(item => item.assessmentId); |
||||
let projectIds = []; |
||||
projectIds = this.multipleSelection.map(item => item.projectId); |
||||
if (this.projectPermissions === 0) { |
||||
url = `${this.api.deleteReportById}?ids=&projectIds=${projectIds.toString()}&projectPermissions=${this.projectPermissions}` |
||||
} else { |
||||
url = `${this.api.deleteReportById}?ids=${ids.toString()}&projectIds=${projectIds.toString()}&projectPermissions=${this.projectPermissions}` |
||||
} |
||||
this.$get(url).then(res => { |
||||
this.multipleSelection = []; |
||||
this.$refs.table.clearSelection(); |
||||
util.successMsg("删除成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
if (this.multipleSelection.length === this.listData.length && this.pageNum > 1) { |
||||
this.handleCurrentChange(this.pageNum - 1) |
||||
} |
||||
}).catch(() => { |
||||
}); |
||||
} else { |
||||
util.errorMsg("请先选择数据 !"); |
||||
} |
||||
}, |
||||
handleSelectionChange (val) { // 多选 |
||||
this.multipleSelection = val; |
||||
}, |
||||
handleCurrentChange (val) { // 切换页码 |
||||
this.page = val |
||||
tabChange (i) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
page: val |
||||
tab: i |
||||
} |
||||
}) |
||||
this.getData(); |
||||
this.active = i |
||||
}, |
||||
initTabs () { |
||||
const { btns } = this |
||||
const tab1 = btns.includes('/course/list:课程管理') |
||||
const tab2 = btns.includes('/course/list:分类管理') |
||||
tab1 || delete this.tabs.first |
||||
tab2 || delete this.tabs.second |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.el-radio.is-bordered + .el-radio.is-bordered { |
||||
margin-left: 0; |
||||
} |
||||
.el-radio-group { |
||||
white-space: nowrap; |
||||
} |
||||
</style> |
@ -0,0 +1,432 @@ |
||||
<template> |
||||
<div class="page"> |
||||
<h6 class="p-title">筛选</h6> |
||||
<div class="tool mul"> |
||||
<ul class="filter"> |
||||
<li v-if="projectPermissions"> |
||||
<label>时间</label> |
||||
<el-radio-group v-model="month" |
||||
@change="initData"> |
||||
<el-radio v-for="(item,index) in dateList" |
||||
:key="index" |
||||
:label="item.id" |
||||
border>{{ item.name }}</el-radio> |
||||
</el-radio-group> |
||||
<el-date-picker v-model="date" |
||||
@blur='pickerInput' |
||||
align="right" |
||||
unlink-panels |
||||
type="daterange" |
||||
start-placeholder="开始日期" |
||||
end-placeholder="结束日期" |
||||
format="yyyy-MM-dd" |
||||
value-format="yyyy-MM-dd" |
||||
clearable |
||||
style="width: 300px"> |
||||
</el-date-picker> |
||||
</li> |
||||
<li> |
||||
<label>实验项目分类</label> |
||||
<el-radio-group v-model="projectPermissions" |
||||
@change="perChange"> |
||||
<el-radio v-for="(item,index) in projectType" |
||||
:key="index" |
||||
:label="item.id" |
||||
border>{{ item.name }}</el-radio> |
||||
</el-radio-group> |
||||
</li> |
||||
<li v-show="projectPermissions === 1"> |
||||
<label>班级</label> |
||||
<el-select v-model="classId" |
||||
@change="classChange"> |
||||
<el-option v-for="item in classList" |
||||
:key="item.id" |
||||
:label="item.className" |
||||
:value="item.id"> |
||||
</el-option> |
||||
</el-select> |
||||
</li> |
||||
<li> |
||||
<label>课程</label> |
||||
<el-select v-model="mallId" |
||||
@change="initData"> |
||||
<el-option v-for="(item, i) in curs" |
||||
:key="i" |
||||
:label="item.curriculumName" |
||||
:value="item.mallId" |
||||
@change="curChange"></el-option> |
||||
</el-select> |
||||
</li> |
||||
<li> |
||||
<el-input placeholder="请输入考核或项目名称" |
||||
prefix-icon="el-icon-search" |
||||
v-model="keyword" |
||||
clearable></el-input> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
<div class="tool mul"> |
||||
<ul class="filter"></ul> |
||||
<div style="margin-bottom: 24px"> |
||||
<el-button v-auth |
||||
type="primary" |
||||
@click="delAllData">批量删除</el-button> |
||||
</div> |
||||
</div> |
||||
<el-table :data="listData" |
||||
class="table" |
||||
ref="table" |
||||
stripe |
||||
header-align="center" |
||||
@selection-change="handleSelectionChange" |
||||
row-key="id"> |
||||
<el-table-column type="selection" |
||||
width="55" |
||||
align="center" |
||||
:reserve-selection="true" |
||||
:selectable="disabledSelection"></el-table-column> |
||||
<el-table-column type="index" |
||||
width="60" |
||||
label="序号" |
||||
align="center"> |
||||
<template slot-scope="scope"> |
||||
{{ scope.$index + (page - 1) * pageSize + 1 }} |
||||
</template> |
||||
</el-table-column> |
||||
<template v-if="projectPermissions == 1"> |
||||
<el-table-column prop="className" |
||||
label="班级" |
||||
align="center" |
||||
min-width="140"></el-table-column> |
||||
<el-table-column prop="experimentalName" |
||||
label="考核名称" |
||||
align="center" |
||||
min-width="180"> |
||||
<template slot-scope="scope"> |
||||
<span class="mul-ellipsis2">{{ scope.row.experimentalName }}</span> |
||||
</template> |
||||
</el-table-column> |
||||
</template> |
||||
<el-table-column prop="projectName" |
||||
label="项目名称" |
||||
align="center" |
||||
min-width="180"></el-table-column> |
||||
<el-table-column prop="projectPermissions" |
||||
label="分类" |
||||
align="center" |
||||
width="100"> |
||||
<template slot-scope="scope"> |
||||
{{ projectPermissions ? '考核' : '练习' }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column prop="experimentalNumber" |
||||
label="成绩报告数量" |
||||
align="center" |
||||
:width="projectPermissions ? 120 : 230"></el-table-column> |
||||
<el-table-column prop="createTime" |
||||
label="创建时间" |
||||
align="center" |
||||
:width="projectPermissions ? 160 : 230"> |
||||
</el-table-column> |
||||
<el-table-column label="操作" |
||||
align="center" |
||||
:width="projectPermissions ? 150 : 230"> |
||||
<template slot-scope="scope"> |
||||
<el-button v-auth="'练习成绩管理'" |
||||
type="text" |
||||
@click="entry(scope.row)">成绩管理</el-button> |
||||
<el-button v-auth |
||||
type="text" |
||||
v-if="scope.row.canDel" |
||||
@click="handleDelete(scope.row)">删除</el-button> |
||||
<el-button v-auth |
||||
type="text" |
||||
v-else |
||||
style='color:#999'>删除</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
<div class="pagination"> |
||||
<el-pagination background |
||||
layout="total, prev, pager, next" |
||||
:total="total" |
||||
@current-change="handleCurrentChange" |
||||
:current-page="page"></el-pagination> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { Loading } from "element-ui"; |
||||
import util from "@/libs/util"; |
||||
export default { |
||||
name: "achievement", |
||||
data () { |
||||
return { |
||||
classId: this.$route.query.class ? +this.$route.query.class : '', |
||||
classList: [], |
||||
mallId: this.$route.query.mallId ? +this.$route.query.mallId : '', |
||||
curriculumList: [], |
||||
projectPermissions: this.$route.query.per ? +this.$route.query.per : 0, |
||||
mallIds: [], |
||||
curs: [], |
||||
keyword: "", |
||||
searchTimer: null, |
||||
startingtime: "", |
||||
endTime: "", |
||||
month: "", |
||||
listData: [], |
||||
multipleSelection: [], |
||||
dateList: [ |
||||
{ |
||||
id: "", |
||||
name: "不限" |
||||
}, { |
||||
id: 1, |
||||
name: "近一个月" |
||||
}, { |
||||
id: 6, |
||||
name: "近六个月" |
||||
} |
||||
], |
||||
projectType: [ |
||||
{ |
||||
id: 0, |
||||
name: "练习" |
||||
}, { |
||||
id: 1, |
||||
name: "考核" |
||||
} |
||||
], |
||||
date: "", |
||||
page: +this.$route.query.page || 1, |
||||
pageSize: 10, |
||||
total: 0, |
||||
loadIns: null |
||||
}; |
||||
}, |
||||
watch: { |
||||
month: function (val) { |
||||
if (val) { |
||||
let unit = 24 * 60 * 60 * 1000; |
||||
this.date = [util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() - unit * 30 * val)), util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() + unit))]; |
||||
} else { |
||||
this.date = []; |
||||
} |
||||
}, |
||||
date: function (val) { |
||||
if (val) { |
||||
this.startingtime = val[0]; |
||||
this.endTime = val[1]; |
||||
} else { |
||||
this.startingtime = ""; |
||||
this.endTime = ""; |
||||
this.month = ''; |
||||
} |
||||
this.initData(); |
||||
}, |
||||
keyword: function (val) { |
||||
clearTimeout(this.searchTimer); |
||||
this.searchTimer = setTimeout(() => { |
||||
this.initData(); |
||||
}, 500); |
||||
} |
||||
}, |
||||
mounted () { |
||||
this.getClassData() |
||||
this.getCourse() |
||||
}, |
||||
methods: { |
||||
pickerInput () { |
||||
this.month = '6' |
||||
}, |
||||
|
||||
// 获取课程 |
||||
async getCourse () { |
||||
const { data } = await this.$get(this.api.getSchoolEffectiveCourse) |
||||
this.curs = data |
||||
this.mallId = this.mallId || data[0].mallId |
||||
this.initData(); |
||||
}, |
||||
// 课程选择回调 |
||||
curChange (id) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
mallId: id |
||||
} |
||||
}) |
||||
this.initData() |
||||
}, |
||||
|
||||
getClassData () { // 获取班级下拉框数据 |
||||
this.$post(this.api.myClass).then(res => { |
||||
this.classList = res.list; |
||||
}).catch(res => { }) |
||||
}, |
||||
getData () { |
||||
this.loadIns = Loading.service({ |
||||
background: "rgba(255,255,255,.6)" |
||||
}); |
||||
const per = this.projectPermissions |
||||
const { mallId } = this |
||||
const cur = this.curs.find(e => e.mallId == mallId) || {} |
||||
let data = { |
||||
classId: this.classId, |
||||
permissions: per, |
||||
curriculumId: cur.cid, |
||||
mallId, |
||||
keyWord: this.keyword, |
||||
startTime: this.startingtime, |
||||
endTime: this.endTime, |
||||
month: this.month, |
||||
pageNum: this.page, |
||||
pageSize: this.pageSize, |
||||
systemId: cur.systemId |
||||
}; |
||||
this.$post(this.api.getAchievementInfo, data).then(res => { |
||||
let list = [] |
||||
if (per == 0) { |
||||
list = res.page |
||||
this.total = res.total |
||||
} else { |
||||
list = res.page.records |
||||
this.total = res.page.total |
||||
} |
||||
console.log(33, per) |
||||
list.map(e => { |
||||
// isAdmin表示这个项目是不是内置的项目,如果为1 表示内置的项目,删除的前提条件就是这个项目删除了isdel=1以及courseDel=1 同时课程管理也移除了这个项目才能删除, 所以要系统内置的项目要满足这三个条件(1.为内置 2.中台删除了、3、课程里面也移除了)才能删除。是isAdmin为0就说明不是内置项目,为当前用户自己创建的项目,所以条件就是isDel为1直接删 |
||||
e.canDel = per ? |
||||
e.isDel : |
||||
(e.isAdmin === 0 && e.isDel === 1) || (e.isAdmin === 1 && e.isDel === 1 && e.courseDel === 1) |
||||
}) |
||||
this.listData = list |
||||
this.$nextTick(() => { |
||||
this.loadIns.close() |
||||
}); |
||||
}).catch(res => { |
||||
this.loadIns.close() |
||||
}); |
||||
}, |
||||
// 项目分类回调 |
||||
perChange (val) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
per: val |
||||
} |
||||
}) |
||||
this.getData() |
||||
}, |
||||
// 班级回调 |
||||
classChange (val) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
class: val |
||||
} |
||||
}) |
||||
this.getData() |
||||
}, |
||||
// 课程回调 |
||||
curriculumChange (val) { |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
curriculum: val |
||||
} |
||||
}) |
||||
this.getData() |
||||
}, |
||||
initData () { |
||||
this.$refs.table.clearSelection(); |
||||
this.page = 1; |
||||
this.getData(); |
||||
}, |
||||
disabledSelection (row, index) { // 禁用勾选 |
||||
if (row.canDel) return true |
||||
return false |
||||
}, |
||||
// 进入实验记录 |
||||
entry (row) { |
||||
this.$router.push(`project?id=${row.assessmentId || row.projectId}&projectName=${row.projectName}&permissions=${row.permissions || 0}`) |
||||
}, |
||||
handleDelete (row) { // 删除 |
||||
this.$confirm("该项目下的所有成绩报告将会删除,是否继续?", "提示", { |
||||
type: "warning" |
||||
}).then(() => { |
||||
let url = ""; |
||||
if (this.projectPermissions === 0) { |
||||
url = `${this.api.deleteReportById}?ids=&projectIds=${row.projectId}&projectPermissions=${this.projectPermissions}`; |
||||
} else { |
||||
url = `${this.api.deleteReportById}?ids=${row.assessmentId}&projectIds=${row.projectId}&projectPermissions=${this.projectPermissions}`; |
||||
} |
||||
this.$get(url).then(res => { |
||||
util.successMsg("删除成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
}).catch(() => { |
||||
}); |
||||
}, |
||||
delAllData () { // 批量删除 |
||||
if (this.multipleSelection.length) { |
||||
this.$confirm("该项目下的所有成绩报告将会删除,是否继续?", "提示", { |
||||
type: "warning" |
||||
}).then(() => { |
||||
let url = ""; |
||||
let ids = []; |
||||
ids = this.multipleSelection.map(item => item.assessmentId); |
||||
let projectIds = []; |
||||
projectIds = this.multipleSelection.map(item => item.projectId); |
||||
if (this.projectPermissions === 0) { |
||||
url = `${this.api.deleteReportById}?ids=&projectIds=${projectIds.toString()}&projectPermissions=${this.projectPermissions}` |
||||
} else { |
||||
url = `${this.api.deleteReportById}?ids=${ids.toString()}&projectIds=${projectIds.toString()}&projectPermissions=${this.projectPermissions}` |
||||
} |
||||
this.$get(url).then(res => { |
||||
this.multipleSelection = []; |
||||
this.$refs.table.clearSelection(); |
||||
util.successMsg("删除成功"); |
||||
this.getData(); |
||||
}).catch(res => { |
||||
}); |
||||
if (this.multipleSelection.length === this.listData.length && this.pageNum > 1) { |
||||
this.handleCurrentChange(this.pageNum - 1) |
||||
} |
||||
}).catch(() => { |
||||
}); |
||||
} else { |
||||
util.errorMsg("请先选择数据 !"); |
||||
} |
||||
}, |
||||
handleSelectionChange (val) { // 多选 |
||||
this.multipleSelection = val; |
||||
}, |
||||
handleCurrentChange (val) { // 切换页码 |
||||
this.page = val |
||||
this.$router.push({ |
||||
path: 'list', |
||||
query: { |
||||
...this.$route.query, |
||||
page: val |
||||
} |
||||
}) |
||||
this.getData(); |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.el-radio.is-bordered + .el-radio.is-bordered { |
||||
margin-left: 0; |
||||
} |
||||
.el-radio-group { |
||||
white-space: nowrap; |
||||
} |
||||
</style> |
@ -0,0 +1,17 @@ |
||||
/** |
||||
* 赛事相关 |
||||
* */ |
||||
export default { |
||||
namespaced: true, |
||||
state: { |
||||
row: null, |
||||
}, |
||||
mutations: { |
||||
setRow: (state, row) => { |
||||
state.row = row |
||||
}, |
||||
}, |
||||
actions: { |
||||
|
||||
} |
||||
}; |
Loading…
Reference in new issue