|
@@ -0,0 +1,717 @@
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ class="page-dialog"
|
|
|
+ :visible.sync="modalIsShow"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ :close-on-press-escape="false"
|
|
|
+ :show-close="false"
|
|
|
+ append-to-body
|
|
|
+ fullscreen
|
|
|
+ @opened="initData"
|
|
|
+ >
|
|
|
+ <div slot="title" class="box-justify">
|
|
|
+ <div>
|
|
|
+ 报告详情<span class="color-gray ml-2"
|
|
|
+ >{{ course.courseName }}({{ course.courseCode }})</span
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <el-button type="primary" @click="toExport">导出报告</el-button>
|
|
|
+ <el-button type="danger" @click="cancel">退出</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- base info -->
|
|
|
+ <div class="page-head">
|
|
|
+ <h2>
|
|
|
+ <span>课程基本情况</span>
|
|
|
+ </h2>
|
|
|
+ </div>
|
|
|
+ <div class="part-box part-box-pad">
|
|
|
+ <table class="table table-tiny">
|
|
|
+ <tr>
|
|
|
+ <td>课程编码</td>
|
|
|
+ <td>{{ baseInfo.courseCode }}</td>
|
|
|
+ <td>课程名称</td>
|
|
|
+ <td>{{ baseInfo.courseName }}</td>
|
|
|
+ <td>课程类别</td>
|
|
|
+ <td>
|
|
|
+ <el-input
|
|
|
+ v-model="baseInfo.courseType"
|
|
|
+ placeholder="请填写课程类别"
|
|
|
+ size="small"
|
|
|
+ ></el-input>
|
|
|
+ </td>
|
|
|
+ <td>学分</td>
|
|
|
+ <td>
|
|
|
+ <el-input-number
|
|
|
+ v-model="baseInfo.stdScore"
|
|
|
+ placeholder="请录入学分"
|
|
|
+ size="small"
|
|
|
+ :min="0"
|
|
|
+ :max="999"
|
|
|
+ :controls="false"
|
|
|
+ style="width: 100px"
|
|
|
+ ></el-input-number>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td>考核方式</td>
|
|
|
+ <td>
|
|
|
+ <el-input
|
|
|
+ v-model="baseInfo.examType"
|
|
|
+ placeholder="请填写考核方式"
|
|
|
+ size="small"
|
|
|
+ ></el-input>
|
|
|
+ </td>
|
|
|
+ <td>开课时间</td>
|
|
|
+ <td>{{ baseInfo.courseStartTime }}</td>
|
|
|
+ <td>授课对象</td>
|
|
|
+ <td>{{ baseInfo.teachClazz }}</td>
|
|
|
+ <td>学时</td>
|
|
|
+ <td>
|
|
|
+ <el-input-number
|
|
|
+ v-model="baseInfo.teachHours"
|
|
|
+ placeholder="请录入学时"
|
|
|
+ :min="0"
|
|
|
+ :max="999"
|
|
|
+ :controls="false"
|
|
|
+ size="small"
|
|
|
+ style="width: 100px"
|
|
|
+ ></el-input-number>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td>选课人数</td>
|
|
|
+ <td>
|
|
|
+ <el-input-number
|
|
|
+ v-model="baseInfo.studentCount"
|
|
|
+ placeholder="请录入选课人数"
|
|
|
+ :min="0"
|
|
|
+ :max="999"
|
|
|
+ :controls="false"
|
|
|
+ size="small"
|
|
|
+ style="width: 125px"
|
|
|
+ ></el-input-number>
|
|
|
+ </td>
|
|
|
+ <td>参评人数</td>
|
|
|
+ <td>{{ baseInfo.commentCount }}</td>
|
|
|
+ <td>课程目标达成度期望值</td>
|
|
|
+ <td colspan="3">
|
|
|
+ <el-select
|
|
|
+ v-model="baseInfo.courseTarget"
|
|
|
+ size="small"
|
|
|
+ style="width: 100%"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in expectancyList"
|
|
|
+ :key="item"
|
|
|
+ :value="item"
|
|
|
+ :label="item"
|
|
|
+ ></el-option>
|
|
|
+ </el-select>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td>任课老师</td>
|
|
|
+ <td>{{ baseInfo.teachTeacher }}</td>
|
|
|
+ <td>评价负责人</td>
|
|
|
+ <td>
|
|
|
+ <el-input
|
|
|
+ v-model="baseInfo.commentManager"
|
|
|
+ placeholder="请填写评价负责人姓名"
|
|
|
+ size="small"
|
|
|
+ ></el-input>
|
|
|
+ </td>
|
|
|
+ <td>评价参与人</td>
|
|
|
+ <td colspan="3">
|
|
|
+ <el-input
|
|
|
+ v-model="baseInfo.commentUsers"
|
|
|
+ placeholder="请填写评价人姓名"
|
|
|
+ size="small"
|
|
|
+ ></el-input>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="page-head">
|
|
|
+ <h2>
|
|
|
+ <span>课程目标考核分布</span>
|
|
|
+ <el-popover
|
|
|
+ popper-class="el-popper-dark"
|
|
|
+ placement="right-start"
|
|
|
+ width="500"
|
|
|
+ trigger="hover"
|
|
|
+ >
|
|
|
+ <i class="el-icon-question" slot="reference"></i>
|
|
|
+ <div>
|
|
|
+ <p>
|
|
|
+ 课程目标分布会自动按题库系统里试卷下试题标记的属性内容进行显示
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </h2>
|
|
|
+ </div>
|
|
|
+ <div class="part-box part-box-pad">
|
|
|
+ <el-table :data="distributionTable">
|
|
|
+ <el-table-column
|
|
|
+ label="试题号"
|
|
|
+ prop="name"
|
|
|
+ width="140"
|
|
|
+ align="center"
|
|
|
+ fixed="left"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ label="合计"
|
|
|
+ prop="totalScore"
|
|
|
+ width="100"
|
|
|
+ align="center"
|
|
|
+ fixed="left"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ v-for="struct in paperStructs"
|
|
|
+ :key="struct.mainNumber"
|
|
|
+ :label="struct.mainNumber"
|
|
|
+ align="center"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ v-for="subNumber in struct.subNumbers"
|
|
|
+ :key="subNumber"
|
|
|
+ :label="subNumber"
|
|
|
+ :prop="`${struct.mainNumber}-${subNumber}`"
|
|
|
+ align="center"
|
|
|
+ >
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div class="chart-box" style="height: 300px; margin-top: 20px">
|
|
|
+ <v-chart
|
|
|
+ v-if="scoreDistributionChartOption"
|
|
|
+ :option="scoreDistributionChartOption"
|
|
|
+ ></v-chart>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="page-head">
|
|
|
+ <h2>
|
|
|
+ <span>课程目标达成评价结果</span>
|
|
|
+ <el-popover
|
|
|
+ popper-class="el-popper-dark"
|
|
|
+ placement="right-start"
|
|
|
+ width="500"
|
|
|
+ trigger="hover"
|
|
|
+ >
|
|
|
+ <i class="el-icon-question" slot="reference"></i>
|
|
|
+ <div>
|
|
|
+ <p>1.评价依据:填写通过考核什么内容实现课程目标的评价;</p>
|
|
|
+ <p>2.目标分值:对应考核环节的满分;</p>
|
|
|
+ <p>
|
|
|
+ 3.权重:对应考核环节在对应的课程目标中的权重,目标下各项权重相加等于1;
|
|
|
+ </p>
|
|
|
+ <p>4.实际平均分:为参与评价的学生在该环节的平均分;</p>
|
|
|
+ <p>5.目标达成评价值:∑(实际平均分/目标分值*权重);</p>
|
|
|
+ <p>6.整体课程目标达成评价值:为课程分目标达成评价值的最小值。</p>
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </h2>
|
|
|
+ </div>
|
|
|
+ <div class="part-box part-box-pad">
|
|
|
+ <h4 class="part-title">课程考核成绩评价结果</h4>
|
|
|
+
|
|
|
+ <table class="table">
|
|
|
+ <tr>
|
|
|
+ <th>课程目标</th>
|
|
|
+ <th>评价依据</th>
|
|
|
+ <th>评价环节</th>
|
|
|
+ <th>权重</th>
|
|
|
+ <th>目标分值</th>
|
|
|
+ <th>实际平均分</th>
|
|
|
+ <th>目标达成评价值</th>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <template v-for="item in courseTargetList">
|
|
|
+ <tr v-for="(step, sind) in item.steps" :key="`${item.name}-${sind}`">
|
|
|
+ <td v-if="!sind" :rowspan="item.steps.length" style="width: 240px">
|
|
|
+ {{ item.name }}
|
|
|
+ </td>
|
|
|
+ <td v-if="!sind" :rowspan="item.steps.length">
|
|
|
+ <p v-for="item in item.indicator.split('\n')" :key="item">
|
|
|
+ {{ item }}
|
|
|
+ </p>
|
|
|
+ </td>
|
|
|
+ <td style="width: 140px">{{ step.name }}</td>
|
|
|
+ <td style="width: 80px">{{ step.rate }}</td>
|
|
|
+ <td style="width: 100px">{{ step.score }}</td>
|
|
|
+ <td style="width: 100px">{{ step.aveScore }}</td>
|
|
|
+ <td v-if="!sind" :rowspan="item.steps.length" style="width: 140px">
|
|
|
+ {{ item.getVal }}
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </template>
|
|
|
+ <tr>
|
|
|
+ <td colspan="6">课程总目标</td>
|
|
|
+ <td>{{ totalGetVal }}</td>
|
|
|
+ </tr>
|
|
|
+ </table>
|
|
|
+
|
|
|
+ <div class="chart-box" style="height: 400px; margin-top: 20px">
|
|
|
+ <v-chart
|
|
|
+ v-if="courseTargetListChartOption"
|
|
|
+ :option="courseTargetListChartOption"
|
|
|
+ ></v-chart>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <h4 class="part-title">课程考核成绩评价明细结果</h4>
|
|
|
+
|
|
|
+ <el-table :data="studentScoreTable" :span-method="studentScoreSpanMethod">
|
|
|
+ <el-table-column
|
|
|
+ label="姓名"
|
|
|
+ prop="name"
|
|
|
+ min-width="120"
|
|
|
+ align="center"
|
|
|
+ fixed="left"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ label="学号"
|
|
|
+ prop="code"
|
|
|
+ width="100"
|
|
|
+ align="center"
|
|
|
+ fixed="left"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ v-for="(target, tindex) in courseTargets"
|
|
|
+ :key="tindex"
|
|
|
+ :label="target.name"
|
|
|
+ align="center"
|
|
|
+ >
|
|
|
+ <el-table-column min-width="120" align="center">
|
|
|
+ <template slot="header">
|
|
|
+ {{ target.endExam }}({{ target.endRate }})
|
|
|
+ </template>
|
|
|
+ <el-table-column
|
|
|
+ v-for="dimension in target.endDimensions"
|
|
|
+ :key="`${target.name}${dimension}`"
|
|
|
+ :label="dimension"
|
|
|
+ :prop="`${target.name}-${target.endExam}-${dimension}`"
|
|
|
+ min-width="60"
|
|
|
+ align="center"
|
|
|
+ >
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column min-width="120" align="center">
|
|
|
+ <template slot="header">
|
|
|
+ {{ target.normalExam }}({{ target.normalRate }})
|
|
|
+ </template>
|
|
|
+ <el-table-column
|
|
|
+ v-for="work in target.normalWorks"
|
|
|
+ :key="`${target.name}${work}`"
|
|
|
+ :label="work"
|
|
|
+ :prop="`${target.name}-${target.normalExam}-${work}`"
|
|
|
+ min-width="60"
|
|
|
+ align="center"
|
|
|
+ >
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ label="学生成绩"
|
|
|
+ prop="totalScore"
|
|
|
+ align="center"
|
|
|
+ width="100"
|
|
|
+ ></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div slot="footer"></div>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { reportData } from "./data";
|
|
|
+import { exportTargetReport } from "../api";
|
|
|
+import { downloadByApi } from "@/plugins/download";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "target-report-detail",
|
|
|
+ props: {
|
|
|
+ course: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {};
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ modalIsShow: true,
|
|
|
+ baseInfo: {},
|
|
|
+ courseTargetList: [],
|
|
|
+ totalGetVal: 0.67,
|
|
|
+ distributionTable: [],
|
|
|
+ scoreDistribution: [],
|
|
|
+ studentScoreTable: [],
|
|
|
+ expectancyList: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
|
|
|
+ scoreDistributionChartOption: null,
|
|
|
+ courseTargetListChartOption: null,
|
|
|
+ paperStructs: [],
|
|
|
+ courseTargets: [],
|
|
|
+ targetColumnCounts: [],
|
|
|
+ downloading: false,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.initData();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ cancel() {
|
|
|
+ this.modalIsShow = false;
|
|
|
+ },
|
|
|
+ open() {
|
|
|
+ this.modalIsShow = true;
|
|
|
+ },
|
|
|
+ initData() {
|
|
|
+ this.baseInfo = reportData.baseInfo;
|
|
|
+ this.courseTargetList = reportData.courseTargetList;
|
|
|
+ this.scoreDistribution = reportData.scoreDistribution;
|
|
|
+ this.parsePaperStructs(reportData.distributionList);
|
|
|
+ this.parseDistributionTable(reportData.distributionList);
|
|
|
+
|
|
|
+ this.parseCourseTargets(reportData.studentScores);
|
|
|
+ this.parseStudentScoreTable(reportData.studentScores);
|
|
|
+
|
|
|
+ this.scoreDistributionChartOption =
|
|
|
+ this.getScoreDistributionChartOption();
|
|
|
+ this.courseTargetListChartOption = this.getCourseTargetListChartOption();
|
|
|
+ },
|
|
|
+ parsePaperStructs(distributionList) {
|
|
|
+ if (!distributionList || !distributionList.length) return;
|
|
|
+
|
|
|
+ const scores = distributionList[0].scores;
|
|
|
+ const structMap = {};
|
|
|
+
|
|
|
+ scores.forEach((item) => {
|
|
|
+ if (!structMap[item.mainNumber]) {
|
|
|
+ structMap[item.mainNumber] = [];
|
|
|
+ }
|
|
|
+ structMap[item.mainNumber].push(item.subNumber + "");
|
|
|
+ });
|
|
|
+ this.paperStructs = Object.keys(structMap).map((mainNumber) => {
|
|
|
+ return {
|
|
|
+ mainNumber,
|
|
|
+ subNumbers: structMap[mainNumber],
|
|
|
+ };
|
|
|
+ });
|
|
|
+ },
|
|
|
+ parseDistributionTable(distributionList) {
|
|
|
+ this.distributionTable = distributionList.map((item) => {
|
|
|
+ const data = {
|
|
|
+ name: item.name,
|
|
|
+ totalScore: item.totalScore,
|
|
|
+ };
|
|
|
+
|
|
|
+ item.scores.forEach((elem) => {
|
|
|
+ data[`${elem.mainNumber}-${elem.subNumber}`] = elem.score;
|
|
|
+ });
|
|
|
+
|
|
|
+ return data;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ parseCourseTargets(studentScores) {
|
|
|
+ if (!studentScores || !studentScores.length) return;
|
|
|
+
|
|
|
+ const targets = studentScores[0].courseTargets;
|
|
|
+
|
|
|
+ let tColumnCounts = [];
|
|
|
+ this.courseTargets = targets.map((target) => {
|
|
|
+ const ntarget = { ...target };
|
|
|
+ ntarget.endDimensions = target.endDimensions.map((item) => item.name);
|
|
|
+ ntarget.normalWorks = target.normalWorks.map((item) => item.name);
|
|
|
+ tColumnCounts.push(
|
|
|
+ ntarget.endDimensions.length + ntarget.normalWorks.length
|
|
|
+ );
|
|
|
+ return ntarget;
|
|
|
+ });
|
|
|
+
|
|
|
+ let tCount = 0;
|
|
|
+ this.targetColumnCounts = tColumnCounts.map((item) => {
|
|
|
+ tCount += item;
|
|
|
+ return tCount;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ parseStudentScoreTable(studentScores) {
|
|
|
+ const studentScoreTable = studentScores.map((student) => {
|
|
|
+ const nitem = {
|
|
|
+ name: student.name,
|
|
|
+ code: student.code,
|
|
|
+ totalScore: student.totalScore,
|
|
|
+ };
|
|
|
+
|
|
|
+ student.courseTargets.forEach((target) => {
|
|
|
+ target.endDimensions.forEach((dimension) => {
|
|
|
+ nitem[`${target.name}-${target.endExam}-${dimension.name}`] =
|
|
|
+ dimension.score;
|
|
|
+ });
|
|
|
+ target.normalWorks.forEach((work) => {
|
|
|
+ nitem[`${target.name}-${target.normalExam}-${work.name}`] =
|
|
|
+ work.score;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return nitem;
|
|
|
+ });
|
|
|
+
|
|
|
+ let targetData = {
|
|
|
+ name: "课程目标达成度",
|
|
|
+ totalScore: "",
|
|
|
+ };
|
|
|
+ this.courseTargets.forEach((target) => {
|
|
|
+ targetData[
|
|
|
+ `${target.name}-${target.endExam}-${target.endDimensions[0]}`
|
|
|
+ ] = target.getVal;
|
|
|
+ });
|
|
|
+ studentScoreTable.push(targetData);
|
|
|
+
|
|
|
+ const fTarget = this.courseTargets[0];
|
|
|
+ studentScoreTable.push({
|
|
|
+ name: "课程达成度",
|
|
|
+ [`${fTarget.name}-${fTarget.endExam}-${fTarget.endDimensions[0]}`]:
|
|
|
+ this.totalGetVal,
|
|
|
+ });
|
|
|
+ this.studentScoreTable = studentScoreTable;
|
|
|
+ },
|
|
|
+ studentScoreSpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
+ const lineCount = this.studentScoreTable.length - 1;
|
|
|
+ const maxTargetColumnCount = this.targetColumnCounts.slice(-1)[0];
|
|
|
+ if (rowIndex === lineCount) {
|
|
|
+ if (columnIndex === 0) {
|
|
|
+ return [1, 2];
|
|
|
+ } else if (columnIndex === 2) {
|
|
|
+ return [1, maxTargetColumnCount + 1];
|
|
|
+ } else {
|
|
|
+ return [0, 0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (rowIndex === lineCount - 1) {
|
|
|
+ const colsMap = {};
|
|
|
+ const targetColumns = [0, ...this.targetColumnCounts.slice(0, -1)];
|
|
|
+ targetColumns.map((item, index) => {
|
|
|
+ colsMap[item] = this.targetColumnCounts[index] - item;
|
|
|
+ });
|
|
|
+ if (columnIndex === 0) {
|
|
|
+ return [1, 2];
|
|
|
+ } else {
|
|
|
+ if (targetColumns.includes(columnIndex - 2)) {
|
|
|
+ return [1, colsMap[columnIndex - 2]];
|
|
|
+ } else if (columnIndex < maxTargetColumnCount + 2) {
|
|
|
+ return [0, 0];
|
|
|
+ } else {
|
|
|
+ return [1, 1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (rowIndex === lineCount - 2) {
|
|
|
+ if (columnIndex === 0) {
|
|
|
+ return [1, 2];
|
|
|
+ } else if (columnIndex === 1) {
|
|
|
+ return [0, 0];
|
|
|
+ } else {
|
|
|
+ return [1, 1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getScoreDistributionChartOption() {
|
|
|
+ let options = {
|
|
|
+ color: ["#556dff", "#3A5AE5"],
|
|
|
+ title: {
|
|
|
+ text: "成绩分布图",
|
|
|
+ left: "center",
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: 40,
|
|
|
+ top: 60,
|
|
|
+ right: 80,
|
|
|
+ bottom: 40,
|
|
|
+ containLabel: true,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: "category",
|
|
|
+ name: "成绩(分)",
|
|
|
+ nameTextStyle: {
|
|
|
+ color: "#363D59",
|
|
|
+ },
|
|
|
+ data: this.scoreDistribution.map((item) => item.name),
|
|
|
+ axisLabel: {
|
|
|
+ color: "#6F7482",
|
|
|
+ interval: 0,
|
|
|
+ fontSize: 12,
|
|
|
+ margin: 12,
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ show: true,
|
|
|
+ lineStyle: {
|
|
|
+ color: "#EFF0F5",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ axisTick: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ axisPointer: {
|
|
|
+ type: "shadow",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: "value",
|
|
|
+ name: "百分比(%)",
|
|
|
+ nameTextStyle: {
|
|
|
+ color: "#363D59",
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ color: "#6F7482",
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: "#EFF0F5",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: "#EFF0F5",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: "占比",
|
|
|
+ type: "bar",
|
|
|
+ barWidth: 60,
|
|
|
+ data: this.scoreDistribution.map((item) => item.val),
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ formatter: "{c}%",
|
|
|
+ position: "top",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ return options;
|
|
|
+ },
|
|
|
+ getCourseTargetListChartOption() {
|
|
|
+ let options = {
|
|
|
+ color: ["#556dff", "#f59a23"],
|
|
|
+ title: {
|
|
|
+ text: "课程目标达成评价值",
|
|
|
+ left: "center",
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: 40,
|
|
|
+ top: 40,
|
|
|
+ right: 80,
|
|
|
+ bottom: 30,
|
|
|
+ containLabel: true,
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ top: 0,
|
|
|
+ data: ["期望值", "达成值"],
|
|
|
+ itemWidth: 12,
|
|
|
+ itemHeight: 4,
|
|
|
+ itemGap: 22,
|
|
|
+ right: 40,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: "category",
|
|
|
+ name: "课程目标",
|
|
|
+ nameTextStyle: {
|
|
|
+ color: "#363D59",
|
|
|
+ },
|
|
|
+ data: this.courseTargetList.map((item) => item.name),
|
|
|
+ axisLabel: {
|
|
|
+ color: "#6F7482",
|
|
|
+ interval: 0,
|
|
|
+ fontSize: 12,
|
|
|
+ margin: 12,
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ show: true,
|
|
|
+ lineStyle: {
|
|
|
+ color: "#EFF0F5",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ axisTick: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ axisPointer: {
|
|
|
+ type: "shadow",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: "value",
|
|
|
+ name: "期望值",
|
|
|
+ min: 0,
|
|
|
+ max: 1,
|
|
|
+ interval: 0.1,
|
|
|
+ nameTextStyle: {
|
|
|
+ color: "#363D59",
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ color: "#6F7482",
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: "#EFF0F5",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: "#EFF0F5",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: "达成值",
|
|
|
+ type: "bar",
|
|
|
+ barWidth: 60,
|
|
|
+ data: this.courseTargetList.map((item) => item.getVal),
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: "top",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "期望值",
|
|
|
+ type: "line",
|
|
|
+ symbol: "none",
|
|
|
+ data: this.courseTargetList.map((item) => this.totalGetVal),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ return options;
|
|
|
+ },
|
|
|
+ async toExport() {
|
|
|
+ if (this.downloading) return;
|
|
|
+ this.downloading = true;
|
|
|
+
|
|
|
+ const res = await downloadByApi(() => {
|
|
|
+ const datas = {
|
|
|
+ examId: this.course.examId,
|
|
|
+ courseCode: this.course.courseCode,
|
|
|
+ paperNumber: this.course.paperNumber,
|
|
|
+ paperType: this.course.paperType,
|
|
|
+ };
|
|
|
+ return exportTargetReport(datas);
|
|
|
+ }).catch((e) => {
|
|
|
+ this.$message.error(e || "下载失败,请重新尝试!");
|
|
|
+ });
|
|
|
+ this.downloading = false;
|
|
|
+
|
|
|
+ if (!res) return;
|
|
|
+ this.$message.success("下载成功!");
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|