analysis.vue 10.3 KB
<template>
  <div>
    <back-box>
      <template slot="title">
        <span>单课分析</span>
      </template>
    </back-box>
    <div class="page-content">
      <div class="tab-box">
        <span class="tab-item" v-for="(item, index) in tabList" :key="index" :class="type == item.value ? 'active' : ''"
          @click="setType(item.value)">{{ item.name }}</span>
      </div>
      <div v-loading="loading">
        <div id="print-content">

          <!-- 学生答题情况 -->
          <Detail v-if="type == 1" :types="types" :detail="detail" />
          <!-- 学生答题情况 -->
          <Example v-if="type == 1" :types="types" :tableData="tableData" />
          <!-- 学生问答 -->
          <AnswerQustion v-if="type == 2" :types="types" :tableData="tableData" />
          <!-- 学生互动表现 -->
          <Interact v-if="type == 3" :types="types" :tableData="tableData" />
          <!-- 签到明细 -->
          <Report v-if="type == 4" :tableData="tableData" />
        </div>
        <div class="pagination-box" v-show="type == 1">
          <el-pagination small="" layout="total,prev, pager, next" :hide-on-single-page="true" :total="total"
            @current-change="changePage" :current-page="page" :page-size="size">
          </el-pagination>
        </div>
        <p class="down">
          <el-button @click="openDown" type="primary" plain round icon="fa fa-cloud-download">导出报表</el-button>
          <el-button v-if="!this.$store.getters.code" @click="print" type="primary" plain round
            icon="el-icon-printer">打印</el-button>
        </p>
      </div>
      <ExportDia :exportStudent="exportStudent" :diaShow="diaShow" @cancel="cancel" @exportData="exportData" />
    </div>
  </div>
</template>

<script>
import { downloadFile, tablePrint } from "@/utils";
import Detail from "./components/detail.vue"
import Example from "./components/example.vue"
import AnswerQustion from "./components/answerQustion.vue"
import Interact from "./components/interact.vue"
import Report from "./components/report.vue"
export default {
  components: {
    Detail, Example, AnswerQustion, Interact, Report
  },
  data() {
    return {
      role: "",
      loading: false,
      id: [],
      type: 1,
      tabList: [],
      detail: {},
      tableData: [],
      page: 1,
      size: 20,
      total: 0,
      status: 0,
      //导出相关
      diaShow: false,
      exportStudent: [],
    };
  },
  created() {
    this.role =
      this.$store.getters.info.showRole ||
      this.$store.getters.info.permissions[0].role;
    this.types = Number(this.$route.query.types)
    if (this.types == 1) {
      this.tabList = [{ name: "答题表现", value: 1 },
      { name: "学生问答表现", value: 2 },
      { name: "学生互动表现", value: 3 },
      { name: "签到明细", value: 4 },]
    } else if (this.types == 2) {
      this.tabList = [{ name: "答题表现", value: 1 },
      { name: "学生问答表现", value: 2 },
      { name: "学生互动表现", value: 3 }]
    } else if (this.types == 3) {
      this.tabList = [
        { name: "学生问答表现", value: 2 },
        { name: "学生互动表现", value: 3 }]
    }
    this.id = JSON.parse(this.$route.query.id)
    this.status = this.$route.query.status ? this.$route.query.status : 0;
    this._QueryData();
    this._QueryDataQuestionRank();
    this.types != 3 ? this.periodDetail() : '';
  },
  methods: {
    print() {
      tablePrint(
        "print-content",
        this.detail.title + "_" + this.tabList[this.type - 1]
      );
    },
    setType(type) {
      this.type = type;
      this.page = 1;
      this._QueryData();
      this._QueryDataQuestionRank()
    },
    setDuration(times) {
      let m = parseInt(times / 1000 / 60);
      let s = parseInt((times / 1000) % 60);
      let ms = times;
      let aTime;
      if (times == 0) {
        aTime = `0`;
      } else {
        if (m == 0 && s == 0) {
          aTime = `${ms}毫秒`;
        } else if (m == 0 && s != 0) {
          aTime = `${s}秒`;
        } else if (m != 0 && s != 0) {
          aTime = `${m}分${s}秒`;
        }
      }
      return aTime;
    },
    changePage(page) {
      this.page = page;
      this._QueryData();
    },
    async periodDetail() {
      const periodDetail = this.role == "ROLE_PERSONAL" ?
        this.$request.pPeriodDetail :
        this.$request.periodDetail;
      let { data, info, status } = await periodDetail({
        periodId: this.id[0],
      });
      if (status == 0) {
        this.detail = { ...data };
        this.detail.duration = this.detail.duration
          ? (this.detail.duration / 60).toFixed(2)
          : 0;
        this.detail.consumingDuration = this.detail.consumingDuration
          ? (this.detail.consumingDuration / 60).toFixed(2)
          : 0;
      } else {
        this.$message.error(info);
      }
    },
    async _QueryData() {
      let queryData;
      let query = {};
      if (this.role == "ROLE_PERSONAL") {
        if (this.types == 1) {
          query.page = this.page
          query.size = this.size
          queryData = this.type == 1
            ? this.$request.pPeriodQuestionReport
            : this.$request.pPeriodStudentReport
        }
        else if (this.types == 2) {
          queryData = this.type == 1
            ? this.$request.pPeriodQuestionReport
            : this.type == 2 ? this.$request.phaseAnswerReport : this.$request.phaseInteractiveReport;
        } else if (this.types == 3) {
          queryData = this.type == 2 ? this.$request.pPhaseAnswerReport : this.$request.pPhaseInteractiveReport;
        }
      } else {
        if (this.types == 1) {
          query.page = this.page
          query.size = this.size
          queryData = this.type == 1
            ? this.$request.periodQuestionReport
            : this.$request.periodStudentReport
        } else if (this.types == 2) {
          queryData = this.type == 1
            ? this.$request.periodQuestionReport
            : this.type == 2 ? this.$request.phaseAnswerReport : this.$request.phaseInteractiveReport;
        } else if (this.types == 3) {
          queryData = this.type == 2 ? this.$request.cTPhaseAnswerReport : this.$request.cTPhaseInteractiveReport;
        }
      }
      if (this.types == 1) {
        query.type = this.type - 1
      }
      this.loading = true;
      let { data, info, status } = await queryData({
        // periodId: this.id,
        periodId: this.id[0],
        ...query,
      });
      this.loading = false;
      if (status === 0) {
        if (this.type == 2) {
          this.tableData = data?.list || []
        } else {
          this.tableData = data?.list.sort((a, b) => {
            return a.questionIndex - b.questionIndex;
          });
        }
        this.total = data.count;
      } else {
        this.$message.error(info);
      }
    },
    async _QueryDataQuestionRank() {
      let queryData;
      if (this.role == "ROLE_PERSONAL") {
        if (this.types == 1) {
          queryData = this.$request.pPeriodStudentReport
        }
        else if (this.types == 2) {
          queryData = this.type == 1
            ? this.$request.pPeriodStudentReport
            : this.type == 2 ? this.$request.phaseAnswerReport : this.$request.phaseInteractiveReport;
        } else if (this.types == 3) {
          this.type == 2 ? this.$request.pPhaseAnswerReport : this.$request.pPhaseInteractiveReport;
        }
      } else {
        if (this.types == 1) {
          queryData = this.$request.periodStudentReport
        } else if (this.types == 2) {
          queryData = this.type == 1
            ? this.$request.periodStudentReport
            : this.type == 2 ? this.$request.phaseAnswerReport : this.$request.phaseInteractiveReport;
        } else if (this.types == 3) {
          queryData = this.type == 2 ? this.$request.cTPhaseAnswerReport : this.$request.cTPhaseInteractiveReport;
        }
      }

      let query = {};
      if (this.types == 1) {
        query.type = this.type - 1
      }
      this.loading = true;
      let { data, info, status } = await queryData({
        // periodId: this.id,
        periodId: this.id[0],
        onlyRate: true,
        ...query,
      });
      this.loading = false;
      if (status === 0) {
        this.exportStudent = [...data?.list] || []
      } else {
        this.$message.error(info);
      }
    },

    //导出  
    openDown() {
      this.diaShow = true;
    },
    cancel() {
      this.diaShow = false;
    },
    async exportData(arr) {
      if (this.exportLoading == true) return;
      this.exportLoading = true;
      let studentIds = arr
      let query = {};
      if (studentIds.length == this.exportStudent.length) {
        query.studentIds = []
      } else if (studentIds.length > 0) {
        query.studentIds = studentIds
      }
      const data = await this.$request.exportPeriodReport({
        // periodId: this.id,
        periodId: this.id[0],
        ...query
      });
      this.exportLoading = false;
      if (data) {
        let blob = new Blob([data], {
          type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        });
        downloadFile(this.status ? "随堂问-已归档单课时报表.xlsx" : "随堂问-单课时报表.xlsx", blob);
      } else {
        this.$message.error("下载失败");
      }
    },
  },
};
</script>
<style>
div::-webkit-scrollbar {
  width: 3px;
  height: 10px;
}

div::-webkit-scrollbar-thumb {
  border-radius: 10px;
  background-color: #ccc;
}
</style>
<style lang="scss" scoped>
.down {
  padding-top: 20px;
  width: 100%;
  display: flex;
  justify-content: space-between;
}

.red {
  color: #f30;
}

.page-content {
  padding: 20px 20px 0;
}

.tab-box {
  width: 800px;
  margin: 0 auto 12px;
  background: #f8f8f8;
  border-radius: 20px;
  display: flex;

  .tab-item {
    flex: 1;
    height: 40px;
    line-height: 40px;
    text-align: center;
    font-size: 16px;
    color: #666;
    font-weight: 500;
    background: transparent;
    border-radius: 20px;
    cursor: pointer;

    &.active {
      background: #667ffd;
      color: #fff;
    }
  }
}

:deep(.el-dialog__body) {
  padding-top: 0;
}

.el-dialog {

  .down-item {
    font-size: 15px;
    margin-bottom: 10px;

    .tit {
      line-height: 18px;
      padding: 10px 0;
    }
  }

  .export-tit {
    text-align: center;
    font-size: 16px;
    padding-bottom: 10px;
  }
}

.dialog-footer {
  text-align: center;
}
</style>