examScheduling.vue 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. <template>
  2. <el-container>
  3. <el-main v-loading="loading" class="el-main-padding">
  4. <commonFormVue :form="form" :getExamCondition="getExamCondition">
  5. <el-row v-show="showAllCondition">
  6. <el-col :span="6">
  7. <el-form-item label="完成状态">
  8. <el-select
  9. v-if="
  10. form.examType == '' ||
  11. form.examType == 'ONLINE' ||
  12. form.examType == 'ONLINE_HOMEWORK'
  13. "
  14. class="form_search_width"
  15. size="small"
  16. v-model="form.finished"
  17. clearable
  18. placeholder="全部"
  19. >
  20. <el-option value="1" label="已完成"></el-option>
  21. <el-option value="0" label="未完成"></el-option>
  22. </el-select>
  23. <el-select
  24. v-if="form.examType == 'OFFLINE'"
  25. class="form_search_width"
  26. size="small"
  27. v-model="form.finished"
  28. clearable
  29. placeholder="全部"
  30. >
  31. <el-option value="0" label="未抽题"></el-option>
  32. <el-option value="1" label="已抽题"></el-option>
  33. <el-option value="2" label="已上传"></el-option>
  34. </el-select>
  35. </el-form-item>
  36. </el-col>
  37. <el-col :span="6">
  38. <el-form-item label="采集人">
  39. <el-input
  40. class="form_search_width"
  41. size="small"
  42. v-model="form.infoCollector"
  43. placeholder="采集人"
  44. ></el-input>
  45. </el-form-item>
  46. </el-col>
  47. </el-row>
  48. </commonFormVue>
  49. <el-col :span="24">
  50. <el-button
  51. @click="search('clickSelectBtn')"
  52. size="small"
  53. type="primary"
  54. icon="el-icon-search"
  55. >查询</el-button
  56. >
  57. <el-button
  58. size="small"
  59. type="primary"
  60. icon="el-icon-more"
  61. v-if="!showAllCondition"
  62. @click="showMoreCondition"
  63. >高级查询</el-button
  64. >
  65. <el-button
  66. size="small"
  67. type="primary"
  68. v-if="showAllCondition"
  69. @click="showSimpleCondition"
  70. >简单查询</el-button
  71. >
  72. <el-button
  73. size="small"
  74. icon="el-icon-refresh"
  75. @click="resetForm"
  76. class="margin-bottom-10"
  77. >重置</el-button
  78. >
  79. </el-col>
  80. <el-row>
  81. <el-col
  82. :span="24"
  83. v-show="currentPagePrivileges.EXAM_PARTICULARS_EXPORT"
  84. >
  85. <div class="block-seperator"></div>
  86. <span>操作:</span>
  87. <commonExportVue
  88. :form="form"
  89. :exportUrl="exportUrl"
  90. :exportFileName="exportFileName"
  91. ></commonExportVue>
  92. </el-col>
  93. </el-row>
  94. <el-row class="margin-top-10">
  95. <el-col :span="24">
  96. <el-table
  97. v-loading="tableLoading"
  98. element-loading-text="数据加载中"
  99. ref="multipleTable"
  100. @selection-change="handleSelectionChange"
  101. :data="tableData"
  102. border
  103. >
  104. <el-table-column
  105. sortable
  106. label="学习中心"
  107. prop="orgName"
  108. width="120"
  109. ></el-table-column>
  110. <el-table-column
  111. sortable
  112. label="姓名"
  113. prop="studentName"
  114. width="120"
  115. ></el-table-column>
  116. <el-table-column
  117. sortable
  118. label="身份证号"
  119. prop="identityNumber"
  120. width="120"
  121. ></el-table-column>
  122. <el-table-column
  123. sortable
  124. label="学号"
  125. prop="studentCode"
  126. width="120"
  127. ></el-table-column>
  128. <el-table-column
  129. sortable
  130. label="课程"
  131. prop="courseName"
  132. width="120"
  133. ></el-table-column>
  134. <el-table-column
  135. sortable
  136. label="课程层次"
  137. prop="courseLevel"
  138. width="120"
  139. ></el-table-column>
  140. <el-table-column
  141. sortable
  142. label="专业"
  143. prop="specialtyName"
  144. width="120"
  145. ></el-table-column>
  146. <el-table-column
  147. sortable
  148. label="已考次数"
  149. prop="usedNum"
  150. width="120"
  151. ></el-table-column>
  152. <el-table-column
  153. sortable
  154. label="学生电话"
  155. prop="phone"
  156. width="120"
  157. ></el-table-column>
  158. <el-table-column
  159. sortable
  160. label="年级"
  161. prop="grade"
  162. width="120"
  163. ></el-table-column>
  164. <el-table-column
  165. sortable
  166. label="采集人"
  167. prop="infoCollector"
  168. width="120"
  169. ></el-table-column>
  170. <el-table-column
  171. sortable
  172. label="完成状态"
  173. prop="finishedStatus"
  174. width="120"
  175. ></el-table-column>
  176. <!-- <el-table-column sortable label="完成状态" width="120">
  177. <template slot-scope="scope">
  178. <span> {{ scope.row.finishedStatus }} </span>
  179. </template>
  180. </el-table-column>-->
  181. <el-table-column fixed="right" label="操作" width="120">
  182. <template slot-scope="scope">
  183. <el-row class="operateRow">
  184. <el-col :span="24">
  185. <el-button
  186. plain
  187. type="primary"
  188. size="mini"
  189. icon="el-icon-view"
  190. @click="previewPaper(scope.row.examStudentId)"
  191. v-if="scope.row.examType == 'OFFLINE'"
  192. >查看考题</el-button
  193. >
  194. </el-col>
  195. </el-row>
  196. <el-row class="operateRow">
  197. <el-col :span="24">
  198. <el-button
  199. plain
  200. type="primary"
  201. size="mini"
  202. icon="el-icon-download"
  203. @click="exportPaper(scope.row.examStudentId)"
  204. v-if="scope.row.examType == 'OFFLINE'"
  205. >下载考题</el-button
  206. >
  207. </el-col>
  208. </el-row>
  209. <el-row class="operateRow">
  210. <el-col :span="24">
  211. <el-button
  212. plain
  213. type="primary"
  214. size="mini"
  215. icon="el-icon-upload2"
  216. @click="openUploadAnswerDialog(scope.row.examStudentId)"
  217. v-if="
  218. scope.row.examType == 'OFFLINE' &&
  219. scope.row.canUploadAttachment
  220. "
  221. >上传作答</el-button
  222. >
  223. </el-col>
  224. </el-row>
  225. <el-row class="operateRow">
  226. <el-col :span="24">
  227. <el-button
  228. plain
  229. type="primary"
  230. size="mini"
  231. icon="el-icon-download"
  232. @click="downloadAnswer(scope.row.offlineFiles)"
  233. v-if="
  234. scope.row.examType == 'OFFLINE' &&
  235. scope.row.offlineFiles
  236. "
  237. >下载作答</el-button
  238. >
  239. </el-col>
  240. </el-row>
  241. </template>
  242. </el-table-column>
  243. </el-table>
  244. <div class="page pull-right">
  245. <el-pagination
  246. @size-change="handleSizeChange"
  247. @current-change="handleCurrentChange"
  248. :current-page.sync="form.pageNo"
  249. :page-sizes="[10, 20, 50, 100, 200, 300]"
  250. :page-size="form.pageSize"
  251. layout="total, sizes, prev, pager, next, jumper"
  252. :total="total"
  253. ></el-pagination>
  254. </div>
  255. </el-col>
  256. </el-row>
  257. <div>
  258. <el-dialog
  259. title="上传作答"
  260. v-loading="uploadAnswerDialogLoading"
  261. :visible.sync="uploadAnswerDialogVisible"
  262. >
  263. <el-form>
  264. <el-form-item label="选择文件类型">
  265. <el-radio-group v-model="fileType" @change="handleFileTypeChange">
  266. <el-radio v-show="optZipVisible" label="zip">ZIP</el-radio>
  267. <el-radio v-show="optPdfVisible" label="pdf">PDF</el-radio>
  268. <el-radio v-show="optImageVisible" label="image"
  269. >图片(*.jpg|*.jpeg|*.png)</el-radio
  270. >
  271. </el-radio-group>
  272. </el-form-item>
  273. <el-form-item label="选择文件">
  274. <div
  275. v-show="fileType == 'image'"
  276. style="width:580px;padding-left:80px;"
  277. >
  278. <el-upload
  279. :class="{ disabled: uploadDisabled }"
  280. ref="upload"
  281. action
  282. :limit="fileLimit"
  283. :http-request="customUpload"
  284. :before-upload="beforeFileUpload"
  285. :on-success="handleSuccess"
  286. :file-list="fileList"
  287. :auto-upload="false"
  288. :accept="accept"
  289. :on-change="handleChange"
  290. multiple
  291. list-type="picture-card"
  292. >
  293. <i slot="default" class="el-icon-plus"></i>
  294. <div slot="file" slot-scope="{ file }">
  295. <img
  296. class="el-upload-list__item-thumbnail"
  297. :src="file.url"
  298. alt
  299. />
  300. <span class="el-upload-list__item-actions">
  301. <span
  302. class="el-upload-list__item-preview"
  303. @click="handlePictureCardPreview(file)"
  304. >
  305. <i class="el-icon-zoom-in"></i>
  306. </span>
  307. <span
  308. v-if="!disabled"
  309. class="el-upload-list__item-delete"
  310. @click="handleRemove(file)"
  311. >
  312. <i class="el-icon-delete"></i>
  313. </span>
  314. </span>
  315. </div>
  316. </el-upload>
  317. <div style="width:580px;">
  318. 温馨提示:仅支持JPG,JPEG和PNG文件,单个图片大小请不要超过5M,图片数量最多6张!
  319. </div>
  320. </div>
  321. <div v-show="fileType != 'image'">
  322. <input
  323. type="file"
  324. accept="application/pdf, application/zip"
  325. id="importFile"
  326. ref="offlineFileInput"
  327. @change="uploadAnswerChange"
  328. v-bind:class="{ offline_file: offlineAnswerFile }"
  329. />
  330. <div>温馨提示:仅支持pdf和zip文件,文件大小请不要超过30M!</div>
  331. </div>
  332. </el-form-item>
  333. <div class="dialog-footer">
  334. <el-button @click="cancelUpload">取 消</el-button>
  335. <el-button
  336. v-show="fileType != 'image'"
  337. :disabled="!offlineAnswerFile"
  338. type="primary"
  339. @click="doUploadAnswer"
  340. >确 定</el-button
  341. >
  342. <el-button
  343. v-show="fileType == 'image'"
  344. :disabled="batchSubmitUploadDisabled"
  345. type="primary"
  346. @click="batchSubmitUpload"
  347. >确 定</el-button
  348. >
  349. </div>
  350. </el-form>
  351. </el-dialog>
  352. <el-dialog :append-to-body="true" :visible.sync="dialogVisible">
  353. <img width="100%" :src="dialogImageUrl" alt />
  354. </el-dialog>
  355. <el-dialog title="图片作答" :visible.sync="downloadImageDialogVisible">
  356. <el-form>
  357. <el-form-item label="作答结果">
  358. <div style="width:580px;padding-left:80px;">
  359. <el-upload
  360. :class="{ disabled: true }"
  361. action
  362. :limit="6"
  363. :file-list="imageAnswerFileList"
  364. multiple
  365. list-type="picture-card"
  366. :disabled="true"
  367. >
  368. <i slot="default" class="el-icon-plus"></i>
  369. <div slot="file" slot-scope="{ file }">
  370. <img
  371. class="el-upload-list__item-thumbnail"
  372. :src="file.url"
  373. :alt="file.name"
  374. />
  375. <span class="el-upload-list__item-actions">
  376. <span
  377. class="el-upload-list__item-preview"
  378. @click="handlePictureCardPreview(file)"
  379. >
  380. <i class="el-icon-zoom-in"></i>
  381. </span>
  382. <span
  383. class="el-upload-list__item-delete"
  384. @click="handleDownload(file)"
  385. >
  386. <i class="el-icon-download"></i>
  387. </span>
  388. </span>
  389. </div>
  390. </el-upload>
  391. </div>
  392. </el-form-item>
  393. <div class="dialog-footer">
  394. <el-button
  395. type="primary"
  396. @click="downloadImageDialogVisible = false"
  397. >确 定</el-button
  398. >
  399. </div>
  400. </el-form>
  401. </el-dialog>
  402. </div>
  403. </el-main>
  404. </el-container>
  405. </template>
  406. <script>
  407. import { mapState } from "vuex";
  408. import commonFormVue from "../component/commonForm.vue";
  409. import commonExportVue from "../component/commonExport.vue";
  410. import pagePrivilege from "../mixin/pagePrivilege.js";
  411. // import MD5 from "js-md5";
  412. import SparkMD5 from "spark-md5";
  413. export default {
  414. components: { commonFormVue, commonExportVue },
  415. mixins: [pagePrivilege],
  416. data() {
  417. return {
  418. dialogImageUrl: "",
  419. dialogVisible: false,
  420. disabled: false,
  421. loading: false,
  422. uploadAnswerDialogLoading: false,
  423. uploadAnswerDialogVisible: false,
  424. total: 0,
  425. tableLoading: false,
  426. showAllCondition: false,
  427. fileType: "zip",
  428. accept: "application/zip",
  429. fileList: [],
  430. downloadImageDialogVisible: false,
  431. imageAnswerFileList: [],
  432. fileLimit: 6,
  433. form: {
  434. examRecordDataId: null,
  435. hasStranger: null,
  436. courseId: null,
  437. courseLevel: null,
  438. examId: null,
  439. faceSuccessPercentLower: null,
  440. faceSuccessPercentUpper: null,
  441. livenessSuccessPercentLower: null,
  442. livenessSuccessPercentUpper: null,
  443. identityNumber: null,
  444. orgId: null,
  445. studentCode: null,
  446. studentName: null,
  447. isWarn: null,
  448. pageNo: 1,
  449. pageSize: 10,
  450. examType: "",
  451. ORG_FIND_ALL: false //查询所有机构
  452. },
  453. getExamCondition: {
  454. params: {
  455. name: "",
  456. examTypes: "ONLINE#OFFLINE#ONLINE_HOMEWORK"
  457. },
  458. filterCondition: ""
  459. },
  460. tableData: [],
  461. exportUrl: "/api/ecs_oe_admin/exam/student/examScheduling/list/export",
  462. exportFileName: "考试进度详情",
  463. currentOfflineExamRecordDataId: "",
  464. offlineAnswerFile: "",
  465. currentPagePrivileges: {
  466. EXAM_PARTICULARS_EXPORT: false //导出
  467. },
  468. summary: "",
  469. summaryList: [],
  470. md5Size: 0,
  471. optZipVisible: false,
  472. optPdfVisible: false,
  473. optImageVisible: false
  474. };
  475. },
  476. computed: {
  477. ...mapState({ user: state => state.user }),
  478. batchSubmitUploadDisabled() {
  479. return this.fileList.length == 0 || this.fileList.length != this.md5Size;
  480. },
  481. //计算是否显示图片上传框
  482. uploadDisabled() {
  483. return this.fileList.length >= this.fileLimit;
  484. }
  485. },
  486. methods: {
  487. cancelUpload() {
  488. this.uploadAnswerDialogVisible = false;
  489. this.removeImgs();
  490. },
  491. handleChange(file, fileList) {
  492. this.fileList = fileList;
  493. this.calcSummary(this.fileList);
  494. },
  495. getFileMD5(dataFile, callback) {
  496. var fileReader = new FileReader();
  497. var spark = new SparkMD5(); //创建md5对象(基于SparkMD5)
  498. if (dataFile.size > 1024 * 1024 * 10) {
  499. var data1 = dataFile.slice(0, 1024 * 1024 * 10); //将文件进行分块 file.slice(start,length)
  500. fileReader.readAsBinaryString(data1); //将文件读取为二进制码
  501. } else {
  502. fileReader.readAsBinaryString(dataFile);
  503. }
  504. //文件读取完毕之后的处理
  505. //a639e28526d1809745b46bf1189594fe 6d9efe0c593b1383482feb229318e03a
  506. fileReader.onload = function(e) {
  507. spark.appendBinary(e.target.result);
  508. var md5 = spark.end();
  509. console.log(md5);
  510. callback(md5);
  511. };
  512. },
  513. handleRemove(file) {
  514. let index = this.fileList.findIndex(p => p.uid == file.uid);
  515. this.fileList.splice(index, 1);
  516. this.calcSummary(this.fileList);
  517. },
  518. calcSummary(fileList) {
  519. this.summaryList = [];
  520. this.md5Size = 0;
  521. for (let i = 0; i < fileList.length; i++) {
  522. let f = fileList[i];
  523. this.getFileMD5(f.raw, md5 => {
  524. this.summaryList.push({ index: i, summary: md5 });
  525. this.md5Size++;
  526. });
  527. }
  528. },
  529. handlePictureCardPreview(file) {
  530. this.dialogImageUrl = file.url;
  531. this.dialogVisible = true;
  532. },
  533. handleDownload(file) {
  534. window.open(file.url);
  535. console.log(file);
  536. },
  537. removeImgs() {
  538. this.fileList = [];
  539. this.$refs.upload.clearFiles();
  540. },
  541. resetForm() {
  542. this.form = {
  543. examRecordDataId: null,
  544. hasStranger: null,
  545. courseId: null,
  546. courseLevel: null,
  547. examId: null,
  548. faceSuccessPercentLower: null,
  549. faceSuccessPercentUpper: null,
  550. livenessSuccessPercentLower: null,
  551. livenessSuccessPercentUpper: null,
  552. identityNumber: null,
  553. orgId: this.form.ORG_FIND_ALL ? null : this.form.orgId,
  554. studentCode: null,
  555. studentName: null,
  556. isWarn: null,
  557. pageNo: 1,
  558. pageSize: 10,
  559. examType: "",
  560. ORG_FIND_ALL: this.form.ORG_FIND_ALL
  561. };
  562. },
  563. showMoreCondition() {
  564. this.showAllCondition = true;
  565. },
  566. showSimpleCondition() {
  567. this.$notify({
  568. title: "提示",
  569. message: "高级查询条件值已重置",
  570. type: "info",
  571. duration: 2000
  572. });
  573. this.resetForm();
  574. this.showAllCondition = false;
  575. },
  576. search(type) {
  577. if (!this.form.examId) {
  578. this.$notify({
  579. title: "警告",
  580. message: "请选择考试",
  581. type: "warning",
  582. duration: 2000
  583. });
  584. return false;
  585. }
  586. if (type && type == "clickSelectBtn") {
  587. this.form.pageNo = 1;
  588. }
  589. this.tableLoading = true;
  590. this.$http
  591. .post("/api/ecs_oe_admin/exam/student/examScheduling/list", this.form)
  592. .then(response => {
  593. if (response.data) {
  594. var dataList = response.data.content;
  595. this.tableData = dataList;
  596. this.total = response.data.totalElements;
  597. } else {
  598. this.tableData = [];
  599. }
  600. this.tableLoading = false;
  601. });
  602. this.getUploadFileType();
  603. },
  604. selectable(row) {
  605. return row.isWarn;
  606. },
  607. handleSelectionChange(val) {
  608. this.multipleSelection = val;
  609. },
  610. /**
  611. * pagesize改变时触发
  612. */
  613. handleSizeChange(val) {
  614. this.form.pageSize = val;
  615. this.search();
  616. },
  617. /**
  618. * 当前页改变时触发
  619. */
  620. handleCurrentChange() {
  621. this.search();
  622. },
  623. previewPaper(examStudentId) {
  624. this.$http
  625. .get("/api/ecs_oe_admin/exam/record/select/byExamStudentId", {
  626. params: { examStudentId: examStudentId }
  627. })
  628. .then(response => {
  629. if (response.data) {
  630. var examRecordList = response.data;
  631. if (examRecordList && examRecordList.length > 0) {
  632. window.open(
  633. "/admin/preview_paper/" + examRecordList[0].basePaperId
  634. );
  635. } else {
  636. this.$notify({
  637. title: "提示",
  638. message: "该考生未参加考试",
  639. type: "error",
  640. duration: 2000
  641. });
  642. }
  643. }
  644. });
  645. },
  646. exportPaper(examStudentId) {
  647. this.loading = true;
  648. var currentUser = this.user;
  649. this.$http
  650. .get("/api/ecs_oe_admin/exam/record/select/byExamStudentId", {
  651. params: { examStudentId: examStudentId }
  652. })
  653. .then(response => {
  654. if (response.data) {
  655. var examRecordList = response.data;
  656. if (examRecordList && examRecordList.length > 0) {
  657. var basePaperId = examRecordList[0].basePaperId;
  658. var rootOrgId = currentUser.rootOrgId;
  659. this.$http
  660. .get(
  661. "/api/ecs_ques/paper/export/" +
  662. basePaperId +
  663. "/PAPER/" +
  664. rootOrgId +
  665. "/" +
  666. basePaperId +
  667. "/offLine",
  668. {
  669. responseType: "arraybuffer",
  670. filename: "utf-8"
  671. }
  672. )
  673. .then(response => {
  674. if (response.data && response.data.byteLength > 0) {
  675. var blob = new Blob([response.data], {
  676. type: "application/zip"
  677. });
  678. var url = URL.createObjectURL(blob);
  679. var fileName = response.headers["content-disposition"]
  680. .split(";")[1]
  681. .replace("filename=", "");
  682. var a = document.createElement("a");
  683. a.href = url;
  684. a.download = decodeURI(fileName);
  685. a.target = "_blank";
  686. a.click();
  687. URL.revokeObjectURL(url);
  688. } else {
  689. this.$notify({
  690. title: "提示",
  691. message: "无相关文件",
  692. type: "error",
  693. duration: 2000
  694. });
  695. }
  696. this.loading = false;
  697. })
  698. .catch(() => {
  699. this.loading = false;
  700. });
  701. } else {
  702. this.loading = false;
  703. this.$notify({
  704. title: "提示",
  705. message: "该考生未参加考试",
  706. type: "error",
  707. duration: 2000
  708. });
  709. }
  710. }
  711. });
  712. },
  713. openUploadAnswerDialog(examStudentId) {
  714. this.fileList = [];
  715. this.imageAnswerFileList = [];
  716. // this.offlineAnswerFile = "";
  717. this.cleanOfflineFile();
  718. this.$http
  719. .get("/api/ecs_oe_admin/exam/record/data/findByExamStudentId", {
  720. params: { examStudentId: examStudentId }
  721. })
  722. .then(response => {
  723. var examRecordDataList = response.data;
  724. if (examRecordDataList.length == 0) {
  725. this.$notify({
  726. title: "提示",
  727. message: "该考生未参加考试",
  728. type: "error",
  729. duration: 2000
  730. });
  731. } else {
  732. this.uploadAnswerDialogVisible = true;
  733. this.currentOfflineExamStudentId = examStudentId;
  734. this.currentOfflineExamRecordDataId = examRecordDataList[0].id;
  735. }
  736. });
  737. },
  738. uploadAnswerChange(event) {
  739. if (event.target.files.length > 0) {
  740. this.offlineAnswerFile = event.target.files[0];
  741. } else {
  742. this.offlineAnswerFile = "";
  743. }
  744. },
  745. doUploadAnswer() {
  746. var index = this.offlineAnswerFile.name.lastIndexOf(".");
  747. var fileNameLength = this.offlineAnswerFile.name.length;
  748. var fileSuffix = this.offlineAnswerFile.name
  749. .substring(index + 1, fileNameLength)
  750. .toUpperCase();
  751. this.$http
  752. .get(
  753. "/api/ecs_exam_work/exam/property/" +
  754. this.form.examId +
  755. "/OFFLINE_UPLOAD_FILE_TYPE"
  756. )
  757. .then(response => {
  758. var allowfileSuffixs = response.data;
  759. if (!allowfileSuffixs || allowfileSuffixs.length == 0) {
  760. this.$notify({
  761. title: "提示",
  762. message: "当前考试设置不允许上传附件",
  763. type: "error",
  764. duration: 2000
  765. });
  766. return false;
  767. }
  768. if (allowfileSuffixs.toString().indexOf(fileSuffix) < 0) {
  769. this.$notify({
  770. title: "提示",
  771. message:
  772. "当前考试允许上传文件格式为:" + allowfileSuffixs.toString(),
  773. type: "error",
  774. duration: 2000
  775. });
  776. return false;
  777. }
  778. this.uploadAnswerDialogLoading = true;
  779. let config = {
  780. headers: { "Content-Type": "multipart/form-data" }
  781. };
  782. let param = new FormData();
  783. param.append("file", this.offlineAnswerFile);
  784. param.append("examRecordDataId", this.currentOfflineExamRecordDataId);
  785. this.$http
  786. .post("/api/ecs_oe_admin/offlineExam/submitPaper", param, config)
  787. .then(() => {
  788. this.$notify({
  789. title: "提示",
  790. message: "上传成功",
  791. type: "success",
  792. duration: 2000
  793. });
  794. this.uploadAnswerDialogVisible = false;
  795. this.uploadAnswerDialogLoading = false;
  796. this.$refs.offlineFileInput.value = "";
  797. this.offlineAnswerFile = "";
  798. this.search();
  799. })
  800. .catch(() => {
  801. this.$notify({
  802. title: "提示",
  803. message: "上传失败",
  804. type: "error",
  805. duration: 2000
  806. });
  807. this.uploadAnswerDialogLoading = false;
  808. this.$refs.offlineFileInput.value = "";
  809. this.offlineAnswerFile = "";
  810. });
  811. });
  812. },
  813. //获取支持的文件上传类型
  814. getUploadFileType() {
  815. this.$http
  816. .get(
  817. "/api/ecs_exam_work/exam/property/" +
  818. this.form.examId +
  819. "/OFFLINE_UPLOAD_FILE_TYPE"
  820. )
  821. .then(response => {
  822. var allowfileSuffixs = response.data;
  823. if (!allowfileSuffixs || allowfileSuffixs.length == 0) {
  824. return false;
  825. }
  826. if (allowfileSuffixs.some(p => p.toUpperCase() == "ZIP")) {
  827. this.optZipVisible = true;
  828. }
  829. if (allowfileSuffixs.some(p => p.toUpperCase() == "PDF")) {
  830. this.optPdfVisible = true;
  831. }
  832. if (allowfileSuffixs.some(p => p.toUpperCase() == "IMAGE")) {
  833. this.optImageVisible = true;
  834. }
  835. });
  836. },
  837. beforeUpload(file) {
  838. var index = file.name.lastIndexOf(".");
  839. var fileNameLength = file.name.length;
  840. var fileSuffix = file.name
  841. .substring(index + 1, fileNameLength)
  842. .toUpperCase();
  843. this.$http
  844. .get(
  845. "/api/ecs_exam_work/exam/property/" +
  846. this.form.examId +
  847. "/OFFLINE_UPLOAD_FILE_TYPE"
  848. )
  849. .then(response => {
  850. var allowfileSuffixs = response.data;
  851. if (!allowfileSuffixs || allowfileSuffixs.length == 0) {
  852. this.$notify({
  853. title: "提示",
  854. message: "当前考试设置不允许上传附件",
  855. type: "error",
  856. duration: 2000
  857. });
  858. return false;
  859. }
  860. if (allowfileSuffixs.toString().indexOf(fileSuffix) < 0) {
  861. this.$notify({
  862. title: "提示",
  863. message:
  864. "当前考试允许上传文件格式为:" + allowfileSuffixs.toString(),
  865. type: "error",
  866. duration: 2000
  867. });
  868. return false;
  869. }
  870. this.offlineAnswerFile = file;
  871. });
  872. this.uploadData = {
  873. examRecordDataId: this.currentOfflineExamRecordDataId,
  874. summary: this.summary
  875. };
  876. console.log(this.uploadData);
  877. let promise = new Promise(resolve => {
  878. this.$nextTick(function() {
  879. resolve(true);
  880. });
  881. });
  882. return promise; //通过返回一个promis对象解决
  883. },
  884. submitUpload() {
  885. this.uploadAnswerDialogLoading = true;
  886. let config = {
  887. headers: { "Content-Type": "multipart/form-data" }
  888. };
  889. let param = new FormData();
  890. param.append("file", this.offlineAnswerFile);
  891. param.append("examRecordDataId", this.currentOfflineExamRecordDataId);
  892. param.append("fileType", this.fileType);
  893. this.$http
  894. .post("/api/ecs_oe_admin/offlineExam/submitPaper", param, config)
  895. .then(() => {
  896. this.$notify({
  897. title: "提示",
  898. message: "上传成功",
  899. type: "success",
  900. duration: 2000
  901. });
  902. this.uploadAnswerDialogVisible = false;
  903. this.$refs.offlineFileInput.value = "";
  904. this.offlineAnswerFile = "";
  905. this.search();
  906. })
  907. .catch(() => {
  908. this.$notify({
  909. title: "提示",
  910. message: "上传失败",
  911. type: "error",
  912. duration: 2000
  913. });
  914. this.uploadAnswerDialogLoading = false;
  915. this.$refs.offlineFileInput.value = "";
  916. this.offlineAnswerFile = "";
  917. });
  918. },
  919. cleanOfflineFile() {
  920. if (this.$refs.offlineFileInput) {
  921. this.$refs.offlineFileInput.value = "";
  922. }
  923. this.offlineAnswerFile = "";
  924. },
  925. downloadAnswer(files) {
  926. if (files && files.length > 0) {
  927. if (files[0].fileType != "image") {
  928. window.open(files[0].offlineFileUrl);
  929. return;
  930. }
  931. this.imageAnswerFileList = [];
  932. for (let f of files) {
  933. this.imageAnswerFileList.push({
  934. url: f.offlineFileUrl,
  935. name: f.offlineFileName
  936. });
  937. }
  938. this.downloadImageDialogVisible = true;
  939. }
  940. },
  941. handleFileTypeChange(ft) {
  942. switch (ft) {
  943. case "zip":
  944. this.accept = "application/zip";
  945. break;
  946. case "pdf":
  947. this.accept = "application/pdf";
  948. break;
  949. case "image":
  950. this.accept = "image/jpeg,image/png";
  951. break;
  952. }
  953. },
  954. batchSubmitUpload() {
  955. this.$refs.upload.submit();
  956. let params = new FormData();
  957. params.append("examRecordDataId", this.currentOfflineExamRecordDataId);
  958. params.append("fileType", this.fileType);
  959. for (let f of this.fileList) {
  960. params.append("fileArray", f.raw);
  961. }
  962. //先对文件md5进行排序(按索引正序排列)
  963. this.summaryList.sort((a, b) => a.index - b.index);
  964. let summaries = [];
  965. for (let s of this.summaryList) {
  966. summaries.push(s.summary);
  967. }
  968. params.append("fileMd5Array", summaries);
  969. let config = {
  970. headers: { "Content-Type": "multipart/form-data" }
  971. };
  972. this.$http
  973. .post("/api/ecs_oe_admin/offlineExam/batchSubmitPaper", params, config)
  974. .then(() => {
  975. this.$notify({
  976. title: "提示",
  977. message: "上传成功",
  978. type: "success",
  979. duration: 2000
  980. });
  981. this.uploadAnswerDialogVisible = false;
  982. this.removeImgs();
  983. this.offlineAnswerFile = "";
  984. this.search();
  985. })
  986. .catch(() => {
  987. this.$notify({
  988. title: "提示",
  989. message: "上传失败",
  990. type: "error",
  991. duration: 2000
  992. });
  993. this.uploadAnswerDialogLoading = false;
  994. this.offlineAnswerFile = "";
  995. });
  996. },
  997. beforeFileUpload(file) {
  998. const isLt5M = file.size / 1024 / 1024 <= 5;
  999. if (!isLt5M) {
  1000. this.$message.error("上传的单个数据文件大小不能超过5MB!");
  1001. let index = this.fileList.findIndex(p => p.uid == file.uid);
  1002. this.fileList.splice(index, 1);
  1003. this.calcSummary(this.fileList);
  1004. }
  1005. return isLt5M;
  1006. },
  1007. handleSuccess(response, file, fileList) {
  1008. console.log(response);
  1009. console.log(file);
  1010. console.log(fileList);
  1011. this.$message.success("上传成功");
  1012. },
  1013. customUpload(file) {
  1014. console.log(file);
  1015. return false;
  1016. }
  1017. },
  1018. created() {
  1019. if (this.form.examId) {
  1020. this.getUploadFileType();
  1021. }
  1022. }
  1023. };
  1024. </script>
  1025. <style scoped>
  1026. .offline_file {
  1027. color: blue;
  1028. }
  1029. .disabled .el-upload--picture-card {
  1030. display: none !important;
  1031. }
  1032. </style>
  1033. <style scoped src="../style/common.css"></style>