TpMain.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. <template>
  2. <div class="markmain pull-left" id="student_paper">
  3. <el-tabs :active-name="activeName">
  4. <el-tab-pane label="考生答卷" name="first">
  5. <div v-if="this.examType != 'OFFLINE'">
  6. <div id="main-source" v-if="this.studentPaper.id != ''">
  7. <div
  8. class="paper"
  9. v-if="!this.markSign"
  10. v-html="this.studentPaper.studentSubjectiveHtml"
  11. ></div>
  12. <div class="paper" v-show="this.markSign">
  13. <div class="fixed marktitle signTitle">
  14. <el-button-group class="itemTitle">
  15. <el-button type="info" size="small">
  16. <span class>当前题</span>
  17. </el-button>
  18. <el-button type="info" size="small">
  19. <span class>{{ itemTitle }}</span>
  20. </el-button>
  21. </el-button-group>
  22. <!--
  23. <el-button type="primary" size="small" @click="saveMarkSign">保存轨迹</el-button>
  24. -->
  25. <el-button type="danger" size="small" @click="delMarkSign"
  26. >清除轨迹</el-button
  27. >
  28. <el-button type="danger" size="small" @click="delAllMarkSign"
  29. >清除全部轨迹</el-button
  30. >
  31. </div>
  32. <div>
  33. <canvas id="canvas" width="800px" height="800px"></canvas>
  34. </div>
  35. </div>
  36. </div>
  37. </div>
  38. <div v-if="this.examType == 'OFFLINE'">
  39. <div v-if="this.studentPaper.id != ''">
  40. <div v-html="getPdfUrl()" style="float: left;"></div>
  41. <div
  42. v-if="
  43. this.studentPaper.studentSubjectiveHtml &&
  44. this.studentPaper.studentSubjectiveHtml != '' &&
  45. this.studentPaper.studentSubjectiveHtml.indexOf('.pdf') > -1
  46. "
  47. style="float: right;margin-right: 20px;"
  48. class="no-print"
  49. >
  50. <el-button size="small" type="success" @click="pdfDown()"
  51. >下载</el-button
  52. >
  53. </div>
  54. </div>
  55. </div>
  56. </el-tab-pane>
  57. <template v-if="this.examType == 'OFFLINE'">
  58. <el-tab-pane label="标答" name="second">
  59. <div id="answer-source" v-if="this.examType == 'OFFLINE'">
  60. <div style="float: right;margin-right: 20px;" class="no-print">
  61. <el-button size="small" type="success" @click="printAnswer()"
  62. >打印</el-button
  63. >
  64. </div>
  65. <div
  66. class="paper"
  67. id="answer-content"
  68. v-html="this.answerHtml"
  69. ></div>
  70. </div>
  71. </el-tab-pane>
  72. </template>
  73. </el-tabs>
  74. </div>
  75. </template>
  76. <script>
  77. import { Drawing } from "../canvas/mark_sign";
  78. import { EVENTHUB } from "../constants/constants";
  79. import { MARKING_API } from "@/constants/constants";
  80. import printJS from "print-js";
  81. import "viewerjs/dist/viewer.css";
  82. import Viewer from "viewerjs";
  83. import { mapState } from "vuex";
  84. export default {
  85. data() {
  86. return {
  87. activeName: "first",
  88. drawing: {},
  89. tmpSignScores: this.signScores,
  90. tmpMarkSign: this.markSign,
  91. picModelKey: Math.random(),
  92. picModel: false,
  93. picForm: {
  94. imgUrl: "",
  95. rotate: 0
  96. }
  97. };
  98. },
  99. props: [
  100. "paperMarkSign",
  101. "studentPaper",
  102. "markSign",
  103. "signOption",
  104. "signScores",
  105. "signItem",
  106. "examType",
  107. "answerHtml"
  108. ],
  109. methods: {
  110. viewPicture(imagesClass, index) {
  111. const viewer = new Viewer(document.querySelector(imagesClass), {
  112. container: "#app",
  113. zIndex: 99999,
  114. title: false,
  115. toolbar: {
  116. zoomIn: 1,
  117. zoomOut: 1,
  118. oneToOne: 1,
  119. reset: 1,
  120. prev: 1,
  121. play: {
  122. show: 0,
  123. size: "large"
  124. },
  125. next: 1,
  126. rotateLeft: 1,
  127. rotateRight: 1,
  128. flipHorizontal: 1,
  129. flipVertical: 1
  130. },
  131. ready() {
  132. viewer.view(index);
  133. },
  134. hidden() {
  135. viewer.destroy();
  136. }
  137. });
  138. viewer.show();
  139. },
  140. getPdfUrl() {
  141. var url = this.studentPaper.studentSubjectiveHtml;
  142. var content = "";
  143. if (url) {
  144. if (url != "" && url.indexOf(".pdf") > -1) {
  145. content =
  146. "<embed src='" + url + "' width='800px' height='800px'></embed>";
  147. }
  148. if (url != "" && url.indexOf(".zip") > -1) {
  149. content = "<a href='" + url + "'>下载</a>";
  150. }
  151. }
  152. return content;
  153. },
  154. createMarkDraw() {
  155. console.log("create");
  156. var drawing = {};
  157. this.signOption.data = this.studentPaper.studentSubjectiveHtml;
  158. drawing = new Drawing("canvas", this.signOption);
  159. this.drawing = drawing;
  160. },
  161. intMarkDraw() {
  162. console.log("init");
  163. if (this.markSign) {
  164. this.clearScoreLoc();
  165. this.clearScores();
  166. this.setMarkDrawHtml();
  167. this.setSignLocation();
  168. }
  169. },
  170. setMarkDrawHtml() {
  171. this.drawing.setHtml(this.studentPaper.studentSubjectiveHtml);
  172. },
  173. saveMarkSign() {
  174. if (this.drawing.canvas && this.signItem.id) {
  175. localStorage.removeItem(this.paperKey);
  176. localStorage.setItem(this.paperKey, JSON.stringify(this.paperSigns));
  177. this.$notify({
  178. message: "轨迹保存成功",
  179. type: "success"
  180. });
  181. } else {
  182. this.$notify({
  183. message: "请选择给分步骤",
  184. type: "error"
  185. });
  186. }
  187. },
  188. setSignLocation() {
  189. let signStorage = localStorage.getItem(this.paperKey);
  190. console.log("signStorage", signStorage);
  191. if (typeof signStorage == "string") {
  192. let paperSigns = JSON.parse(signStorage);
  193. if (
  194. this.drawing.scoreLoc.length == 0 ||
  195. paperSigns.length > this.drawing.scoreLoc.length
  196. ) {
  197. this.drawing.setLocation(paperSigns, "localStorage");
  198. } else {
  199. this.drawing.setLocation(this.drawing.scoreLoc, "cache");
  200. }
  201. } else {
  202. this.drawing.setLocation(this.drawing.scoreLoc, "cache");
  203. }
  204. this.setSignItemId();
  205. },
  206. setSignItemId() {
  207. var signItem = Object.assign({}, this.signItem);
  208. this.drawing.setItemId(signItem.id);
  209. },
  210. setSignScores() {
  211. let signStorage = localStorage.getItem(this.paperKey);
  212. if (typeof signStorage == "string") {
  213. let paperSigns = JSON.parse(signStorage);
  214. if (paperSigns.length > 0) {
  215. for (let [index, paperSign] of paperSigns.entries()) {
  216. console.log("score index:", index);
  217. if (paperSign.itemId == this.signItem.id) {
  218. this.tmpSignScores.push(paperSign.score);
  219. }
  220. }
  221. }
  222. }
  223. console.log("signScores", this.signScores);
  224. },
  225. delMarkSign() {
  226. if (this.drawing.canvas) {
  227. this.removeItemSign();
  228. this.clearScores();
  229. this.drawing.ResetDrawAll();
  230. this.setSignLocation();
  231. this.$notify({
  232. message: "轨迹清除成功",
  233. type: "success"
  234. });
  235. }
  236. },
  237. removeItemSign() {
  238. let signStorage = localStorage.getItem(this.paperKey);
  239. if (typeof signStorage == "string") {
  240. let paperSigns = JSON.parse(signStorage);
  241. this.removeLS(paperSigns);
  242. this.removeCache();
  243. } else {
  244. this.removeCache();
  245. }
  246. },
  247. removeLS(paperSigns) {
  248. for (let i = paperSigns.length - 1; i >= 0; i--) {
  249. if (paperSigns[i].itemId == this.signItem.id) {
  250. paperSigns.splice(i, 1);
  251. }
  252. }
  253. if (paperSigns.length > 0) {
  254. localStorage.removeItem(this.paperKey);
  255. localStorage.setItem(this.paperKey, JSON.stringify(paperSigns));
  256. } else {
  257. localStorage.removeItem(this.paperKey);
  258. this.clearScoreLoc();
  259. }
  260. },
  261. removeCache() {
  262. for (let i = this.drawing.scoreLoc.length - 1; i >= 0; i--) {
  263. if (this.drawing.scoreLoc[i].itemId == this.signItem.id) {
  264. this.drawing.scoreLoc.splice(i, 1);
  265. }
  266. }
  267. },
  268. delAllMarkSign() {
  269. if (this.drawing.canvas) {
  270. localStorage.removeItem(this.paperKey);
  271. this.clearScores();
  272. this.clearScoreLoc();
  273. this.drawing.ResetDrawAll();
  274. this.$notify({
  275. message: "轨迹全部清除成功",
  276. type: "success"
  277. });
  278. }
  279. },
  280. changeMarkSign() {
  281. if (this.signItem) {
  282. this.drawing.ResetDrawAll();
  283. console.log("paperSign", localStorage.getItem(this.paperKey));
  284. this.setSignLocation();
  285. this.setSignScores();
  286. }
  287. },
  288. //清除分数
  289. clearScores() {
  290. this.tmpSignScores.splice(0, this.tmpSignScores.length);
  291. this.$emit("clearScores");
  292. },
  293. //清除分数坐标
  294. clearScoreLoc() {
  295. this.drawing.clearScoreLoc();
  296. },
  297. //打印
  298. printAnswer() {
  299. printJS({ printable: "answer-content", type: "html" });
  300. },
  301. pdfDown() {
  302. var fileurl = this.studentPaper.studentSubjectiveHtml;
  303. if (fileurl != "undefined" && fileurl != "") {
  304. let url =
  305. MARKING_API +
  306. "/fileDownLoad?url=" +
  307. fileurl +
  308. "&$key=" +
  309. this.user.key +
  310. "&$token=" +
  311. this.user.token;
  312. window.location.href = url;
  313. } else {
  314. this.$notify({
  315. message: "离线url为空",
  316. type: "warning"
  317. });
  318. }
  319. }
  320. },
  321. computed: {
  322. ...mapState({ user: state => state.user }),
  323. itemTitle() {
  324. if (!this.markSign) return "无";
  325. var title = "无";
  326. if (this.signItem.id) {
  327. title =
  328. Number.parseInt(this.signItem.mainNumber) +
  329. 1 +
  330. "(" +
  331. this.signItem.orders +
  332. ")";
  333. }
  334. return title;
  335. },
  336. itemKey() {
  337. if (!this.markSign) return "";
  338. return this.studentPaper.id + "-" + this.signItem.id;
  339. },
  340. paperKey() {
  341. if (!this.markSign) return "";
  342. return this.studentPaper.id;
  343. },
  344. paperSigns() {
  345. if (!this.markSign) return [];
  346. var paperSigns = [];
  347. if (this.drawing.scoreLoc.length > 0) {
  348. for (let scoreLoc of this.drawing.scoreLoc) {
  349. paperSigns.push({
  350. loc: scoreLoc.loc,
  351. score: scoreLoc.score,
  352. itemId: scoreLoc.itemId
  353. });
  354. }
  355. }
  356. return paperSigns;
  357. }
  358. },
  359. watch: {
  360. signItem(val) {
  361. if (this.markSign) {
  362. console.log("signItem", val);
  363. this.changeMarkSign();
  364. }
  365. },
  366. studentPaper() {
  367. if (this.markSign) {
  368. this.intMarkDraw();
  369. }
  370. },
  371. tmpSignScores(val) {
  372. this.$emit("changeSignScores", val);
  373. },
  374. signScores(val) {
  375. this.tmpSignScores = val;
  376. },
  377. markSign() {
  378. this.intMarkDraw();
  379. },
  380. paperSigns(val) {
  381. this.$emit("changePaperSign", val);
  382. }
  383. },
  384. updated() {},
  385. mounted() {
  386. //this.createMarkDraw();
  387. window.viewPicture = this.viewPicture;
  388. },
  389. created() {
  390. EVENTHUB.$on("positionDiv", function(id) {
  391. let o = document.getElementById("student_paper");
  392. o.scrollTop = 0;
  393. var height = 0;
  394. let outObject = document.getElementById("anchor-" + id);
  395. if (outObject) {
  396. if (outObject.currentStyle) {
  397. height = parseInt(outObject.currentStyle["marginTop"]);
  398. } else {
  399. height = parseInt(
  400. document.defaultView.getComputedStyle(outObject, null)["marginTop"]
  401. );
  402. }
  403. var y = document.getElementById("anchor-" + id).offsetTop - height / 2;
  404. o.scrollTop = y - 5;
  405. }
  406. });
  407. }
  408. };
  409. </script>
  410. <style scoped>
  411. .markmain {
  412. width: 74%;
  413. overflow: auto;
  414. max-height: calc(100vh - 65px);
  415. }
  416. .markmain::-webkit-scrollbar {
  417. /*滚动条整体样式*/
  418. width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
  419. }
  420. .markmain::-webkit-scrollbar-thumb {
  421. /*滚动条里面小方块*/
  422. border-radius: 5px;
  423. box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
  424. background: rgba(0, 0, 0, 0.2);
  425. }
  426. .markmain::-webkit-scrollbar-track {
  427. /*滚动条里面轨道*/
  428. box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
  429. border-radius: 0;
  430. background: rgba(0, 0, 0, 0.1);
  431. }
  432. .marktitle {
  433. margin-right: 20px;
  434. margin-bottom: 20px;
  435. }
  436. .signTitle {
  437. margin-left: 35%;
  438. }
  439. .itemTitle {
  440. margin-right: 10px;
  441. }
  442. .titlefont {
  443. font-size: 15px;
  444. }
  445. li {
  446. list-style-type: none;
  447. }
  448. .markbutton {
  449. width: 40px;
  450. height: 40px;
  451. }
  452. img {
  453. width: 100%;
  454. height: 100%;
  455. }
  456. .paper {
  457. width: 90%;
  458. min-height: 600px;
  459. }
  460. .fixed {
  461. position: fixed;
  462. }
  463. .paper >>> .question-item {
  464. border: 1px solid #ccc;
  465. border-radius: 5px;
  466. margin: 10px;
  467. padding: 0 10px;
  468. }
  469. .paper >>> .answer {
  470. border: 1px solid #ccc;
  471. border-radius: 5px;
  472. margin: 10px;
  473. padding: 0 10px;
  474. background: rgb(250, 250, 250);
  475. overflow-wrap: break-word;
  476. }
  477. .paper >>> .right-font {
  478. font-weight: bold;
  479. color: rgb(85, 191, 255);
  480. }
  481. .paper >>> .student-font {
  482. font-weight: bold;
  483. color: black;
  484. }
  485. .paper >>> .max-number {
  486. font-size: 20px;
  487. color: #444444;
  488. }
  489. .paper >>> img.photo-answer {
  490. width: 100px;
  491. padding: 10px;
  492. height: 100px;
  493. }
  494. .paper >>> .photo-answers-block {
  495. width: 350px !important;
  496. }
  497. .paper >>> .photo-answers-block a {
  498. cursor: pointer;
  499. }
  500. .img-div {
  501. text-align: center;
  502. }
  503. </style>