Răsfoiți Sursa

feat: 统计页面

zhangjie 11 luni în urmă
părinte
comite
191df6df1b

+ 14 - 0
src/components/SecpSelect.vue

@@ -28,6 +28,18 @@
         :exam-id="filter.examId"
       ></print-plan-select>
     </el-form-item>
+    <el-form-item
+      v-if="filterProps.includes('openCollegeId')"
+      label="开课学院:"
+    >
+      <org-select
+        v-model="filter.openCollegeId"
+        placeholder="开课学院"
+        :filter-param="{
+          withoutSecondOrg: true,
+        }"
+      ></org-select>
+    </el-form-item>
     <el-form-item
       v-if="filterProps.includes('courseId')"
       label="课程(代码):"
@@ -38,6 +50,7 @@
         :semester-id="filter.semesterId"
         :exam-id="filter.examId"
         :print-plan-id="filter.printPlanId"
+        :open-college-id="filter.openCollegeId"
         placeholder="课程(代码)"
         clearable
       ></course-select>
@@ -62,6 +75,7 @@ const fullProps = [
   "semesterId",
   "examId",
   "printPlanId",
+  "openCollegeId",
   "courseId",
   "paperNumber",
 ];

+ 9 - 0
src/components/base/CourseSelect.vue

@@ -34,6 +34,7 @@ export default {
     semesterId: { type: String, default: "" },
     examId: { type: String, default: "" },
     printPlanId: { type: [String, Array], default: "" },
+    openCollegeId: { type: String, default: "" },
   },
   data() {
     return {
@@ -69,6 +70,13 @@ export default {
         this.$emit("change", {});
       }
     },
+    openCollegeId(val, oldval) {
+      if (val !== oldval) {
+        this.search();
+        this.$emit("input", "");
+        this.$emit("change", {});
+      }
+    },
   },
   async created() {
     this.search();
@@ -82,6 +90,7 @@ export default {
         semesterId: this.semesterId,
         examId: this.examId,
         printPlanId: this.printPlanId,
+        openCollegeId: this.openCollegeId,
       };
 
       const res = await conditionListCourse(objFilterNull(data));

+ 7 - 1
src/modules/base/api.js

@@ -34,11 +34,17 @@ export const conditionListPrintPlan = ({ semesterId, examId }) => {
   });
 };
 // course
-export const conditionListCourse = ({ semesterId, examId, printPlanId }) => {
+export const conditionListCourse = ({
+  semesterId,
+  examId,
+  printPlanId,
+  openCollegeId,
+}) => {
   return $postParam("/api/admin/basic/condition/list_course", {
     semesterId,
     examId,
     printPlanId,
+    openCollegeId,
   });
 };
 // paper_number

+ 6 - 6
src/modules/base/components/ModifyCardRule.vue

@@ -351,16 +351,16 @@ export default {
         firstLevelSubheading: [
           {
             required: false,
-            max: 26,
-            message: "一级副标题最多只能输入26字",
+            max: 52,
+            message: "一级副标题最多只能输入52个字",
             trigger: "change",
           },
         ],
         secondLevelSubheading: [
           {
             required: false,
-            max: 26,
-            message: "二级副标题最多只能输入26字",
+            max: 52,
+            message: "二级副标题最多只能输入52个字",
             trigger: "change",
           },
         ],
@@ -372,7 +372,7 @@ export default {
           },
           {
             max: 26,
-            message: "客观题注意事项最多只能输入26个字",
+            message: "客观题注意事项最多只能输入26个字",
             trigger: "change",
           },
         ],
@@ -384,7 +384,7 @@ export default {
           },
           {
             max: 26,
-            message: "主观题注意事项最多只能输入26个字",
+            message: "主观题注意事项最多只能输入26个字",
             trigger: "change",
           },
         ],

+ 3 - 8
src/modules/base/views/ExamStudentManage.vue

@@ -7,13 +7,6 @@
           defaultSelectExam
           @exam-default="search"
         ></secp-select>
-        <el-form-item label="课程(代码):">
-          <course-common-select
-            v-model="filter.courseId"
-            placeholder="课程(代码)"
-            clearable
-          ></course-common-select>
-        </el-form-item>
         <el-form-item label="任课老师:">
           <el-input
             v-model.trim="filter.teacher"
@@ -368,9 +361,11 @@ export default {
       filterSe: {
         semesterId: "",
         examId: "",
+        openCollegeId: "",
+        courseId: "",
+        paperNumber: "",
       },
       filter: {
-        courseId: "",
         teacher: "",
         college: "",
         major: "",

+ 20 - 0
src/modules/statistics/api.js

@@ -0,0 +1,20 @@
+import { $postParam } from "@/plugins/axios";
+
+// scan-task-stat
+export const scanTaskStatListPage = (datas) => {
+  return $postParam("/api/admin/exam/structure/list_user_class", datas);
+};
+export const scanTaskStatExport = (datas) => {
+  return $postParam("/api/admin/exam/structure/list_user_class", datas, {
+    responseType: "blob",
+  });
+};
+// print-task-stat
+export const printTaskStatListPage = (datas) => {
+  return $postParam("/api/admin/exam/structure/list_user_class", datas);
+};
+export const printTaskStatExport = (datas) => {
+  return $postParam("/api/admin/exam/structure/list_user_class", datas, {
+    responseType: "blob",
+  });
+};

+ 15 - 0
src/modules/statistics/router.js

@@ -0,0 +1,15 @@
+import PrintTaskStat from "./views/PrintTaskStat.vue";
+import ScanTaskStat from "./views/ScanTaskStat.vue";
+
+export default [
+  {
+    path: "/statistics/marker-login",
+    name: "PrintTaskStat",
+    component: PrintTaskStat,
+  },
+  {
+    path: "/statistics/score-archive",
+    name: "ScanTaskStat",
+    component: ScanTaskStat,
+  },
+];

+ 184 - 0
src/modules/statistics/views/PrintTaskStat.vue

@@ -0,0 +1,184 @@
+<template>
+  <div>
+    <div class="part-box part-box-filter">
+      <el-form ref="FilterForm" label-position="left" label-width="90px" inline>
+        <template v-if="checkPrivilege('condition', 'condition')">
+          <secp-select
+            v-model="filterSe"
+            defaultSelectExam
+            @exam-default="search"
+          ></secp-select>
+          <el-form-item label="题卡类型:" label-width="90px">
+            <el-select
+              v-model="filter.cardType"
+              style="width: 120px"
+              placeholder="题卡类型"
+              clearable
+            >
+              <el-option
+                v-for="(val, key) in CARD_TYPE"
+                :key="key"
+                :value="key"
+                :label="val"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="状态:">
+            <el-select
+              v-model="filter.status"
+              placeholder="状态"
+              clearable
+              style="width: 120px"
+            >
+              <el-option
+                v-for="(val, key) in DATA_TASK_STATUS"
+                :key="key"
+                :value="key"
+                :label="val"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </template>
+        <el-form-item>
+          <el-button
+            v-if="checkPrivilege('button', 'select')"
+            type="primary"
+            @click="toPage(1)"
+            >查询</el-button
+          >
+        </el-form-item>
+      </el-form>
+      <div class="box-justify">
+        <div></div>
+        <div>
+          <el-button
+            v-if="checkPrivilege('button', 'export')"
+            type="primary"
+            icon="el-icon-download"
+            :loading="loading"
+            @click="toExport"
+            >导出印刷进度</el-button
+          >
+        </div>
+      </div>
+    </div>
+
+    <div class="part-box part-box-pad">
+      <el-table ref="TableList" :data="dataList">
+        <el-table-column
+          type="index"
+          label="序号"
+          width="70"
+          :index="indexMethod"
+        ></el-table-column>
+        <el-table-column
+          prop="printPlanName"
+          label="印刷计划"
+          min-width="160"
+        ></el-table-column>
+        <el-table-column label="课程(代码)" min-width="260">
+          <template slot-scope="scope">
+            {{ scope.row.courseName | defaultFieldFilter }}({{
+              scope.row.courseCode | defaultFieldFilter
+            }})
+          </template>
+        </el-table-column>
+        <el-table-column prop="paperNumber" label="试卷编号" width="200">
+        </el-table-column>
+        <el-table-column prop="type" label="题卡类型" width="100">
+          <span slot-scope="scope">{{ scope.row.type | cardTypeFilter }}</span>
+        </el-table-column>
+        <el-table-column prop="openCollege" label="开课学院" min-width="160">
+        </el-table-column>
+        <el-table-column prop="createMethod" label="总考场数" width="100">
+        </el-table-column>
+        <el-table-column prop="createMethod" label="已生成/未生成" width="120">
+        </el-table-column>
+        <el-table-column prop="createMethod" label="已印刷/未印刷" width="120">
+        </el-table-column>
+        <el-table-column prop="createMethod" label="已打回/已作废" width="120">
+        </el-table-column>
+        <el-table-column prop="status" label="状态" width="100">
+        </el-table-column>
+      </el-table>
+      <div class="part-page">
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :pager-count="5"
+          :current-page="current"
+          :total="total"
+          :page-size="size"
+          @current-change="toPage"
+          @size-change="pageSizeChange"
+        >
+        </el-pagination>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { CARD_TYPE, DATA_TASK_STATUS } from "../../../constants/enumerate";
+import { printTaskStatListPage, printTaskStatExport } from "../api";
+import { downloadByApi } from "@/plugins/download";
+
+export default {
+  name: "print-task-stat",
+  data() {
+    return {
+      filter: {
+        semesterId: "",
+        examId: "",
+        printPlanId: "",
+        openCollegeId: "",
+        courseId: "",
+        paperNumber: "",
+        cardType: "",
+        status: "",
+      },
+      dataList: [],
+      CARD_TYPE,
+      DATA_TASK_STATUS,
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      loading: false,
+    };
+  },
+  methods: {
+    async getList() {
+      if (!this.checkPrivilege("list", "list")) return;
+
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size,
+      };
+      const data = await printTaskStatListPage(datas);
+      this.dataList = data.records;
+      this.total = data.total;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    search() {
+      this.toPage(1);
+    },
+    async toExport() {
+      if (this.loading) return;
+      this.loading = true;
+      const res = await downloadByApi(() => {
+        return printTaskStatExport(this.filter);
+      }, "").catch((e) => {
+        this.$message.error(e || "导出失败,请重新尝试!");
+      });
+      this.loading = false;
+
+      if (!res) return;
+      this.$message.success("导出成功!");
+    },
+  },
+};
+</script>

+ 162 - 0
src/modules/statistics/views/ScanTaskStat.vue

@@ -0,0 +1,162 @@
+<template>
+  <div>
+    <div class="part-box part-box-filter">
+      <el-form ref="FilterForm" label-position="left" label-width="90px" inline>
+        <template v-if="checkPrivilege('condition', 'condition')">
+          <secp-select
+            v-model="filterSe"
+            defaultSelectExam
+            @exam-default="search"
+          ></secp-select>
+          <el-form-item label="题卡类型:" label-width="90px">
+            <el-select
+              v-model="filter.cardType"
+              style="width: 120px"
+              placeholder="题卡类型"
+              clearable
+            >
+              <el-option
+                v-for="(val, key) in CARD_TYPE"
+                :key="key"
+                :value="key"
+                :label="val"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </template>
+        <el-form-item>
+          <el-button
+            v-if="checkPrivilege('button', 'select')"
+            type="primary"
+            @click="toPage(1)"
+            >查询</el-button
+          >
+        </el-form-item>
+      </el-form>
+      <div class="box-justify">
+        <div></div>
+        <div>
+          <el-button
+            v-if="checkPrivilege('button', 'export')"
+            type="primary"
+            icon="el-icon-download"
+            :loading="loading"
+            @click="toExport"
+            >导出扫描进度</el-button
+          >
+        </div>
+      </div>
+    </div>
+
+    <div class="part-box part-box-pad">
+      <el-table ref="TableList" :data="dataList">
+        <el-table-column
+          type="index"
+          label="序号"
+          width="70"
+          :index="indexMethod"
+        ></el-table-column>
+        <el-table-column
+          prop="openCollege"
+          label="开课学院"
+          min-width="160"
+        ></el-table-column>
+        <el-table-column label="课程(代码)" min-width="260">
+          <template slot-scope="scope">
+            {{ scope.row.courseName | defaultFieldFilter }}({{
+              scope.row.courseCode | defaultFieldFilter
+            }})
+          </template>
+        </el-table-column>
+        <el-table-column prop="paperNumber" label="试卷编号" width="200">
+        </el-table-column>
+        <el-table-column prop="type" label="题卡类型" width="100">
+          <span slot-scope="scope">{{ scope.row.type | cardTypeFilter }}</span>
+        </el-table-column>
+        <el-table-column prop="createMethod" label="考生数" width="100">
+        </el-table-column>
+        <el-table-column prop="createMethod" label="已扫张数" width="100">
+        </el-table-column>
+        <el-table-column prop="createMethod" label="缺考数" width="100">
+        </el-table-column>
+        <el-table-column prop="createMethod" label="扫描进度" width="100">
+        </el-table-column>
+      </el-table>
+      <div class="part-page">
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :pager-count="5"
+          :current-page="current"
+          :total="total"
+          :page-size="size"
+          @current-change="toPage"
+          @size-change="pageSizeChange"
+        >
+        </el-pagination>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { CARD_TYPE } from "../../../constants/enumerate";
+import { scanTaskStatListPage, scanTaskStatExport } from "../api";
+import { downloadByApi } from "@/plugins/download";
+
+export default {
+  name: "scan-task-stat",
+  data() {
+    return {
+      filter: {
+        semesterId: "",
+        examId: "",
+        openCollegeId: "",
+        courseId: "",
+        paperNumber: "",
+        cardType: "",
+      },
+      dataList: [],
+      CARD_TYPE,
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      loading: false,
+    };
+  },
+  methods: {
+    async getList() {
+      if (!this.checkPrivilege("list", "list")) return;
+
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size,
+      };
+      const data = await scanTaskStatListPage(datas);
+      this.dataList = data.records;
+      this.total = data.total;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    search() {
+      this.toPage(1);
+    },
+    async toExport() {
+      if (this.loading) return;
+      this.loading = true;
+      const res = await downloadByApi(() => {
+        return scanTaskStatExport(this.filter);
+      }, "").catch((e) => {
+        this.$message.error(e || "导出失败,请重新尝试!");
+      });
+      this.loading = false;
+
+      if (!res) return;
+      this.$message.success("导出成功!");
+    },
+  },
+};
+</script>

+ 2 - 0
src/router.js

@@ -15,6 +15,7 @@ import analysis from "./modules/analysis/router";
 import mark from "./modules/mark/router";
 import course from "./modules/course/router";
 import target from "./modules/target/router";
+import statistics from "./modules/statistics/router";
 // card part
 import card from "./modules/card/router";
 // admin
@@ -70,6 +71,7 @@ let router = new Router({
         ...mark,
         ...course,
         ...target,
+        ...statistics,
       ],
     },
     { ...login },