Browse Source

试卷审批表下载

zhangjie 3 năm trước cách đây
mục cha
commit
2ec8caa8b4

+ 82 - 0
src/assets/styles/paper-approve.css

@@ -0,0 +1,82 @@
+body,
+div,
+h1,
+p,
+tr,
+th,
+td,
+span {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+
+body {
+  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
+    "Microsoft YaHei", Arial, sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  font-size: 14px;
+  color: #1f2230;
+}
+
+.paper-main {
+  width: 210mm;
+  margin: 0 auto;
+  color: #1f2230;
+}
+.paper-a4 {
+  width: 210mm;
+  height: 297mm;
+  padding: 40px;
+  overflow: hidden;
+  page-break-after: always;
+}
+.paper-h1 {
+  font-size: 24px;
+  text-align: center;
+  line-height: 1;
+  padding-top: 20px;
+  padding-bottom: 30px;
+}
+.paper-base {
+  margin-bottom: 30px;
+}
+.paper-row {
+  margin: 0 -5px 10px;
+}
+.paper-item {
+  display: inline-block;
+  vertical-align: top;
+  width: 50%;
+  padding: 0 5px;
+}
+.paper-item > span:first-child {
+  float: left;
+  width: 80px;
+  text-align: right;
+}
+.paper-item > span:last-child {
+  display: block;
+  margin-left: 80px;
+}
+
+.paper-table {
+  width: 100%;
+  border-spacing: 0;
+  border-collapse: collapse;
+  margin-bottom: 40px;
+  text-align: center;
+}
+.paper-table th {
+  padding: 8px;
+  line-height: 20px;
+  letter-spacing: 1px;
+  border: 1px solid #1f2230;
+}
+.paper-table td {
+  padding: 8px;
+  line-height: 20px;
+  border: 1px solid #1f2230;
+}

+ 15 - 0
src/modules/exam/api.js

@@ -52,6 +52,21 @@ export const batchAddExamTask = datas => {
 export const taskApplyAuditHistory = flowId => {
   return $postParam("/api/admin/exam/task/review_list", { flowId });
 };
+export const examTaskApproveForm = examTaskId => {
+  return $postParam("/api/admin/exam/task/find_approve_form_json", {
+    examTaskId
+  });
+};
+export const downloadExamTaskApproveForm = ({ examTaskId, htmlContent }) => {
+  return $post(
+    "/api/admin/exam/task/find_approve_form_pdf",
+    {
+      examTaskId,
+      htmlContent
+    },
+    { responseType: "blob" }
+  );
+};
 
 // task-apply-manage
 export const taskApplyListPage = datas => {

+ 321 - 0
src/modules/exam/components/PaperApproveTable.vue

@@ -0,0 +1,321 @@
+<template>
+  <el-dialog
+    class="paper-approve-table"
+    :visible.sync="modalIsShow"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    :show-close="false"
+    append-to-body
+    fullscreen
+    @open="initData"
+  >
+    <div class="box-justify" slot="title">
+      <span class="el-dialog__title">试卷审批表</span>
+      <div>
+        <el-button type="success" :disabled="loading" @click="toDownload"
+          >下载</el-button
+        >
+        <el-button @click="cancel">取消</el-button>
+      </div>
+    </div>
+
+    <div class="paper-container" ref="PaperContainer">
+      <div class="paper-main" v-if="!pages.length">
+        <div class="paper-a4">
+          <h1 class="paper-h1" id="paper-head">试卷审批表</h1>
+
+          <div class="paper-base" id="paper-base">
+            <div class="paper-row">
+              <div class="paper-item">
+                <span>教研室:</span>
+                <span>{{ basicInfo.teachingRoomName }}</span>
+              </div>
+              <div class="paper-item">
+                <span>试卷名称:</span>
+                <span>{{ basicInfo.paperName || "" }}</span>
+              </div>
+            </div>
+            <div class="paper-row">
+              <div class="paper-item">
+                <span>考试时间:</span>
+                <span>{{ basicInfo.examTime }}</span>
+              </div>
+              <div class="paper-item">
+                <span>拟卷老师:</span>
+                <span>{{ basicInfo.teacherName }}</span>
+              </div>
+            </div>
+          </div>
+
+          <table class="paper-table">
+            <tr>
+              <th>使用班级</th>
+              <th>人数</th>
+              <th>总印份数</th>
+            </tr>
+            <tr v-for="item in examRoomInfoList" :key="item.id" :id="item.id">
+              <td>{{ item.clazzNames }}</td>
+              <td style="width: 100px;">{{ item.studentCount }}</td>
+              <td style="width: 140px;">{{ item.printCount }}</td>
+            </tr>
+          </table>
+
+          <table class="paper-table" id="paper-approve">
+            <tr>
+              <th>审批部门</th>
+              <th>审批人</th>
+              <th>审批时间</th>
+              <th>审批意见</th>
+            </tr>
+            <tr v-for="(item, index) in approvalInfoList" :key="index">
+              <td>{{ item.levelName }}</td>
+              <td>{{ item.approveName }}</td>
+              <td>{{ item.time | timestampFilter }}</td>
+              <td>{{ item.remark }}</td>
+            </tr>
+          </table>
+        </div>
+      </div>
+      <div class="paper-main" v-else>
+        <div class="paper-a4" v-for="(page, pindex) in pages" :key="pindex">
+          <template v-if="pindex === 0">
+            <h1 class="paper-h1">试卷审批表</h1>
+
+            <div class="paper-base">
+              <div class="paper-row">
+                <div class="paper-item">
+                  <span>教研室:</span>
+                  <span>{{ basicInfo.teachingRoomName }}</span>
+                </div>
+                <div class="paper-item">
+                  <span>试卷名称:</span>
+                  <span>{{ basicInfo.paperName || "" }}</span>
+                </div>
+              </div>
+              <div class="paper-row">
+                <div class="paper-item">
+                  <span>考试时间:</span>
+                  <span>{{ basicInfo.examTime }}</span>
+                </div>
+                <div class="paper-item">
+                  <span>拟卷老师:</span>
+                  <span>{{ basicInfo.teacherName }}</span>
+                </div>
+              </div>
+            </div>
+          </template>
+
+          <template v-for="(part, tindex) in page">
+            <table
+              v-if="part.type === 'room'"
+              class="paper-table"
+              :key="tindex"
+            >
+              <tr>
+                <th>使用班级</th>
+                <th>人数</th>
+                <th>总印份数</th>
+              </tr>
+              <tr v-for="item in part.data" :key="item.id">
+                <td>{{ item.clazzNames }}</td>
+                <td style="width: 100px;">{{ item.studentCount }}</td>
+                <td style="width: 140px;">{{ item.printCount }}</td>
+              </tr>
+            </table>
+
+            <table v-else class="paper-table" :key="tindex">
+              <tr>
+                <th>审批部门</th>
+                <th>审批人</th>
+                <th>审批时间</th>
+                <th>审批意见</th>
+              </tr>
+              <tr v-for="(item, index) in part.data" :key="index">
+                <td>{{ item.levelName }}</td>
+                <td>{{ item.approveName }}</td>
+                <td>{{ item.time | timestampFilter }}</td>
+                <td>{{ item.remark }}</td>
+              </tr>
+            </table>
+          </template>
+        </div>
+      </div>
+    </div>
+
+    <div slot="footer"></div>
+  </el-dialog>
+</template>
+
+<script>
+import { downloadBlob, parseTimeRangeDateAndTime } from "@/plugins/utils";
+import { examTaskApproveForm, downloadExamTaskApproveForm } from "../api";
+
+export default {
+  name: "paper-approve-table",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      }
+    }
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      loading: false,
+      basicInfo: {},
+      examRoomInfoList: {},
+      approvalInfoList: {},
+      pages: []
+    };
+  },
+  methods: {
+    async initData() {
+      this.pages = [];
+      this.basicInfo = {};
+      this.examRoomInfoList = {};
+      this.approvalInfoList = {};
+      const paper = await examTaskApproveForm(this.instance.id);
+
+      this.basicInfo = paper.basicInfo;
+      this.examRoomInfoList = paper.examRoomInfoList.map(item => {
+        item.id = this.$randomCode();
+        item.height = 0;
+        return item;
+      });
+      const levelNames = {
+        2: "教研室审批意见",
+        3: "二级学院(部)审批意见"
+      };
+      this.approvalInfoList = paper.approvalInfoList.map(item => {
+        item.levelName = levelNames[item.level];
+        return item;
+      });
+      this.approvalInfoList.sort((a, b) => a.level - b.level);
+
+      const { date, time } = parseTimeRangeDateAndTime(
+        this.basicInfo.examStartTime,
+        this.basicInfo.examEndTime
+      );
+
+      this.basicInfo.examTime = `${date}  ${time}`;
+      this.$nextTick(() => {
+        this.rebuildPaper();
+      });
+    },
+    rebuildPaper() {
+      const pageHeight = 1043;
+
+      const pageLimitHeight = [
+        pageHeight -
+          document.getElementById("paper-head").clientHeight -
+          document.getElementById("paper-base").clientHeight -
+          30 -
+          37
+      ];
+      let pages = [];
+      let curPage = [];
+      let curPageLimitHeight = pageHeight;
+      let curPageHeight = 0;
+
+      let roomData = [];
+      this.examRoomInfoList.forEach(item => {
+        const curPageNo = pages.length;
+        curPageLimitHeight = pageLimitHeight[curPageNo] || pageHeight;
+
+        const rowHeight = document.getElementById(item.id).clientHeight;
+        if (rowHeight + curPageHeight <= curPageLimitHeight) {
+          roomData.push(item);
+          curPageHeight += rowHeight;
+        } else {
+          curPage.push({
+            type: "room",
+            data: roomData
+          });
+          pages.push(curPage);
+          curPage = [];
+          roomData = [];
+          roomData.push(item);
+          curPageHeight = rowHeight + 37;
+        }
+      });
+      curPage.push({
+        type: "room",
+        data: roomData
+      });
+      if (
+        curPageHeight +
+          30 +
+          document.getElementById("paper-approve").clientHeight >
+        curPageLimitHeight
+      ) {
+        pages.push(curPage);
+        curPage = [];
+      }
+      curPage.push({
+        type: "approve",
+        data: this.approvalInfoList
+      });
+      pages.push(curPage);
+
+      this.pages = pages;
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    getHtmlContent() {
+      const htmlContent = this.$refs.PaperContainer.innerHTML;
+      const cssContent = `body,div,h1,p,tr,th,td,span{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:rgba(255,255,255,0)}body{font-family:"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:14px;color:#1f2230}.paper-main{width:210mm;margin:0 auto;color:#1f2230}.paper-a4{width:210mm;height:297mm;padding:40px;overflow:hidden;page-break-after:always}.paper-h1{font-size:24px;text-align:center;line-height:1;padding-top:20px;padding-bottom:30px}.paper-base{margin-bottom:30px}.paper-row{margin:0 -5px 10px}.paper-item{display:inline-block;vertical-align:top;width:50%;padding:0 5px}.paper-item>span:first-child{float:left;width:80px;text-align:right}.paper-item>span:last-child{display:block;margin-left:80px}.paper-table{width:100%;border-spacing:0;border-collapse:collapse;margin-bottom:40px;text-align:center}.paper-table th{padding:8px;line-height:20px;letter-spacing:1px;border:1px solid #1f2230}.paper-table td{padding:8px;line-height:20px;border:1px solid #1f2230}`;
+
+      return `
+        <!DOCTYPE html>
+          <html>
+            <head>
+              <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+              <meta name="viewport" content="width=device-width,initial-scale=1.0,
+              maximum-scale=1.0,minimum-scale=1.0, user-scalable=no" "="">
+              <meta name=" renderer" content="webkit|ie-comp|ie-stand" />
+              <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+              <title>试卷审批表</title>
+
+            </head>
+            <style>${cssContent}</style>
+            <body>${htmlContent}</body>
+          </html>
+        `;
+    },
+    async toDownload() {
+      if (this.loading) return;
+
+      this.loading = true;
+      const datas = {
+        htmlContent: this.getHtmlContent(),
+        examTaskId: this.instance.id
+      };
+      const res = await downloadBlob(() => {
+        return downloadExamTaskApproveForm(datas);
+      }, `${this.instance.courseName}-试卷审批表.pdf`).catch(() => {});
+
+      this.loading = false;
+
+      if (res) {
+        this.$message.success("文件下载成功!");
+      } else {
+        this.$message.error("文件下载失败,请重新尝试!");
+      }
+    }
+  }
+};
+</script>
+
+<style scoped>
+.paper-approve-table .paper-a4 {
+  box-shadow: 0 0 1px #666;
+  margin-bottom: 10px;
+}
+</style>
+<style src="@/assets/styles/paper-approve.css" scoped></style>

+ 1 - 1
src/modules/exam/components/createExamAndPrintTask/CreateTaskApply.vue

@@ -90,7 +90,7 @@ const initExamTask = {
   cardRuleId: COMMON_CARD_RULE_ID,
   teachingRoomId: "",
   teacherName: "",
-  lecturerName: ""
+  paperName: ""
 };
 
 const initExamTaskDetail = {

+ 4 - 4
src/modules/exam/components/createExamAndPrintTask/InfoExamTask.vue

@@ -64,11 +64,11 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="主讲教师:">
+            <el-form-item label="试卷名称:">
               <el-input
-                v-model.trim="examTask.lecturerName"
-                placeholder="请输入主讲教师"
-                :maxlength="50"
+                v-model.trim="examTask.paperName"
+                placeholder="请输入试卷名称"
+                :maxlength="100"
                 clearable
               ></el-input>
             </el-form-item>

+ 24 - 2
src/modules/exam/views/ExamTaskManage.vue

@@ -175,7 +175,12 @@
             scope.row.createTime | timestampFilter
           }}</span>
         </el-table-column>
-        <el-table-column class-name="action-column" label="操作" width="120px">
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          width="120px"
+          align="center"
+        >
           <template slot-scope="scope">
             <el-button
               v-if="checkPrivilege('link', 'preview')"
@@ -207,6 +212,12 @@
               @click="toEnable(scope.row)"
               >{{ scope.row.enable ? "禁用" : "启用" }}</el-button
             >
+            <el-button
+              class="btn-primary"
+              type="text"
+              @click="toDownloadForm(scope.row)"
+              >下载审批表</el-button
+            >
           </template>
         </el-table-column>
       </el-table>
@@ -240,6 +251,11 @@
       ref="CreateTaskApply"
       @modified="taskModified"
     ></create-task-apply>
+    <!-- PaperApproveTable -->
+    <paper-approve-table
+      :instance="curExamTask"
+      ref="PaperApproveTable"
+    ></paper-approve-table>
   </div>
 </template>
 
@@ -247,6 +263,7 @@
 import ModifyExamTask from "../components/ModifyExamTask";
 import BatchAddExamTask from "../components/BatchAddExamTask";
 import CreateTaskApply from "../components/createExamAndPrintTask/CreateTaskApply";
+import PaperApproveTable from "../components/PaperApproveTable";
 import { ABLE_TYPE, EXAM_TASK_STATUS } from "@/constants/enumerate";
 import pickerOptions from "@/constants/datePickerOptions";
 import { examTaskListPage, ableExamTask } from "../api";
@@ -257,7 +274,8 @@ export default {
   components: {
     ModifyExamTask,
     BatchAddExamTask,
-    CreateTaskApply
+    CreateTaskApply,
+    PaperApproveTable
   },
   data() {
     return {
@@ -373,6 +391,10 @@ export default {
       this.editType = "PREVIEW";
       this.$refs.ModifyExamTask.open();
     },
+    toDownloadForm(row) {
+      this.curExamTask = row;
+      this.$refs.PaperApproveTable.open();
+    },
     taskModified() {
       this.getList();
       this.updateWaitTaskCount();