xiatian 5 سال پیش
والد
کامیت
c5ae26252c

+ 5 - 0
src/modules/reports/routes/routes.js

@@ -3,6 +3,7 @@ import Tips from "../../portal/views/tips/Tips.vue";
 import Project from "../views/Project.vue";
 import Overview from "../views/Overview.vue";
 import ComputeJobList from "../views/ComputeJobList.vue";
+import ReportView from "../views/ReportView.vue";
 
 export default [
   {
@@ -26,6 +27,10 @@ export default [
       {
         path: "compute-job-list/:projectId",
         component: ComputeJobList
+      },
+      {
+        path: "report-view/:projectId",
+        component: ReportView
       }
     ]
   }

+ 1 - 18
src/modules/reports/views/ComputeJobList.vue

@@ -92,24 +92,7 @@ export default {
       tableData: [],
       currentPage: 1,
       pageSize: 10,
-      total: 10,
-
-      rules: {
-        passScore: [
-          { required: true, message: "请输入及格分数", trigger: "change" }
-        ],
-        totalScore: [
-          { required: true, message: "请输入满分分数", trigger: "change" }
-        ],
-        partitionDetails: [
-          {
-            required: true,
-            type: "array",
-            message: "请设置分数段",
-            trigger: "change"
-          }
-        ]
-      }
+      total: 10
     };
   },
   computed: {

+ 6 - 1
src/modules/reports/views/Overview.vue

@@ -88,7 +88,7 @@
                 type="primary"
                 :disabled="disViewReport(scope.row)"
                 plain
-                @click="openEdtDialog(scope.row)"
+                @click="viewReport(scope.row.id)"
               >
                 查看报表
               </el-button>
@@ -357,6 +357,11 @@ export default {
         return false;
       }
     },
+    viewReport(projectId) {
+      this.$router.push({
+        path: "/reports/report-view/" + projectId
+      });
+    },
     viewComputeJob(projectId) {
       this.$router.push({
         path: "/reports/compute-job-list/" + projectId

+ 813 - 0
src/modules/reports/views/ReportView.vue

@@ -0,0 +1,813 @@
+<template>
+  <section class="content">
+    <div class="box box-info">
+      <div
+        class="box-body"
+        v-loading.body="loading"
+        v-loading.fullscreen="loading"
+        element-loading-text="请稍后..."
+      >
+        <!-- 表单 -->
+        <el-form inline :model="formSearch">
+          <el-form-item label="项目名称">
+            <el-input
+              v-model="formSearch.name"
+              :readonly="true"
+              style="width: 180px"
+            />
+          </el-form-item>
+          <el-form-item label="分析类型">
+            <el-input
+              v-model="formSearch.analyseTypeName"
+              :readonly="true"
+              style="width: 180px"
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button size="small" type="primary" @click="back">
+              返回
+            </el-button>
+          </el-form-item>
+        </el-form>
+
+        <div class="block-seperator"></div>
+        <el-tabs type="border-card">
+          <el-tab-pane label="学习中心分析">
+            <div class="row-div">
+              <el-form inline>
+                <el-form-item label="展示项选择">
+                  <el-checkbox v-model="examOrgMainListShow.a"
+                    >实考</el-checkbox
+                  >
+                  <el-checkbox v-model="examOrgMainListShow.b"
+                    >缺考</el-checkbox
+                  >
+                  <el-checkbox v-model="examOrgMainListShow.c"
+                    >及格</el-checkbox
+                  >
+                  <el-checkbox v-model="examOrgMainListShow.d"
+                    >分数段</el-checkbox
+                  >
+                </el-form-item>
+                <el-form-item>
+                  <el-button size="small" type="primary" @click="expoetExamOrg">
+                    导出
+                  </el-button>
+                </el-form-item>
+              </el-form>
+            </div>
+            <el-table
+              :data="examOrgMainList"
+              border
+              resizable
+              stripe
+              style="width: 100%;"
+            >
+              <el-table-column prop="examName" label="考试名称">
+              </el-table-column>
+              <el-table-column prop="orgName" width="100" label="中心名称">
+              </el-table-column>
+              <el-table-column
+                width="100"
+                :sortable="true"
+                prop="signCount"
+                label="报名人数"
+              >
+              </el-table-column>
+              <el-table-column
+                :sortable="true"
+                width="100"
+                prop="participantCount"
+                label="实考人数"
+              >
+              </el-table-column>
+              <el-table-column
+                width="100"
+                :sortable="true"
+                prop="missCount"
+                label="缺考人数"
+              >
+              </el-table-column>
+              <el-table-column
+                width="100"
+                :sortable="true"
+                prop="missRatio"
+                label="缺考率(%)"
+              >
+              </el-table-column>
+              <el-table-column
+                width="100"
+                :sortable="true"
+                prop="passCount"
+                label="及格人数"
+              >
+              </el-table-column>
+              <el-table-column
+                :sortable="true"
+                width="100"
+                prop="passSignRatio"
+                label="及格报名人数占比(%)"
+              >
+              </el-table-column>
+              <el-table-column
+                :sortable="true"
+                width="100"
+                prop="passParticipantRatio"
+                label="及格实考人数占比(%)"
+              >
+              </el-table-column>
+              <el-table-column label="分段统计">
+                <el-table-column
+                  :sortable="true"
+                  v-for="(item, index) in this.examOrgMainListCol"
+                  :key="index"
+                  width="100"
+                  :prop="item.key"
+                  :label="item.label"
+                >
+                </el-table-column>
+              </el-table-column>
+            </el-table>
+            <!-- 实考人数 -->
+            <div class="row-div" v-if="this.examOrgMainListShow.a">
+              <div>
+                <div>实考人数前十</div>
+                <el-table
+                  :data="examOrgMainTopTen.participantDesc"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="participantCount"
+                    label="实考人数"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+              <div><v-charts :options="participantDescBar"></v-charts></div>
+              <div>
+                <div>实考人数后十</div>
+                <el-table
+                  :data="examOrgMainTopTen.participant"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="participantCount"
+                    label="实考人数"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+            </div>
+            <!-- 实考比例 -->
+            <div class="row-div" v-if="this.examOrgMainListShow.a">
+              <div>
+                <div>实考比例前十</div>
+                <el-table
+                  :data="examOrgMainTopTen.participantRatioDesc"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="participantRatio"
+                    label="实考比例(%)"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+              <div>
+                <v-charts :options="participantRatioDescBar"></v-charts>
+              </div>
+              <div>
+                <div>实考比例后十</div>
+                <el-table
+                  :data="examOrgMainTopTen.participantRatio"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="participantRatio"
+                    label="实考比例(%)"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+            </div>
+            <!-- 缺考人数 -->
+            <div class="row-div" v-if="this.examOrgMainListShow.b">
+              <div>
+                <div>缺考人数前十</div>
+                <el-table
+                  :data="examOrgMainTopTen.missDesc"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="missCount"
+                    label="缺考人数"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+              <div><v-charts :options="missDescBar"></v-charts></div>
+              <div>
+                <div>缺考人数后十</div>
+                <el-table
+                  :data="examOrgMainTopTen.miss"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="missCount"
+                    label="缺考人数"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+            </div>
+            <!-- 缺考比例 -->
+            <div class="row-div" v-if="this.examOrgMainListShow.b">
+              <div>
+                <div>缺考比例前十</div>
+                <el-table
+                  :data="examOrgMainTopTen.missRatioDesc"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="missRatio"
+                    label="缺考比例(%)"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+              <div><v-charts :options="missRatioDescBar"></v-charts></div>
+              <div>
+                <div>缺考比例后十</div>
+                <el-table
+                  :data="examOrgMainTopTen.missRatio"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="missRatio"
+                    label="缺考比例(%)"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+            </div>
+            <!-- 及格人数 -->
+            <div class="row-div" v-if="this.examOrgMainListShow.c">
+              <div>
+                <div>及格人数前十</div>
+                <el-table
+                  :data="examOrgMainTopTen.passDesc"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="passCount"
+                    label="及格人数"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+              <div><v-charts :options="passDescBar"></v-charts></div>
+              <div>
+                <div>及格人数后十</div>
+                <el-table
+                  :data="examOrgMainTopTen.pass"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="passCount"
+                    label="及格人数"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+            </div>
+            <!-- 及格实考比例 -->
+            <div class="row-div" v-if="this.examOrgMainListShow.c">
+              <div>
+                <div>及格实考比例前十</div>
+                <el-table
+                  :data="examOrgMainTopTen.passParticipantRatioDesc"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="passParticipantRatio"
+                    label="及格实考比例(%)"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+              <div>
+                <v-charts :options="passParticipantRatioDescBar"></v-charts>
+              </div>
+              <div>
+                <div>及格实考比例后十</div>
+                <el-table
+                  :data="examOrgMainTopTen.passParticipantRatio"
+                  border
+                  resizable
+                  stripe
+                  style="width: 100%;"
+                >
+                  <el-table-column prop="examName" label="考试名称">
+                  </el-table-column>
+                  <el-table-column prop="orgName" width="100" label="中心名称">
+                  </el-table-column>
+                  <el-table-column
+                    width="100"
+                    prop="passParticipantRatio"
+                    label="及格实考比例(%)"
+                  >
+                  </el-table-column>
+                </el-table>
+              </div>
+            </div>
+            <span
+              v-if="
+                examOrgMainTopTen.partition != null && examOrgMainListShow.d
+              "
+            >
+              <span
+                v-for="(item, index) in this.formSearch.partitionCount"
+                :key="index"
+              >
+                <!-- 分段人数 -->
+                <div class="row-div">
+                  <div>
+                    <div>分段{{ index + 1 }}人数前十</div>
+                    <el-table
+                      :data="examOrgMainTopTen.partition[index].countDesc"
+                      border
+                      resizable
+                      stripe
+                      style="width: 100%;"
+                    >
+                      <el-table-column prop="examName" label="考试名称">
+                      </el-table-column>
+                      <el-table-column
+                        prop="orgName"
+                        width="100"
+                        label="中心名称"
+                      >
+                      </el-table-column>
+                      <el-table-column
+                        width="100"
+                        prop="count"
+                        :label="'分段' + (index + 1) + '人数'"
+                      >
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                  <div>
+                    <v-charts
+                      :options="partitionCountDescBar[index]"
+                    ></v-charts>
+                  </div>
+                  <div>
+                    <div>分段{{ index + 1 }}人数后十</div>
+                    <el-table
+                      :data="examOrgMainTopTen.partition[index].countAsc"
+                      border
+                      resizable
+                      stripe
+                      style="width: 100%;"
+                    >
+                      <el-table-column prop="examName" label="考试名称">
+                      </el-table-column>
+                      <el-table-column
+                        prop="orgName"
+                        width="100"
+                        label="中心名称"
+                      >
+                      </el-table-column>
+                      <el-table-column
+                        width="100"
+                        prop="count"
+                        :label="'分段' + (index + 1) + '人数'"
+                      >
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                </div>
+                <!-- 分段实考比例 -->
+                <div class="row-div">
+                  <div>
+                    <div>分段{{ index + 1 }}实考比例前十</div>
+                    <el-table
+                      :data="
+                        examOrgMainTopTen.partition[index].participantRatioDesc
+                      "
+                      border
+                      resizable
+                      stripe
+                      style="width: 100%;"
+                    >
+                      <el-table-column prop="examName" label="考试名称">
+                      </el-table-column>
+                      <el-table-column
+                        prop="orgName"
+                        width="100"
+                        label="中心名称"
+                      >
+                      </el-table-column>
+                      <el-table-column
+                        width="100"
+                        prop="participantRatio"
+                        :label="'分段' + (index + 1) + '实考比例(%)'"
+                      >
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                  <div>
+                    <v-charts
+                      :options="partitionParticipantRatioDescBar[index]"
+                    ></v-charts>
+                  </div>
+                  <div>
+                    <div>分段{{ index + 1 }}实考比例后十</div>
+                    <el-table
+                      :data="
+                        examOrgMainTopTen.partition[index].participantRatioAsc
+                      "
+                      border
+                      resizable
+                      stripe
+                      style="width: 100%;"
+                    >
+                      <el-table-column prop="examName" label="考试名称">
+                      </el-table-column>
+                      <el-table-column
+                        prop="orgName"
+                        width="100"
+                        label="中心名称"
+                      >
+                      </el-table-column>
+                      <el-table-column
+                        width="100"
+                        prop="participantRatio"
+                        :label="'分段' + (index + 1) + '实考比例(%)'"
+                      >
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                </div>
+              </span>
+            </span>
+          </el-tab-pane>
+          <el-tab-pane label="考试课程分析"></el-tab-pane>
+        </el-tabs>
+      </div>
+    </div>
+  </section>
+</template>
+<script>
+import { REPORTS_API } from "@/constants/constants.js";
+import { mapState } from "vuex";
+import ECharts from "vue-echarts/components/ECharts";
+import "echarts/lib/chart/bar";
+export default {
+  components: {
+    "v-charts": ECharts
+  },
+  name: "ReportView",
+  data() {
+    return {
+      loading: false,
+      formSearch: {
+        name: "",
+        analyseTypeName: "",
+        projectId: "",
+        partitionCount: 0
+      },
+      examOrgMainListShow: {
+        a: true,
+        b: true,
+        c: true,
+        d: true
+      },
+      examOrgMainList: [],
+      examOrgMainListCol: [],
+      examOrgMainTopTen: {},
+      participantDescBar: this.getBar("实考人数前十", "实考人数"),
+      participantRatioDescBar: this.getBar("实考比例前十", "实考比例"),
+      missDescBar: this.getBar("缺考人数前十", "缺考人数"),
+      missRatioDescBar: this.getBar("缺考比例前十", "缺考比例"),
+      passDescBar: this.getBar("及格人数前十", "及格人数"),
+      passParticipantRatioDescBar: this.getBar(
+        "及格实考比例前十",
+        "及格实考比例"
+      ),
+      partitionCountDescBar: [],
+      partitionParticipantRatioDescBar: []
+    };
+  },
+  computed: {
+    ...mapState({ user: state => state.user }),
+    isSuperAdmin() {
+      return this.user.roleList.some(role => role.roleCode == "SUPER_ADMIN");
+    }
+  },
+  methods: {
+    expoetExamOrg() {
+      window.open(
+        REPORTS_API +
+          "/examOrgReport/export?$key=" +
+          this.user.key +
+          "&$token=" +
+          this.user.token +
+          "&projectId=" +
+          this.formSearch.projectId
+      );
+    },
+    setBarData(bar, seriesName, data, fieldName) {
+      bar.series = [
+        {
+          name: seriesName,
+          type: "bar",
+          barWidth: "20",
+          data: this.getYdata(data, fieldName)
+        }
+      ];
+      bar.xAxis = [
+        {
+          type: "category",
+          data: this.getXdata(data),
+          axisTick: {
+            alignWithLabel: true
+          },
+          axisLabel: {
+            interval: 0,
+            rotate: 20
+          }
+        }
+      ];
+    },
+    getBar(text, seriesName) {
+      return {
+        color: ["#3398DB"],
+        title: {
+          text: text,
+          left: "center"
+        },
+        tooltip: {
+          trigger: "item",
+          formatter: "{a} <br/>{b} : {c}"
+        },
+        xAxis: [
+          {
+            type: "category",
+            axisTick: {
+              alignWithLabel: true
+            },
+            axisLabel: {
+              interval: 0,
+              rotate: 30
+            }
+          }
+        ],
+        yAxis: [
+          {
+            type: "value"
+          }
+        ],
+        series: [
+          {
+            name: seriesName,
+            type: "bar"
+          }
+        ]
+      };
+    },
+    getXdata(data) {
+      let xdata = [];
+      data.forEach(e => {
+        xdata.push(e.examName + "-" + e.orgName);
+      });
+      return xdata;
+    },
+    getYdata(data, col) {
+      let ydata = [];
+      data.forEach(e => {
+        ydata.push(e[col]);
+      });
+      return ydata;
+    },
+    setViewCols(partitionData, cols) {
+      for (var i = 0; i < this.formSearch.partitionCount; i++) {
+        let coldata1 = {};
+        coldata1.label = "分段" + (i + 1) + "人数";
+        coldata1.key = "partitionCount" + i;
+        cols.push(coldata1);
+        let coldata2 = {};
+        coldata2.label = "分段" + (i + 1) + "人数实考占比(%)";
+        coldata2.key = "participantRatio" + i;
+        cols.push(coldata2);
+      }
+      partitionData.forEach(e => {
+        for (var i = 0; i < e.partitionData.length; i++) {
+          let key1 = "partitionCount" + i;
+          e[key1] = e.partitionData[i].count;
+          let key2 = "participantRatio" + i;
+          e[key2] = e.partitionData[i].participantRatio;
+        }
+      });
+    },
+    back() {
+      this.$router.push({
+        path: "/reports/overview"
+      });
+    },
+    //查询
+    getExamOrgMainList() {
+      var url =
+        REPORTS_API +
+        "/examOrgReport/getExamOrgMainList?projectId=" +
+        this.formSearch.projectId;
+      this.$httpWithMsg.get(url).then(response => {
+        this.examOrgMainList = response.data;
+        this.setViewCols(this.examOrgMainList, this.examOrgMainListCol);
+      });
+    },
+    getExamOrgMainTopTen() {
+      var url =
+        REPORTS_API +
+        "/examOrgReport/getExamOrgMainTop10?projectId=" +
+        this.formSearch.projectId;
+      this.$httpWithMsg.get(url).then(response => {
+        this.examOrgMainTopTen = response.data;
+        this.setBarData(
+          this.participantDescBar,
+          "实考人数",
+          this.examOrgMainTopTen.participantDesc,
+          "participantCount"
+        );
+        this.setBarData(
+          this.participantRatioDescBar,
+          "实考比例",
+          this.examOrgMainTopTen.participantRatioDesc,
+          "participantRatio"
+        );
+        this.setBarData(
+          this.missDescBar,
+          "缺考人数",
+          this.examOrgMainTopTen.missDesc,
+          "missCount"
+        );
+        this.setBarData(
+          this.missRatioDescBar,
+          "缺考比例",
+          this.examOrgMainTopTen.missRatioDesc,
+          "missRatio"
+        );
+        this.setBarData(
+          this.passDescBar,
+          "及格人数",
+          this.examOrgMainTopTen.passDesc,
+          "passCount"
+        );
+        this.setBarData(
+          this.passParticipantRatioDescBar,
+          "及格实考比例",
+          this.examOrgMainTopTen.passParticipantRatioDesc,
+          "passParticipantRatio"
+        );
+        for (let i = 0; i < this.formSearch.partitionCount; i++) {
+          this.setBarData(
+            this.partitionCountDescBar[i],
+            "分段" + (i + 1) + "人数",
+            this.examOrgMainTopTen.partition[i].countDesc,
+            "count"
+          );
+          this.setBarData(
+            this.partitionParticipantRatioDescBar[i],
+            "分段" + (i + 1) + "实考比例",
+            this.examOrgMainTopTen.partition[i].participantRatioDesc,
+            "participantRatio"
+          );
+        }
+      });
+    },
+    async init() {
+      var url = REPORTS_API + "/project/" + this.formSearch.projectId;
+      await this.$httpWithMsg.get(url).then(response => {
+        this.formSearch.name = response.data.name;
+        this.formSearch.analyseTypeName = response.data.analyseTypeName;
+        this.formSearch.partitionCount = response.data.partitionCount;
+        for (let i = 0; i < this.formSearch.partitionCount; i++) {
+          this.partitionCountDescBar[i] = this.getBar(
+            "分段" + (i + 1) + "人数前十",
+            "分段" + (i + 1) + "人数"
+          );
+          this.partitionParticipantRatioDescBar[i] = this.getBar(
+            "分段" + (i + 1) + "实考比例前十",
+            "分段" + (i + 1) + "实考比例"
+          );
+        }
+      });
+      this.getExamOrgMainList();
+      this.getExamOrgMainTopTen();
+    }
+  },
+  //初始化查询
+  created() {
+    this.formSearch.projectId = this.$route.params.projectId;
+    this.init();
+  }
+};
+</script>
+
+<style scoped>
+.row-div {
+  display: flex;
+  overflow-x: auto;
+  border: 1px solid #ddd;
+  padding: 5px;
+  margin-top: 10px;
+}
+</style>