Browse Source

阅卷3.0改造

nikang 6 năm trước cách đây
mục cha
commit
d90f74c17e

+ 115 - 0
src/modules/marking/canvas/mark_sign.js

@@ -0,0 +1,115 @@
+export function Drawing(canvas, option) {
+  typeof canvas == "string" && (canvas = document.getElementById(canvas));
+  if (!canvas || !canvas.getContext) {
+    throw new Error(100, "do not support canvas!");
+  }
+  this.init(canvas, option);
+}
+Drawing.prototype = {
+  init: function(canvas, option) {
+    typeof option == "object" ||
+      (option = { score: 0, data: "", width: 500, height: 500, loc: [] });
+    this.itemId = "";
+    this.paperKey = "";
+    this.scoreLoc = [];
+    this.option = option;
+    this.canvas = canvas;
+    this.context = this.canvas.getContext("2d");
+    this.context.fillStyle = "red";
+    this.clearDraw();
+    this.bindEvent();
+    this.drawHtml(option.data);
+  },
+  setItemId: function(itemId) {
+    this.itemId = itemId;
+  },
+  setPaperKey: function(paperKey) {
+    this.paperKey = paperKey;
+  },
+  setImg: function(imgSrc) {
+    var img = new Image();
+    img.src = imgSrc;
+    this.img = img;
+    this.drawImg();
+  },
+  setHtml: function(html) {
+    this.clearDraw();
+    this.option.data = html;
+    this.drawHtml(this.option.data);
+  },
+  setLocation: function(scoreLocs, type) {
+    if (!scoreLocs) return;
+    //初始化时从localStorage中获取
+    if (type == "localStorage") {
+      this.scoreLoc = Object.assign([], scoreLocs);
+    }
+    for (let scoreLoc of this.scoreLoc) {
+      this.option.score = scoreLoc.score;
+      this.drawScoreLoc(scoreLoc.loc);
+    }
+  },
+  getLocation: function(x, y) {
+    var bbox = this.canvas.getBoundingClientRect();
+    return {
+      x: (x - bbox.left) * (this.canvas.width / bbox.width),
+      y: (y - bbox.top) * (this.canvas.height / bbox.height)
+    };
+  },
+  drawHtml: function(data) {
+    if (!data) return;
+    var self = this;
+    rasterizeHTML
+      .drawHTML(data, this.canvas, {
+        width: this.option.width,
+        height: this.option.height
+      })
+      .then(function(renderResult) {
+        self.img = renderResult.image;
+        self.context.drawImage(renderResult.image, 0, 0);
+      });
+  },
+  drawImg: function() {
+    this.context.drawImage(this.img, 0, 0);
+  },
+  bindEvent: function() {
+    var self = this;
+    this.canvas.addEventListener(
+      "click",
+      function(e) {
+        var location = self.getLocation(e.clientX, e.clientY);
+        self.onClick(location);
+      },
+      false
+    );
+  },
+  removeEvent: function() {
+    this.canvas.removeEventListener("click", function(event) {}, false);
+  },
+  ResetDrawAll: function() {
+    this.clearDraw();
+    this.drawImg();
+  },
+  clearDraw: function() {
+    this.context.clearRect(0, 0, this.option.width, this.option.height);
+  },
+  clearScoreLoc: function() {
+    this.scoreLoc.splice(0, this.scoreLoc.length);
+  },
+  drawScoreLoc(pos) {
+    this.context.font = "48px serif";
+    this.context.fillText(this.option.score, pos.x, pos.y);
+  },
+  onClick: function(pos) {
+    var numReg = /^\d+$/;
+    if (numReg.test(this.option.score)) {
+      this.drawScoreLoc(pos);
+      this.scoreLoc.push({
+        loc: { x: pos.x, y: pos.y },
+        score: this.option.score,
+        itemId: this.itemId
+      });
+      //选中一次分数只能标记一次
+      this.option.score = "";
+    }
+  }
+};

+ 44 - 0
src/modules/marking/constants/constants.js

@@ -0,0 +1,44 @@
+export const CORE_API = "/api/ecs_core"; //基础信息API
+export const EXAM_WORK_API = "/api/ecs_exam_work"; //考务信息API
+export const MARKING_API = "/api/ecs_marking"; //阅卷API
+export const DATA_PROCESS_API = "/api/ecs_data_process"; //数据中间层API
+export const OE_API = "/api/ecs_oe"; //网考API
+export const Q_API = "/api/ecs_ques"; //题库API
+export const LEVEL_TYPE = [
+  { label: "专升本", value: "ZSB" },
+  { label: "高起专", value: "GQZ" },
+  { label: "不限", value: "ALL" }
+];
+import Vue from "vue";
+//标记卷类型
+export const TAGS = [
+  { label: "雷同卷", value: "SAME" },
+  { label: "空白卷", value: "BLANK" },
+  { label: "答非所问", value: "IRRELEVANT" },
+  { label: "科目错误", value: "SUBJECT_ERROR" },
+  { label: "非手写", value: "QUESTIONABLE" }
+];
+//标记卷过滤器
+Vue.filter("tagFilter", function(val) {
+  for (let tag of TAGS) {
+    if (tag.value === val) {
+      return tag.label;
+    }
+  }
+});
+//考试类型
+export const EXAMTYPES = [
+  { label: "在线考试", value: "ONLINE" },
+  { label: "离线考试", value: "OFFLINE" },
+  { label: "传统考试", value: "TRADITION" },
+  { label: "练习", value: "PRACTICE" }
+];
+//考试类型过滤器
+Vue.filter("examTypeFilter", function(val) {
+  for (let examType of EXAMTYPES) {
+    if (examType.value === val) {
+      return examType.label;
+    }
+  }
+});
+export const EVENTHUB = new Vue();

+ 290 - 0
src/modules/marking/views/batchMark.vue

@@ -0,0 +1,290 @@
+<style lang="css">
+</style>
+
+<template lang="html">
+  <div>
+    <section class="content">
+      <div class="box box-info">
+        <div class="box-header with-border">
+          <h3 class="box-title">请选择评卷工作</h3>
+          <div class="box-tools pull-right">
+            <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
+            </button>
+          </div>
+        </div>
+        <div class="box-body">
+          <el-form :inline="true" :model="formSearch" label-position="right" label-width="110px">
+            <el-form-item label="课程代码" class="pull-left">
+              <el-input placeholder="课程代码" v-model="formSearch.courseCode"></el-input>
+            </el-form-item>
+            <el-form-item label="课程名称" class="pull-left">
+              <el-input placeholder="课程名称" v-model="formSearch.courseName"></el-input>
+            </el-form-item>
+            <el-form-item class="pull-right">
+              <el-button type="primary" icon="search" @click="searchMarkWork">查询</el-button>
+              <el-button  type="success" icon="caret-left" @click="backIndex">返回</el-button>
+            </el-form-item>
+          </el-form>
+          <el-table v-loading="loading" element-loading-text="拼命加载中" :data="tableData" border style="width: 100%">
+            <el-table-column  label="课程名称" width="200">
+              <div>
+                <span style="margin-left: 10px">{{row.courseName}}</span>
+              </div>
+            </el-table-column>
+            <el-table-column  label="课程代码" width="250">
+              <div>
+                <span style="margin-left: 10px">{{row.courseCode}}</span>
+              </div>
+            </el-table-column>
+            <el-table-column  label="试卷数" width="200">
+              <div>
+                <span style="margin-left: 10px">{{row.totalCount}}</span>
+              </div>
+            </el-table-column>
+            <el-table-column  label="进度">
+              <div>
+                <span style="margin-left: 10px">{{((row.totalCount-row.leftCount)*100/row.totalCount).toFixed(2)}}%</span>
+              </div>
+            </el-table-column>
+            <el-table-column  label="未评数">
+              <div>
+                <span style="margin-left: 10px">{{row.leftCount}}</span>
+              </div>
+            </el-table-column>
+            <el-table-column :context="_self"  label="操作">
+              <div class="pull-left">
+                <el-button @click="batchUserPaperInfo(row)" type="success" size="mini" >批量下载</el-button>
+                <el-button @click="uploadMarkScore(row)" type="info" size="mini" >上传评分</el-button>
+              </div>
+            </el-table-column>
+          </el-table>
+
+          <!--导入弹窗-->
+          <el-dialog title="离线分数" size="tiny" v-model="batchScoreImportDialog">
+            <el-form>
+              <el-row>
+                <el-form-item style="margin-left:20px">
+                  <el-upload class="form_left" ref="upload" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" :action="uploadAction" :headers="uploadHeaders" :data="uploadData" :before-upload="beforeUpload" :on-progress="uploadProgress" :on-success="uploadSuccess" :on-error="uploadError" :file-list="fileList" :auto-upload="false" :multiple="false">
+                    <el-button size="small" slot="trigger" type="primary">选择文件</el-button>
+                    <el-button size="small" type="success" @click="submitUpload">确认上传</el-button>
+                    <el-button size="small" type="danger" @click="removeFile">清空文件</el-button>
+                    <!--<el-button size="small" type="info" @click="exportFile">下载模板</el-button>-->
+                    <div slot="tip" class="el-upload__tip">只能上传xlsx文件</div>
+                  </el-upload>
+                </el-form-item>
+              </el-row>
+            </el-form>
+          </el-dialog>
+
+          <!--导入错误信息列表-->
+          <el-dialog title="错误提示" v-model="errDialog">
+            <div class="text-danger" v-for="errMessage in errMessages" :key="errMessage.row">
+              第{{errMessage.row}}行:{{errMessage.excelErrorType}}
+            </div>
+            <span slot="footer" class="dialog-footer">
+                            <el-button @click="errDialog = false">确定</el-button>
+                        </span>
+          </el-dialog>
+
+          <div class="page pull-right">
+            <el-pagination background @current-change="paging"
+                           :current-page="currentPage"
+                           :page-size="pageSize"
+                           layout="total, prev, pager, next, jumper"
+                           :total="total">
+            </el-pagination>
+          </div>
+        </div>
+      </div>
+    </section>
+  </div>
+</template>
+
+<script>
+  import {DATA_PROCESS_API} from '../constants/constants'
+  import { mapState } from 'vuex'
+  export default {
+    data() {
+      return {
+        formSearch: {
+          courseCode:'',
+          courseName:''
+        },
+        tableData: [],
+        currentPage: 1,
+        pageSize:10,
+        total:0,
+        loading:false,
+        batchScoreImportDialog:false,
+        uploadAction: DATA_PROCESS_API + '/markTasks/batchImportScore',
+        uploadHeaders: {},
+        uploadData: {workId:this.$route.params.workId,courseCode:''},
+        errMessages: [],
+        errDialog: false,
+        fileLoading: false,
+        fileList: []
+      }
+    },
+    methods: {
+      searchMarkWork(){
+        var self = this;
+        this.loading = true;
+        this.workId = this.$route.params.workId;
+        var userId = this.user.userId;
+        $.ajax({
+          type: "GET",
+          url: DATA_PROCESS_API+"/markTasks?workId="+self.workId+"&userId="+userId,
+          async: false,
+            beforeSend: function (XMLHttpRequest) {
+                XMLHttpRequest.setRequestHeader("key", self.user.key);
+                XMLHttpRequest.setRequestHeader("token", self.user.token);
+            },
+          success: function(response){
+            self.tableData = response;
+            self.total = self.tableData.length;
+            self.filterMarkWork();
+            self.paging();
+            self.loading = false;
+          }
+        })
+      },
+      filterMarkWork(){
+          var tempData = this.tableData.filter((element)=>{
+          var flag = true;
+          if(this.formSearch.courseCode || this.formSearch.courseName){
+            if(this.formSearch.courseCode){
+              flag = flag && element.courseCode.includes(this.formSearch.courseCode)
+            }
+            if(this.formSearch.courseName){
+              flag = flag && element.courseName.includes(this.formSearch.courseName)
+            }
+            return flag
+          }else{
+            return flag
+          }
+        });
+        this.tableData = tempData;
+        this.total = tempData.length;
+      },
+      handleCurrentChange(val){
+        this.currentPage = val;
+        this.searchMarkWork();
+      },
+      paging(){
+        var start = (this.currentPage - 1) * this.pageSize;
+        var end = (this.currentPage)*this.pageSize < this.total ? (this.currentPage)*this.pageSize:this.total;
+        var tempData = [];
+        console.log(`当前页: ${this.currentPage},开始:${start},结束:${end}`);
+        for(let i = start;i < end;i++){
+          tempData.push(this.tableData[i])
+        }
+        console.log(tempData);
+        this.tableData = tempData;
+      },
+      batchUserPaperInfo(row){
+        this.$notify({
+          message: '离线考试批量评阅',
+          type: 'warning'
+        })
+      },
+      uploadMarkScore(row){
+        this.uploadData.courseCode = row.courseCode;
+        this.batchScoreImportDialog = true;
+        this.initUpload();
+      },
+      backIndex(){
+        this.$router.push({path: '/index/mark_setting_work/marking'})
+      },
+      //关于导入/导出
+      beforeUpload(file) {
+        console.log(file);
+      },
+      uploadProgress(event, file, fileList) {
+        console.log("uploadProgress");
+      },
+      uploadSuccess(response, file, fileList) {
+
+        console.log("uploadSuccess");
+        console.log(response);
+        if (!response || response.length == 0) {
+          this.$notify({
+            message: '上传成功',
+            type: 'success'
+          });
+        } else {
+          this.errMessages = response;
+          this.errDialog = true;
+        }
+        this.fileLoading = false;
+        this.batchScoreImportDialog = false;
+        this.searchMarkWork();
+      },
+      uploadError(err, file, fileList) {
+        var result = err.message.match(/\{.+}/);
+        var errMessage = JSON.parse(result[0]).errorMsg;
+        this.$notify({
+          message: errMessage,
+          type: 'error'
+        });
+        this.fileLoading = false;
+      },
+      initUpload() {
+        this.fileList = [];
+      },
+      checkUpload() {
+        var fileList = this.$refs.upload.uploadFiles;
+        if (fileList.length == 0) {
+          this.$notify({
+            message: '上传文件不能为空',
+            type: 'error'
+          });
+          return false;
+        }
+        if (fileList.length > 1) {
+          this.$notify({
+            message: '每次只能上传一个文件',
+            type: 'error'
+          });
+          return false;
+        }
+        for (let file of fileList) {
+          if (!file.name.endsWith(".xlsx")) {
+            this.$notify({
+              message: '上传文件必须为xlsx格式',
+              type: 'error'
+            });
+            this.initUpload();
+            return false;
+          }
+        }
+        return true;
+      },
+      //确定上传
+      submitUpload() {
+        if (!this.checkUpload()) {
+          return false;
+        }
+        this.$refs.upload.submit();
+        this.fileLoading = true;
+      },
+      //清空文件
+      removeFile() {
+        this.$refs.upload.clearFiles();
+      },
+      //下载模板
+      exportFile() {
+        window.location.href = "/api/sms/teacher/download";
+      }
+    },
+    computed:{
+      ...mapState({ user: state => state.user })
+    },
+    created(){
+      this.uploadHeaders = {
+          key:this.user.key,
+          token:this.user.token
+      };
+      this.searchMarkWork();
+    }
+  }
+</script>

+ 162 - 0
src/modules/marking/views/course_detail.vue

@@ -0,0 +1,162 @@
+<style lang="css">
+
+li {
+    list-style-type: none;
+}
+
+.searchFrame {
+    margin-right: 10px;
+    margin-bottom: 10px;
+}
+
+.page{
+  margin-top: 10px;
+}
+.f_button{
+    display:block;
+    width:57px;
+    height:20px;
+    border:1px solid #CCC;
+    background:#FFF;
+    font-size: small;
+}
+
+</style>
+
+<template>
+
+<div>
+    <section class="content">
+        <div class="box box-info">
+            <div class="box-header with-border">
+                <h3 class="box-title">
+                  <span>课程详情</span>
+                  <span>({{$route.params.courseName}}-{{$route.params.courseCode}})</span>
+                </h3>
+                <div class="box-tools pull-right">
+
+                </div>
+            </div>
+            <div class="box-body">
+                <el-form :inline="true" :model="formSearch" label-position="right" label-width="80px">
+                  <el-form-item label="姓名" class="pull-left">
+                      <el-input placeholder="姓名" v-model="formSearch.userName"></el-input>
+                  </el-form-item>
+                    <el-form-item label="登录名" class="pull-left">
+                      <el-input placeholder="登录名" v-model="formSearch.userLoginName"></el-input>
+                  </el-form-item>
+
+                  <el-form-item class="pull-right">
+                    <el-button size="small"  type="primary" icon="search" @click="searchSetting">查询</el-button>
+                    <!--<el-button size="small"  type="primary" icon="info" @click="exportMarker">导出</el-button>-->
+                    <el-button size="small"  type="primary" icon="caret-left" @click="back">返回</el-button>
+                  </el-form-item>
+                </el-form>
+
+                <!--页面列表-->
+                <el-table v-loading="loading" element-loading-text="拼命加载中" :data="tableData" border style="width: 100%">
+                  <el-table-column  label="姓名" width="200" prop="userName"/>
+                    <el-table-column  label="登录名" min-width="100" prop="userLoginName"/>
+                    <el-table-column  label="试卷类型" min-width="200" prop="markRangeName"/>
+                    <el-table-column  label="完成数量" min-width="100" prop="markedCount"/>
+                    <el-table-column  label="最低分" min-width="100" prop="minScore"/>
+                    <el-table-column  label="最高分" min-width="100" prop="maxScore"/>
+                    <el-table-column  label="平均分" min-width="100" prop="avgScore"/>
+                    <el-table-column  label="标准方差" min-width="100" prop="stdDev"/>
+                </el-table>
+                <div class="page pull-right">
+                    <el-pagination background @current-change="handleSettingCurrentChange"
+                    :current-page="currentPage"
+                    :page-size="10"
+                    layout="total, prev, pager, next, jumper"
+                    :total="total">
+                    </el-pagination>
+                </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+</template>
+
+<script>
+import { CORE_API,EXAM_WORK_API,MARKING_API,DATA_PROCESS_API,OE_API } from '../constants/constants'
+import { mapState } from 'vuex'
+export default {
+    data() {
+            return {
+                formSearch: {
+                    userLoginName:'',
+                    userName:''
+                },
+                tableData: [],
+                oldData:[],
+                currentPage: 1,
+                pageSize:10,
+                total:10,
+                loading:true,
+                workId:'',
+                examId:'',
+                courseCode:'',
+                examName:''
+            }
+        },
+        methods: {
+            handleSettingCurrentChange(val){
+              this.currentPage = val
+              this.searchSetting()
+            },
+            pagingSetting(){
+              var start = (this.currentPage - 1) * this.pageSize
+              var end = (this.currentPage)*this.pageSize < this.total ? (this.currentPage)*this.pageSize:this.total
+              var tempData = []
+              console.log(`当前页: ${this.currentPage},开始:${start},结束:${end}`)
+              for(let i = start;i < end;i++){
+                tempData.push(this.tableData[i])
+              }
+              this.tableData = tempData
+            },
+            initSetting(){
+              this.loading = true
+              this.$http.get(DATA_PROCESS_API+"/markTasks/all/0/"+this.pageSize+"?workId="+this.workId+"&examId="+this.examId+"&courseCode="+this.courseCode)
+                .then((response) => {
+                  console.log(response)
+                  this.tableData = response.data.content
+                  this.total = response.data.totalElements
+                  this.loading = false
+              })
+            },
+            searchSetting(){
+              this.loading = true
+                this.$http.get(DATA_PROCESS_API+"/markTasks/all/"+(this.currentPage - 1)+"/"+this.pageSize+"?workId="+this.workId+"&examId="+this.examId+"&courseCode="+this.courseCode,{params:this.formSearch})
+                        .then((response) => {
+                            console.log(response)
+                            this.tableData = response.data.content
+                            this.total = response.data.totalElements
+                            this.loading = false
+                        })
+            },
+            exportMarker(){
+                window.location.href="/api/ecs_data_process/markTasks/exportMarker?workId="+this.workId+"&examId="+this.examId+"&courseCode="+this.courseCode;
+            },
+            back() {
+                this.$router.push({
+                    path: '/index/mark_work_overview/'+this.workId+"/"+this.examId+"/"+this.examName
+                })
+            }
+
+        },
+        computed:{
+            ...mapState({ user: state => state.user })
+        },
+        created(){
+          this.workId = this.$route.params.workId
+          this.examId = this.$route.params.examId
+          this.examName = this.$route.params.name
+          this.courseCode = this.$route.params.courseCode
+          this.initSetting();
+        }
+
+}
+
+</script>

+ 182 - 0
src/modules/marking/views/index.vue

@@ -0,0 +1,182 @@
+<template>
+  <div>
+      <el-container>
+          <el-header>
+              <a href="javascript:void(0)" class="logo">
+                  <span class="logo-mini"><b>阅</b></span>
+                  <span class="logo-lg"><b>云阅卷</b></span>
+              </a>
+              <!-- Header Navbar: style can be found in header.less -->
+              <nav class="navbar navbar-static-top">
+                  <!-- Sidebar toggle button-->
+                  <a href="javascript:void(0)" class="sidebar-toggle" data-toggle="offcanvas" role="button">
+                      <span class="sr-only">Toggle navigation</span>
+                  </a>
+                  <!-- Navbar Right Menu -->
+                  <div class="navbar-custom-menu">
+                      <ul class="nav navbar-nav">
+                          <!-- User Account: style can be found in dropdown.less -->
+                          <li class="dropdown user user-menu">
+                              <a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown">
+                                    <span class="hidden-xs">
+                                        <i class="fa fa-user"></i> {{user.displayName}}
+							        </span>
+                              </a>
+                          </li>
+
+                          <li class="user user-menu">
+                              <a href="javascript:void(0)" click="backIndex">
+                                  <i class="fa fa-home"></i> <span>主页面</span>
+                              </a>
+                          </li>
+
+                          <li class="user user-menu">
+                              <a href="javascript:void(0)" click="logout">
+                                  <i class="fa fa-sign-out"></i> <span>退出</span>
+                              </a>
+                          </li>
+                      </ul>
+                  </div>
+
+              </nav>
+          </el-header>
+          <el-container>
+              <el-aside width="200px">
+                  <ul class="sidebar-menu">
+                      <li class="header"></li>
+                      <li class="treeview active">
+                          <a href="javascript:void(0)">
+                              <i class="fa fa-database"></i>
+                              <span>云阅卷</span> <span class="pull-right-container">
+                                    <i class="fa fa-angle-left pull-right"></i>
+                              </span>
+                          </a>
+
+                          <ul class="treeview-menu">
+                              <li v-for="menu1 in menuList" v-if="menu1.parentId == null && menu1.ext1 == 'menu'" :key="menu1">
+                                  <a href="#" v-if="menu1.ext2 == null">
+                                      <i v-bind:class="menu1.ext3"></i>{{menu1.name}}
+                                      <span class="pull-right-container">
+                                            <i class="fa fa-angle-left pull-right"></i>
+                                        </span>
+                                  </a>
+                                  <router-link v-else :to="{path:menu1.ext2}"><i v-bind:class="menu1.ext3"></i>{{menu1.name}}
+                                  </router-link>
+                                  <ul class="treeview-menu">
+                                      <li v-for="menu2 in menuList"  v-if="menu2.parentId==menu1.id && menu2.ext1 == 'menu'" :key="menu2">
+                                          <router-link :to="{path:menu2.ext2}">
+                                              <i v-bind:class="menu2.ext3"></i>{{menu2.name}}
+                                          </router-link>
+                                      </li>
+                                  </ul>
+                              </li>
+                          </ul>
+
+                      </li>
+                  </ul>
+              </el-aside>
+              <el-container>
+                  <el-main>
+                      <div class="content-wrapper">
+                          <!-- Content Header (Page header) -->
+                          <section class="content">
+                              <div class="row">
+                                  <router-view></router-view>
+                              </div>
+                          </section>
+                          <!-- Main content -->
+                      </div>
+                  </el-main>
+              </el-container>
+          </el-container>
+      </el-container>
+  </div>
+</template>
+<style>
+  span.logo-lg {
+    font-family: "Micrsoft YaHei";
+    font-size: 30px;
+  }
+</style>
+<script>
+  import {mapActions} from 'vuex'
+  import {mapState} from 'vuex'
+  import {CORE_API} from '../constants/constants'
+  import {USER_SIGNOUT} from "../../portal/store/user"
+
+  export default {
+    data() {
+      return {
+        menuList: [],
+      }
+    },
+    components: {},
+    computed: {
+      ...mapState({user: state => state.user}),
+    },
+    methods: {
+      ...mapActions([USER_SIGNOUT]),
+      logout() {
+        var loginUrl = sessionStorage.getItem("loginUrl");
+        this.$http.post(CORE_API + "/auth/logout"
+        ).then((response) => {
+          this.USER_SIGNOUT();
+          sessionStorage.clear();
+          if (loginUrl) {
+            window.location.href = loginUrl;
+          } else {
+            window.location.href = "about:blank";
+          }
+        }).catch((response) => {
+          this.USER_SIGNOUT();
+          sessionStorage.clear();
+          if (loginUrl) {
+            window.location.href = loginUrl;
+          } else {
+            window.location.href = "about:blank";
+          }
+        });
+      },
+      backIndex() {
+        var indexUrl = sessionStorage.getItem("indexUrl");
+        if (indexUrl) {
+          window.location.href = indexUrl;
+        } else {
+          window.location.href = "about:blank";
+        }
+      },
+        getUserPrivileges(){
+            var self = this;
+            var url = CORE_API + "/rolePrivilege/getUserPrivileges";
+            let config = {
+                url:url,
+                method:'post',
+                params:{
+                    groupCode: "MARK_WORK_MENUS", full: false
+                },
+                headers: {
+                    'Content-Type': 'application/x-www-form-urlencoded'
+                }
+            };
+            this.$http.post(config).then((response) => {
+                self.menuList = response.data;
+                for(let menu in self.menuList){
+                    let menuItem = self.menuList[menu];
+                    if(menuItem.ext1 == 'button'){
+                        sessionStorage.setItem(menuItem.code,true);
+                    }
+                }
+            }).catch((thrown) => {
+                self.$notify({
+                    showClose: true,
+                    message: thrown.message,
+                    type: 'error'
+                });
+            });
+        }
+    },
+    created() {
+        this.getUserPrivileges();
+    }
+  }
+</script>

+ 21 - 0
src/modules/marking/views/logout.vue

@@ -0,0 +1,21 @@
+<style scoped>
+</style>
+<template>
+    <div>
+        <a href="javascript:void(0)" @click="submit">退出</a>
+    </div>
+</template>
+<script>
+    import { mapActions } from 'vuex'
+    import { USER_SIGNOUT } from '../../portal/store/user'
+    export default {
+        methods: {
+            ...mapActions([USER_SIGNOUT]),
+            submit:function() {
+                this.USER_SIGNOUT()
+                this.$router.replace({ path: '/login' })
+                window.location.reload()
+            }
+        }
+    }
+</script>

+ 292 - 0
src/modules/marking/views/mark_grade_main.vue

@@ -0,0 +1,292 @@
+<style lang="css">
+
+li {
+    list-style-type: none;
+}
+
+.searchFrame {
+    margin-right: 10px;
+    margin-bottom: 10px;
+}
+
+.page{
+  margin-top: 10px;
+}
+
+.el-select{
+  width: 165px;
+}
+
+</style>
+
+<template>
+
+<div>
+    <section class="content">
+        <div class="box box-info">
+            <div class="box-header with-border">
+                <h3 class="box-title">成绩查询</h3>
+                <div class="box-tools pull-right">
+
+                </div>
+            </div>
+            <div class="box-body">
+                <el-form :inline="true" :model="formSearch" label-position="right" label-width="90px">
+                  <el-row :gutter="10">
+                    <el-col :xs="7" :sm="7" :md="7" :lg="7">
+                    </el-col>
+                    <el-col :xs="7" :sm="7" :md="7" :lg="7">
+                      <el-form-item label="姓名" class="pull-left">
+                          <el-input placeholder="姓名" v-model="formSearch.studentName"></el-input>
+                      </el-form-item>
+                    </el-col>
+                    <el-col :xs="7" :sm="7" :md="7" :lg="7">
+                      <el-form-item label="学号" class="pull-left">
+                          <el-input placeholder="学号" v-model="formSearch.studentCode"></el-input>
+                      </el-form-item>
+                    </el-col>
+                    <el-col :xs="7" :sm="7" :md="7" :lg="7">
+                      <el-form-item label="课程" class="pull-left" style="">
+                          <el-select :remote-method="getCourses"
+                                     remote :loading="getCoursesSearchLoading" filterable class="input" v-model="formSearch.courseCode" placeholder="请选择">
+                              <el-option value="">请选择</el-option>
+                              <el-option
+                                      v-for="item in courseAllListSelect"
+                                      :label="item.courseInfo"
+                                      :value="item.code"
+                                      :key="item.code">
+                              </el-option>
+                          </el-select>
+                      </el-form-item>
+                    </el-col>
+                  </el-row>
+
+                  <el-row :gutter="10">
+                    <el-col :xs="7" :sm="7" :md="7" :lg="7">
+                      <el-form-item label="层次" class="pull-left">
+                          <el-select class="input" v-model="formSearch.specialtyLevel" placeholder="层次">
+                              <el-option value="">请选择</el-option>
+                              <el-option v-for="item in specialtyLevels" :label="item.label" :value="item.value" :key="item.value">
+                              </el-option>
+                          </el-select>
+                      </el-form-item>
+                    </el-col>
+                    <el-col :xs="7" :sm="7" :md="7" :lg="7">
+                      <el-form-item label="学习中心" class="pull-left">
+                          <el-select :remote-method="getOrgs"
+                                     remote :loading="getOrgsSearchLoading" filterable class="input" v-model="formSearch.campusId" placeholder="请选择">
+                              <el-option value="">请选择</el-option>
+                              <el-option
+                                      v-for="item in orgList"
+                                      :id = "item.id"
+                                      :label="item.name"
+                                      :value="item.id"
+                                      :key="item.id">
+                              </el-option>
+                          </el-select>
+                      </el-form-item>
+                    </el-col>
+                      <el-col :xs="7" :sm="7" :md="7" :lg="7">
+                          <el-form-item label="采集人" class="pull-left">
+                              <el-input placeholder="采集人" v-model="formSearch.info_collector"></el-input>
+                          </el-form-item>
+                      </el-col>
+                  </el-row>
+
+                  <el-form-item class="pull-right">
+                    <span>
+                      <el-button size="small" type="primary" icon="search" @click="searchMarkGrade">查询</el-button>
+                      <el-button size="small" type="success" icon="caret-left"  @click="back">返回</el-button>
+                    </span>
+                  </el-form-item>
+                </el-form>
+                <el-table v-loading="loading" element-loading-text="拼命加载中" :data="tableData" border style="width: 100%">
+                    <el-table-column  label="姓名" width="100" prop="studentName"/>
+                    <el-table-column  label="学号" width="100" prop="studentCode"/>
+                    <el-table-column  label="课程" width="200" prop="courseName"/>
+                    <el-table-column  label="层次" width="80" prop="specialtyLevel"/>
+                    <el-table-column  label="专业" width="200" prop="specialtyName"/>
+                    <el-table-column  label="年级" width="80" prop="grade"/>
+                    <el-table-column  label="采集人" width="80" prop="infoCollector"/>
+                    <el-table-column  label="客观总分" width="100" prop="objectiveScore"/>
+                    <el-table-column  label="主观总分" width="100" prop="subjectiveScore"/>
+                    <el-table-column  label="试卷总分" width="100" prop="totalScore"/>
+                    <el-table-column  label="备注" width="120">
+                        <template slot-scope="scope">
+                            <el-popover trigger="hover" name="text" placement="top">
+                                <div style="width:200px;">{{updateRemarkValue(scope.row.studentpaperPk) }}</div>
+                                <div slot="reference">
+                                    <span>{{ interceptStr(updateRemarkValue(scope.row.studentpaperPk)) }}</span>
+                                </div>
+                            </el-popover>
+                        </template>
+                    </el-table-column>
+                </el-table>
+                <div class="page pull-right">
+                    <el-pagination background @current-change="handleCurrentChange"
+                    :current-page="currentPage"
+                    :page-size="pageSize"
+                    layout="total, prev, pager, next, jumper"
+                    :total="total">
+                    </el-pagination>
+                </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import { CORE_API,EXAM_WORK_API,MARKING_API,DATA_PROCESS_API,OE_API,LEVEL_TYPE } from '../constants/constants'
+export default {
+    data() {
+        return {
+            formSearch: {
+              batchId:'',
+              examRecordId: '',
+              studentName:'',
+              studentCode:'',
+              courseCode:'',
+              specialtyLevel:'',
+                specialtyCode:'',
+                remark:'',
+                studentPaperPk:'',
+              campusId:''
+            },
+            specialtyLevels:LEVEL_TYPE,
+            tableData: [],
+            courseList:[],
+            orgList:[],
+            examList:[],
+            specialtyList:[],
+            remarkList:[],
+            currentPage: 1,
+            pageSize:10,
+            total:0,
+            loading:false,
+            getOrgsSearchLoading:false,
+            getCoursesSearchLoading:false
+          }
+        },
+        computed:{
+            ...mapState({ user: state => state.user }),
+            courseAllListSelect(){
+                let courseSelect = [];
+                for(let course of this.courseList){
+                    let courseInfo = course.name+"("+course.code+")";
+                    courseSelect.push({code:course.code,courseInfo:courseInfo});
+                }
+                return courseSelect;
+            },
+            getRemarkList(){
+                let remarks = [];
+                for(let item of this.remarkList){
+                    remarks.push({id:item.studentPaper.studentId,value:item.remark});
+                }
+                return remarks;
+            }
+
+        },
+        methods: {
+          //查询所有课程
+          getCourses(name) {
+            this.getCoursesSearchLoading=true;
+            this.$http.get(CORE_API+"/course/query?name="+name)
+              .then((response) => {
+                this.getCoursesSearchLoading = false;
+                this.courseList = response.data;
+            });
+          },
+          getOrgs(name){
+            this.getOrgsSearchLoading = true;
+            this.$http.get(CORE_API+"/org/query?name="+name)
+              .then((response) => {
+                this.getOrgsSearchLoading = false;
+                this.orgList = response.data;
+            });
+          },
+          getCourseName(code){
+            for(let course of this.courseList){
+              if(course.code == code){
+                return course.name;
+              }
+            }
+          },
+          getOrgName(id){
+            for(let org of this.orgList){
+              if(org.id == id){
+                return org.name;
+              }
+            }
+          },
+            updateRemarkValue(studentpaperPk){
+              let rList = this.getRemarkList;
+                if(rList != []){
+                    for(let item of rList){
+                        if(item.id == studentpaperPk){
+                            return item.value;
+                            break;
+                        }
+                    }
+                }
+            },
+            //字符串截取
+            interceptStr(str){
+              if(str){
+                  let l = str.length;
+                  if(l>5){
+                      return  str.substring(0,5)+'...';
+                  }else{
+                      return str;
+                  }
+              }
+            },
+          searchMarkGrade(){
+              //查询从考务提供接口
+              this.loading = true;
+              var url = DATA_PROCESS_API + "/markGrade/all/" + (this.currentPage - 1) + "/" + this.pageSize;
+              this.$http.get(url,{params:this.formSearch}).then((response)=>{
+                  console.log("查询的列表集合",response);
+                  this.tableData = response.data.list;
+                  this.total = response.data.total;
+                  this.loading = false;
+              }).catch(function (response) {
+                  if (response.status == 500) {
+                      this.$notify({
+                          showClose: true,
+                          message: response.data.desc,
+                          type: 'error'
+                      });
+                  }
+                  this.loading = false;
+              })
+          },
+          levelFormatter(specialtyLevel){
+            var level = ''
+            for(let tempLevel of this.specialtyLevels){
+              if(tempLevel.value == specialtyLevel){
+                level = tempLevel.label
+              }
+            }
+            return level
+          },
+          handleCurrentChange(val){
+            this.currentPage = val
+            this.searchMarkGrade()
+          },
+          back() {
+            this.$router.push({
+              path: '/index/mark_setting_work/grade'
+            })
+          }
+        },
+        created(){
+          this.formSearch.batchId = parseInt(this.$route.params.examId);
+          this.formSearch.rootOrgId = this.user.rootOrgId;
+            this.searchMarkGrade();
+        }
+}
+
+</script>

+ 308 - 0
src/modules/marking/views/mark_paper_check.vue

@@ -0,0 +1,308 @@
+<style lang="css">
+</style>
+
+<template>
+
+    <div>
+        <section class="content">
+            <div class="box box-info">
+                <div class="box-header with-border">
+                    <h3 class="box-title">试卷检查</h3>
+                    <div class="box-tools pull-right">
+                        <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
+                        </button>
+                    </div>
+                </div>
+                <div class="box-body">
+                    <el-form :inline="true" :model="formSearch" label-position="right" label-width="100px">
+                        <el-form-item label="学习中心" class="pull-left">
+                            <el-select :remote-method="getOrgs"
+                                       remote :loading="getOrgsSearchLoading" class="input" clearable v-model="formSearch.orgCode" placeholder="请选择" filterable>
+                                <el-option label="请选择" value=""></el-option>
+                                <el-option
+                                        v-for="item in orgList"
+                                        :label="item.name"
+                                        :value="item.code"
+                                        :key="item.code">
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="姓名" class="pull-left">
+                            <el-input placeholder="请输入姓名" v-model="formSearch.studentName"></el-input>
+                        </el-form-item>
+                        <el-form-item label="学号" class="pull-left">
+                            <el-input placeholder="请输入学号" v-model="formSearch.studentCode"></el-input>
+                        </el-form-item>
+                        <el-form-item label="标记卷" class="pull-left">
+                            <el-select clearable v-model="formSearch.tag" placeholder="请选择" filterable>
+                                <el-option label="请选择" value=""></el-option>
+                                <el-option
+                                        v-for="item in tags"
+                                        :label="item.name"
+                                        :value="item.code"
+                                        :key="item.code">
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="课程" class="pull-left">
+                            <el-select clearable @change="getUserList" filterable class="input" v-model="formSearch.courseCode" placeholder="请选择">
+                                <el-option label="请选择" value=""></el-option>
+                                <el-option
+                                        v-for="item in courseAllListSelect"
+                                        :label="item.courseInfo"
+                                        :value="item.code"
+                                        :key="item.code">
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="评委" class="pull-left">
+                            <el-select clearable class="input" filterable v-model="formSearch.userId" placeholder="请选择">
+                                <el-option label="请选择" value=""></el-option>
+                                <el-option
+                                        v-for="item in userList"
+                                        :label="item.name"
+                                        :value="item.userId"
+                                        :key="item.userId">
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item class="pull-right">
+                              <el-button size="small" type="primary" icon="search" @click="searchMarkPaperCheck">查询</el-button>
+                        </el-form-item>
+                    </el-form>
+                    <!-- 页面列表 -->
+                    <el-table v-loading="loading" element-loading-text="拼命加载中" :data="tableData" border style="width: 100%">
+                        <el-table-column  label="学习中心" width="150" prop="orgName"/>
+                        <el-table-column  label="学号" width="120" prop="studentCode"/>
+                        <el-table-column  label="姓名" width="120" prop="studentName"/>
+                        <el-table-column  label="课程代码" width="120" prop="courseCode"/>
+                        <el-table-column  label="课程" width="120" prop="courseName"/>
+                        <el-table-column  label="试卷类型" width="120" prop="paperType"/>
+                        <el-table-column  label="评卷员" width="120" prop="userName"/>
+                        <el-table-column  label="主观总分" width="120" prop="score"/>
+                        <el-table-column  label="客观总分" width="120" prop="objectiveScore"/>
+                        <el-table-column  label="卷面总分" width="120" prop="totalScore"/>
+                        <el-table-column  label="标记卷" width="120">
+                            <template slot-scope="scope">
+                                <div>
+                                    <span>{{(scope.row.tag)|tagFilter}}</span>
+                                </div>
+                            </template>
+                        </el-table-column>
+                        <el-table-column  label="评卷备注" width="120">
+                            <template slot-scope="scope">
+                                <el-popover trigger="hover" name="text" placement="top">
+                                    <div style="width:200px;">{{ scope.row.markRemark }}</div>
+                                    <div slot="reference">
+                                        <span>{{ interceptStr(scope.row.markRemark) }}</span>
+                                    </div>
+                                </el-popover>
+                            </template>
+                        </el-table-column>
+                        <el-table-column  label="原卷" width="120">
+                            <template slot-scope="scope">
+                                <div>
+                                    <el-button @click="viewPaper(scope.row)" type="success" size="mini">查看</el-button>
+                                </div>
+                            </template>
+                        </el-table-column>
+                        <el-table-column  label="操作" width="120">
+                            <template slot-scope="scope">
+                                <div>
+                                    <el-button @click="backRefresh(scope.row)" type="danger" size="mini">打回</el-button>
+                                </div>
+                            </template>
+                        </el-table-column>
+                    </el-table>
+                    <div class="page pull-right">
+                        <el-pagination background @current-change="handleCurrentChange"
+                                       :current-page="currentPage"
+                                       :page-size="pageSize"
+                                       layout="total, prev, pager, next, jumper"
+                                       :total="total">
+                        </el-pagination>
+                    </div>
+                </div>
+            </div>
+        </section>
+    </div>
+
+</template>
+
+<script>
+    import { mapState } from 'vuex'
+    import { CORE_API,EXAM_WORK_API,MARKING_API,DATA_PROCESS_API,OE_API,TAGS } from '../constants/constants'
+    export default {
+        data() {
+            return {
+                formSearch:{
+                    orgCode:'',
+                    studentName:'',
+                    studentCode:'',
+                    tag:'',
+                    courseCode:'',
+                    userId:'',
+                    workId:'',
+                    specialtyCode:'',
+                    examType:'',
+                    remark:''
+                },
+                orgList:[],
+                courseList:[],
+                specialtyList:[],
+                userList:[],
+                tableData:[],
+                currentPage: 1,
+                pageSize:10,
+                total:0,
+                workId:'',
+                examId:'',
+                paper:'',
+                tags:[],
+                loading:false,
+                examType:'',
+                getOrgsSearchLoading:false
+            }
+        },
+        computed: {
+            ...mapState({ user: state => state.user }),
+            isAdmin(){
+              if(sessionStorage.getItem("AdminButtonShow")){
+                return true;
+              }
+                return false;
+            },
+            isMarker(){
+              if(sessionStorage.getItem("MarkButtonShow")){
+                return true;
+              }
+                return false;
+            },
+            courseAllListSelect(){
+                let courseSelect = [];
+                for(let course of this.courseList){
+                    let courseInfo = course.name+"("+course.code+")";
+                    courseSelect.push({code:course.code,courseInfo:courseInfo});
+                }
+                return courseSelect;
+            }
+        },
+        methods: {
+            //查询学习中心
+            getOrgs(name){
+                this.getOrgsSearchLoading = true;
+                this.$http.get(CORE_API+"/org/query?name="+name)
+                    .then((response) => {
+                        this.getOrgsSearchLoading = false;
+                        this.orgList = response.data;
+                    });
+            },
+            //查询课程
+            getCourses() {
+                this.$http.get(MARKING_API+"/markResults/queryExamCourseList?workId=" + this.workId)
+                    .then((response) => {
+                        this.courseList = response.data;
+                    });
+            },
+            //查询评委
+            getUserList(){
+                this.formSearch.userId = '';
+                this.$http.get(DATA_PROCESS_API+"/markUsers/assign?workId="+this.workId+"&courseCode="+this.formSearch.courseCode)
+                    .then((response) => {
+                        this.userList = response.data
+                    })
+            },
+            //查询标记卷
+            getTags(){
+                this.$http.get(MARKING_API+"/markResults/tag")
+                    .then((response) => {
+                        console.log("取到的标记卷:",response);
+                        this.tags = response.data;
+                        //移除科目错误
+                        for(let i=0;i < this.tags.length;i++){
+                            if(this.tags[i].code === 'SUBJECT_ERROR'){
+                                this.tags.splice(i,1);
+                            }
+                        }
+                    })
+            },
+            //查询专业
+            getSpecialtys() {
+                var orgId = this.user.rootOrgId;
+                this.$http.get(CORE_API+"/specialty/all?orgId=" + orgId)
+                        .then((response) => {
+                    this.specialtyList = response.data;
+                });
+            },
+            //查询方法
+            searchMarkPaperCheck(){
+                var orgId = this.user.rootOrgId;
+                this.formSearch.workId = this.workId;
+                this.formSearch.examType = this.examType;
+                this.loading = true;
+                var url = DATA_PROCESS_API + "/markResults/all/" + (this.currentPage - 1) + "/" + this.pageSize;
+                this.$http.get(url,{params:this.formSearch}).then((response)=>{
+                    console.log("查询的列表集合",response);
+                    this.tableData = response.data.data;
+                    this.total = response.data.pageInfo.totalElements;
+                    this.loading = false;
+                }).catch(function (response) {
+                    console.log(response);
+                })
+            },
+            //导出
+            exp(){
+
+            },
+            handleCurrentChange(val){
+                this.currentPage = val;
+                this.searchMarkPaperCheck();
+            },
+            //查看原卷
+            viewPaper(row){
+                if(this.examType!='OFFLINE'){
+                    var studentPaperId = row.studentPaper.id;
+                    console.log('studentPaperId:',studentPaperId);
+                    var urls = '/index/view_paper/'+this.workId +"/"+this.examId + "/" + studentPaperId+"/"+this.examType;
+                    this.$router.push({
+                        path:urls
+                    })
+                }else{
+                    var url= row.studentSubjectiveHtml;
+                    window.open(url);
+                }
+            },
+            //打回
+            backRefresh(row){
+                var userId = this.user.userId;
+                var url = MARKING_API + "/markResults/" + row.id + "/reject?creatorId=" + userId;
+                this.$http.post(url).then((response)=>{
+                    console.log(response);
+                    this.searchMarkPaperCheck();
+                })
+            },
+            //字符串截取
+            interceptStr(str){
+                if(str){
+                    let l = str.length;
+                    if(l>3){
+                        return  str.substring(0,3)+'...';
+                    }else{
+                        return str;
+                    }
+                }
+            }
+        },
+        created(){
+            this.workId = this.$route.params.workId
+            this.examId = this.$route.params.examId
+            this.examType = this.$route.params.examType
+            //查询标记卷
+            this.getTags();
+            this.getCourses();
+            //查询列表
+            this.searchMarkPaperCheck();
+        }
+    }
+
+</script>

+ 117 - 0
src/modules/marking/views/mark_setting_adv.vue

@@ -0,0 +1,117 @@
+<style lang="css">
+
+li {
+    list-style-type: none;
+}
+
+.searchFrame {
+    margin-right: 10px;
+    margin-bottom: 10px;
+}
+
+.page{
+  margin-top: 10px;
+}
+
+</style>
+
+<template>
+
+<div>
+    <section class="content">
+        <div class="box box-info">
+            <div class="box-header with-border">
+                <h3 class="box-title">评卷任务设置</h3>
+                <div class="box-tools pull-right">
+
+                </div>
+            </div>
+            <div class="box-body">
+                <el-form :inline="true" label-position="right" label-width="70px">
+                    <el-form-item class="pull-right">
+                        <el-button size="small" type="primary" icon="plus" @click="handleAdd">新增</el-button>
+                        <el-button size="small" type="success" icon="caret-left" @click="back">返回</el-button>
+                    </el-form-item>
+                </el-form>
+                <el-table :data="tableData" border style="width: 100%">
+                    <el-table-column  label="任务名称" min-width="250">
+                        <div>
+                            <span>{{row.taskName}}</span>
+                        </div>
+                    </el-table-column>
+                    <el-table-column  label="大题满分" min-width="200">
+                        <div>
+                            <span>{{row.fullScore}}</span>
+                        </div>
+                    </el-table-column>
+                    <el-table-column  label="状态" min-width="200">
+                        <div>
+                            <span>{{row.status}}</span>
+                        </div>
+                    </el-table-column>
+                    <el-table-column :context="_self"  label="操作">
+                        <div>
+                            <el-button size="small" type="danger" @click="handleDelete($index, row)">
+                                删除
+                            </el-button>
+                        </div>
+                    </el-table-column>
+                </el-table>
+                <div class="page pull-right">
+                    <el-pagination background @current-change="handleCurrentChange"
+                    :current-page="currentPage"
+                    :page-size="10"
+                    layout="total, prev, pager, next, jumper"
+                    :total="total">
+                    </el-pagination>
+                </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+</template>
+
+<script>
+
+export default {
+    data() {
+            return {
+                formSearch: {
+
+                },
+                tableData: [{
+                    taskName: '大学英语1-2',
+                    fullScore: '20',
+                    status:'启用'
+                }, {
+                  taskName: '大学英语3-4',
+                  fullScore: '40',
+                  status:'启用'
+                }],
+                currentPage: 1,
+                total:10
+            }
+        },
+        methods: {
+            handleAdd() {
+              this.$router.push({
+                path: '/index/mark_setting_detail'
+              })
+            },
+            handleDelete(index, row) {
+
+            },
+            back() {
+              this.$router.push({
+                path: '/index/mark_setting_main'
+              })
+            },
+            handleCurrentChange(val){
+              this.currentPage = val;
+              console.log(`当前页: ${val}`);
+            }
+        }
+}
+
+</script>

+ 335 - 0
src/modules/marking/views/mark_setting_detail.vue

@@ -0,0 +1,335 @@
+<style lang="css">
+
+li {
+    list-style-type: none;
+}
+
+.searchFrame {
+    margin-right: 10px;
+    margin-bottom: 10px;
+}
+
+.page{
+  margin-top: 10px;
+}
+
+.row{
+  margin-top: 10px;
+  margin-bottom: 10px;
+}
+
+</style>
+
+<template>
+
+<div>
+    <section class="content">
+        <div class="box box-info">
+            <div class="box-header with-border">
+                <h3 class="box-title">评卷设置明细</h3>
+                <div class="box-tools pull-right">
+
+                </div>
+            </div>
+            <div class="box-body">
+                <el-form :model="formTask" :rule="rules" ref="formTask" label-position="right" label-width="70px">
+                    <el-row :gutter="10">
+                      <el-col>
+                        <el-form-item class="pull-right">
+                            <el-button type="primary" icon="circle-check" @click="handleSave">保存</el-button>
+                            <el-button type="success" icon="caret-left" @click="back">返回</el-button>
+                        </el-form-item>
+                      </el-col>
+                    </el-row>
+                    <el-row :gutter="10">
+                      <el-col :xs="8" :sm="8" :md="8" :lg="8">
+                        <el-form-item label="名称" prop="taskName">
+                            <el-input placeholder="名称" v-model="formTask.taskName"></el-input>
+                        </el-form-item>
+                      </el-col>
+                    </el-row>
+
+                    <el-row :gutter="10">
+                      <el-col :xs="8" :sm="8" :md="8" :lg="8">
+                        <el-form-item  label="满分" prop="fullScore">
+                            <el-input placeholder="满分" v-model="formTask.fullScore"></el-input>
+                        </el-form-item>
+                      </el-col>
+                      <el-col :xs="8" :sm="8" :md="8" :lg="8">
+                        <el-form-item  label="多评次数" prop="mutipleMark">
+                            <el-select @change="" v-model="formTask.mutipleMark" placeholder="多评次数">
+                                <el-option v-for="item in mutipleMarkSelect" :label="item.label" :value="item.value":key="item.value">
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                      </el-col>
+                    </el-row>
+
+                    <el-row :gutter="10">
+                      <el-col :xs="8" :sm="8" :md="8" :lg="8">
+                        <el-form-item  label="误差值" prop="zoneError">
+                            <el-input placeholder="误差值" v-model="formTask.zoneError"></el-input>
+                        </el-form-item>
+                      </el-col>
+                      <el-col :xs="8" :sm="8" :md="8" :lg="8">
+                        <el-form-item  label="仲裁" prop="abitrate">
+                        <el-select @change="" v-model="formTask.abitrate" placeholder="仲裁">
+                            <el-option v-for="item in abitrateSelect" :label="item.label" :value="item.value":key="item.value">
+                            </el-option>
+                        </el-select>
+                      </el-form-item>
+                      </el-col>
+                    </el-row>
+
+                    <el-row :gutter="10">
+                      <el-col :xs="8" :sm="8" :md="8" :lg="8">
+                        <el-form-item  label="计分方法" prop="scoring">
+                          <el-select @change="" v-model="formTask.scoring" placeholder="计分方法">
+                            <el-option v-for="item in scoringSelect" :label="item.label" :value="item.value":key="item.value">
+                            </el-option>
+                          </el-select>
+                        </el-form-item>
+                      </el-col>
+                    </el-row>
+
+                    <el-row :gutter="10">
+                      <el-col :xs="15" :sm="15" :md="15" :lg="15">
+                        <el-form-item  label="试题范围" prop="range">
+                          <el-select multiple @change="" v-model="formTask.range" placeholder="试题范围">
+                            <el-option v-for="item in rangeSelect" :label="item.label" :value="item.value":key="item.value">
+                            </el-option>
+                          </el-select>
+                        </el-form-item>
+                      </el-col>
+                    </el-row>
+
+                    <el-row :gutter="10">
+                      <el-col :xs="15" :sm="15" :md="15" :lg="15">
+                        <el-form-item  label="给分步骤" prop="itemData">
+                          <el-button type="primary" icon="plus" @click="handleItemAdd">新增</el-button>
+                        </el-form-item>
+                        <el-table :data="formTask.itemData" border style="width: 100%">
+                            <el-table-column  label="名称" min-width="200">
+                                <div>
+                                    <span>{{row.itemName}}</span>
+                                </div>
+                            </el-table-column>
+                            <el-table-column  label="满分" min-width="100">
+                                <div>
+                                    <span>{{row.fullScore}}</span>
+                                </div>
+                            </el-table-column>
+                            <el-table-column  label="间隔分" min-width="100">
+                                <div>
+                                    <span>{{row.interval}}</span>
+                                </div>
+                            </el-table-column>
+                            <el-table-column :context="_self"  label="操作">
+                                <div>
+                                    <el-button size="small" type="danger" @click="handleItemDelete($index, row)">
+                                        删除
+                                    </el-button>
+                                </div>
+                            </el-table-column>
+                        </el-table>
+                      </el-col>
+                    </el-row>
+
+                    <div class="row"></div>
+
+                    <el-row :gutter="10">
+                      <el-col :xs="15" :sm="15" :md="15" :lg="15">
+                        <el-form-item  label="评卷员" prop="markerData">
+                          <el-button type="primary" icon="plus" @click="handleMarkerAdd">新增</el-button>
+                        </el-form-item>
+                        <el-table :data="formTask.markerData" border style="width: 100%">
+                            <el-table-column  label="姓名" min-width="100">
+                                <div>
+                                    <span>{{row.userName}}</span>
+                                </div>
+                            </el-table-column>
+                            <el-table-column  label="登录名" min-width="100">
+                                <div>
+                                    <span>{{row.loginName}}</span>
+                                </div>
+                            </el-table-column>
+                            <el-table-column  label="角色" min-width="100">
+                                <div>
+                                    <span>{{row.role}}</span>
+                                </div>
+                            </el-table-column>
+                            <el-table-column :context="_self"  label="操作">
+                                <div>
+                                    <el-button size="small" type="danger" @click="handleMarkerDelete($index, row)">
+                                        删除
+                                    </el-button>
+                                </div>
+                            </el-table-column>
+                        </el-table>
+                      </el-col>
+                    </el-row>
+
+                </el-form>
+            </div>
+        </div>
+    </section>
+</div>
+
+</template>
+
+<script>
+
+export default {
+    data() {
+            return {
+                mutipleMarkSelect:[
+                  {
+                    value: '2',
+                    label: '2评'
+                  },
+                  {
+                    value: '3',
+                    label: '3评'
+                  },
+                  {
+                    value: '4',
+                    label: '4评'
+                  },
+                  {
+                    value: '5',
+                    label: '5评'
+                  }
+                ],
+                abitrateSelect:[
+                  {
+                    value: 'abitrate_back',
+                    label: '评委重评'
+                  },
+                  {
+                    value: 'leader_score',
+                    label: '科组长打分'
+                  }
+                ],
+                scoringSelect:[
+                  {
+                    value: 'direct_avg',
+                    label: '直接均分法'
+                  },
+                  {
+                    value: 'remove_hl_avg',
+                    label: '去高低均分法'
+                  }
+                ],
+                rangeSelect:[
+                  {
+                    value: '1-1',
+                    label: '一(1)'
+                  },
+                  {
+                    value: '1-2',
+                    label: '一(2)'
+                  },
+                  {
+                    value: '1-3',
+                    label: '一(3)'
+                  },
+                  {
+                    value: '1-4',
+                    label: '一(4)'
+                  },
+                  {
+                    value: '2-1',
+                    label: '二(1)'
+                  },
+                  {
+                    value: '2-2',
+                    label: '二(2)'
+                  },
+                  {
+                    value: '3-1',
+                    label: '三(1)'
+                  },
+                  {
+                    value: '3-2',
+                    label: '三(2)'
+                  }
+                ],
+                formTask: {
+                  taskName:'',
+                  fullScore:'',
+                  mutipleMark:'',
+                  zoneError:'',
+                  abitrate:'',
+                  scoring:'',
+                  range:'',
+                  itemData:[
+                    {itemName:'一(1)',fullScore:'3',interval:'1'},
+                    {itemName:'一(2)',fullScore:'4',interval:'1'}
+                  ],
+                  markerData:[
+
+                  ]
+                },
+                rules:{
+                  taskName:[
+                    { required: true, message: '请输入名称', trigger: 'blur' }
+                  ],
+                  fullScore:[
+                    { required: true, message: '请输入满分', trigger: 'blur' }
+                  ],
+                  mutipleMark:[
+                    { required: true, message: '请输入多评次数', trigger: 'blur' }
+                  ],
+                  zoneError:[
+                    { required: true, message: '请输入误差值', trigger: 'blur' }
+                  ],
+                  abitrate:[
+                    { required: true, message: '请输入仲裁', trigger: 'blur' }
+                  ],
+                  scoring:[
+                    { required: true, message: '请输入计分方法', trigger: 'blur' }
+                  ],
+                  range:[
+                    { required: true, message: '请输入试题范围', trigger: 'blur' }
+                  ],
+                  itemData:[
+                    { required: true, message: '请输入给分步骤', trigger: 'blur' }
+                  ],
+                  markerData:[
+                    { required: true, message: '请输入评卷员', trigger: 'blur' }
+                  ]
+                },
+                markType:''
+            }
+        },
+        methods: {
+            handleSave() {
+
+            },
+            handleChange() {
+
+            },
+            handleItemAdd(){
+
+            },
+            handleMarkerAdd(){
+
+            },
+            handleItemDelete(index,row){
+
+            },
+            handleMarkerDelete(index,row){
+              
+            },
+            back() {
+              this.$router.push({
+                path: '/index/mark_setting_adv'
+              })
+            }
+        },
+        created(){
+
+        }
+}
+
+</script>

+ 301 - 0
src/modules/marking/views/mark_setting_fast.vue

@@ -0,0 +1,301 @@
+<style lang="css">
+
+li {
+    list-style-type: none;
+}
+
+.searchFrame {
+    margin-right: 10px;
+    margin-bottom: 10px;
+}
+
+.page{
+  margin-top: 10px;
+}
+
+.el-tag{
+  margin-right: 10px;
+}
+
+</style>
+
+<template>
+
+<div>
+    <section class="content">
+        <div class="box box-info">
+            <div class="box-header with-border">
+                <h3 class="box-title">
+                  <span>评卷快速设置</span>
+                  <span>({{$route.params.name}}-{{$route.params.courseCode}}-{{$route.params.courseName}})</span>
+                </h3>
+                <div class="box-tools pull-right">
+
+                </div>
+            </div>
+            <div class="box-body">
+                  <div class="scroll">
+                    <el-form :inline="true" :model="markerSearch" label-position="right" label-width="50px">
+                      <el-row :gutter="10" v-if="selectedMarker.length!=0">
+                        <el-col :xs="30" :sm="30" :md="30" :lg="30">
+                          <el-form-item label="已选">
+                            <el-tag
+                                v-for="tag in selectedMarker"
+                                :closable="tagClosable"
+                                :close-transition="false"
+                                @close="tagClose(tag)"
+                                :type="tagType"
+                                :key="tag.userId"
+                            >
+                            {{tag.name}}
+                          </el-tag>
+                          </el-form-item>
+                        </el-col>
+                      </el-row>
+                        <el-form-item label="姓名" class="pull-left">
+                            <el-input placeholder="姓名" v-model="markerSearch.name" @change="searchMarker"></el-input>
+                        </el-form-item>
+                        <el-form-item class="pull-right">
+                            <el-button size="small"  type="primary" icon="search" @click="searchMarker">查询</el-button>
+                            <el-button size="small"  type="primary" icon="check"  @click="markerSelect">确定</el-button>
+                            <el-button size="small"  type="primary" icon="caret-left"  @click="back">返回</el-button>
+                        </el-form-item>
+                    </el-form>
+                    <el-table v-loading="loading" element-loading-text="拼命加载中" :data="markerData" border style="width: 100%" @selection-change="selectChange">
+                        <el-table-column type="selection" width="55"></el-table-column>
+                        <el-table-column  label="姓名" width="250" prop="name">
+                        </el-table-column>
+                        <el-table-column  label="登录名" width="250" prop="loginName">
+                        </el-table-column>
+                    </el-table>
+                    <div class="page pull-right">
+                        <el-pagination background @current-change="handleMarkerCurrentChange"
+                        :current-page="curMarker"
+                        :page-size="10"
+                        layout="total, prev, pager, next, jumper"
+                        :total="totalMarker">
+                        </el-pagination>
+                    </div>
+                  </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+</template>
+
+<script>
+import { CORE_API,EXAM_WORK_API,MARKING_API,DATA_PROCESS_API,OE_API } from '../constants/constants'
+import { mapState } from 'vuex'
+export default {
+    data() {
+            return {
+                markerSearch: {
+                  name: ''
+                },
+                markerData: [],
+                oldData:[],
+                selectedMarker:[],
+                oldSelectedMarker:[],
+                curMarker: 1,
+                totalMarker:10,
+                pageSize:10,
+                loading:true,
+                workId:'',
+                examId:'',
+                examName:'',
+                courseCode:'',
+                markTasks:{
+                  workId:'',
+                  userId:[],
+                  paperId:''
+                },
+                paperId:'',
+                tagType:'primary',
+                tagClosable:true,
+                marked:false,
+                progress:0
+            }
+        },
+        methods: {
+            selectChange(val){
+              var selectedMarker = this.selectedMarker
+              val.forEach((element,index)=>{
+                selectedMarker.push(element)
+                this.removeMarkerData(element.userId)
+              })
+              this.selectedMarker = selectedMarker
+            },
+            markerSelect(){
+              if(this.selectedIds.length == 0){
+                this.$message.error('请选择评卷员!');
+              }else{
+                console.log(this.selectedIds)
+                this.markTasks = {
+                  workId:this.workId,
+                  userIds:this.selectedIds,
+                  examId:this.examId,
+                  courseCode:this.courseCode
+                }
+                this.loading = true
+                this.$http.post(DATA_PROCESS_API+"/markTasks",this.markTasks)
+                  .then((response) => {
+                    this.$notify({
+                      message: '快速设置成功',
+                      type: 'success'
+                    })
+                    this.loading = false
+                    this.initMarker()
+                    this.searchSelectedMarker()
+                },(response) => {
+                  this.$notify({
+                    message: '快速设置失败',
+                    type: 'error'
+                  })
+                  this.loading = false
+                  this.initMarker()
+                  this.searchSelectedMarker()
+              })
+              }
+            },
+            filterMarker(){
+              var tempData = this.markerData.filter((element)=>{
+                if(this.markerSearch.name){
+                  return (element.name.includes(this.markerSearch.name))
+                }else{
+                  return true
+                }
+              })
+              this.markerData = tempData
+              this.totalMarker = tempData.length
+            },
+            handleMarkerCurrentChange(val){
+              this.curMarker = val
+              this.searchMarker()
+            },
+            pagingMarker(){
+              var start = (this.curMarker - 1) * this.pageSize
+              var end = (this.curMarker)*this.pageSize < this.totalMarker ? (this.curMarker)*this.pageSize:this.totalMarker
+              var tempData = []
+              console.log(`当前页: ${this.curMarker},开始:${start},结束:${end}`)
+              for(let i = start;i < end;i++){
+                tempData.push(this.markerData[i])
+              }
+              console.log(tempData)
+              this.markerData = tempData
+            },
+            searchMarker(){
+              this.loading = true
+              this.markerData = this.oldData
+              this.filterMarker()
+              this.pagingMarker()
+              this.loading = false
+            },
+            initMarker(){
+              this.loading = true
+              this.$http.get(DATA_PROCESS_API+"/markUsers?workId="+this.workId+"&courseCode="+this.courseCode)
+                .then((response) => {
+                  this.markerData = response.data
+                  this.oldData = this.markerData.slice(0)
+                  this.totalMarker = response.data.length
+                  this.searchMarker()
+                  this.loading = false
+              })
+            },
+            checkMarked(){
+              var self = this
+              self.loading = true;
+                self.$http.get(MARKING_API+"/markWorks/"+self.workId).then((response) => {
+                    self.loading = false
+                    if(response.progress > 0){
+                        self.marked = true;
+                        self.progress = response.progress
+                    }
+                    }).catch((error) =>{
+                        this.$notify({
+                            message: error.message,
+                            type: 'error'
+                        })
+                    });
+            },
+            searchSelectedMarker(){
+              this.loading = true
+              this.$http.get(DATA_PROCESS_API+"/markUsers/assign?workId="+this.workId+"&courseCode="+this.courseCode)
+                .then((response) => {
+                  this.selectedMarker = response.data
+                  this.oldSelectedMarker = this.selectedMarker.slice(0)
+                  this.loading = false
+              })
+            },
+            back() {
+              this.$router.push({
+                path: '/index/mark_setting_main/'+this.$route.params.workId+"/"+this.$route.params.examId+"/"+this.$route.params.name
+              })
+            },
+            isOldSelectedMarker(marker){
+              var flag = false
+              for(let tempMarker of this.oldSelectedMarker){
+                if(tempMarker.userId == marker.userId){
+                  flag = true
+                  break
+                }
+              }
+              return flag
+            },
+            tagClose(tag){
+              this.checkMarked()
+              if(this.marked && this.isOldSelectedMarker(tag)){
+                this.$notify({
+                  message: '评卷工作已开始(进度为'+(this.progress)+'%),不能删除该评卷员!',
+                  type: 'error'
+                })
+                return
+              }
+              for (let [index,marker] of this.selectedMarker.entries()) {
+                if(tag.userId == marker.userId){
+                  this.selectedMarker.splice(index,1)
+                  this.markerData.push(tag)
+                  this.oldData.push(tag)
+                  break
+                }
+              }
+            },
+            removeMarkerData(userId){
+              for (let [index,marker] of this.markerData.entries()) {
+                if(userId == marker.userId){
+                  this.markerData.splice(index,1)
+                  break
+                }
+              }
+              for (let [index,marker] of this.oldData.entries()) {
+                if(userId == marker.userId){
+                  this.oldData.splice(index,1)
+                  break
+                }
+              }
+            }
+        },
+        computed:{
+          ...mapState({ user: state => state.user }),
+          selectedIds(){
+            var selectedIds = []
+            for (let marker of this.selectedMarker) {
+              selectedIds.push(marker.userId)
+            }
+            return selectedIds
+          }
+        },
+        created(){
+          this.workId = this.$route.params.workId
+          this.examId = this.$route.params.examId
+          this.examName = this.$route.params.name
+          this.courseCode = this.$route.params.courseCode
+          this.initMarker()
+          this.searchSelectedMarker()
+          //校验评卷工作是否开始,如果开始则不能删除评卷员
+          this.checkMarked()
+        }
+
+}
+
+</script>

+ 383 - 0
src/modules/marking/views/mark_setting_main.vue

@@ -0,0 +1,383 @@
+<style lang="css">
+
+li {
+    list-style-type: none;
+}
+
+.searchFrame {
+    margin-right: 10px;
+    margin-bottom: 10px;
+}
+
+.page{
+  margin-top: 10px;
+}
+.f_button{
+    display:block;
+    width:57px;
+    height:20px;
+    border:1px solid #CCC;
+    background:#FFF;
+    font-size: small;
+}
+
+</style>
+
+<template>
+
+<div>
+    <section class="content">
+        <div class="box box-info" v-loading="fileLoading" element-loading-text="导入需要较长时间,请耐心等候">
+            <div class="box-header with-border">
+                <h3 class="box-title">
+                  <span>评卷设置</span>
+                  <span>({{$route.params.name}})</span>
+                </h3>
+                <div class="box-tools pull-right">
+
+                </div>
+            </div>
+            <div class="box-body">
+                <el-form :inline="true" :model="formSearch" label-position="right" label-width="80px" >
+                <el-form-item label="课程" class="pull-left">
+                    <el-select  clearable filterable class="input" v-model="formSearch.courseCode" placeholder="请选择">
+                        <el-option value="">请选择</el-option>
+                        <el-option
+                                v-for="item in courseAllListSelect"
+                                :label="item.courseInfo"
+                                :value="item.code"
+                                :key="item.code">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                  <el-form-item class="pull-right">
+                    <el-button size="small"  type="primary" icon="search" @click="initSetting">查询</el-button>
+                    <el-button size="small"  type="primary" icon="caret-left"  @click="back">返回</el-button>
+                    <el-button size="small"  type="primary" icon="upload2" @click="imp">导入</el-button>
+                      <el-button size="small"  type="primary" icon="download" @click="exportCourse">导出</el-button>
+                  </el-form-item>
+                </el-form>
+                <!--导入弹窗-->
+                <el-dialog  title="导入窗口" size="tiny" :visible.sync="impDialog">
+                    <el-form>
+                        <el-row>
+                            <el-form-item>
+                                <el-upload
+                                        class="form_left"
+                                        ref="upload"
+                                        accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+                                        :action="uploadAction"
+                                        :headers="uploadHeaders"
+                                        :data="uploadData"
+                                        :before-upload="beforeUpload"
+                                        :on-progress="uploadProgress"
+                                        :on-success="uploadSuccess"
+                                        :on-error="uploadError"
+                                        :file-list="fileList"
+                                        :auto-upload="false"
+                                        :multiple="false">
+                                    <el-button slot="trigger" type="primary" size="small">选择文件</el-button>
+                                    <el-button size="small" style="margin-left:5px;" type="success" @click="submitUpload">确认上传
+                                    </el-button>
+                                    <el-button size="small" style="margin-left:5px;" type="danger" @click="removeFile">清空文件
+                                    </el-button>
+                                    <el-button size="small" style="margin-left:5px;" type="info" @click="exportFile">下载模板
+                                    </el-button>
+                                    <div slot="tip" class="el-upload__tip">只能上传xlsx文件</div>
+                                </el-upload>
+                            </el-form-item>
+                        </el-row>
+                    </el-form>
+                </el-dialog>
+                <!--导入错误信息列表-->
+                <el-dialog title="错误提示" :visible.sync="errDialog">
+                    <div class="text-danger" v-for="errMessage in errMessages" :key="errMessage.row">
+                        第{{errMessage.row}}行:{{errMessage.excelErrorType}}
+                    </div>
+                    <span slot="footer" class="dialog-footer">
+							             <el-button @click="errDialog = false">确定</el-button>
+						            </span>
+                </el-dialog>
+                <!--页面列表-->
+                <el-table v-loading="loading" element-loading-text="拼命加载中" :data="tableData" border style="width: 100%">
+                  <el-table-column  label="课程名称" width="200" prop="name">
+                  </el-table-column>
+                    <el-table-column  label="课程代码" min-width="100" prop="code">
+                    </el-table-column>
+                    <el-table-column  label="试卷数" min-width="100" prop="totalCount">
+                    </el-table-column>
+                    <el-table-column  label="评卷员数" min-width="100" prop="markerCount">
+                    </el-table-column>
+                    <el-table-column :context="_self"  label="操作" >
+                        <template slot-scope="scope">
+                              <div class="pull-left" v-if="scope.row.totalCount > 0">
+                                <el-button @click="fastSetting(scope.$index, scope.row)" type="success" size="mini">快速设置</el-button>
+                              </div>
+                        </template>
+                    </el-table-column>
+                </el-table>
+                <div class="page pull-right">
+                    <el-pagination background @current-change="handleSettingCurrentChange"
+                    :current-page="currentPage"
+                    :page-size="10"
+                    layout="total, prev, pager, next, jumper"
+                    :total="total">
+                    </el-pagination>
+                </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+</template>
+
+<script>
+import { CORE_API,EXAM_WORK_API,MARKING_API,DATA_PROCESS_API,OE_API } from '../constants/constants'
+import { mapState } from 'vuex'
+export default {
+    data() {
+            return {
+                formSearch: {
+                  courseCode: '',
+                  courseName: '',
+                  specialtyLevel:'',
+                  specialtyName:'',
+                  leader:''
+                },
+                courseList:[],
+                tableData: [],
+                oldData:[],
+                currentPage: 1,
+                pageSize:10,
+                total:10,
+                loading:true,
+                workId:'',
+                examId:'',
+                examName:'',
+                markTasks:{
+                  workId:'',
+                  userId:[],
+                  paperId:''
+                },
+                paperId:'',
+                impDialog:false,
+                uploadAction: DATA_PROCESS_API+'/markTasks/import',
+                uploadHeaders:{},
+                uploadData: {workId:''},
+                errMessages:[],
+                errDialog:false,
+                fileLoading: false,
+                fileList: []
+            }
+        },
+        methods: {
+            //查询课程
+            getCourses() {
+                this.$http.get(MARKING_API+"/markResults/queryExamCourseList?workId=" + this.$route.params.workId)
+                    .then((response) => {
+                        this.courseList = response.data;
+                    });
+            },
+            fastSetting(index, row) {
+              this.paperId = row.pk
+              var url = '/index/mark_setting_fast/'+this.$route.params.workId+"/"+this.$route.params.examId+"/"+this.$route.params.name+"/"+row.code+"/"+row.name
+              this.$router.push({
+                path: url
+              })
+            },
+            advanceSetting(index, row) {
+              this.paperId = row.pk
+              this.$router.push({
+                path: '/index/mark_setting_adv'
+              })
+            },
+            filterSetting(){
+              if(!this.formSearch.courseCode && !this.formSearch.courseName){
+                return;
+              }
+              var tempData = this.tableData.filter((element)=>{
+                var flag = true
+                if(this.formSearch.courseCode || this.formSearch.courseName){
+                  if(this.formSearch.courseCode){
+                    flag = flag && element.courseCode.includes(this.formSearch.courseCode)
+                  }
+                  if(this.formSearch.courseName){
+                    flag = flag && element.courseName.includes(this.formSearch.courseName)
+                  }
+                  return flag
+                }else{
+                  return true
+                }
+              })
+              this.tableData = tempData
+              this.total = tempData.length
+            },
+            handleSettingCurrentChange(val){
+              this.currentPage = val
+              this.initSetting()
+            },
+            pagingSetting(){
+              var start = (this.currentPage - 1) * this.pageSize
+              var end = (this.currentPage)*this.pageSize < this.total ? (this.currentPage)*this.pageSize:this.total
+              var tempData = []
+              console.log(`当前页: ${this.currentPage},开始:${start},结束:${end}`)
+              for(let i = start;i < end;i++){
+                tempData.push(this.tableData[i])
+              }
+              console.log(tempData)
+              this.tableData = tempData
+            },
+            handleCommand(command){
+              if(command == 'importSub'){
+                console.log('导入主观题')
+              }else if(command == 'importOb'){
+                console.log('导入客观题')
+              }else if(command == 'importMarker'){
+                console.log('导入评卷员')
+              }
+            },
+            initSetting(){
+              this.loading = true;
+              this.$http.get(MARKING_API+"/markCourses/all/"+(this.currentPage - 1) + "/" + this.pageSize + "?workId="+this.workId,{params:this.formSearch})
+                .then((response) => {
+                    console.log(response.data);
+                  this.tableData = response.data.content;
+                  this.total = response.data.totalElements;
+                  this.oldData = this.tableData.slice(0);
+                  this.loading = false;
+              })
+            },
+            searchSetting(){
+              this.loading = true
+              this.tableData = this.oldData.slice(0)
+              this.total = this.tableData.length
+              this.filterSetting()
+              this.pagingSetting()
+              this.loading = false
+            },
+            back() {
+              this.$router.push({
+                path: '/index/mark_setting_work/setting'
+              })
+            },
+            //导入
+            imp(){
+                this.impDialog = true;
+                this.initUpload();
+            },
+            initUpload(){
+                this.fileList = [];
+            },
+            beforeUpload(file){
+                console.log(file);
+            },
+            uploadProgress(event, file, fileList) {
+                console.log("uploadProgress");
+            },
+            uploadSuccess(response, file, fileList) {
+                console.log("uploadSuccess");
+                console.log(response);
+                if(!response || response.length == 0){
+                    this.$notify({
+                        message: '上传成功',
+                        type: 'success'
+                    });
+                  this.fileLoading = false;
+                  this.impDialog = false;
+                  window.location.reload();
+                }else{
+                    this.errMessages = response;
+                    this.errDialog = true;
+                  this.fileLoading = false;
+                  this.impDialog = false;
+                }
+            },
+            uploadError(err, file, fileList) {
+                var result = err.message.match(/\{.+}/);
+                var errMessage = JSON.parse(result[0]).desc;
+                this.$notify({
+                    message: errMessage,
+                    type: 'error'
+                });
+                this.fileLoading = false;
+            },
+            //确定上传
+            submitUpload(){
+                if (!this.checkUpload()) {
+                    return false;
+                }
+                this.$refs.upload.submit();
+                this.fileLoading = true;
+            },
+            checkUpload(){
+                var fileList = this.$refs.upload.uploadFiles;
+                if (fileList.length == 0) {
+                    this.$notify({
+                        message: '上传文件不能为空',
+                        type: 'error'
+                    });
+                    return false;
+                }
+                if (fileList.length > 1) {
+                    this.$notify({
+                        message: '每次只能上传一个文件',
+                        type: 'error'
+                    });
+                    return false;
+                }
+                for (let file of fileList) {
+                    if (!file.name.endsWith(".xlsx")) {
+                        this.$notify({
+                            message: '上传文件必须为xlsx格式',
+                            type: 'error'
+                        });
+                        this.initUpload();
+                        return false;
+                    }
+                }
+                return true;
+            },
+            //清空文件
+            removeFile(){
+                this.fileList = [];
+            },
+            //下载模板
+            exportFile(){
+                var key = this.user.key;
+                var token = this.user.token;
+                window.location.href="/api/ecs_data_process/markTasks/export?$key="+key+"&$token="+token;
+            },
+            //下载课程列表
+            exportCourse(){
+                var key = this.user.key;
+                var token = this.user.token;
+                window.location.href="/api/ecs_marking/markCourses/export?workId="+this.workId+"&$key="+key+"&$token="+token;
+            }
+        },
+        computed:{
+            ...mapState({ user: state => state.user }),
+            courseAllListSelect(){
+                let courseSelect = [];
+                for(let course of this.courseList){
+                    let courseInfo = course.name+"("+course.code+")";
+                    courseSelect.push({code:course.code,courseInfo:courseInfo});
+                }
+                return courseSelect;
+            }
+        },
+        created(){
+          this.workId = this.$route.params.workId;
+          this.examId = this.$route.params.examId;
+          this.examName = this.$route.params.name;
+          this.uploadData.workId = this.workId;
+          this.uploadHeaders = {
+            key:this.user.key,
+            token:this.user.token
+          };
+          this.initSetting();
+          this.getCourses();
+        }
+
+}
+
+</script>

+ 232 - 0
src/modules/marking/views/mark_setting_work.vue

@@ -0,0 +1,232 @@
+<style lang="css">
+</style>
+
+<template lang="html">
+  <div>
+      <section class="content">
+          <div class="box box-info">
+              <div class="box-header with-border">
+                  <h3 class="box-title">请选择评卷工作</h3>
+                  <div class="box-tools pull-right">
+                  </div>
+              </div>
+              <div class="box-body">
+                  <el-form :inline="true" :model="formSearch" label-position="right" label-width="110px">
+                    <el-form-item label="评卷工作名称" class="pull-left">
+                        <el-input placeholder="评卷工作名称" v-model="formSearch.name" @keyup.native="searchMarkWork"></el-input>
+                    </el-form-item>
+                    <!--<el-form-item class="pull-right">-->
+                      <!--<el-button type="primary" icon="search" @click="searchMarkWork">查询</el-button>-->
+                    <!--</el-form-item>-->
+                  </el-form>
+                  <el-table v-loading="loading" element-loading-text="拼命加载中" :data="tableData" border style="width: 100%">
+                      <el-table-column  label="评卷工作名称" width="250" prop="name">
+                      </el-table-column>
+                      <el-table-column  label="考试批次" width="250" prop="examName">
+                      </el-table-column>
+                      <el-table-column  label="考试类型" width="100">
+                          <template slot-scope="scope">
+                              <div>
+                                  <span>{{scope.row.examType|examTypeFilter}}</span>
+                              </div>
+                          </template>
+                      </el-table-column>
+                      <el-table-column  label="进度" width="100">
+                          <template slot-scope="scope">
+                              <div>
+                                  <span>{{Number.parseFloat(scope.row.progress)}}%</span>
+                              </div>
+                          </template>
+                      </el-table-column>
+                      <el-table-column  label="备注" width="100" prop="remark">
+                      </el-table-column>
+                      <el-table-column :context="_self"  label="操作">
+                          <template slot-scope="scope">
+                                <div class="pull-left">
+                                  <span v-if="isAdmin">
+                                    <span v-if="routeType=='overview'">
+                                      <el-button @click="markWorkOverview(scope.row)" type="success" size="mini">评卷进度</el-button>
+                                    </span>
+                                    <span v-if="routeType=='marker'">
+                                      <el-button @click="marker(scope.row)" type="success" size="mini">评卷员一览</el-button>
+                                    </span>
+                                    <span v-if="routeType=='setting'">
+                                      <el-button @click="settingMarkWork(scope.row)" type="success" size="mini">评卷设置</el-button>
+                                    </span>
+                                    <span v-if="routeType=='checking'">
+                                       <el-button @click="paperCheck(scope.row)" type="success" size="mini">试卷检查</el-button>
+                                    </span>
+                                    <span v-if="routeType=='grade'">
+                                      <el-button @click="viewGrade(scope.row)" type="success" size="mini">成绩查询</el-button>
+                                    </span>
+                                  </span>
+                                  <span v-if="isMarker && routeType=='marking'">
+                                    <el-button @click="marking(scope.row)" type="success" size="mini" >评阅试卷</el-button>
+                                  </span>
+                                </div>
+                          </template>
+                      </el-table-column>
+                  </el-table>
+                  <div class="page pull-right">
+                      <el-pagination background @current-change="handleCurrentChange"
+                      :current-page="currentPage"
+                      :page-size="pageSize"
+                      layout="total, prev, pager, next, jumper"
+                      :total="total">
+                      </el-pagination>
+                  </div>
+              </div>
+          </div>
+      </section>
+  </div>
+</template>
+
+<script>
+import { CORE_API,EXAM_WORK_API,MARKING_API,DATA_PROCESS_API,EXAMTYPES } from '../constants/constants'
+import { mapActions } from 'vuex'
+import { mapState } from 'vuex'
+export default {
+        data() {
+            return {
+                formSearch: {
+                  name: ''
+                },
+                tableData: [],
+                totalTableData:[],
+                currentPage: 1,
+                pageSize:10,
+                total:0,
+                markWorkId:'',
+                loading:false,
+                isMarkingView:true
+            }
+        },
+        methods: {
+          initMarkWork(){
+            this.loading = true;
+            if(this.isAdmin){
+              this.$http.get(DATA_PROCESS_API+"/markWorks")
+                  .then((response) => {
+                    this.totalTableData = response.data
+                    this.total = response.data.length
+                    this.filterMarkWork()
+                    this.paging()
+                    this.loading = false
+                  })
+            }else{
+              this.$http.get(DATA_PROCESS_API+"/markWorks?userId="+this.user.userId)
+                  .then((response) => {
+                    this.totalTableData = response.data
+                    this.total = response.data.length
+                    this.filterMarkWork()
+                    this.paging()
+                    this.loading = false
+                  })
+            }
+          },
+          searchMarkWork(){
+            this.filterMarkWork();
+            this.paging();
+          },
+          filterMarkWork(){
+            var tempData = this.totalTableData.filter((element)=>{
+              if(this.formSearch.name){
+                return (element.name.includes(this.formSearch.name))
+              }else{
+                return true
+              }
+            })
+            this.tableData = tempData
+            this.total = tempData.length
+          },
+          handleCurrentChange(val){
+            this.currentPage = val;
+            this.filterMarkWork();
+            this.paging();
+            //this.searchMarkWork()
+          },
+          paging(){
+            var start = (this.currentPage - 1) * this.pageSize
+            var end = (this.currentPage)*this.pageSize < this.total ? (this.currentPage)*this.pageSize:this.total
+            var tempData = []
+            console.log(`当前页: ${this.currentPage},开始:${start},结束:${end}`)
+            for(let i = start;i < end;i++){
+              tempData.push(this.tableData[i])
+            }
+            console.log(tempData)
+            this.tableData = tempData
+          },
+          settingMarkWork(row){
+            var url = '/index/mark_setting_main/'+row.id+"/"+row.examId+"/"+row.name
+            this.$router.push({
+              path: url
+            })
+          },
+          markWorkOverview(row){
+            var url = '/index/mark_work_overview/'+row.id+"/"+row.examId+"/"+row.name
+            this.$router.push({
+              path: url
+            })
+          },
+          marker(row){
+            var url = '/index/marker/'+row.id+"/"+row.examId+"/"+row.name
+            this.$router.push({
+              path: url
+            })
+          },
+          paperCheck(row){
+            var url = '/index/mark_paper_check/'+row.id +"/"+row.examId+'/'+row.examType;
+            this.$router.push({
+                path:url
+            })
+          },
+          viewGrade(row){
+            var url = '/index/mark_grade_main/'+row.examId
+            this.$router.push({
+              path: url
+            })
+          },
+          marking(row){
+            var userId = this.user.userId;
+            var self = this;
+            var url = '/marking/'+row.id+'/'+row.examType;
+            self.$http.get(DATA_PROCESS_API+"/markTasks?workId="+row.id+"&userId="+userId).then((response) => {
+                console.log(response);
+                if(response.data.length > 0){
+                    self.$router.push({
+                        path: url
+                    })
+                }else{
+                    self.$notify({
+                        message: '没有评卷任务',
+                        type: 'warning'
+                    })
+                }
+            })
+          }
+        },
+        computed:{
+          routeType(){
+            return this.$route.params.type
+          },
+          ...mapState({ user: state => state.user }),
+          isAdmin(){
+            if(sessionStorage.getItem("AdminButtonShow")){
+              return true;
+            }
+            return false;
+          },
+          isMarker(){
+              return true;
+            if(sessionStorage.getItem("MarkButtonShow")){
+              return true;
+            }
+            return false;
+          }
+        },
+        created(){
+            this.user.userId = 55666;
+          this.initMarkWork();
+        }
+}
+</script>

+ 457 - 0
src/modules/marking/views/mark_work.vue

@@ -0,0 +1,457 @@
+<template>
+    <div>
+                    <section class="content">
+                        <div>
+                            <div>
+                                <h3>评卷工作</h3>
+                                <div>
+                                </div>
+                            </div>
+                            <div>
+                                <el-form :inline="true" :model="formSearch" label-position="right" label-width="110px">
+                                    <el-form-item label="评卷工作名称">
+                                        <el-input placeholder="评卷工作名称" v-model="formSearch.name" @keyup.native="searchMarkWork"></el-input>
+                                    </el-form-item>
+                                    <el-form-item>
+                                                <span v-if="isAdmin">
+                                                  <el-button size="small" type="primary" icon="plus" @click="addMarkWorkModal">新增</el-button>
+                                                </span>
+                                    </el-form-item>
+                                </el-form>
+                                <el-table stripe v-loading="loading" element-loading-text="拼命加载中" :data="tableData" border style="width: 100%">
+                                    <el-table-column  label="评卷工作名称" width="250">
+                                        <template slot-scope="scope">
+                                            <div>
+                                                <span>{{scope.row.name}}</span>
+                                            </div>
+                                        </template>
+                                    </el-table-column>
+                                    <el-table-column  label="考试批次" width="250">
+                                        <template slot-scope="scope">
+                                            <div>
+                                                <span>{{scope.row.examName}}</span>
+                                            </div>
+                                        </template>
+                                    </el-table-column>
+                                    <el-table-column  label="考试类型" width="100">
+                                        <template slot-scope="scope">
+                                            <div>
+                                                <span>{{scope.row.examType|examTypeFilter}}</span>
+                                            </div>
+                                        </template>
+                                    </el-table-column>
+                                    <el-table-column  label="进度" width="100">
+                                        <template slot-scope="scope">
+                                            <div>
+                                                <span>{{Number.parseFloat(scope.row.progress)}}%</span>
+                                            </div>
+                                        </template>
+                                    </el-table-column>
+                                    <el-table-column  label="备注" width="100">
+                                        <template slot-scope="scope">
+                                            <div>
+                                                <span>{{scope.row.remark}}</span>
+                                            </div>
+                                        </template>
+                                    </el-table-column>
+                                    <el-table-column  label="操作">
+                                        <template slot-scope="scope">
+                                            <div class="pull-left" v-if="isAdmin">
+                                                        <span class="button-right" v-if="scope.row.status == 2">
+                                                            <el-button @click="recreate(scope.row)" type="primary" size="mini">重新创建</el-button>
+                                                        </span>
+                                                        <span>
+                                                            <el-button @click="editMarkWorkModal(scope.row)" type="primary" size="mini">编辑</el-button>
+                                                        </span>
+                                                        <span>
+                                                            <el-button @click="delMarkWork(scope.row)" type="danger" size="mini">删除</el-button>
+                                                        </span>
+                                                        <span>
+                                                            <el-button @click="pubGrade(scope.row)" type="danger" size="mini">成绩发布</el-button>
+                                                        </span>
+                                            </div>
+                                        </template>
+                                    </el-table-column>
+                                </el-table>
+
+                                <div class="page pull-right">
+                                    <el-pagination background @current-change="handleCurrentChange"
+                                                   :current-page="currentPage"
+                                                   :page-size="pageSize"
+                                                   layout="total, prev, pager, next, jumper"
+                                                   :total="total">
+                                    </el-pagination>
+                                </div>
+
+                                <el-dialog @open="openModal" @close="closeModal" :close-on-click-modal="closeClickModal" :title="examTitle" v-loading="loading" element-loading-text="拼命加载中" :visible.sync="markWorkDialog">
+                                    <el-form :model="formMarkWork" :rules="rules" ref="formMarkWork" label-position="right" label-width="110px">
+                                        <el-row :gutter="10">
+                                            <el-col :xs="12" :sm="12" :md="12" :lg="12">
+                                                <el-form-item label="评卷工作名称" prop="name">
+                                                    <el-input :autofocus="autofocus" placeholder="评卷工作名称" v-model="formMarkWork.name"></el-input>
+                                                </el-form-item>
+                                            </el-col>
+                                        </el-row>
+                                        <el-row :gutter="10">
+                                            <el-col :xs="12" :sm="12" :md="12" :lg="12">
+                                                <el-form-item label="考试批次" prop="examId">
+                                                    <el-select v-if="!examDisabled" @change="update" v-model="formMarkWork.examId" filterable placeholder="考试批次">
+                                                        <el-option v-for="item in examSelect" :label="item.label" :value="item.value" :key="item.value">
+                                                        </el-option>
+                                                    </el-select>
+                                                    <el-input v-if="examDisabled" :disabled="true" v-model="formMarkWork.examName"></el-input>
+                                                </el-form-item>
+                                            </el-col>
+                                        </el-row>
+                                        <el-row :gutter="10">
+                                            <el-col :xs="20" :sm="20" :md="20" :lg="20">
+                                                <el-form-item label="备注" prop="remark">
+                                                    <el-input type="textarea" :rows="5" placeholder="备注" v-model="formMarkWork.remark"></el-input>
+                                                </el-form-item>
+                                            </el-col>
+                                        </el-row>
+                                        <el-row :gutter="10">
+                                            <el-col>
+                                                <el-form-item>
+                                                    <el-button type="primary" @click="saveMarkWork">保存</el-button>
+                                                    <el-button @click="closeMarkWork">取消</el-button>
+                                                    <el-button @click="resetForm">重置</el-button>
+                                                </el-form-item>
+                                            </el-col>
+                                        </el-row>
+                                    </el-form>
+                                </el-dialog>
+
+                            </div>
+                        </div>
+                    </section>
+    </div>
+</template>
+
+<script>
+    import { mapState } from 'vuex'
+    import { CORE_API,MARKING_API,DATA_PROCESS_API} from '../constants/constants'
+    export default {
+        data() {
+            return {
+                formSearch: {
+                    name: ''
+                },
+                formMarkWork: {
+                    name: '',
+                    examId:'',
+                    remark:''
+                },
+                rules:{
+                    name:[
+                        { required: true, message: '请输入名称', trigger: 'blur'}
+                    ],
+                    examId:[
+                        { required: true, message: '请选择考试批次', trigger: 'blur,change' }
+                    ]
+                },
+                statusList:[
+                    {code:0,name:'创建中'},
+                    {code:1,name:'创建成功'},
+                    {code:2,name:'创建失败'}
+                ],
+                examSelect: [],
+                tableData: [],
+                totalTableData:[],
+                currentPage: 1,
+                pageSize:10,
+                total:0,
+                markWorkDialog:false,
+                markWorkId:'',
+                examDisabled:false,
+                examTitle:'',
+                loading:true,
+                closeClickModal:false,
+                autofocus:true,
+                isAdmin:false,
+                oldWorkName:''
+            }
+        },
+        computed: {
+            ...mapState({ user: state => state.user })
+        },
+        methods: {
+            getStatus(code){
+                for(let status of this.statusList){
+                    if(status.code == code){
+                        return status.name;
+                    }
+                }
+            },
+            recreate(row){
+                this.loading = true;
+                this.$http.put(DATA_PROCESS_API+"/markWorks/"+row.id)
+                    .then((response) => {
+                        this.$notify({
+                            message: '评卷工作保存成功',
+                            type: 'success'
+                        });
+                        this.initMarkWorkData();
+                        this.loading = false;
+                    });
+            },
+            getExamSelect(){
+                var orgId = this.user.rootOrgId;
+                var tempSelect = [];
+                //this.loading = true;
+                this.$http.get(DATA_PROCESS_API+"/exam/all?orgId="+orgId)
+                    .then((response) => {
+                        response.data.forEach((element,index)=>{
+                            tempSelect[index] = {value:element.id.toString(),label:element.name}
+                        })
+                        this.examSelect = tempSelect;
+                        //this.loading = false;
+                    });
+            },
+            initMarkWorkData(){
+                var orgId = this.user.rootOrgId;
+                this.loading = true;
+                this.$http.get(DATA_PROCESS_API+"/markWorks?orgId=" + orgId)
+                    .then((response) => {
+                        console.log(response);
+                        this.totalTableData = response.data;
+                        this.total = response.data.length;
+                        this.filterMarkWork();
+                        this.paging();
+                        this.loading = false;
+                    })
+            },
+            searchMarkWork(){
+                this.filterMarkWork();
+                this.paging();
+            },
+            filterMarkWork(){
+                var tempData = this.totalTableData.filter((element)=>{
+                    if(this.formSearch.name){
+                        return (element.name.includes(this.formSearch.name))
+                    }else{
+                        return true
+                    }
+                })
+                this.tableData = tempData;
+                this.total = tempData.length
+            },
+            paging(){
+                var start = (this.currentPage - 1) * this.pageSize
+                var end = (this.currentPage)*this.pageSize < this.total ? (this.currentPage)*this.pageSize:this.total
+                var tempData = []
+                console.log(`当前页: ${this.currentPage},开始:${start},结束:${end}`)
+                for(let i = start;i < end;i++){
+                    tempData.push(this.tableData[i])
+                }
+                this.tableData = tempData
+            },
+            openModal(){
+                console.log("open")
+            },
+            closeModal(){
+                this.$refs.formMarkWork.resetFields()
+                this.formMarkWork = {}
+            },
+            initModal(){
+                this.formMarkWork = {name:'',examId:'',remark:''};
+                this.markWorkId = '';
+                this.examDisabled = false;
+                this.markWorkDialog = true;
+                this.getExamSelect();
+
+            },
+            addMarkWorkModal(){
+                this.initModal();
+                this.examTitle = '新增评卷工作';
+                this.oldWorkName = '';
+                if (this.$refs['formMarkWork']!==undefined) {
+                    this.$refs['formMarkWork'].resetFields();
+                }
+            },
+            editMarkWorkModal(row){
+                this.initModal()
+                this.examTitle = '编辑评卷工作'
+                this.formMarkWork = Object.assign({},row)
+                this.oldWorkName = this.formMarkWork.name;
+                this.markWorkId = row.id
+                this.examDisabled = true
+                this.loading = false
+            },
+            delMarkWork(row){
+                this.$confirm('确认删除评卷工作?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    this.loading = true
+                    this.$http.delete(MARKING_API+"/markWorks/"+row.id)
+                        .then((response) => {
+                            this.$notify({
+                                message: '删除成功',
+                                type: 'success'
+                            })
+                            this.initMarkWorkData();
+                        }).catch((throws) => {
+                        this.$notify({
+                            message: '删除失败',
+                            type: 'success'
+                        })
+                    })
+                    this.loading = false
+                })
+            },
+            pubGrade(row){
+                if(!(Number.parseInt(row.progress) == 100)){
+                    this.$notify({
+                        message: '进度未达到100%,不能进行成绩发布',
+                        type: 'error'
+                    })
+                    return
+                }
+                this.$confirm('确认成绩发布?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    this.loading = true
+                    this.$http.post(DATA_PROCESS_API+"/markWorks/"+row.examId+"/publish")
+                        .then((response) => {
+                            this.$notify({
+                                message: '成绩发布成功',
+                                type: 'success'
+                            })
+                        },(response) =>{
+                            this.$notify({
+                                message: '成绩发布失败',
+                                type: 'error'
+                            })
+                        })
+                    this.initMarkWorkData();
+                    this.loading = false
+                })
+            },
+            checkWorkName(workName){
+                for(let workList of this.totalTableData){
+                    if(workList.name == workName){
+                        this.$notify({
+                            message: '评卷工作名称已存在,请重新输入!',
+                            type: 'warning'
+                        });
+                        return true;
+                    }
+                }
+                return false;
+            },
+            saveMarkWork(){
+                this.$refs.formMarkWork.validate((valid) => {
+                    if (valid) {
+                        var newWorkName = this.formMarkWork.name;
+                        if(newWorkName != this.oldWorkName){
+                            if(this.checkWorkName(newWorkName)){
+                                return;
+                            }
+                        };
+                        this.oldWorkName = '';
+                        this.loading = true;
+                        if(this.markWorkId){
+                            this.$http.put(MARKING_API+"/markWorks/"+this.markWorkId,this.formMarkWork)
+                                .then((response) => {
+                                    this.$notify({
+                                        message: '评卷工作保存成功',
+                                        type: 'success'
+                                    })
+                                    this.closeMarkWork();
+                                    this.initMarkWorkData();
+                                    this.loading = false
+                                },(response) =>{
+                                    console.log(response);
+                                    this.$notify({
+                                        message: response.dataText,
+                                        type: 'error'
+                                    });
+                                    this.loading = false
+                                })
+                        }else{
+                            this.$http.post(DATA_PROCESS_API+"/markWorks",this.formMarkWork)
+                                .then((response) => {
+                                    this.$notify({
+                                        message: '评卷工作新增成功',
+                                        type: 'success'
+                                    });
+                                    this.closeMarkWork();
+                                    this.initMarkWorkData();
+                                    this.loading = false
+                                },(response) =>{
+                                    console.log(response);
+                                    this.$notify({
+                                        message: response.dataText,
+                                        type: 'error'
+                                    });
+                                    this.loading = false
+                                })
+                        }
+                    } else {
+                        return false
+                    }
+                });
+            },
+            closeMarkWork(){
+                this.markWorkDialog = false
+            },
+            resetForm(){
+                this.formMarkWork.name = '';
+                this.formMarkWork.remark = '';
+            },
+            handleCurrentChange(val){
+                this.currentPage = val;
+                this.filterMarkWork();
+                this.paging();
+                //this.searchMarkWork()
+            },
+            update(selected){
+                this.formMarkWork.examId = selected
+            },
+            getUserPrivileges(){
+
+                var url = CORE_API + "/rolePrivilege/getUserPrivileges";
+                let config = {
+                    url:url,
+                    method:'post',
+                    params:{
+                        groupCode: "MARK_WORK_MENUS", full: false
+                    },
+                    headers: {
+                        'Content-Type': 'application/x-www-form-urlencoded'
+                    }
+                }
+                this.$http(config).then((response) => {
+                    let temp = response.data;
+                    for(let menu in temp){
+                        let menuItem = temp[menu];
+                        if(menuItem.ext1 == 'button'){
+                            sessionStorage.setItem(menuItem.code,true);
+                        }
+                    }
+                    if(sessionStorage.getItem("AdminButtonShow")){
+                        this.isAdmin = true;
+                    }
+                }).catch((response) => {
+                    this.$notify({
+                        showClose: true,
+                        message: response.data,
+                        type: 'error'
+                    });
+                });
+            }
+        },
+        created(){
+            this.user.rootOrgId = 7;
+            this.getUserPrivileges();
+            this.initMarkWorkData();
+            //this.getExamSelect();
+
+        }
+    }
+
+</script>

+ 396 - 0
src/modules/marking/views/mark_work_overview.vue

@@ -0,0 +1,396 @@
+<style lang="css" scoped>
+
+li {
+    list-style-type: none;
+}
+
+.searchFrame {
+    margin-right: 10px;
+    margin-bottom: 10px;
+}
+
+.page{
+  margin-top: 10px;
+}
+.f_button{
+    display:block;
+    width:57px;
+    height:20px;
+    border:1px solid #CCC;
+    background:#FFF;
+    font-size: small;
+}
+.echarts {
+    display: flex;
+}
+    .pie{
+        width: 450px;
+        height: 350px;
+    }
+</style>
+
+<template>
+
+<div>
+    <section class="content">
+        <div class="box box-info">
+            <div class="box-header with-border">
+                <h3 class="box-title">
+                  <span>评卷总览</span>
+                  <span>({{$route.params.name}})</span>
+                </h3>
+                <div class="box-tools pull-right">
+
+                </div>
+            </div>
+
+            <div class="box-body">
+                <div class="echarts">
+                    <!--<div class="pie"><IEcharts :option="pie"></IEcharts></div>-->
+                    <!--<div class="pie"><IEcharts :option="pie1"></IEcharts></div>-->
+                </div>
+
+                <el-form :inline="true" :model="formSearch" label-position="right" label-width="80px" >
+                    <el-row>
+                       <el-col :span="20">
+                           <el-form-item label="课程">
+                               <el-select clearable filterable class="input" v-model="formSearch.courseCode" placeholder="请选择">
+                                   <el-option value="">请选择</el-option>
+                                   <el-option
+                                           v-for="item in courseAllListSelect"
+                                           :label="item.courseInfo"
+                                           :value="item.code"
+                                           :key="item.code">
+                                   </el-option>
+                               </el-select>
+                           </el-form-item>
+                           <el-form-item >
+                               <el-button size="small"  type="primary" icon="search" @click="searchSetting">查询</el-button>
+                           </el-form-item>
+                       </el-col>
+                    </el-row>
+                </el-form>
+                <!--页面列表-->
+                <el-table v-loading="loading" element-loading-text="拼命加载中" :data="tableData" border style="width: 100%">
+                  <el-table-column  label="课程名称" width="200" prop="name">
+                  </el-table-column>
+                    <el-table-column  label="课程代码" min-width="100" prop="code">
+                    </el-table-column>
+                    <el-table-column  label="任务总数" min-width="100" prop="totalCount">
+                    </el-table-column>
+                    <el-table-column  label="完成数" min-width="100" prop="markedCount">
+                    </el-table-column>
+                    <el-table-column  label="待完成" min-width="100" prop="leftCount">
+                    </el-table-column>
+                    <el-table-column  label="进度" min-width="100">
+                        <template slot-scope="scope">
+                            <div>
+                                <span>{{scope.row.progress}}%</span>
+                            </div>
+                        </template>
+                    </el-table-column>
+                    <el-table-column :context="_self"  label="操作" >
+                        <template slot-scope="scope">
+                            <el-button @click="courseDetail(scope.row)" type="primary" size="mini">详情</el-button>
+                        </template>
+                    </el-table-column>
+                </el-table>
+                <div class="page pull-right">
+                    <el-pagination background @current-change="handleSettingCurrentChange"
+                    :current-page="currentPage"
+                    :page-size="10"
+                    layout="total, prev, pager, next, jumper"
+                    :total="total">
+                    </el-pagination>
+                </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+</template>
+
+<script>
+import {MARKING_API} from '../constants/constants'
+import { mapState } from 'vuex'
+// import IEcharts from 'vue-echarts-v3/src/full.vue'
+export default {
+    components: {
+        // IEcharts
+    },
+    data() {
+            return {
+                formSearch: {
+                  courseCode: '',
+                },
+                tableData: [],
+                oldData:[],
+                currentPage: 1,
+                pageSize:10,
+                total:10,
+                loading:true,
+                workId:'',
+                examId:'',
+                examName:'',
+                courseList:[],
+                pie: {
+                    title: {
+                        text: '试卷进度情况',
+                        x:'center'
+                    },
+                    tooltip : {
+                        trigger: 'item',
+                        formatter: "{a} <br/>{b} : {c} ({d}%)"
+                    },
+                    legend: {
+                        orient: 'vertical',
+                        left: 'left',
+                        data: ['待完成','完成数']
+                    },
+                    series : [
+                        {
+                            name: '试卷总数:0',
+                            type: 'pie',
+                            radius : '55%',
+                            center: ['50%', '60%'],
+                            data:[
+                                {value:0,name:'待完成',
+                                    itemStyle: {
+                                        normal: {
+                                            color: '#FE8463'
+                                        }
+                                    }
+                                },
+                                {value:0, name:'完成数',
+                                    itemStyle: {
+                                        normal: {
+                                            color: '#7CB5EC'
+                                        }
+                                    }
+                                }
+                            ],
+                            itemStyle: {
+                                emphasis: {
+                                    shadowBlur: 10,
+                                    shadowOffsetX: 0,
+                                    shadowColor: 'rgba(0, 0, 0, 0.5)'
+                                }
+                            }
+                        }
+                    ]
+                },
+                pie1: {
+                    title: {
+                        text: '课程进度情况',
+                        x:'center'
+                    },
+                    tooltip : {
+                        trigger: 'item',
+                        formatter: "{a} <br/>{b} : {c} ({d}%)"
+                    },
+                    legend: {
+                        orient: 'vertical',
+                        left: 'left',
+                        data: ['待完成','完成数']
+                    },
+                    series : [
+                        {
+                            name: '课程总数:0',
+                            type: 'pie',
+                            radius : '55%',
+                            center: ['50%', '60%'],
+                            data:[
+                                {value:0, name:'待完成',
+                                    itemStyle: {
+                                        normal: {
+                                            color: '#FE8463'
+                                        }
+                                    }
+                                },
+                                {value:0, name:'完成数',
+                                    itemStyle: {
+                                        normal: {
+                                            color: '#7CB5EC'
+                                        }
+                                    }
+                                }
+                            ],
+                            itemStyle: {
+                                emphasis: {
+                                    shadowBlur: 10,
+                                    shadowOffsetX: 0,
+                                    shadowColor: 'rgba(0, 0, 0, 0.5)'
+                                }
+                            }
+                        }
+                    ]
+                }
+            }
+        },
+        methods: {
+          getCourses() {
+              this.$http.get(MARKING_API+"/markResults/queryExamCourseList?workId=" + this.workId)
+                  .then((response) => {
+                      this.courseList = response.data;
+                  });
+          },
+            handleSettingCurrentChange(val){
+              this.currentPage = val
+              this.searchSetting()
+            },
+            pagingSetting(){
+              var start = (this.currentPage - 1) * this.pageSize
+              var end = (this.currentPage)*this.pageSize < this.total ? (this.currentPage)*this.pageSize:this.total
+              var tempData = []
+              console.log(`当前页: ${this.currentPage},开始:${start},结束:${end}`)
+              for(let i = start;i < end;i++){
+                tempData.push(this.tableData[i])
+              }
+              this.tableData = tempData
+            },
+            initSetting(){
+              this.loading = true
+              this.$http.get(MARKING_API+"/markCourses/all/0/"+this.pageSize+"?workId="+this.workId)
+                .then((response) => {
+                  this.tableData = response.data.content
+                  this.total = response.data.totalElements
+                  this.loading = false
+              })
+            },
+            searchSetting(){
+              this.loading = true
+              this.$http.get(MARKING_API+"/markCourses/all/"+(this.currentPage - 1)+"/"+this.pageSize+"?workId="+this.workId,{params:this.formSearch})
+                .then((response) => {
+                this.tableData = response.data.content
+                this.total = response.data.totalElements
+                this.loading = false
+              })
+            },
+            courseDetail(row) {
+              var url = '/index/course_detail/'+this.$route.params.workId+"/"+this.$route.params.examId+"/"+this.$route.params.name+"/"+row.code+"/"+row.name
+              this.$router.push({
+                path: url
+              })
+            },
+            doPie() {
+                this.loading = true
+                this.$http.get(MARKING_API+"/markWorks/"+this.workId)
+                        .then((response) => {
+                            this.pie.series= [
+                                {
+                                    name: '试卷总数:'+response.data.totalStudentPaper,
+                                    type: 'pie',
+                                    radius : '55%',
+                                    center: ['50%', '60%'],
+                                    data:[
+                                        {value:response.data.totalStudentPaper-response.data.markedStudentPaper,
+                                            name:'待完成',
+                                            itemStyle: {
+                                                normal: {
+                                                    color: '#FE8463'
+                                                }
+                                            }, selected:true
+                                        },
+                                        {value:response.data.markedStudentPaper,
+                                            name:'完成数',
+                                            itemStyle: {
+                                                normal: {
+                                                    color: '#7CB5EC'
+                                                }
+                                            }}
+                                    ],
+                                    itemStyle: {
+                                        normal : {
+                                            label : {
+                                                show: true,
+                                                formatter :  "{b}:{d}%"
+                                            },
+                                            labelLine : {
+                                                show : true
+                                            }
+                                        },
+                                        emphasis: {
+                                            shadowBlur: 10,
+                                            shadowOffsetX: 0,
+                                            shadowColor: 'rgba(0, 0, 0, 0.5)',
+                                            label : {
+                                                show : true,
+                                                formatter : "{b}:{d}%"
+                                            }
+                                        }
+                                    }
+                                }
+                            ];
+                            this.pie1.series= [
+                                {
+                                    name: '课程总数:'+response.data.totalCourse,
+                                    type: 'pie',
+                                    radius : '55%',
+                                    center: ['50%', '60%'],
+                                    data:[
+                                        {value:response.data.totalCourse-response.data.markedCourse,
+                                            name:'待完成',
+                                            itemStyle: {
+                                                normal: {
+                                                    color: '#FE8463'
+                                                }
+                                            }, selected:true
+                                        },
+                                        {value:response.data.markedCourse,
+                                            name:'完成数',
+                                            itemStyle: {
+                                                normal: {
+                                                    color: '#7CB5EC'
+                                                }
+                                            }
+                                        }
+                                    ],
+                                    itemStyle: {
+                                        normal : {
+                                            label : {
+                                                show: true,
+                                                formatter :  "{b}:{d}%"
+                                            },
+                                            labelLine : {
+                                                show : true
+                                            }
+                                        },
+                                        emphasis: {
+                                            shadowBlur: 10,
+                                            shadowOffsetX: 0,
+                                            shadowColor: 'rgba(0, 0, 0, 0.5)',
+                                            label : {
+                                                show : true,
+                                                formatter : "{b}:{d}%"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                            this.loading = false
+                        })
+            }
+
+        },
+        computed:{
+            ...mapState({ user: state => state.user }),
+            courseAllListSelect(){
+                let courseSelect = [];
+                for(let course of this.courseList){
+                    let courseInfo = course.name+"("+course.code+")";
+                    courseSelect.push({code:course.code,courseInfo:courseInfo});
+                }
+                return courseSelect;
+            }
+        },
+        created(){
+          this.workId = this.$route.params.workId
+          this.examId = this.$route.params.examId
+          this.examName = this.$route.params.name
+          this.initSetting();
+          this.doPie();
+          this.getCourses();
+        }
+}
+
+</script>

+ 162 - 0
src/modules/marking/views/marker.vue

@@ -0,0 +1,162 @@
+<style lang="css">
+
+li {
+    list-style-type: none;
+}
+
+.searchFrame {
+    margin-right: 10px;
+    margin-bottom: 10px;
+}
+
+.page{
+  margin-top: 10px;
+}
+.f_button{
+    display:block;
+    width:57px;
+    height:20px;
+    border:1px solid #CCC;
+    background:#FFF;
+    font-size: small;
+}
+
+</style>
+
+<template>
+
+<div>
+    <section class="content">
+        <div class="box box-info">
+            <div class="box-header with-border">
+                <h3 class="box-title">
+                  <span>评卷员一览</span>
+                  <span>({{$route.params.name}})</span>
+                </h3>
+                <div class="box-tools pull-right">
+
+                </div>
+            </div>
+            <div class="box-body">
+                <el-form :inline="true" :model="formSearch" label-position="right" label-width="80px">
+                    <el-form-item label="姓名" class="pull-left">
+                        <el-input placeholder="姓名" v-model="formSearch.userName"></el-input>
+                    </el-form-item>
+                    <el-form-item label="登录名" class="pull-left">
+                        <el-input placeholder="登录名" v-model="formSearch.userLoginName"></el-input>
+                    </el-form-item>
+
+                    <el-form-item class="pull-right">
+                        <el-button size="small"  type="primary" icon="search" @click="searchSetting">查询</el-button>
+                    </el-form-item>
+                </el-form>
+
+                <!--页面列表-->
+                <el-table v-loading="loading" element-loading-text="拼命加载中" :data="tableData" border style="width: 100%">
+                    <el-table-column  label="姓名" width="200" prop="userName"/>
+                    <el-table-column  label="登录名" min-width="100" prop="userLoginName"/>
+                    <el-table-column  label="分配课程" min-width="200" prop="courseCount"/>
+                    <el-table-column  label="完成课程" min-width="100" prop="finishedCount"/>
+                    <el-table-column  label="完成数量" min-width="100" prop="markedCount"/>
+                    <el-table-column  label="最低分" min-width="100" prop="minScore"/>
+                    <el-table-column  label="最高分" min-width="100" prop="maxScore"/>
+                    <el-table-column  label="平均分" min-width="100" prop="avgScore"/>
+                    <el-table-column  label="标准方差" min-width="100" prop="stdDev"/>
+                    <el-table-column :context="_self"  label="操作" >
+                        <template slot-scope="scope">
+                            <el-button @click="markerDetail(scope.row)" type="primary" size="mini">详情</el-button>
+                        </template>
+                    </el-table-column>
+                </el-table>
+                <div class="page pull-right">
+                    <el-pagination background @current-change="handleSettingCurrentChange"
+                    :current-page="currentPage"
+                    :page-size="10"
+                    layout="total, prev, pager, next, jumper"
+                    :total="total">
+                    </el-pagination>
+                </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+</template>
+
+<script>
+import { CORE_API,EXAM_WORK_API,MARKING_API,DATA_PROCESS_API,OE_API } from '../constants/constants'
+import { mapState } from 'vuex'
+export default {
+    data() {
+            return {
+                formSearch: {
+                    userLoginName:'',
+                    userName:''
+                },
+                tableData: [],
+                oldData:[],
+                currentPage: 1,
+                pageSize:10,
+                total:10,
+                loading:true,
+                workId:'',
+                examId:'',
+                examName:''
+            }
+        },
+        methods: {
+            handleSettingCurrentChange(val){
+              this.currentPage = val
+              this.searchSetting()
+            },
+            pagingSetting(){
+              var start = (this.currentPage - 1) * this.pageSize
+              var end = (this.currentPage)*this.pageSize < this.total ? (this.currentPage)*this.pageSize:this.total
+              var tempData = []
+              console.log(`当前页: ${this.currentPage},开始:${start},结束:${end}`)
+              for(let i = start;i < end;i++){
+                tempData.push(this.tableData[i])
+              }
+              this.tableData = tempData
+            },
+            initSetting(){
+              this.loading = true
+              this.$http.get(DATA_PROCESS_API+"/markers/all/"+(this.currentPage-1)+"/"+this.pageSize+"?workId="+this.workId)
+                .then((response) => {
+                  console.log(response)
+                  this.tableData = response.data.content
+                  this.total = response.data.totalElements
+                  this.loading = false
+              })
+            },
+            searchSetting(){
+                this.loading = true
+                this.$http.get(DATA_PROCESS_API+"/markers/all/"+(this.currentPage-1)+"/"+this.pageSize+"?workId="+this.workId,{params:this.formSearch})
+                        .then((response) => {
+                            console.log(response)
+                            this.tableData = response.data.content
+                            this.total = response.data.totalElements
+                            this.loading = false
+                        })
+            },
+            markerDetail(row) {
+                var url = '/index/marker_detail/'+this.$route.params.workId+"/"+this.$route.params.examId+"/"+this.$route.params.name+"/"+row.userId+"/"+row.userName
+                this.$router.push({
+                    path: url
+                })
+            }
+
+        },
+        computed:{
+            ...mapState({ user: state => state.user })
+        },
+        created(){
+          this.workId = this.$route.params.workId
+          this.examId = this.$route.params.examId
+          this.examName = this.$route.params.name
+          this.initSetting();
+        }
+
+}
+
+</script>

+ 164 - 0
src/modules/marking/views/marker_detail.vue

@@ -0,0 +1,164 @@
+<style lang="css">
+
+li {
+    list-style-type: none;
+}
+
+.searchFrame {
+    margin-right: 10px;
+    margin-bottom: 10px;
+}
+
+.page{
+  margin-top: 10px;
+}
+.f_button{
+    display:block;
+    width:57px;
+    height:20px;
+    border:1px solid #CCC;
+    background:#FFF;
+    font-size: small;
+}
+
+</style>
+
+<template>
+
+<div>
+    <section class="content">
+        <div class="box box-info">
+            <div class="box-header with-border">
+                <h3 class="box-title">
+                  <span>评卷员详情</span>
+                  <span>({{$route.params.userName}})</span>
+                </h3>
+                <div class="box-tools pull-right">
+
+                </div>
+            </div>
+            <div class="box-body">
+                <el-form :inline="true" :model="formSearch" label-position="right" label-width="80px">
+                  <el-form-item label="课程代码" class="pull-left">
+                      <el-input placeholder="课程代码" v-model="formSearch.courseCode"></el-input>
+                  </el-form-item>
+                    <el-form-item label="课程名称" class="pull-left">
+                      <el-input placeholder="课程名称" v-model="formSearch.courseName"></el-input>
+                  </el-form-item>
+
+                  <el-form-item class="pull-right">
+                    <el-button size="small"  type="primary" icon="search" @click="searchSetting">查询</el-button>
+                    <!--<el-button size="small"  type="primary" icon="info" @click="exportMarker">导出</el-button>-->
+                    <el-button size="small"  type="primary" icon="caret-left" @click="back">返回</el-button>
+                  </el-form-item>
+                </el-form>
+
+                <!--页面列表-->
+                <el-table v-loading="loading" element-loading-text="拼命加载中" :data="tableData" border style="width: 100%">
+                  <el-table-column  label="课程名称" width="200" prop="name"/>
+                    <el-table-column  label="课程代码" min-width="100" prop="code"/>
+                    <el-table-column  label="已评数量" min-width="200" prop="markedCount"/>
+                    <el-table-column  label="打回数量" min-width="100" prop="rejectCount"/>
+                    <el-table-column  label="完成状态" min-width="100">
+                        <template slot-scope="scope">
+                            <div>
+                                <span v-if="scope.row.leftCount==0">完成</span>
+                                <span v-if="scope.row.leftCount!=0">未完成</span>
+                            </div>
+                        </template>
+                    </el-table-column>
+                </el-table>
+                <div class="page pull-right">
+                    <el-pagination background @current-change="handleSettingCurrentChange"
+                    :current-page="currentPage"
+                    :page-size="10"
+                    layout="total, prev, pager, next, jumper"
+                    :total="total">
+                    </el-pagination>
+                </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+</template>
+
+<script>
+import { CORE_API,EXAM_WORK_API,MARKING_API,DATA_PROCESS_API,OE_API } from '../constants/constants'
+import { mapState } from 'vuex'
+export default {
+    data() {
+            return {
+                formSearch: {
+                    courseCode:'',
+                    courseName:''
+                },
+                tableData: [],
+                oldData:[],
+                currentPage: 1,
+                pageSize:10,
+                total:10,
+                loading:true,
+                workId:'',
+                examId:'',
+                courseCode:'',
+                examName:''
+            }
+        },
+        methods: {
+            handleSettingCurrentChange(val){
+              this.currentPage = val
+              this.searchSetting()
+            },
+            pagingSetting(){
+              var start = (this.currentPage - 1) * this.pageSize
+              var end = (this.currentPage)*this.pageSize < this.total ? (this.currentPage)*this.pageSize:this.total
+              var tempData = []
+              console.log(`当前页: ${this.currentPage},开始:${start},结束:${end}`)
+              for(let i = start;i < end;i++){
+                tempData.push(this.tableData[i])
+              }
+              this.tableData = tempData
+            },
+            initSetting(){
+              this.loading = true
+              this.$http.get(MARKING_API+"/markCourses/all/marker/0/"+this.pageSize+"?workId="+this.workId+"&userId="+this.userId)
+                .then((response) => {
+                  console.log(response)
+                  this.tableData = response.data.content
+                  this.total = response.data.totalElements
+                  this.loading = false
+              })
+            },
+            searchSetting(){
+              this.loading = true
+                this.$http.get(MARKING_API+"/markCourses/all/marker/"+(this.currentPage - 1)+"/"+this.pageSize+"?workId="+this.workId+"&userId="+this.userId,{params:this.formSearch})
+                        .then((response) => {
+                            console.log(response)
+                            this.tableData = response.data.content
+                            this.total = response.data.totalElements
+                            this.loading = false
+                        })
+            },
+            back() {
+                this.$router.push({
+                    path: '/index/marker/'+this.workId+"/"+this.examId+"/"+this.examName
+                })
+            },
+
+        },
+        computed:{
+            ...mapState({ user: state => state.user })
+        },
+        created(){
+          this.workId = this.$route.params.workId
+          this.examId = this.$route.params.examId
+          this.examName = this.$route.params.name
+            this.userName = this.$route.params.userName
+            this.userId = this.$route.params.markerId
+          this.initSetting();
+        }
+
+}
+
+</script>

+ 569 - 0
src/modules/marking/views/marking.vue

@@ -0,0 +1,569 @@
+<style scoped>
+  .el-select{
+    width: 160px;
+  }
+  .content{
+    margin-top: 10px;
+  }
+  small{
+    font-size: 18px;
+    font-weight: bold;
+    margin-left: 10px;
+    margin-top: 20px;
+  }
+  .content-header{
+    margin-top: 10px;
+  }
+  section{
+    margin-top: 10px;
+    margin-bottom: 20px;
+  }
+  .box-body{
+    height: 100%;
+    width: 100%;
+  }
+  .backcolor{
+    background-color: #ECF0F5;
+  }
+  li{
+    list-style-type:none;
+  }
+  .marktitle{
+    margin-right: 10px;
+    margin-bottom: 10px;
+  }
+  .titlefont{
+    font-size: 15px;
+  }
+  .box-card{
+    width: 200px;
+    height: 120px;
+  }
+  .block{
+    display: inline-block;
+  }
+  .text{
+    text-align: center;
+  }
+  .markcount{
+    margin-right: 10px;
+  }
+  .scroll{
+    overflow:auto;
+    height: 450px;
+  }
+  .reject{
+    color: red;
+  }
+  .marksign{
+    margin-left: 20px;
+  }
+</style>
+<template>
+  <div v-loading="loading" element-loading-text="拼命加载中">
+  <section class="content-header">
+    <span>
+      <span class="pull-left">
+        <small class="marktitle">
+          <span class="label-danger">{{mark_type}}</span>
+        </small>
+        <small class="marktitle titlefont">
+          <span>课程:{{task.courseName}}</span>
+        </small>
+        <small class="marktitle titlefont">
+          <span>试卷编号:{{task.paperName}}</span>
+        </small>
+        <small class="marktitle">
+          <el-button-group>
+            <el-button size="small"><span class="titlefont">已评</span></el-button>
+            <el-button size="small" @click="markedClick"><span class="titlefont">{{task.markedCount}}</span></el-button>
+          </el-button-group>
+        </small>
+        <small class="marktitle">
+          <el-button-group>
+            <el-button size="small"><span class="titlefont">待评</span></el-button>
+            <el-button size="small"><span class="titlefont">{{task.leftCount}}</span></el-button>
+          </el-button-group>
+        </small>
+        <small class="marktitle">
+          <el-button-group>
+            <el-button size="small"><span class="titlefont">进度</span></el-button>
+            <el-button size="small"><span class="titlefont">{{((task.totalCount-task.leftCount)*100/task.totalCount).toFixed(2)}}%</span></el-button>
+          </el-button-group>
+        </small>
+        <small class="marktitle">
+          <el-button type="primary" @click="taskChange" size="small">
+              <span class="titlefont">切换任务
+                <i class="el-icon-caret-bottom el-icon--right"></i>
+              </span>
+          </el-button>
+        </small>
+        <small class="marktitle">
+          <el-button-group>
+            <el-button size="small"><span class="titlefont"><i class="fa fa-user"></i></span></el-button>
+            <el-button size="small"><span class="titlefont">{{user.displayName}}</span></el-button>
+          </el-button-group>
+        </small>
+        <small class="marktitle titlefont marksign">
+          <el-button type="success" @click="backIndex" size="small">
+              <i class="fa fa-sign-out"></i>
+              <span class="titlefont">退回
+              </span>
+          </el-button>
+        </small>
+
+
+        <el-dialog title="切换任务" :visible.sync="taskVisible" size="large">
+          <div class="scroll">
+            <el-form :inline="true" :model="taskFormSearch" label-position="right" label-width="70px">
+                <el-form-item label="课程代码" class="pull-left">
+                    <el-input placeholder="课程代码" v-model="taskFormSearch.courseCode"></el-input>
+                </el-form-item>
+                <el-form-item label="课程名称" class="pull-left">
+                    <el-input placeholder="课程名称" v-model="taskFormSearch.courseName"></el-input>
+                </el-form-item>
+                <el-form-item class="pull-right">
+                    <el-button type="primary" icon="search" @click="getChangeTasks">查询</el-button>
+                </el-form-item>
+            </el-form>
+            <el-table :data="changeTasks" border style="width: 100%">
+                <el-table-column  label="课程代码" width="250" prop="courseCode"/>
+                <el-table-column  label="课程名称" width="200" prop="courseName"/>
+                <el-table-column  label="任务" width="200" prop="markRangeName"/>
+                <el-table-column  label="已评" prop="markedCount"/>
+                <el-table-column  label="待评" prop="leftCount"/>
+                <el-table-column :context="_self"  label="操作">
+                    <template slot-scope="scope">
+                        <div>
+                            <el-button size="small" type="success" @click="tasksSelect(scope.$index, scope.row)">
+                                选择
+                            </el-button>
+                        </div>
+                     </template>
+                </el-table-column>
+            </el-table>
+            <div class="page pull-right">
+                <el-pagination background @current-change="taskCurrentChange"
+                :current-page="taskCurrentPage"
+                :page-size="pageSize"
+                layout="total, prev, pager, next, jumper"
+                :total="changeTaskTotal">
+                </el-pagination>
+            </div>
+          </div>
+        </el-dialog>
+
+        <el-dialog title="已评任务" :visible.sync="markedTaskVisible" size="large">
+          <div class="scroll">
+            <el-form :inline="true" :model="markTaskFormSearch" label-position="right" label-width="70px">
+            </el-form>
+            <el-table :data="markedResults" border style="width: 100%">
+                <el-table-column  label="答卷Id" width="100" prop="studentPaperId"/>
+                <el-table-column  label="得分" prop="score"/>
+                <el-table-column  label="评阅时间">
+                    <template slot-scope="scope">
+                        <div>
+                            <span style="margin-left: 10px">{{dateFormatter(scope.row)}}</span>
+                        </div>
+                     </template>
+                </el-table-column>
+                <el-table-column  label="状态">
+                    <div>
+                        <span style="margin-left: 10px">已评</span>
+                    </div>
+                </el-table-column>
+                <el-table-column  label="问题卷">
+                    <template slot-scope="scope">
+                        <div>
+                            <span style="margin-left: 10px">{{getTagName(scope.row.tag)}}</span>
+                        </div>
+                    </template>
+                </el-table-column>
+              <el-table-column  label="评卷备注">
+                  <template slot-scope="scope">
+                        <div>
+                            <span style="margin-left: 10px">{{scope.row.markRemark}}</span>
+                        </div>
+                  </template>
+                </el-table-column>
+                <el-table-column :context="_self"  label="操作">
+                    <template slot-scope="scope">
+                        <div>
+                            <el-button size="small" type="success" @click="markTaskSelect(scope.$index, scope.row)">
+                                选择
+                            </el-button>
+                        </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+            <div class="page pull-right">
+                <el-pagination background @current-change="markedCurrentChange"
+                :current-page="markedCurrentPage"
+                :page-size="pageSize"
+                layout="total, prev, pager, next, jumper"
+                :total="markedTotal">
+                </el-pagination>
+            </div>
+          </div>
+        </el-dialog>
+      </span>
+    </span>
+  </section>
+
+  <section class="content">
+      <div class="box box-info backcolor">
+        <div class="box-body">
+          <!--文本图片阅卷主界面-->
+          <tpMain @changePaperSign="changePaperSign" @clearScores="clearScores" @changeSignScores="changeSignScores" :paperMarkSign="paperMarkSign" :signItem="signItem" :signScores="signScores" :signOption="signOption" :markSign="markSign" :studentPaper="studentPaper" :examType="examType"></tpMain>
+          <!--文本图片给分板-->
+          <tpScoreboard @submitMark="getNext" @changeSign="changeSign" :paperMarkSign="paperMarkSign" :signItem="signItem" :signScores="signScores" :signOption="signOption" :markSign="markSign" :paperMark="paperMark" :markedResult="markedResult" :resultItems="resultItems" :studentPaperId="studentPaper.id" :markTaskId="task.id"></tpScoreboard>
+        </div>
+      </div>
+  </section>
+
+</div>
+</template>
+<script>
+    import { mapState } from 'vuex'
+    import tpMain from './/tp_main.vue'
+    import tpScoreboard from './/tp_scoreboard.vue'
+    import {MARKING_API,DATA_PROCESS_API} from '../constants/constants'
+    export default {
+      components:{
+        tpMain,
+        tpScoreboard
+      },
+      data(){
+        return{
+          markSign:false,
+          paperMarkSign:[],
+          signScores:[],
+          signItem:{},
+          signOption:{score:0,data:'',width:800,height:8000,loc:[]},
+          tasks: [],
+          task:{},
+          changeTasks:[],
+          changeTaskTotal:0,
+          studentPaper:{},
+          markRange:{},
+          resultItems:[],
+          markedResults:[],
+          markedResult:{},
+          loading:true,
+          taskCurrentPage: 1,
+          taskTotal:0,
+          markedCurrentPage: 1,
+          markedTotal:0,
+          pageSize:10,
+          mark_type:'正评',
+          mark_task:{},
+          taskVisible:false,
+          markedTaskVisible:false,
+          problemTaskVisible:false,
+          degree:[{label:'是',value:'Y'},{label:'否',value:'N'}],
+          markTaskFormSearch:{
+            courseCode:'',
+            courseName:'',
+            degree:''
+          },
+          taskFormSearch:{
+            courseCode:'',
+            courseName:'',
+            paperCode:''
+          },
+          course:{},
+          workId:'',
+          examType:'',
+          markSearch:{
+            userId:'',
+            workId:''
+          },
+          //回评标志
+          backMark:false,
+          //获取试卷标志(成功获取true,没有试卷false)
+          paperMark:true,
+          tags:[]
+        }
+      },
+      methods:{
+          getTags(){
+            this.$http.get(MARKING_API+"/markResults/tag")
+              .then((response) => {
+                  this.tags = response.data;
+            })
+          },
+          getTagName(code){
+            for(let tag of this.tags){
+              if(tag.code === code){
+                return tag.name;
+              }
+            }
+          },
+          clearScores(val){
+            this.signScores.splice(0,this.signScores.length)
+          },
+          changePaperSign(val){
+            this.paperMarkSign = val
+          },
+          changeSignScores(val){
+            this.signScores = val
+          },
+          changeSign(val){
+            console.log(val)
+            this.signItem = val
+          },
+          taskChange(){
+            this.taskVisible = true
+            this.getChangeTasks()
+          },
+          async tasksSelect(index,row){
+            await this.initMarkItem()
+            await this.markInit()
+            this.task = row
+            await this.getPaper()
+            await this.getMarkRange()
+            await this.getMarkedTask()
+            this.taskVisible = false
+          },
+          markedClick(){
+            this.markedTaskVisible = true
+            this.getMarkedTask()
+          },
+          problemClick(){
+            this.problemTaskVisible = true
+          },
+          backIndex(){
+            this.$router.push({path: '/index/mark_setting_work/marking'})
+          },
+          taskCurrentChange(val){
+            this.taskCurrentPage = val
+            this.getChangeTasks()
+          },
+          markedCurrentChange(val){
+            this.markedCurrentPage = val
+            this.getMarkedTask()
+          },
+          markTaskSelect(index,row){
+            this.backMark = true
+            this.paperMark = true
+            this.textarea = row.markRemark;
+            this.getMarkedPaper(row.studentPaperId)
+            this.getMarkedResultItems(row.id)
+            this.markedTaskVisible = false
+          },
+         async markInit(){
+            console.log('markInit');
+            var self = this;
+            this.workId = this.$route.params.workId;
+              this.examType = this.$route.params.examType;
+            var userId = this.user.userId;
+            await self.$http.get(DATA_PROCESS_API+"/markTasks?workId="+self.workId+"&userId="+userId).then((response) => {
+                self.tasks = response.data;
+                self.taskTotal = self.tasks.length
+                //切换任务提交试卷后,继续维持该任务
+                if(self.changeTaskCur != self.taskCur){
+                    //切换任务评完后,继续跳转原来的任务
+                    if(self.tasks[self.changeTaskCur].leftCount == 0){
+                        if(self.tasks[self.taskCur]){
+                            self.task = self.tasks[self.taskCur]
+                        }
+                    }else if(self.tasks[self.changeTaskCur]){
+                        self.task = self.tasks[self.changeTaskCur]
+                    }
+                }else{
+                    if(self.tasks[self.taskCur]){
+                        self.task = self.tasks[self.taskCur]
+                    }
+                }
+                console.log('tasks',self.tasks)
+            });
+          },
+          async getChangeTasks(){
+            console.log('getChangeTasks');
+            var self = this;
+            this.workId = this.$route.params.workId;
+            var userId = this.user.userId;
+            await self.$http.get(DATA_PROCESS_API+"/markTasks?workId="+self.workId+"&userId="+userId).then((response) => {
+                self.changeTasks = response.data;
+                self.changeTaskTotal = self.changeTasks.length
+                self.filterChangeTasks()
+                self.pagingChangeTasks()
+                console.log('changeTasks',self.changeTasks)
+            });
+          },
+          filterChangeTasks(){
+            var tempData = this.changeTasks.filter((element)=>{
+              var flag = true;
+              if(this.taskFormSearch.courseCode || this.taskFormSearch.courseName){
+                if(this.taskFormSearch.courseCode){
+                  flag = flag && element.courseCode.includes(this.taskFormSearch.courseCode)
+                }
+                if(this.taskFormSearch.courseName){
+                  flag = flag && element.courseName.includes(this.taskFormSearch.courseName)
+                }
+                return flag
+              }else{
+                return flag
+              }
+            })
+            this.changeTasks = tempData
+            this.changeTaskTotal = tempData.length
+          },
+          pagingChangeTasks(){
+            var start = (this.taskCurrentPage - 1) * this.pageSize
+            var end = (this.taskCurrentPage)*this.pageSize < this.changeTaskTotal ? (this.taskCurrentPage)*this.pageSize:this.changeTaskTotal
+            var tempData = []
+            console.log(`当前页: ${this.taskCurrentPage},开始:${start},结束:${end}`)
+            for(let i = start;i < end;i++){
+              tempData.push(this.changeTasks[i])
+            }
+            this.changeTasks = tempData
+          },
+          async getPaper(){
+            console.log('getPaper')
+            var self = this;
+            await self.$http.get(DATA_PROCESS_API+"/studentPapers?markTaskId="+self.task.id+"&examType="+self.examType).then((response) => {
+                if(!response){
+                    self.$notify({
+                        message: '该任务下试卷已评完,如有剩余任务将自动切换任务',
+                        type: 'info'
+                    })
+                    self.studentPaper = {id:""}
+                    self.paperMark = false
+                    return false
+                }else{
+                    self.studentPaper = response.data;
+                    self.paperMark = true
+                    console.log('paper',self.studentPaper)
+                }
+            });
+            return true
+          },
+          async getMarkedTask(){
+            console.log('getMarkedTask')
+            var self = this;
+            await self.$http.get(MARKING_API+"/markResults/"+this.task.id+"/"+this.markedCurrentPage+"/"+this.pageSize).then((response) => {
+                self.markedResults = response.data.data;
+                self.markedTotal = response.data.pageInfo.totalElements
+                self.markedCurrentPage = response.data.pageInfo.page + 1
+                console.log('markedTask',self.markedResults)
+            });
+          },
+          async getMarkedPaper(studentPaperId){
+            var self = this;
+            await self.$http.get(DATA_PROCESS_API+"/studentPapers/"+studentPaperId+"/"+this.examType).then((response) => {
+                self.studentPaper = response.data;
+            });
+          },
+          async getMarkedResultItems(markResultId){
+            var self = this;
+              await self.$http.get(MARKING_API+"/markResults/"+markResultId).then((response) => {
+                  self.resultItems = response.data.resultItems;
+                  self.markedResult = response.data;
+                  console.log(self.markedResult);
+              });
+          },
+          async getMarkRange(){
+            console.log('getMarkRange')
+            if(!this.paperMark){
+              return
+            }
+            var self = this;
+            await self.$http.get(MARKING_API+"/markRanges/"+self.task.markRangeId).then((response) => {
+                self.markRange = response.data;
+                self.getResultItems(self.markRange)
+                console.log('markRange',self.markRange)
+                console.log('resultItems',self.resultItems)
+            });
+          },
+          getResultItems(markRange){
+            for(let markItem of markRange.markItems){
+              var resultItem = {markItem:markItem,score:''}
+              this.resultItems.push(resultItem)
+            }
+          },
+          async getNext(){
+            //试卷全部评完且回评时不继续获取试卷
+            if(this.backMark && this.allMarked){
+              return
+            }
+            this.initMarkItem()
+            await this.markInit()
+            await this.getPaper()
+            await this.getChangeTasks()
+            await this.getMarkRange()
+            await this.getMarkedTask()
+            this.backMark = false
+          },
+          dateFormatter(row){
+            var fulldate = new Date(row.markedOn)
+            var year = fulldate.getFullYear()
+            var month = fulldate.getMonth() + 1
+            var date = fulldate.getDate()
+            var formatDate = [year,month,date].join('-')
+            return formatDate
+          },
+          initMarkItem(){
+            this.resultItems.splice(0,this.resultItems.length)
+            this.markResult = {}
+            this.markedResult = {}
+          },
+          markSignChange(){
+            if(this.markSign){
+              this.$message({
+                showClose: true,
+                message: '轨迹模式已开启,只支持鼠标操作',
+                type: 'warning'
+              })
+            }
+          }
+      },
+      computed:{
+        allMarked(){
+          if(this.tasks.length == 0){
+              return false
+          }else{
+            for(let task of this.tasks){
+              if(task.leftCount > 0){
+                return false
+              }
+            }
+            return true
+          }
+        },
+        taskCur(){
+          //任务及时动态切换
+          if(this.tasks.length == 0){
+              return 0
+          }else{
+            for(let [index,task] of this.tasks.entries()){
+              if(task.leftCount > 0){
+                return index
+              }
+            }
+            return 0
+          }
+        },
+        changeTaskCur(){
+          for(let [index,task] of this.tasks.entries()){
+            if(task.id == this.task.id){
+              return index
+            }
+          }
+          return this.taskCur
+        },
+        ...mapState({ user: state => state.user })
+      },
+      async created(){
+        this.user.userId=55666;
+        this.loading = true;
+        await this.markInit();
+        await this.getChangeTasks();
+        await this.getPaper();
+        await this.getMarkRange();
+        await this.getMarkedTask();
+        this.getTags();
+        this.loading = false;
+      }
+  }
+</script>

+ 402 - 0
src/modules/marking/views/tp_main.vue

@@ -0,0 +1,402 @@
+<style scoped>
+  .markmain{
+    width:74%;
+  }
+  .scroll{
+    overflow:auto;
+    height: 600px;
+  }
+  .marktitle{
+     margin-right: 20px;
+     margin-bottom: 20px;
+  }
+  .signTitle{
+    margin-left: 35%;
+  }
+  .itemTitle{
+    margin-right: 10px;
+  }
+  .titlefont{
+    font-size: 15px;
+  }
+  li{
+    list-style-type:none;
+  }
+  .markbutton{
+    width:40px;
+    height:40px;
+  }
+  img{
+    width:100%;
+    height:100%;
+  }
+  .paper{
+    width: 90%;
+    min-height: 600px;
+  }
+  .fixed{
+    position: fixed;
+  }
+</style>
+<script src="../assets/js/Print.js"></script>
+<template>
+    <div class="markmain pull-left scroll" id="student_paper">
+      <el-tabs :active-name="activeName">
+        <el-tab-pane label="考生答卷" name="first">
+            <div v-if="this.examType!='OFFLINE'">
+                <div id="main-source" v-if="this.studentPaper.id!=''">
+                    <div class="paper" v-if="!this.markSign" v-html="this.studentPaper.studentSubjectiveHtml">
+                    </div>
+                    <div class="paper" v-show="this.markSign">
+                        <div class="fixed marktitle signTitle">
+                            <el-button-group class="itemTitle">
+                                <el-button type="info" size="small"><span class="">当前题</span></el-button>
+                                <el-button type="info" size="small"><span class="">{{itemTitle}}</span></el-button>
+                            </el-button-group>
+                            <!-- <el-button type="primary" size="small" @click="saveMarkSign">保存轨迹</el-button> -->
+                            <el-button type="danger" size="small" @click="delMarkSign">清除轨迹</el-button>
+                            <el-button type="danger" size="small" @click="delAllMarkSign">清除全部轨迹</el-button>
+                        </div>
+                        <div><canvas id="canvas" width="800px" height="800px"></canvas></div>
+                    </div>
+                </div>
+            </div>
+            <div v-if="this.examType=='OFFLINE'">
+                <div v-if="this.studentPaper.id!=''">
+                    <div v-html="getPdfUrl()" style="float: left;"></div>
+                    <div v-if="this.studentPaper.studentSubjectiveHtml != '' && this.studentPaper.studentSubjectiveHtml.indexOf('.pdf')>-1" style="float: right;margin-right: 20px;" class="no-print">
+                        <el-button size="small" type="success" @click="pdfDown();">
+                            下载
+                        </el-button>
+                    </div>
+                </div>
+            </div>
+
+        </el-tab-pane>
+        <template v-if="this.examType=='OFFLINE'">
+              <el-tab-pane label="标答" name="second">
+                  <div id="answer-source"  v-if="this.examType=='OFFLINE'">
+
+                      <div v-if="" style="float: right;margin-right: 20px;" class="no-print">
+                          <el-button size="small" type="success" @click="printAnswer();">
+                              打印
+                          </el-button>
+                      </div>
+                      <div class="paper" id="answer-content" v-html="getAnswerHtml()"></div>
+                  </div>
+              </el-tab-pane>
+        </template>
+
+        <!-- <el-tab-pane label="标答" name="second">
+          <div id="answer-source" v-if="this.markTask.answer_source.type=='text'">
+            <embed :src="this.markTask.answer_source.url"></embed>
+          </div>
+          <div v-if="this.markTask.answer_source.type=='picture'">
+            <div v-for="url in this.markTask.answer_source.url">
+              <img :src="url"></img>
+            </div>
+          </div>
+        </el-tab-pane>
+
+        <el-tab-pane label="试卷" name="third">
+          <div id="paper-source" v-if="this.markTask.paper_source.type=='text'">
+            <embed :src="this.markTask.paper_source.url"></embed>
+          </div>
+          <div v-if="this.markTask.paper_source.type=='picture'">
+            <div v-for="url in this.markTask.paper_source.url">
+              <img :src="url"></img>
+            </div>
+          </div>
+        </el-tab-pane> -->
+      </el-tabs>
+    </div>
+</template>
+<script>
+    import {Drawing} from '../canvas/mark_sign'
+    import { EVENTHUB,Q_API } from '../constants/constants'
+    export default {
+      data(){
+        return{
+            activeName:'first',
+            drawing:{},
+            tmpSignScores:this.signScores,
+            tmpMarkSign:this.markSign
+        }
+      },
+      props:['paperMarkSign','studentPaper','markSign','signOption','signScores','signItem','examType'],
+      methods:{
+          getPdfUrl(){
+              var url= this.studentPaper.studentSubjectiveHtml;
+              var content ="";
+              if(this.studentPaper.studentSubjectiveHtml != '' && this.studentPaper.studentSubjectiveHtml.indexOf('.pdf')>-1){
+                  content = "<embed src='"+url+"'  width='800px' height='800px'></embed>";
+              }
+              if(this.studentPaper.studentSubjectiveHtml != '' && this.studentPaper.studentSubjectiveHtml.indexOf('.zip')>-1){
+                  content = "<a href='"+url+"'>下载</a>";
+              }
+              return content;
+          },
+          getAnswerHtml(){
+            var content="";
+            if(this.studentPaper.basePaperId){
+              var paperId = this.studentPaper.basePaperId;
+              $.ajax({
+                type: "GET",
+                url: Q_API+"/extract/getAnswerHtml/"+paperId,
+                async: false,
+                success: function(response){
+                  console.log("response:"+response);
+                  content = response
+                }
+              })
+              console.log("answer:"+content);
+            }
+              return content;
+          },
+        createMarkDraw(){
+          console.log('create');
+          var drawing = {};
+          this.signOption.data = this.studentPaper.studentSubjectiveHtml;
+          drawing = new Drawing('canvas',this.signOption);
+          this.drawing = drawing;
+        },
+        intMarkDraw(){
+          console.log('init');
+          if(this.markSign){
+            this.clearScoreLoc();
+            this.clearScores();
+            this.setMarkDrawHtml();
+            this.setSignLocation();
+          }
+        },
+        setMarkDrawHtml(){
+          this.drawing.setHtml(this.studentPaper.studentSubjectiveHtml);
+        },
+        saveMarkSign(){
+          if(this.drawing.canvas && this.signItem.id){
+              localStorage.removeItem(this.paperKey);
+              localStorage.setItem(this.paperKey,JSON.stringify(this.paperSigns));
+              this.$notify({
+                message: '轨迹保存成功',
+                type: 'success'
+              });
+          }else{
+            this.$notify({
+              message: '请选择给分步骤',
+              type: 'error'
+            });
+          }
+        },
+        setSignLocation(){
+          let signStorage = localStorage.getItem(this.paperKey);
+          console.log('signStorage',signStorage);
+          if(typeof signStorage == 'string'){
+            let paperSigns = JSON.parse(signStorage);
+            if(this.drawing.scoreLoc.length == 0 ||
+                paperSigns.length > this.drawing.scoreLoc.length){
+              this.drawing.setLocation(paperSigns,'localStorage');
+            }else{
+              this.drawing.setLocation(this.drawing.scoreLoc,'cache');
+            }
+          }else{
+            this.drawing.setLocation(this.drawing.scoreLoc,'cache');
+          }
+          this.setSignItemId();
+        },
+        setSignItemId(){
+          var signItem = Object.assign({},this.signItem);
+          this.drawing.setItemId(signItem.id);
+        },
+        setSignScores(){
+          let signStorage = localStorage.getItem(this.paperKey);
+          if(typeof signStorage == 'string'){
+            let paperSigns = JSON.parse(signStorage);
+            if(paperSigns.length > 0){
+              for(let [index,paperSign] of paperSigns.entries()){
+                if(paperSign.itemId == this.signItem.id){
+                    this.tmpSignScores.push(paperSign.score);
+                }
+              }
+            }
+          }
+          console.log('signScores',this.signScores);
+        },
+        delMarkSign(){
+          if(this.drawing.canvas){
+            this.removeItemSign();
+            this.clearScores();
+            this.drawing.ResetDrawAll();
+            this.setSignLocation();
+            this.$notify({
+              message: '轨迹清除成功',
+              type: 'success'
+            });
+          }
+        },
+        removeItemSign(){
+          let signStorage = localStorage.getItem(this.paperKey);
+          if(typeof signStorage == 'string'){
+            let paperSigns = JSON.parse(signStorage);
+            this.removeLS(paperSigns);
+            this.removeCache();
+          }else{
+            this.removeCache();
+          }
+        },
+        removeLS(paperSigns){
+            for (let i = paperSigns.length - 1; i >= 0; i--) {
+              if(paperSigns[i].itemId == this.signItem.id){
+                  paperSigns.splice(i,1);
+              }
+            }
+            if(paperSigns.length > 0){
+              localStorage.removeItem(this.paperKey);
+              localStorage.setItem(this.paperKey,JSON.stringify(paperSigns));
+            }else{
+              localStorage.removeItem(this.paperKey);
+              this.clearScoreLoc();
+            }
+        },
+        removeCache(){
+          for (let i = this.drawing.scoreLoc.length - 1; i >= 0; i--) {
+            if(this.drawing.scoreLoc[i].itemId == this.signItem.id){
+                this.drawing.scoreLoc.splice(i,1);
+            }
+          }
+        },
+        delAllMarkSign(){
+          if(this.drawing.canvas){
+            localStorage.removeItem(this.paperKey);
+            this.clearScores();
+            this.clearScoreLoc();
+            this.drawing.ResetDrawAll();
+            this.$notify({
+              message: '轨迹全部清除成功',
+              type: 'success'
+            });
+          }
+        },
+        changeMarkSign(){
+          if(this.signItem){
+            this.drawing.ResetDrawAll();
+            console.log('paperSign',localStorage.getItem(this.paperKey));
+            this.setSignLocation();
+            this.setSignScores();
+          }
+        },
+        //清除分数
+        clearScores(){
+          this.tmpSignScores.splice(0,this.tmpSignScores.length);
+          this.$emit('clearScores');
+        },
+        //清除分数坐标
+        clearScoreLoc(){
+          this.drawing.clearScoreLoc();
+        },
+          //打印
+          printAnswer(){
+             Print('#answer-source');
+          },
+          pdfDown(){
+              var url= this.studentPaper.studentSubjectiveHtml;
+              if(url != ''){
+                  url = url.replace(UPAI_YUN,'');
+                  let xhr = new XMLHttpRequest()
+                  xhr.responseType = 'blob'
+                  xhr.open('GET', url, true)
+                  xhr.onload = function () {
+                      if (this.status === 200) {
+                          let blob = this.response
+                          let reader = new FileReader()
+                          reader.readAsDataURL(blob)
+                          reader.onload = function (e) {
+                              let a = document.createElement('a')
+                              a.download = url.substr(url.lastIndexOf("/")+1)
+                              a.href = e.target.result
+                              document.body.appendChild(a)
+                              a.click()
+                              a.parentNode.removeChild(a)
+                          }
+                      }
+                  }
+                  xhr.send()
+              }else {
+                  this.$notify({
+                      message: '离线url为空',
+                      type: 'warning'
+                  })
+              }
+          }
+
+    },
+      computed:{
+        itemTitle(){
+          if(!this.markSign)return '无';
+          var title = '无';
+          if(this.signItem.id){
+            title = (Number.parseInt(this.signItem.mainNumber)+1)+"("+this.signItem.orders+")";
+          }
+          return title;
+        },
+        itemKey(){
+          if(!this.markSign)return '';
+          return this.studentPaper.id+"-"+this.signItem.id;
+        },
+        paperKey(){
+          if(!this.markSign)return '';
+          return this.studentPaper.id;
+        },
+        paperSigns(){
+          if(!this.markSign)return [];
+          var paperSigns = [];
+          if(this.drawing.scoreLoc.length > 0){
+            for(let scoreLoc of this.drawing.scoreLoc){
+              paperSigns.push({
+                loc:scoreLoc.loc,
+                score:scoreLoc.score,
+                itemId:scoreLoc.itemId});
+            }
+          }
+          return paperSigns;
+        }
+      },
+      watch:{
+        signItem(val){
+          if(this.markSign){
+            console.log('signItem',val);
+            this.changeMarkSign();
+          }
+        },
+        studentPaper(val){
+          if(this.markSign){
+            this.intMarkDraw();
+          }
+        },
+        tmpSignScores(val){
+          this.$emit('changeSignScores',val);
+        },
+        signScores(val){
+          this.tmpSignScores = val
+        },
+        markSign(val){
+          this.intMarkDraw();
+        },
+        paperSigns(val){
+          this.$emit('changePaperSign',val);
+        }
+      },
+      updated(){
+      },
+      mounted(){
+        //this.createMarkDraw();
+      },
+      created(){
+        EVENTHUB.$on("positionDiv",function (id) {
+            $("#student_paper").scrollTop(0);
+            var height = $("#anchor-"+id).outerHeight(true);
+            var y = $("#anchor-"+id).offset().top-height/2;
+            $("#student_paper").scrollTop(y-5);
+        })
+      }
+    }
+</script>

+ 703 - 0
src/modules/marking/views/tp_scoreboard.vue

@@ -0,0 +1,703 @@
+<style scoped>
+  .scoreboard{
+    width:25%;
+    border-left:3px solid #20A0FF;
+    min-height: 600px;
+  }
+  .scroll{
+    overflow:auto;
+    height: 300px;
+  }
+  .itemScroll{
+    overflow:auto;
+    height: 150px;
+  }
+  .scoreScroll{
+    overflow:auto;
+    height: 100px;
+  }
+  .scoretitle{
+     margin-right: 20px;
+     margin-bottom: 20px;
+  }
+  li{
+    list-style-type:none;
+  }
+  .scorebutton{
+    width:40px;
+    height:40px;
+  }
+  .titlebutton{
+    width:50px;
+    height:56px;
+  }
+  .actionbutton{
+    width:80px;
+    height:30px;
+  }
+  .score{
+    color: red;
+    display: block;
+  }
+  .totalScore{
+    color: red;
+    text-align: center;
+  }
+  .clear{ clear:both}
+  .backcolor{
+    background-color: #e4eaec;
+  }
+  .board-margin{
+    margin-left: 20px;
+  }
+  .sub-btn{
+    margin-right:15px;
+  }
+  .active-btn{
+    background-color: #4cb0f9;
+    border-color: #4cb0f9;
+    color: #FFF;
+  }
+  .box-card {
+    margin-bottom: 30px;
+    text-align: center;
+  }
+  .score-input{
+    background-color: #ECF0F5;
+    border: 1px solid #000;
+    border-top: 0;
+    border-left: 0;
+    border-right: 0;
+    box-sizing: border-box;
+    color: #1f2d3d;
+    font-size: 20px;
+    height: 30px;
+    width:60px;
+    padding: 2px 10px;
+    transition: border-color .2s cubic-bezier(.645,.045,.355,1);
+    outline:none;
+}
+</style>
+<template>
+    <div class="scoreboard pull-right">
+      <div class="board-margin">
+        <div class="pull-right">
+          <el-switch v-model="isMouseMode" on-text="鼠标" off-text="键盘" on-color="#4cb0f9" off-color="#13ce66"></el-switch>
+        </div>
+        <h3 class="totalScore">总分:{{this.totalScore}}分</h3>
+        <!--鼠标模式-->
+        <div v-if="isMouseMode">
+          <el-tabs :active-name="activeName">
+            <el-tab-pane label="评分" name="first">
+              <ul class="itemScroll">
+                <li :key="resultItem.markItem.id" v-for="(resultItem,index) in resultItems" class="pull-left scoretitle">
+                  <a v-bind:class="{'active-btn':itemClass[index]}" :id="resultItem.markItem.id" @click="itemClick(resultItem.markItem.id,$event,resultItem.markItem.orders)" class='button button-border button-box button-primary button-small titlebutton'>
+                    <label class="">{{(resultItem.markItem.mainNumber)}}({{resultItem.markItem.orders}})</label>
+                    <label class="score">{{resultItem.score}}分</label>
+                  </a>
+                </li>
+                <li class="clear"></li>
+              </ul>
+            </el-tab-pane>
+          </el-tabs>
+
+          <el-tabs :active-name="markType" v-if="markTypeView">
+            <el-tab-pane label="打分" name="mouse">
+              <ul class="scoreScroll">
+                <li :key="score" v-for="score in itemScores" class="pull-left scoretitle">
+                  <button @click="scoreClick(score)" class='button button-primary button-box scorebutton'>
+                    <label>{{score}}</label>
+                  </button>
+                </li>
+              </ul>
+            </el-tab-pane>
+          </el-tabs>
+        </div>
+        <!--键盘模式-->
+        <div v-if="!isMouseMode">
+          <el-tabs :active-name="activeName">
+            <el-tab-pane label="评分" name="first">
+              <ul class="scroll">
+                <li :key="resultItem.markItem.id" v-for="(resultItem,index) in resultItems" class="pull-left scoretitle">
+                    <div class="box-card">
+                      <div>
+                        <el-button-group>
+                          <el-button size="small" type="primary">
+                            <span style="font-size:15px;font-weight:bold">
+                              {{(resultItem.markItem.mainNumber)}}({{resultItem.markItem.orders}})
+                            </span>
+                          </el-button>
+                          <el-button size="small" type="primary">
+                            <span style="font-size:15px;font-weight:bold">
+                              <span>{{resultItem.markItem.maxScore}}分</span>
+                            </span>
+                          </el-button>
+                          <el-button size="small" type="primary">
+                            <span style="font-size:15px;font-weight:bold;">间隔:{{resultItem.markItem.scoreInterval}}
+                            </span>
+                          </el-button>
+                        </el-button-group>
+                      </div>
+                      <div style="text-align:center;font-size:15px;font-weight:bold">
+                        <input :id="getItemId(resultItem.markItem.id)"
+                          @focus="scoreFocus(resultItem)" 
+                          @keydown.enter="scoreEnter(index,resultItem)" 
+                          @keydown.up="scoreUp(index,resultItem)" 
+                          @keydown.down="scoreDown(index,resultItem)" 
+                          @change="scoreChange(index,resultItem.score)"
+                               v-model="resultItem.score" class="score-input"/>
+                        分
+                      </div>
+                    </div>
+                </li>
+                <li class="clear"></li>
+              </ul>
+            </el-tab-pane>
+          </el-tabs>
+
+
+        </div>
+
+        <el-tabs :active-name="activeName">
+          <el-tab-pane label="备注" name="first">
+            <ul class="scoreScroll">
+              <li>
+                <el-input
+                        type="textarea"
+                        :rows="3"
+                        placeholder="请输入内容"
+                        v-model="textarea" :value="this.markRemarkInfo">
+                </el-input>
+              </li>
+            </ul>
+          </el-tab-pane>
+        </el-tabs>
+
+        <el-tabs :active-name="op">
+          <el-tab-pane label="操作" name="first">
+            <ul v-if="problemView">
+              <span v-if="tagFlag">
+                <el-radio-group v-model="markedResult.tag" @change="processTagPaper">
+                  <li class="pull-left scoretitle" v-for="tag in tags">
+                      <el-radio :label="tag.code">{{tag.name}}</el-radio>
+                  </li>
+                </el-radio-group>
+              </span>
+              <span v-if="!tagFlag">
+                <el-radio-group v-model="unusualType" @change="processTagPaper">
+                    <li class="pull-left scoretitle" v-for="tag in tags">
+                        <el-radio :label="tag.code" :key="tag.code">{{tag.name}}</el-radio>
+                    </li>
+                </el-radio-group>
+              </span>
+              <li class="clear"></li>
+            </ul>
+            <ul>
+              <li class="pull-left scoretitle" v-if="paperMark">
+                <el-button id="subMarkBtn" :loading="loading" type="primary" size="large" @keydown.enter="submitMark" @click="submitMark"><span class="sub-btn">提</span><span>交</span></el-button>
+              </li>
+              <li class="pull-left scoretitle" v-if="paperMark">
+                <el-button type="danger" size="large" @click="problemClick">问题卷</el-button>
+              </li>
+              <li class="pull-left scoretitle" v-if="paperMark && problemView">
+                <el-button type="danger" size="large" @click="resetProblem">清除问题卷</el-button>
+              </li>
+            </ul>
+          </el-tab-pane>
+        </el-tabs>
+      </div>
+    </div>
+</template>
+<script>
+import { mapActions } from 'vuex'
+import { USER_SIGNOUT } from '../../portal/store/user'
+import { mapState } from 'vuex'
+import { CORE_API,MARKING_API} from '../constants/constants'
+    export default {
+      data(){
+        return{
+            activeName:'first',
+            markType:'mouse',
+            isMouseMode:true,
+            op:'first',
+            maxScore:0,
+            markItemId:'',
+            resultItem:{
+              markItem: {},
+              score: 0
+            },
+            markTypeView:false,
+            problemView:false,
+            markBack:false,
+            markSame:false,
+            markBlank:false,
+            markDiff:false,
+            curIndex:0,
+            steps:[],
+            loading:false,
+            tmpSignItem:this.signItem,
+            tags:[],
+            unusualType:'',
+            scoreError:[],
+            textarea:''
+        }
+      },
+      props:['paperMarkSign','signScores','signChange','signOption','markSign','markRange','studentPaperId','markTaskId','resultItems','markedResult','paperMark'],
+      methods:{
+        ...mapActions([USER_SIGNOUT]),
+        resetProblem(){
+          if(this.markedResult.tag){
+            this.markedResult.tag = '';
+          }
+          if(this.unusualType){
+            this.unusualType = '';
+          }
+        },
+        //处理问题卷
+        processTagPaper(tag){
+          if(!this.markedResult.id){
+            if(this.unusualType){
+              for(let resultItem of this.resultItems){
+                resultItem.score = 0;
+              }
+            }
+          }else{
+            if(this.markedResult.tag){
+              for(let resultItem of this.resultItems){
+                resultItem.score = 0;
+              }
+            }
+          }
+        },
+        getTags(){
+          this.$http.get(MARKING_API+"/markResults/tag")
+            .then((response) => {
+                this.tags = response.data;
+                //移除科目错误
+                for(let i=0;i < this.tags.length;i++){
+                  if(this.tags[i].code === 'SUBJECT_ERROR'){
+                    this.tags.splice(i,1);
+                  }
+                }
+          })
+        },
+        saveMarkSign(){
+          localStorage.removeItem(this.paperKey);
+          localStorage.setItem(this.paperKey,JSON.stringify(this.paperMarkSign));
+        },
+        checkItemClass(resultItem){
+          if(resultItem.score.length > 0){
+            return true
+          }else{
+            return false
+          }
+        },
+        itemClick(id,event,order){
+          this.markTypeView = true
+          this.resultItems.find((value, index, array) => {
+              if(value.markItem.id === id){
+                  this.maxScore = value.markItem.maxScore
+                  this.markItemId = value.markItem.id
+                  if(value.score.length>0){
+                      this.resultItem = value
+                  }else {
+                      this.resultItem = {
+                          markItem: value.markItem,
+                          score: "" }
+                  }
+                  this.curIndex = index
+              }
+          })
+          this.showItemTitle()
+          if(this.markSign){
+            this.tmpSignItem = this.resultItem.markItem
+            this.signScores.splice(0,this.signScores.length)
+          }
+          this.positionDiv(order);
+        },
+        positionDiv(order){
+          this.$emit("positionDiv",order);
+        },
+        showItemTitle(){
+          var title = (this.resultItem.markItem.mainNumber)+"("+this.resultItem.markItem.orders+")"
+          this.$message({
+            showClose: true,
+            message: '当前选择题目为'+title,
+            type: 'info',
+            duration: 1000
+          })
+        },
+        checkSignScore(score){
+          var sum = 0
+          for(let signScore of this.signScores){
+            sum += signScore
+          }
+          if(sum + score > this.maxScore){
+            return false
+          }else{
+            return true
+          }
+        },
+        checkScore(resultItem){
+          var score = resultItem.score + "";
+          var maxScore = resultItem.markItem.maxScore + "";
+          var scoreInterval = resultItem.markItem.scoreInterval + "";
+          if(score.trim().length === 0){
+            this.$notify({
+                message: '分数不能为空',
+                type: 'error',
+                duration: 1000
+            });
+            return false;
+          }else{
+            let regex = scoreInterval == 1 ? "^\\d+$" : "^\\d+(\\.[5])?$";
+            if(!score.match(regex)){
+              this.$notify({
+                message: '分数必须为数字,且格式要正确(包括间隔分)',
+                type: 'error',
+                duration: 1000
+              });
+              return false;
+            }else{
+              if(parseFloat(score) > parseFloat(maxScore)){
+                this.$notify({
+                  message: '分数不能超过'+maxScore+'分',
+                  type: 'error',
+                  duration: 1000
+                });
+                return false;
+              }
+            }
+          }
+          return true;
+        },
+        scoreClick(score){
+          //轨迹模式处理分值问题
+          if(this.markSign){
+            if(this.checkSignScore(score)){
+              this.signScores.push(score)
+              this.signOption.score = score
+              this.resultItem.score = this.signScoreSum
+              this.resultItems[this.curIndex].score = this.signScoreSum
+            }else{
+              this.$notify({
+                message: '轨迹总分不能超过满分',
+                type: 'error'
+              })
+            }
+          }else{//正常模式
+            this.resultItem.score = score;
+            this.resultItems[this.curIndex].score = score;
+          }
+        },
+        //键盘打分板change事件
+        scoreChange(index,score){
+          this.resultItem.score = score;
+          this.resultItems[index].score = score;
+        },
+        //键盘打分板聚焦后试卷跳转对应试题
+        scoreFocus(resultItem){
+          var order = resultItem.markItem.orders;
+          this.positionDiv(order);
+        },
+        //键盘打分板下键跳转下一题
+        scoreDown(index,resultItem){
+          var curItemId = this.resultItems[index].markItem.id;
+          var curItemInput = "item"+curItemId;
+          if(!this.checkScore(resultItem)){
+            document.getElementById(curItemInput).focus();
+            return;
+          }
+          if(index === this.resultItems.length - 1){
+            return;
+          }else{
+            var nextResultItem = this.resultItems[index+1];
+            var nextItemId = nextResultItem.markItem.id;
+            var nextItemInput = "item"+nextItemId;
+            var order = nextResultItem.markItem.orders;
+            document.getElementById(nextItemInput).focus();
+            this.positionDiv(order);
+          }
+        },
+        //键盘打分板上键跳转上一题
+        scoreUp(index,resultItem){
+          var curItemId = this.resultItems[index].markItem.id;
+          var curItemInput = "item"+curItemId;
+          if(!this.checkScore(resultItem)){
+            document.getElementById(curItemInput).focus();
+            return;
+          }
+          if(index === 0){
+            var preResultItem = this.resultItems[0];
+            var preItemId = preResultItem.markItem.id;
+            var preItemInput = "item"+preItemId;
+            var order = preResultItem.markItem.orders;
+            document.getElementById(preItemInput).focus();
+            this.positionDiv(order);
+          }else{
+            var preResultItem = this.resultItems[index-1];
+            var preItemId = preResultItem.markItem.id;
+            var preItemInput = "item"+preItemId;
+            var order = preResultItem.markItem.orders;
+            document.getElementById(preItemInput).focus();
+            this.positionDiv(order);
+          }
+        },
+        //键盘打分板回车后跳转下一题
+        scoreEnter(index,resultItem){
+          if(!this.checkScore(resultItem)){
+            var curItemId = this.resultItems[index].markItem.id;
+            var curItemInput = "item"+curItemId;
+            document.getElementById(curItemInput).focus();
+            return;
+          }
+          if(index === this.resultItems.length - 1){
+            document.getElementById("#subMarkBtn").focus();
+          }else{
+            var nextResultItem = this.resultItems[index+1];
+            var nextItemId = nextResultItem.markItem.id;
+            var nextItemInput = "item"+nextItemId;
+            var order = nextResultItem.markItem.orders;
+            document.getElementById(nextItemInput).focus();
+            this.positionDiv(order);
+          }
+        },
+        getItemId(itemId){
+          return "item"+itemId;
+        },
+        problemClick(){
+          this.problemView = !(this.problemView);
+        },
+        checkItems(){
+          var itemName = ''
+          for (var resultItem of this.resultItems) {
+            if(resultItem.score.length == 0){
+              itemName = Number.parseInt(resultItem.markItem.mainNumber)+"("+resultItem.markItem.orders+")"
+              this.$notify({
+                message: itemName + '没有打分,请打分',
+                type: 'error'
+              })
+              return false;
+            }else{
+              if(!this.checkScore(resultItem)){
+                return false;
+              }
+            }
+          }
+          return true;
+        },
+        submitMark(){
+          if(!this.checkItems()){
+              return;
+          }
+          this.processTagPaper();
+          this.loading = true;
+          if(!this.markedResult.id){
+            console.log('提交resultItems',this.resultItems)
+            this.$http.post(MARKING_API+"/markResults?studentPaperId="
+              +this.studentPaperId+"&markTaskId="+this.markTaskId+"&tag="+this.unusualType+"&remark="+this.textarea,this.resultItems)
+              .then((response) => {
+                  this.saveMarkSign()
+                  console.log(response)
+                  if(response.data.id){
+                    this.$notify({
+                      message: '提交成功',
+                      type: 'success'
+                    })
+                  }else{
+                    this.$notify({
+                      message: '提交失败',
+                      type: 'error'
+                    })
+                  }
+                  this.$emit('submitMark')
+                  this.loading = false
+                  this.markTypeView = false
+                  this.problemView = false
+                  this.unusualType = '';
+                  //this.textarea = '';
+            }, (response) => {
+                // 响应错误回调
+                console.log(response)
+                if(response.data.desc){
+                  var errorInfo = response.data.desc
+                  if(errorInfo.includes("超时")){
+                    this.$alert('该评卷任务已超时,请点击确定重新登录!', '提示', {
+                      confirmButtonText: '确定',
+                      callback: action => {
+                          var loginUrl = sessionStorage.getItem("loginUrl");
+                          this.$http.post(CORE_API + "/auth/logout"
+                          ).then((response) => {
+                              this.USER_SIGNOUT();
+                              sessionStorage.clear();
+                              if (loginUrl) {
+                                  window.location.href = loginUrl;
+                              } else {
+                                  window.location.href = "about:blank";
+                              }
+                          }).catch((response) => {
+                              this.USER_SIGNOUT();
+                              sessionStorage.clear();
+                              if (loginUrl) {
+                                  window.location.href = loginUrl;
+                              } else {
+                                  window.location.href = "about:blank";
+                              }
+                          });
+                        return
+                      }
+                    })
+                  }else{
+                    this.$notify({
+                      message: response.data.desc,
+                      type: 'error'
+                    })
+                    this.$emit('submitMark')
+                    this.loading = false
+                    this.markTypeView = false
+                    this.problemView = false
+                    this.unusualType = '';
+                    //this.textarea = '';
+                  }
+                }else{
+                  this.$notify({
+                    message: '提交失败',
+                    type: 'error'
+                  })
+                  this.$emit('submitMark')
+                  this.loading = false
+                  this.markTypeView = false
+                  this.problemView = false
+                  this.unusualType = '';
+                  //this.textarea = '';
+                }
+            })
+          }else{
+            console.log('markedResult',this.markedResult)
+            this.markedResult.resultItems = this.resultItems
+            this.markedResult.remark = this.textarea;
+            this.$http.put(MARKING_API+"/markResults",this.markedResult)
+              .then((response) => {
+                  this.saveMarkSign()
+                  console.log(response)
+                  this.$notify({
+                    message: '提交成功',
+                    type: 'success'
+                  })
+                  this.$emit('submitMark')
+                  this.loading = false
+                  this.markTypeView = false
+                  this.problemView = false
+                  this.unusualType = '';
+                  //this.textarea = '';
+            }, (response) => {
+                // 响应错误回调
+                console.log(response)
+                if(response.data.desc){
+                  this.$notify({
+                    message: response.data.desc,
+                    type: 'error'
+                  })
+                }else{
+                  this.$notify({
+                    message: '提交失败',
+                    type: 'error'
+                  })
+                }
+                this.$emit('submitMark')
+                this.loading = false
+                this.markTypeView = false
+                this.problemView = false
+                this.unusualType = '';
+                //this.textarea = '';
+            })
+          }
+        },
+        initKeyBoardMode(){
+          var itemId = this.resultItems[0].markItem.id;
+          var order = this.resultItems[0].markItem.orders;
+          var itemInput = "item"+itemId;
+            setTimeout(function(){ document.getElementById(itemInput).focus();}, 1);
+          this.positionDiv(order);
+        }
+      },
+      watch:{
+        signItem(val){
+          this.tmpSignItem = val
+        },
+        tmpSignItem(val){
+          this.$emit('changeSign',val)
+        },
+        isMouseMode(val){
+          if(!val){
+            this.initKeyBoardMode();
+          }
+        },
+        studentPaperId(val){
+          if(!this.isMouseMode){
+            this.initKeyBoardMode();
+          }
+        }
+      },
+      computed:{
+        tagFlag(){
+          if(this.markedResult.id){
+            return true;
+          }else{
+            return false;
+          }
+        },
+        paperKey(){
+          if(!this.markSign)return '';
+          return this.studentPaperId;
+        },
+        signScoreSum(){
+          var sum = 0
+          for(let signScore of this.signScores){
+            sum += signScore
+          }
+          return sum
+        },
+        itemClass(){
+          var itemClass = []
+          for (let resultItem of this.resultItems) {
+            if(resultItem.score.length == 0){
+              itemClass.push(false)
+            }else{
+              itemClass.push(true)
+            }
+          }
+          return itemClass
+        },
+        totalScore(){
+          var totalScore = 0
+          for (let resultItem of this.resultItems) {
+            if(resultItem.score.length == 0){
+              totalScore += 0
+            }else{
+              totalScore += Number.parseFloat(resultItem.score)
+            }
+          }
+          return totalScore
+        },
+        itemScores(){
+          var itemScores = [];
+          var scoreInterval = this.resultItem.markItem.scoreInterval;
+          for(let i = 0,j = 0;i <= this.resultItem.markItem.maxScore;i+=scoreInterval,j++){
+            itemScores[j] = i;
+          }
+          return itemScores;
+        },
+        markRemarkInfo(){
+          this.textarea = '';
+          if(this.markedResult.id){
+            this.textarea = this.markedResult.markRemark;
+          }
+        },
+        ...mapState({ user: state => state.user })
+      },
+      created(){
+        this.getTags();
+      }
+    }
+</script>