uploadPaper.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. <template>
  2. <section class="content">
  3. <div class="breadcrumb">
  4. <el-breadcrumb separator="/">
  5. <el-breadcrumb-item><a href="/">阅卷管理</a></el-breadcrumb-item>
  6. <el-breadcrumb-item>上传试卷</el-breadcrumb-item>
  7. </el-breadcrumb>
  8. </div>
  9. <!-- 上传试卷 -->
  10. <el-row :gutter="20">
  11. <el-col :span="24">
  12. <!-- <el-row>
  13. <el-col :span="6">参考人数:{{studentsList.length}}</el-col>
  14. <el-col :span="6">已上传:{{studentsList.length}}</el-col>
  15. <el-col :span="6">识别异常:</el-col>
  16. </el-row> -->
  17. <el-form :inline="true">
  18. <el-form-item label="姓名">
  19. <el-input size="mini" placeholder="请输入姓名/考号" v-model="queryName" clearable></el-input>
  20. </el-form-item>
  21. <!--<el-form-item label="识别异常">
  22. <el-select v-model="queryMarkStatus" size="mini" clearable>
  23. <el-option v-for="item in $const.recErrorList" :label="item.label" :value="item.value"></el-option>
  24. </el-select>
  25. </el-form-item>-->
  26. <el-form-item>
  27. <el-button type="primary" size="mini" @click="searchMarkData">搜索</el-button>
  28. <el-button size="mini" @click="reSetMarkData">重置</el-button>
  29. <el-button @click="downloadObjectiveResult(curTaskId)" type="warning" size="mini" icon="el-icon-download">
  30. 导出</el-button>
  31. <el-button @click="reTryMark" size="mini" type="success" icon="el-icon-printer">重新识别</el-button>
  32. </el-form-item>
  33. <el-form-item>
  34. <el-button size="mini" type="warning" icon="el-icon-printer" @click='starScanPaper(curTaskId,"http://test.scxjc.club/api/admin/papers/uploadpaper")'>试卷扫描</el-button>
  35. </el-form-item>
  36. <el-form-item>
  37. <el-upload class="upload-demo" action="http://test.scxjc.club/api/admin/papers/uploadpaper"
  38. :on-success="handleUploadSuccess" :data="{taskid:taskid}" :on-change="handleChange" list-type="picture"
  39. multiple>
  40. <el-button size="mini" type="primary" @click="openTaskImgList">点击上传</el-button>
  41. </el-upload>
  42. </el-form-item>
  43. </el-form>
  44. <el-row>
  45. <el-col :span="24">
  46. <el-tabs v-model="activeName" @tab-click="handleTabClick">
  47. <el-tab-pane :label="'正确('+recSucTotal+')'" name="1"></el-tab-pane>
  48. <el-tab-pane :label="'定位异常('+recKhErrTotal+')'" name="-5"></el-tab-pane>
  49. <el-tab-pane :label="'考号异常('+recKhErrTotal+')'" name="-1"></el-tab-pane>
  50. <el-tab-pane :label="'考号重复('+recKhErrTotal+')'" name="-3"></el-tab-pane>
  51. <el-tab-pane :label="'缺考异常('+recKhErrTotal+')'" name="-4"></el-tab-pane>
  52. <el-tab-pane :label="'客观题异常('+recObjErrTotal+')'" name="-2"></el-tab-pane>
  53. <el-tab-pane :label="'待上传('+recWaitingErrTotal+')'" name="0"></el-tab-pane>
  54. </el-tabs>
  55. </el-col>
  56. </el-row>
  57. <el-table v-loading="loading" :data="studentsList" style="width: 100%; margin-top: 10px"
  58. @selection-change="handleSelectionChange" height="60vh">
  59. <el-table-column type="selection" width="45" v-if="activeName==100"></el-table-column>
  60. <el-table-column align="center" prop="student_name" label="姓名" width="80" />
  61. <el-table-column align="center" prop="student_no" label="考号" width="150">
  62. <template slot-scope="scope">
  63. <el-button type="text" @click="showStudentImgs(scope.row)" size="mini">{{scope.row.student_no}}
  64. </el-button>
  65. </template>
  66. </el-table-column>
  67. <el-table-column align="center" prop="objective_ans_str" label="客观题识别结果"/>
  68. <el-table-column align="center" prop="objective_score" label="客观题得分" width="100" />
  69. <el-table-column align="center" prop="mark_status_name" label="识别状态" width="80">
  70. <template slot-scope="scope">
  71. <span v-if="scope.row.mark_status<=0" style="color:#f78989;">{{scope.row.mark_status_name}}</span>
  72. <span v-if="scope.row.mark_status==1" style="color:#85ce61;">正常</span>
  73. </template>
  74. </el-table-column>
  75. <el-table-column align="center" prop="ctime" label="时间" width="140px">
  76. <template slot-scope="scope">
  77. <span style="font-size:12px;">{{scope.row.ctime}}</span>
  78. </template>
  79. </el-table-column>
  80. <el-table-column align="center" prop="date" label="操作" fixed="right" width="160px">
  81. <template slot-scope="scope">
  82. <!--<el-button v-if="scope.row.mark_status!=0" @click="showCurRecImg(scope.row)" size="mini" type="text">查看
  83. </el-button>
  84. <el-button v-if="scope.row.mark_status!=0" @click="showCurRecKhImg(scope.row)" size="mini" type="text">
  85. 考号</el-button>-->
  86. <el-button @click="delStudents(scope.row.student_id,scope.$index,'delRec')" size="mini" type="text">删除识别结果
  87. </el-button>
  88. <el-button @click="delStudents(scope.row.student_id,scope.$index,'delStudent')" size="mini" type="text">删除学生
  89. </el-button>
  90. </template>
  91. </el-table-column>
  92. </el-table>
  93. <Page ref="pageButton" :current="recPage" :page_size="recPageSize" :total="recTotal"
  94. @pageChange="goRecPage" />
  95. </el-col>
  96. </el-row>
  97. <!-- 试卷上传预览 -->
  98. <el-dialog title="试卷预览" :visible.sync="imgListVisible" width="750px" @close="closeTaskImgDialog" append-to-body>
  99. <div style="text-align:right;">
  100. <font>成功上传:{{taskImgTotal}}</font>&nbsp;&nbsp;&nbsp;&nbsp;
  101. <el-button v-loading="loading" type="primary" size="mini" @click="startRecPaper">开始识别</el-button>
  102. </div>
  103. <div style="width:156px;display: inline-block;margin:10px;border:1px solid #ccc;"
  104. v-for="(item,index) in fileList">
  105. <el-image width="100px" alt="" :src="item.url" :preview-src-list="[item.url]"></el-image>
  106. </div>
  107. <Page ref="pageImgButton" :current="imgForm.page" :page_size="imgForm.page_size" :total="taskImgTotal" @pageChange="goTaskImg" />
  108. </el-dialog>
  109. <!-- 预览识别结果 -->
  110. <el-dialog title="异常处理" :visible.sync="showAnsVisible" width="90%" append-to-body>
  111. <el-form ref="form" :model="form" :rules="rules" label-width="120px" :inline="true">
  112. <el-row :gutter="20">
  113. <!--试卷预览-->
  114. <el-col :span="16" style="border:1px solid #ccc;">
  115. <img :src="curStudentRecImg" id="myCanvasImg" style="display:none;" />
  116. <canvas id="myCanvas" ref="myCanvas" :width="srcImgWidth*canvasImgScale" :height="srcImgHeight*canvasImgScale"></canvas>
  117. </el-col>
  118. <!--异常处理-->
  119. <el-col :span="8">
  120. <!--考号异常-->
  121. <el-row v-if="activeName==-1">
  122. <el-col :span="20">
  123. <el-form-item v-if="activeName==-1" label-width="80">
  124. <el-input v-model="curStudentNo" size="mini" />
  125. </el-form-item>
  126. </el-col>
  127. <el-col :span="4">
  128. <el-form-item v-if="activeName==-1">
  129. <el-button type="primary" @click="searchStudents" size="mini">搜索</el-button>
  130. </el-form-item>
  131. </el-col>
  132. </el-row>
  133. <!--客观题异常-->
  134. <el-row v-if="activeName==-2">
  135. <div class="kgtContainer">
  136. <div class="topContainer">
  137. <div class="topItem">待处理:2</div>
  138. <div class="topItem">
  139. <el-button type="primary" size="mini" @click="saveModifQueAns">保存</el-button>
  140. </div>
  141. </div>
  142. <div class="kgtItem" v-for="oitem in objectiveRecResult">
  143. <span class="tag-group__title">{{oitem.qno}}、</span>
  144. <el-tag :effect="oitem.fillNum.indexOf(index)!=-1?'dark':'plain'" v-for="(item,index) in oitem.points.length" :key="item.label" type="success"
  145. @click="setStdAns(oitem,index)"
  146. size="small">
  147. {{ $const.ansOptionList[index]["label"] }}
  148. </el-tag>&nbsp;&nbsp;&nbsp;&nbsp;
  149. <el-tag effect="dark" size="small" :type="oitem.fillNum.length<1?'danger':'plain'">未涂</el-tag>
  150. <el-tag effect="dark" size="small" :type="oitem.fillNum.length>1 && oitem.qtype==1?'danger':'plain'">多涂</el-tag>
  151. </div>
  152. </div>
  153. </el-row>
  154. <el-row style="border:1px solid #ccc;padding:10px;" v-for="(item,index) in searchStudentsData">
  155. <el-col :span="20">
  156. <p>{{item.name}}</p>
  157. <p>{{item.student_no}}</p>
  158. <p>{{item.school_name}}{{item.grade_name}}{{item.class_name}}</p>
  159. </el-col>
  160. <el-col :span="4">
  161. <el-button type="primary" @click="saveModifyStudentNo" size="mini">确定</el-button>
  162. </el-col>
  163. </el-row>
  164. </el-col>
  165. </el-row>
  166. </el-form>
  167. <div slot="footer" class="dialog-footer">
  168. <el-button @click="showAnsVisible = false">关 闭</el-button>
  169. </div>
  170. </el-dialog>
  171. <!-- 重新识别 -->
  172. <el-dialog title="重新识别" :visible.sync="remarkDialogVisible" width="60%" @close="closeRemarkDialog">
  173. <el-form :inline="true">
  174. <el-form-item label="考号噪声参数">
  175. <el-input-number v-model="form.khVoiceNum" :min="1" :max="5"></el-input-number>
  176. </el-form-item>
  177. <el-form-item label="考号填涂比例阈值">
  178. <el-input-number v-model="form.khFillRate" :min="1" :max="5"></el-input-number>
  179. </el-form-item>
  180. <el-form-item label="题目噪声参数">
  181. <el-input-number v-model="form.tmVoiceNum" :min="1" :max="5"></el-input-number>
  182. </el-form-item>
  183. <el-form-item label="题目填涂比例阈值">
  184. <el-input-number v-model="form.tmFillRate" :min="1" :max="5"></el-input-number>
  185. </el-form-item>
  186. </el-form>
  187. <div slot="footer" class="dialog-footer">
  188. <el-button type="primary" @click="doReTryMark">确 定</el-button>
  189. </div>
  190. </el-dialog>
  191. <!--阅卷设置-->
  192. <MarkTaskSetDialog :remarkSetVisible="remarkSetVisible" :paperId="curPaperId" :taskId="curTaskId" @close="closeMarkTaskSet" />
  193. <!-- 图片预览 -->
  194. <div id="imgReviewList" style="position:absolute;right:20px;top:0px;width:20%;z-index:10000;height:880px;overflow:scroll;"></div>
  195. </section>
  196. </template>
  197. <script>
  198. import Page from "../../components/Page";
  199. import MarkTaskSetDialog from "./components/MarkTaskSetDialog";
  200. import OpenDwSource from "../../utils/xscan.js"
  201. import Cropper from 'cropperjs'
  202. export default {
  203. components: {
  204. Page,
  205. MarkTaskSetDialog
  206. },
  207. data() {
  208. return {
  209. loading: false,
  210. drawerVisible:true,
  211. queryParams: {
  212. page: 1,
  213. page_size: 20
  214. },
  215. form: {
  216. khVoiceNum: 5,
  217. khFillRate: 3.0,
  218. tmVoiceNum: 3,
  219. tmFillRate: 1.8,
  220. class_list: ["高三一班", "高三二班"],
  221. checkList: []
  222. },
  223. imgForm:{
  224. page:1,
  225. page_size:20
  226. },
  227. form1: {},
  228. form2: {},
  229. list: [{}, {}],
  230. total: 0,
  231. imgTotal:0,
  232. title: "新增用户",
  233. open: false,
  234. doctorList: [],
  235. rules: {},
  236. uploadDialogVisible: false,
  237. remarkDialogVisible: false,
  238. fileList: [],
  239. papersList: [],
  240. taskid: null,
  241. timer: null,
  242. timer2: null,
  243. studentsList: [],
  244. showAnsVisible: false,
  245. curStudentRecImg: "",
  246. activeName: "1",
  247. curTaskId: null,
  248. curPaperId:null,
  249. recPage: 1,
  250. recPageSize: 20,
  251. recTotal: 0,
  252. recParams: {},
  253. recSucTotal: 0,
  254. recKhErrTotal: 0,
  255. recObjErrTotal: 0,
  256. recWaitingErrTotal:0,
  257. queryName: "",
  258. queryMarkStatus: null,
  259. selectException: [],
  260. checkClassList: [],
  261. schoolList: [],
  262. gradeList: [],
  263. classList: [],
  264. imgListVisible: false,
  265. taskImgTotal: 0,
  266. remarkSetVisible: false,
  267. activeSetName: "first",
  268. addQueForm:{},
  269. objectiveQueList:[],
  270. subjectiveQueList:[],
  271. subjectiveMarkTeacherList:[],
  272. checkList:[],
  273. srcImgWidth:null,
  274. srcImgHeight:null,
  275. canvasImgScale:1,
  276. ctx:null,
  277. curStudentNo:null,
  278. searchStudentsData:[],
  279. ansOptionList: [{
  280. label: "A",
  281. value: "A",
  282. flag: 0
  283. },
  284. {
  285. label: "B",
  286. value: "B",
  287. flag: 0
  288. },
  289. {
  290. label: "C",
  291. value: "C",
  292. flag: 0
  293. },
  294. {
  295. label: "D",
  296. value: "D",
  297. flag: 0
  298. },
  299. {
  300. label: "E",
  301. value: "E",
  302. flag: 0
  303. },
  304. {
  305. label: "F",
  306. value: "F",
  307. flag: 0
  308. },
  309. {
  310. label: "G",
  311. value: "G",
  312. flag: 0
  313. }
  314. ],
  315. objectiveRecResult:[]
  316. };
  317. },
  318. methods: {
  319. jump(url, id) {
  320. id == 2 ? localStorage.setItem("sonNav", 2) : '';
  321. if (url) {
  322. this.$router.push(url);
  323. }
  324. },
  325. submitUpload() {
  326. this.$refs.upload.submit();
  327. },
  328. edit(row){
  329. this.open = true;
  330. this.form = row;
  331. this.classList = row.class_id.split(",");
  332. },
  333. del(id) {
  334. this.$confirm("确认删除?", "提示", {
  335. type: "warning",
  336. }).then(() => {
  337. this.$api
  338. .delMarkTask({
  339. id: id,
  340. })
  341. .then((res) => {
  342. if (!res.data.code) {
  343. this.msgSuccess("删除成功");
  344. this.getData();
  345. } else {
  346. this.$msgError(res.data.message);
  347. }
  348. });
  349. });
  350. },
  351. gopage(size) {
  352. if (size) {
  353. this.queryParams.page_size = size;
  354. }
  355. this.queryParams.page = this.$refs.pageButton.page;
  356. this.getData();
  357. },
  358. goTaskImg(page){
  359. if (page) {
  360. this.imgForm.page_size = size;
  361. }
  362. this.imgForm.page = this.$refs.pageImgButton.page;
  363. let that = this;
  364. that.$api.getTaskImgList({
  365. task_id: that.curTaskId,
  366. page:that.imgForm.page,
  367. page_size:that.imgForm.page_size
  368. }).then(res => {
  369. that.fileList = res.data.data.list
  370. that.taskImgTotal = res.data.data.total;
  371. })
  372. },
  373. goRecPage(size) {
  374. if (size) {
  375. this.recPageSize = size;
  376. }
  377. this.recPage = this.$refs.pageButton.page;
  378. this.recParams = {
  379. task_id: this.curTaskId,
  380. page: this.recPage,
  381. page_size: this.recPageSize,
  382. status: this.activeName,
  383. name: this.queryName,
  384. err_status: this.queryMarkStatus
  385. }
  386. window.clearInterval(this.timer);
  387. this.getData(this.curTaskId)
  388. },
  389. searchMarkData() {
  390. this.recParams.name = this.queryName;
  391. this.recParams.errStatus = this.queryMarkStatus;
  392. window.clearInterval(this.timer);
  393. this.getData(this.curTaskId);
  394. },
  395. reSetMarkData() {
  396. this.queryName = null;
  397. this.queryMarkStatus = null;
  398. this.queryParams.name = null;
  399. this.queryParams.err_status = null;
  400. window.clearInterval(this.timer);
  401. this.getData(this.curTaskId);
  402. },
  403. getData() {
  404. let id = this.$route.query.id;
  405. this.curTaskId = id
  406. this.uploadDialogVisible = true
  407. this.taskid = id
  408. let that = this;
  409. this.loading = true;
  410. this.recParams = {
  411. task_id: id,
  412. page: this.recPage,
  413. page_size: this.recPageSize,
  414. status: this.activeName,
  415. name: this.queryName,
  416. err_status: this.queryMarkStatus
  417. }
  418. this.$api.getMarkTaskStudents(this.recParams).then(res => {
  419. this.studentsList = res.data.data.list;
  420. this.studentsList.forEach(item => {
  421. let mark_status = item.mark_status;
  422. if (mark_status != 1) {
  423. item.mark_status_name = this.$const.recErrorList.filter((ritem) => {
  424. return ritem.value == mark_status;
  425. })[0].label
  426. } else {
  427. item.mark_status_name = "正常"
  428. }
  429. })
  430. this.recTotal = res.data.data.total;
  431. this.recSucTotal = res.data.data.suc_total;
  432. this.recKhErrTotal = res.data.data.kh_err_total;
  433. this.recObjErrTotal = res.data.data.obj_err_cnt;
  434. this.recWaitingErrTotal = res.data.data.waiting_cnt;
  435. this.loading = false;
  436. })
  437. window.clearInterval(this.timer);
  438. this.timer = setInterval(function () {
  439. that.$api.getMarkTaskStudents(that.recParams).then(res => {
  440. that.studentsList = res.data.data.list;
  441. that.studentsList.forEach(item => {
  442. let mark_status = item.mark_status;
  443. if (mark_status != 1) {
  444. item.mark_status_name = that.$const.recErrorList.filter((ritem) => {
  445. return ritem.value == mark_status;
  446. })[0].label
  447. } else {
  448. item.mark_status_name = "正常"
  449. }
  450. })
  451. that.recTotal = res.data.data.total;
  452. that.recSucTotal = res.data.data.suc_total;
  453. that.recKhErrTotal = res.data.data.kh_err_total;
  454. that.recObjErrTotal = res.data.data.obj_err_cnt;
  455. that.recWaitingErrTotal = res.data.data.waiting_cnt;
  456. })
  457. }, 4000)
  458. },
  459. closeRemarkDialog() {
  460. this.remarkDialogVisible = false;
  461. this.fileList = []
  462. },
  463. closeTaskImgDialog() {
  464. this.imgListVisible = false;
  465. window.clearInterval(this.timer2);
  466. },
  467. handlePreview(file) {
  468. console.log(file);
  469. },
  470. handleChange(file, fileList) {},
  471. openTaskImgList() {
  472. let that = this;
  473. this.imgListVisible = true
  474. window.clearInterval(this.timer2);
  475. this.timer2 = setInterval(function () {
  476. that.$api.getTaskImgList({
  477. task_id: that.curTaskId,
  478. page:that.imgForm.page,
  479. page_size:that.imgForm.page_size
  480. }).then(res => {
  481. that.fileList = res.data.data.list
  482. that.taskImgTotal = res.data.data.total;
  483. })
  484. }, 2000)
  485. },
  486. handleUploadSuccess(res, file, fileList) {
  487. if (!res.code) {
  488. if (fileList.every(item => item.status == "success")) {
  489. fileList.map(item => {
  490. item.response && this.fileList.push({
  491. "url": res.data.url,
  492. "name": res.data.name
  493. })
  494. })
  495. }
  496. }
  497. },
  498. delStudents(id, index,action) {
  499. this.$api.delMarkTaskStudents({
  500. id: id,
  501. action:action
  502. }).then(res => {
  503. this.msgSuccess("删除成功!");
  504. this.studentsList.splice(index, 1)
  505. })
  506. },
  507. handleRemove(e) {
  508. console.log(e)
  509. },
  510. drawRect(x, y, lineW, lineY) {
  511. // 开始绘制;
  512. this.ctx.beginPath();
  513. // //设置线条颜色,必须放在绘制之前
  514. this.ctx.strokeStyle = "red";
  515. // console.log("44444444");
  516. // // 线宽设置,必须放在绘制之前
  517. this.ctx.lineWidth = 1;
  518. // console.log("5555555555");
  519. // strokeRect参数:(左上角x坐标,y:左上角y坐标,绘画矩形的宽度,绘画矩形的高度)
  520. this.ctx.strokeRect(x, y, lineW, lineY);
  521. // console.log("66666666666666");
  522. },
  523. showStudentImgs(row) {
  524. this.curStudentRecImg = JSON.parse(row.imgs)[0];
  525. this.showAnsVisible = true;
  526. this.curStudentNo = row.student_no;
  527. this.form.student_no = this.curStudentNo;
  528. this.searchStudentsData = [];
  529. let that = this;
  530. let objective_result = row.objective_result;
  531. let objective_ans = row.objective_ans;
  532. // 获取试卷客观题标准填涂
  533. let paper_id = row.paper_id;
  534. that.objectiveRecResult = [];
  535. this.$api.getPaperQueInfo({id:paper_id}).then(res=>{
  536. let stdQueList = JSON.parse(res.data.data.stdQueList)
  537. stdQueList.forEach(item=>{
  538. that.objectiveRecResult = that.objectiveRecResult.concat(item);
  539. console.log(objective_ans,222222222222222)
  540. // 补全填涂答案
  541. let rec_result = {}
  542. let rec_result_num = {}
  543. objective_ans.forEach(iitem=>{
  544. let fillAns = iitem["ans"];
  545. let fillNum = [];
  546. fillAns.split(",").forEach(fans=>{
  547. fillNum.push(this.$const.ansOptionIndex[fans])
  548. })
  549. rec_result[iitem["qno"]] = fillAns
  550. rec_result_num[iitem["qno"]] = fillNum
  551. })
  552. that.objectiveRecResult.forEach(orr=>{
  553. orr["fillAns"] = rec_result[orr["qno"]]?rec_result[orr["qno"]]:""
  554. orr["fillNum"] = rec_result_num[orr["qno"]]?rec_result_num[orr["qno"]]:[]
  555. })
  556. })
  557. })
  558. this.$nextTick(function () {
  559. that.canvas = document.getElementById("myCanvas");
  560. that.ctx = that.canvas.getContext("2d");
  561. let image = new Image();
  562. image.src = that.curStudentRecImg;
  563. image.onload = function(){
  564. that.srcImgWidth = image.width;
  565. that.srcImgHeight = image.height;
  566. that.canvasImgScale = 680/image.width;
  567. that.ctx.drawImage(image, 0, 0, that.srcImgWidth, that.srcImgHeight, 0, 0, that.srcImgWidth*that.canvasImgScale, that
  568. .srcImgHeight*that.canvasImgScale)
  569. objective_result.forEach(item=>{
  570. item.forEach(iitem=>{
  571. that.drawRect(iitem.absX*that.canvasImgScale,iitem.absY*that.canvasImgScale,iitem.w*that.canvasImgScale,iitem.h*that.canvasImgScale);
  572. that.ctx.font = '12px Arial';
  573. that.ctx.fillStyle = 'red';
  574. if(iitem.ans){
  575. that.ctx.fillText(iitem.ans, iitem.absX*that.canvasImgScale,iitem.absY*that.canvasImgScale);
  576. }
  577. })
  578. })
  579. }
  580. })
  581. },
  582. saveModifQueAns(){
  583. let params = {
  584. task_id:this.curTaskId,
  585. student_no:this.curStudentNo
  586. }
  587. let objective_ans = [];
  588. this.objectiveRecResult.forEach(item=>{
  589. if(item.fillNum.length>0){
  590. objective_ans.push({
  591. qno:item.qno,
  592. ans:item.fillAns
  593. })
  594. }
  595. })
  596. params.objective_ans = objective_ans;
  597. let that = this;
  598. this.$api.saveModifQueAns(params).then(res=>{
  599. if(!res.data.code){
  600. this.msgSuccess("保存成功!");
  601. this.showAnsVisible = false;
  602. }else{
  603. this.msgError(res.data.message);
  604. }
  605. })
  606. },
  607. setStdAns(oitem, index) {
  608. //oitem表示每一题,index表示每一个选项
  609. let fillNum = oitem.fillNum; //已识别的填涂选项
  610. if(fillNum.indexOf(index)==-1){
  611. fillNum.push(index)
  612. }else{
  613. fillNum.splice(fillNum.indexOf(index),1);
  614. }
  615. //重新计算fillAns
  616. let fillAns = [];
  617. fillNum.forEach(num=>{
  618. if(num){
  619. fillAns.push(this.$const.ansOptionIndex[num])
  620. }
  621. })
  622. oitem.fillAns = fillAns.join();
  623. this.$forceUpdate();
  624. },
  625. searchStudents(){
  626. let params = {
  627. student_no:this.curStudentNo
  628. }
  629. this.$api.searchStudents(params).then(res=>{
  630. this.searchStudentsData = res.data.data;
  631. })
  632. },
  633. saveModifyStudentNo(){
  634. let params = {
  635. student_no:this.curStudentNo,
  636. task_id:this.curTaskId
  637. }
  638. this.$api.saveModifyStudentNo(params).then(res=>{
  639. console.log(res,1111111111111)
  640. this.showAnsVisible = false;
  641. })
  642. },
  643. showCurRecImg(row) {
  644. this.curStudentRecImg = row.ans_imgs.replace(".png", "_draw_ans.png");
  645. this.showAnsVisible = true;
  646. },
  647. showCurRecKhImg(row) {
  648. let ext = row.ans_imgs.split("/").pop()
  649. if (ext) {
  650. ext = "." + ext.split(".")[1]
  651. }
  652. this.curStudentRecImg = row.ans_imgs.replace("_ans" + ext, "_sno" + ext);
  653. this.showAnsVisible = true;
  654. },
  655. handleTabClick(tab, event) {
  656. this.activeName = tab.name;
  657. this.recPage = 1;
  658. this.recParams = {
  659. task_id: this.curTaskId,
  660. page: this.recPage,
  661. page_size: this.recPageSize,
  662. status: this.activeName,
  663. name: this.queryName,
  664. err_status: this.queryMarkStatus
  665. }
  666. window.clearInterval(this.timer);
  667. this.getData(this.curTaskId)
  668. },
  669. downloadObjectiveResult(task_id) {
  670. this.$api
  671. .downloadObjectiveResult({
  672. task_id: task_id
  673. })
  674. .then((res) => {
  675. var elink = document.createElement("a");
  676. let blob = new Blob([res.data], {
  677. type: "application/vnd.ms-excel,charset=UTF-8",
  678. });
  679. let objUrl = URL.createObjectURL(blob);
  680. let file_name = decodeURIComponent(
  681. res.headers["content-disposition"].split("=")[1]
  682. );
  683. elink.download = file_name;
  684. elink.style.display = "none";
  685. elink.href = objUrl;
  686. document.body.appendChild(elink);
  687. elink.click();
  688. document.body.removeChild(elink);
  689. this.download_loading = false;
  690. });
  691. },
  692. handleSelectionChange(val) {
  693. this.selectException = [];
  694. if (val.length > 0) {
  695. val.forEach(item => {
  696. let task_img = item.task_id + ";;" + item.imgs + ";;" + item.id;
  697. this.selectException.push(task_img);
  698. })
  699. window.clearInterval(this.timer);
  700. }
  701. },
  702. reTryMark() {
  703. if (this.selectException.length < 1) {
  704. this.msgError("请选择需要重新识别的答卷!");
  705. } else {
  706. this.remarkDialogVisible = true;
  707. }
  708. },
  709. doReTryMark() {
  710. let urls = []
  711. this.selectException.forEach(item => {
  712. item = item + ";;" + String(this.form.khVoiceNum) + ";;" + String(this.form.khFillRate);
  713. item = item + ";;" + String(this.form.tmVoiceNum) + ";;" + String(this.form.tmFillRate);
  714. urls.push(item);
  715. })
  716. let that = this;
  717. this.$api.reTryMarkPaper({
  718. urls: urls
  719. }).then(res => {
  720. this.remarkDialogVisible = false;
  721. this.getData();
  722. window.clearInterval(this.timer);
  723. this.timer = setInterval(function () {
  724. that.$api.getMarkTaskStudents(that.recParams).then(res => {
  725. that.studentsList = res.data.data.list;
  726. that.studentsList.forEach(item => {
  727. let mark_status = item.mark_status;
  728. if (mark_status != 1) {
  729. item.mark_status_name = that.$const.recErrorList.filter((ritem) => {
  730. return ritem.value == mark_status;
  731. })[0].label
  732. } else {
  733. item.mark_status_name = "正常"
  734. }
  735. })
  736. that.recTotal = res.data.data.total;
  737. that.recSucTotal = res.data.data.suc_total;
  738. that.recKhErrTotal = res.data.data.kh_err_total;
  739. that.recObjErrTotal = res.data.data.obj_err_cnt;
  740. that.recWaitingErrTotal = res.data.data.waiting_cnt;
  741. })
  742. }, 4000)
  743. })
  744. },
  745. startRecPaper() {
  746. this.loading = true
  747. this.$api.startRecPaper({
  748. task_id: this.curTaskId
  749. }).then(res => {
  750. this.loading = false
  751. })
  752. },
  753. remarkSet(row) {
  754. this.remarkSetVisible = true
  755. this.curTaskId = row.task_id;
  756. this.curPaperId = row.paper_id;
  757. },
  758. closeMarkTaskSet(){
  759. this.remarkSetVisible = false
  760. },
  761. starScanPaper(taskId,remoteHost){
  762. OpenDwSource(taskId,remoteHost)
  763. }
  764. },
  765. created() {
  766. this.getData();
  767. this.getSchoolList();
  768. this.getGradeList();
  769. this.getClassList();
  770. },
  771. };
  772. </script>
  773. <style lang="scss">
  774. .el-upload-list {
  775. display: none !important;
  776. }
  777. .el-upload-list--picture .el-upload-list__item {
  778. width: 150px;
  779. float: left;
  780. margin-right: 10px;
  781. position: relative;
  782. }
  783. .el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name {
  784. position: absolute;
  785. z-index: 100;
  786. height: 70px;
  787. line-height: 130px;
  788. }
  789. .el-upload-list--picture .el-upload-list__item-thumbnail {
  790. width: 125px;
  791. }
  792. .prosss_box .el-progress.el-progress--line {
  793. width: 88px;
  794. margin: auto 5px auto 0;
  795. }
  796. .prosss_box .el-progress-bar {
  797. padding-right: 0;
  798. }
  799. .prosss_box .el-progress__text {
  800. display: none;
  801. }
  802. .prosss_box {
  803. display: flex;
  804. }
  805. .kgtContainer{
  806. border:1px solid #ccc;
  807. padding:10px;
  808. .topContainer{
  809. display:flex;
  810. .topItem{
  811. width:50%;
  812. flex-direction:column;
  813. }
  814. .topItem:last-child{
  815. width:50%;
  816. flex-direction:column;
  817. text-align:right;
  818. }
  819. }
  820. .kgtItem{
  821. margin:10px;
  822. }
  823. }
  824. </style>