TpMain.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. <template>
  2. <div class="markmain pull-left scroll" 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 printJS from "print-js";
  80. export default {
  81. data() {
  82. return {
  83. activeName: "first",
  84. drawing: {},
  85. tmpSignScores: this.signScores,
  86. tmpMarkSign: this.markSign
  87. };
  88. },
  89. props: [
  90. "paperMarkSign",
  91. "studentPaper",
  92. "markSign",
  93. "signOption",
  94. "signScores",
  95. "signItem",
  96. "examType",
  97. "answerHtml"
  98. ],
  99. methods: {
  100. getPdfUrl() {
  101. var url = this.studentPaper.studentSubjectiveHtml;
  102. var content = "";
  103. if (url) {
  104. if (url != "" && url.indexOf(".pdf") > -1) {
  105. content =
  106. "<embed src='" + url + "' width='800px' height='800px'></embed>";
  107. }
  108. if (url != "" && url.indexOf(".zip") > -1) {
  109. content = "<a href='" + url + "'>下载</a>";
  110. }
  111. }
  112. return content;
  113. },
  114. createMarkDraw() {
  115. console.log("create");
  116. var drawing = {};
  117. this.signOption.data = this.studentPaper.studentSubjectiveHtml;
  118. drawing = new Drawing("canvas", this.signOption);
  119. this.drawing = drawing;
  120. },
  121. intMarkDraw() {
  122. console.log("init");
  123. if (this.markSign) {
  124. this.clearScoreLoc();
  125. this.clearScores();
  126. this.setMarkDrawHtml();
  127. this.setSignLocation();
  128. }
  129. },
  130. setMarkDrawHtml() {
  131. this.drawing.setHtml(this.studentPaper.studentSubjectiveHtml);
  132. },
  133. saveMarkSign() {
  134. if (this.drawing.canvas && this.signItem.id) {
  135. localStorage.removeItem(this.paperKey);
  136. localStorage.setItem(this.paperKey, JSON.stringify(this.paperSigns));
  137. this.$notify({
  138. message: "轨迹保存成功",
  139. type: "success"
  140. });
  141. } else {
  142. this.$notify({
  143. message: "请选择给分步骤",
  144. type: "error"
  145. });
  146. }
  147. },
  148. setSignLocation() {
  149. let signStorage = localStorage.getItem(this.paperKey);
  150. console.log("signStorage", signStorage);
  151. if (typeof signStorage == "string") {
  152. let paperSigns = JSON.parse(signStorage);
  153. if (
  154. this.drawing.scoreLoc.length == 0 ||
  155. paperSigns.length > this.drawing.scoreLoc.length
  156. ) {
  157. this.drawing.setLocation(paperSigns, "localStorage");
  158. } else {
  159. this.drawing.setLocation(this.drawing.scoreLoc, "cache");
  160. }
  161. } else {
  162. this.drawing.setLocation(this.drawing.scoreLoc, "cache");
  163. }
  164. this.setSignItemId();
  165. },
  166. setSignItemId() {
  167. var signItem = Object.assign({}, this.signItem);
  168. this.drawing.setItemId(signItem.id);
  169. },
  170. setSignScores() {
  171. let signStorage = localStorage.getItem(this.paperKey);
  172. if (typeof signStorage == "string") {
  173. let paperSigns = JSON.parse(signStorage);
  174. if (paperSigns.length > 0) {
  175. for (let [index, paperSign] of paperSigns.entries()) {
  176. console.log("score index:", index);
  177. if (paperSign.itemId == this.signItem.id) {
  178. this.tmpSignScores.push(paperSign.score);
  179. }
  180. }
  181. }
  182. }
  183. console.log("signScores", this.signScores);
  184. },
  185. delMarkSign() {
  186. if (this.drawing.canvas) {
  187. this.removeItemSign();
  188. this.clearScores();
  189. this.drawing.ResetDrawAll();
  190. this.setSignLocation();
  191. this.$notify({
  192. message: "轨迹清除成功",
  193. type: "success"
  194. });
  195. }
  196. },
  197. removeItemSign() {
  198. let signStorage = localStorage.getItem(this.paperKey);
  199. if (typeof signStorage == "string") {
  200. let paperSigns = JSON.parse(signStorage);
  201. this.removeLS(paperSigns);
  202. this.removeCache();
  203. } else {
  204. this.removeCache();
  205. }
  206. },
  207. removeLS(paperSigns) {
  208. for (let i = paperSigns.length - 1; i >= 0; i--) {
  209. if (paperSigns[i].itemId == this.signItem.id) {
  210. paperSigns.splice(i, 1);
  211. }
  212. }
  213. if (paperSigns.length > 0) {
  214. localStorage.removeItem(this.paperKey);
  215. localStorage.setItem(this.paperKey, JSON.stringify(paperSigns));
  216. } else {
  217. localStorage.removeItem(this.paperKey);
  218. this.clearScoreLoc();
  219. }
  220. },
  221. removeCache() {
  222. for (let i = this.drawing.scoreLoc.length - 1; i >= 0; i--) {
  223. if (this.drawing.scoreLoc[i].itemId == this.signItem.id) {
  224. this.drawing.scoreLoc.splice(i, 1);
  225. }
  226. }
  227. },
  228. delAllMarkSign() {
  229. if (this.drawing.canvas) {
  230. localStorage.removeItem(this.paperKey);
  231. this.clearScores();
  232. this.clearScoreLoc();
  233. this.drawing.ResetDrawAll();
  234. this.$notify({
  235. message: "轨迹全部清除成功",
  236. type: "success"
  237. });
  238. }
  239. },
  240. changeMarkSign() {
  241. if (this.signItem) {
  242. this.drawing.ResetDrawAll();
  243. console.log("paperSign", localStorage.getItem(this.paperKey));
  244. this.setSignLocation();
  245. this.setSignScores();
  246. }
  247. },
  248. //清除分数
  249. clearScores() {
  250. this.tmpSignScores.splice(0, this.tmpSignScores.length);
  251. this.$emit("clearScores");
  252. },
  253. //清除分数坐标
  254. clearScoreLoc() {
  255. this.drawing.clearScoreLoc();
  256. },
  257. //打印
  258. printAnswer() {
  259. printJS({ printable: "answer-content", type: "html" });
  260. },
  261. pdfDown() {
  262. var url = this.studentPaper.studentSubjectiveHtml;
  263. if (url != "undefined" && url != "") {
  264. url = new URL(url);
  265. url = url.pathname;
  266. url = decodeURIComponent(url);
  267. let xhr = new XMLHttpRequest();
  268. xhr.responseType = "blob";
  269. xhr.open("GET", url, true);
  270. xhr.onload = function() {
  271. if (this.status === 200) {
  272. let blob = this.response;
  273. let reader = new FileReader();
  274. reader.readAsDataURL(blob);
  275. reader.onload = function(e) {
  276. let a = document.createElement("a");
  277. a.download = url.substr(url.lastIndexOf("/") + 1);
  278. a.href = e.target.result;
  279. document.body.appendChild(a);
  280. a.click();
  281. a.parentNode.removeChild(a);
  282. };
  283. }
  284. };
  285. xhr.send();
  286. } else {
  287. this.$notify({
  288. message: "离线url为空",
  289. type: "warning"
  290. });
  291. }
  292. }
  293. },
  294. computed: {
  295. itemTitle() {
  296. if (!this.markSign) return "无";
  297. var title = "无";
  298. if (this.signItem.id) {
  299. title =
  300. Number.parseInt(this.signItem.mainNumber) +
  301. 1 +
  302. "(" +
  303. this.signItem.orders +
  304. ")";
  305. }
  306. return title;
  307. },
  308. itemKey() {
  309. if (!this.markSign) return "";
  310. return this.studentPaper.id + "-" + this.signItem.id;
  311. },
  312. paperKey() {
  313. if (!this.markSign) return "";
  314. return this.studentPaper.id;
  315. },
  316. paperSigns() {
  317. if (!this.markSign) return [];
  318. var paperSigns = [];
  319. if (this.drawing.scoreLoc.length > 0) {
  320. for (let scoreLoc of this.drawing.scoreLoc) {
  321. paperSigns.push({
  322. loc: scoreLoc.loc,
  323. score: scoreLoc.score,
  324. itemId: scoreLoc.itemId
  325. });
  326. }
  327. }
  328. return paperSigns;
  329. }
  330. },
  331. watch: {
  332. signItem(val) {
  333. if (this.markSign) {
  334. console.log("signItem", val);
  335. this.changeMarkSign();
  336. }
  337. },
  338. studentPaper() {
  339. if (this.markSign) {
  340. this.intMarkDraw();
  341. }
  342. },
  343. tmpSignScores(val) {
  344. this.$emit("changeSignScores", val);
  345. },
  346. signScores(val) {
  347. this.tmpSignScores = val;
  348. },
  349. markSign() {
  350. this.intMarkDraw();
  351. },
  352. paperSigns(val) {
  353. this.$emit("changePaperSign", val);
  354. }
  355. },
  356. updated() {},
  357. mounted() {
  358. //this.createMarkDraw();
  359. },
  360. created() {
  361. EVENTHUB.$on("positionDiv", function(id) {
  362. let o = document.getElementById("student_paper");
  363. o.scrollTop = 0;
  364. var height = 0;
  365. let outObject = document.getElementById("anchor-" + id);
  366. if (outObject) {
  367. if (outObject.currentStyle) {
  368. height = parseInt(outObject.currentStyle["marginTop"]);
  369. } else {
  370. height = parseInt(
  371. document.defaultView.getComputedStyle(outObject, null)["marginTop"]
  372. );
  373. }
  374. var y = document.getElementById("anchor-" + id).offsetTop - height / 2;
  375. o.scrollTop = y - 5;
  376. }
  377. });
  378. }
  379. };
  380. </script>
  381. <style scoped>
  382. .markmain {
  383. width: 74%;
  384. }
  385. .scroll {
  386. overflow: auto;
  387. height: 600px;
  388. }
  389. .marktitle {
  390. margin-right: 20px;
  391. margin-bottom: 20px;
  392. }
  393. .signTitle {
  394. margin-left: 35%;
  395. }
  396. .itemTitle {
  397. margin-right: 10px;
  398. }
  399. .titlefont {
  400. font-size: 15px;
  401. }
  402. li {
  403. list-style-type: none;
  404. }
  405. .markbutton {
  406. width: 40px;
  407. height: 40px;
  408. }
  409. img {
  410. width: 100%;
  411. height: 100%;
  412. }
  413. .paper {
  414. width: 90%;
  415. min-height: 600px;
  416. }
  417. .fixed {
  418. position: fixed;
  419. }
  420. </style>