StudentPaper.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. <template>
  2. <el-dialog title="预览答题卡" :visible.sync="showDialog" class="page_full_dialog" fullscreen height="100%">
  3. <div class="page_header">
  4. <div class="back_button" @click="GoBack()">
  5. <i class="iconfont icon_return"></i>返回
  6. </div>
  7. <div class="header_title">
  8. {{ pageTitle }}{{ studentCode }}<span class="header_title_tip">(右键点击图片另存为可保存图片到本地)</span>
  9. </div>
  10. </div>
  11. <div class="dialog_paper">
  12. <div class="paper_content">
  13. <div class="canvas_button">
  14. <div :class="currentIndex==0?'disable_button_item':'button_item'" @click="LastPaper()">
  15. <i class="el-icon-arrow-left"></i>
  16. </div>
  17. </div>
  18. <div class="canvas_image" v-loading="isLoading" element-loading-text="加载中……" element-loading-spinner="el-icon-loading" element-loading-background="#ffffff">
  19. <PaperImage :paperImgUrl="currentPaperUrl" :drawData="currentDrawData" :usedCardType="usedCardType" :downLoadName="currentDownLoadName"></PaperImage>
  20. </div>
  21. <div class="canvas_button">
  22. <div :class="currentIndex==paperImageList.length-1?'disable_button_item':'button_item'" @click="NextPaper()">
  23. <i class="el-icon-arrow-right"></i>
  24. </div>
  25. </div>
  26. </div>
  27. <div class="paper_question">
  28. <div class="area_table">
  29. <el-table :data="questionList" border ref="questionTable" :max-height="questionTableHeight">
  30. <el-table-column label="小题名称" prop="questionName" align="center">
  31. <template slot-scope="scope">
  32. {{ scope.row.questionName }}
  33. </template>
  34. </el-table-column>
  35. <el-table-column label="满分/答案" align="center">
  36. <template slot-scope="scope">
  37. {{ scope.row.fullScore }}
  38. <span v-if="scope.row.questionAnswer">/{{ scope.row.questionAnswer }}</span>
  39. </template>
  40. </el-table-column>
  41. <el-table-column label="得分/答案" align="center">
  42. <template slot-scope="scope">
  43. <div :class="scope.row.fullScore==scope.row.score?'':'question_score'">
  44. <template v-if="scope.row.displayType === 0 || scope.row.displayType === 2">{{ scope.row.displayName }}</template>
  45. <template v-else>
  46. <img v-if="scope.row.correctType==0" src="@/assets/icon/icon_all_wrong.svg" style="width: 12px;" />
  47. <img v-else-if="scope.row.correctType==2" src="@/assets/icon/icon_all_right.svg" style="width: 12px;" />
  48. <img v-else src="@/assets/icon/icon_half_right.svg" style="width: 12px;" />
  49. </template>
  50. <span v-if="scope.row.answer">/{{ scope.row.answer }}</span>
  51. </div>
  52. </template>
  53. </el-table-column>
  54. </el-table>
  55. </div>
  56. </div>
  57. </div>
  58. </el-dialog>
  59. </template>
  60. <script>
  61. import PaperImage from '@/components/PaperImage.vue';//学生试卷组件
  62. export default {
  63. name: 'StudentPaper',//学生试卷组件
  64. components:
  65. {
  66. PaperImage,
  67. },
  68. props: {
  69. paperInfo:
  70. {
  71. type: Object,
  72. default: () => { }
  73. },//试卷信息
  74. pageTitle:
  75. {
  76. type: String,
  77. default: ''
  78. },//试卷标题
  79. value: {
  80. type: Boolean,
  81. required: true,
  82. },//是否显示弹窗
  83. currentPageIndex:{//默认显示第一页答题卡
  84. type: Number,
  85. required: 0,
  86. }
  87. },
  88. computed: {
  89. showDialog: {
  90. get() {
  91. return this.value;
  92. },
  93. set(val) {
  94. this.$emit("input", val);
  95. },
  96. },
  97. },
  98. watch:{
  99. value(newVal)
  100. {
  101. if (newVal) {
  102. this.currentIndex=this.currentPageIndex;
  103. this.GetStudentPaperInfo();
  104. }
  105. }
  106. },
  107. data() {
  108. return {
  109. paperImageList: [],//学生试卷图片列表
  110. currentIndex: 0,//当前学生试卷图片索引
  111. currentPaperUrl: '',//当前学生试卷图片地址
  112. currentDownLoadName: '',//当前学生试卷图片下载名称
  113. currentDrawData:[],//当前学生试卷答题标记数据
  114. questionList: [],//学生试卷题目列表
  115. questionTableHeight: 0,//学生试卷题目列表高度
  116. usedCardType:null,//学生系统卡类型
  117. isLoading:false,//是否正在加载中
  118. studentName: '',//学生姓名
  119. studentCode:''
  120. }
  121. },
  122. created() {
  123. },
  124. mounted() {
  125. // 禁用鼠标右键
  126. document.addEventListener('contextmenu', this.DisableRightClick);
  127. },
  128. beforeDestroy()
  129. {
  130. document.removeEventListener('contextmenu', this.DisableRightClick);
  131. },
  132. methods: {
  133. // 禁用右键菜单的方法
  134. DisableRightClick(event) {
  135. event.preventDefault();
  136. return false;
  137. },
  138. // 返回
  139. GoBack()
  140. {
  141. this.showDialog=false;
  142. },
  143. //上一个试卷
  144. LastPaper()
  145. {
  146. console.log("上一个试卷");
  147. if (this.currentIndex > 0)
  148. {
  149. this.currentIndex--;
  150. this.UpdateCurrentPaperData();
  151. console.log("切换到上一张试卷,当前索引:", this.currentIndex);
  152. } else {
  153. console.log("已经是第一张试卷");
  154. // 可以添加提示信息,如:this.$message.warning('已经是第一张试卷');
  155. }
  156. },
  157. //下一个试卷
  158. NextPaper()
  159. {
  160. console.log("下一个试卷");
  161. if (this.currentIndex < this.paperImageList.length - 1)
  162. {
  163. this.currentIndex++;
  164. this.UpdateCurrentPaperData();
  165. console.log("切换到下一张试卷,当前索引:", this.currentIndex);
  166. } else {
  167. console.log("已经是最后一张试卷");
  168. // 可以添加提示信息,如:this.$message.warning('已经是最后一张试卷');
  169. }
  170. },
  171. // 获取学生试卷详情信息
  172. GetStudentPaperInfo()
  173. {
  174. if(this.paperInfo.examId!='' && this.paperInfo.subjectCode!=null)
  175. {
  176. this.isLoading=true;
  177. this.$api.reportStudent.findStudentCard(this.paperInfo).then(res=>{
  178. console.log("打印学生试卷详情信息",res);
  179. if(res.code==200)
  180. {
  181. this.paperImageList=res?.data?.pageVOS || [];
  182. const studentCode = res?.data?.studentCode ?? '';
  183. this.studentCode = studentCode ?`【${studentCode}】`:'';
  184. this.usedCardType=res.data.usedCardType;
  185. // 重置索引并更新当前试卷数据
  186. // this.currentIndex = 0;
  187. this.UpdateCurrentPaperData();
  188. console.log("打印学生试卷当前图片地址",this.currentPaperUrl);
  189. // 合并所有试卷图片中的题目列表
  190. let allQuestions = [];
  191. //先添加总分数据
  192. let totalScore = {
  193. questionName: '总分',
  194. fullScore: res?.data?.fullScore || 150,
  195. score: res?.data?.levelName ?? res?.data?.totalScore,
  196. displayType:res.data.displayType,//显示类型 0-分数 1-对错 2-等级
  197. displayName: res.data.displayName,//显示值
  198. correctType: res.data.correctType,//显示对错的时候 0-错 1-半对 2-全对
  199. questionAnswer: '',
  200. answer: '',
  201. samplingPosition:"{\"x\":195,\"y\":247,\"page\":1}",
  202. };
  203. if (this.paperImageList.length > 0 && this.paperImageList[0].questionVOS) {
  204. this.paperImageList[0].questionVOS.unshift(totalScore);
  205. }
  206. this.paperImageList.forEach(item => {
  207. if (item.questionVOS && item.questionVOS.length > 0) {
  208. allQuestions = allQuestions.concat(item.questionVOS);
  209. }
  210. });
  211. this.questionList = allQuestions;
  212. console.log("合并后的题目列表", this.questionList);
  213. this.CalculateTableHeight();//计算表格高度
  214. this.$nextTick(() => {
  215. this.isLoading=false;
  216. });
  217. }
  218. else
  219. {
  220. this.studentCode = '';
  221. this.$nextTick(() => {
  222. this.isLoading=false;
  223. });
  224. }
  225. })
  226. }
  227. },
  228. // 计算表格高度(更精确的方式)
  229. CalculateTableHeight()
  230. {
  231. this.$nextTick(() => {
  232. const paperQuestionElement = this.$el.querySelector('.paper_question');
  233. const tableHeaderElement = this.$el.querySelector('.page_header');
  234. if (paperQuestionElement && tableHeaderElement) {
  235. // 获取页面相关元素的高度
  236. const pageHeaderHeight = tableHeaderElement.offsetHeight || 40;
  237. const paperQuestionPadding = 40; // 20px * 2 padding
  238. // 计算可用高度
  239. const availableHeight = window.innerHeight - 65 - 80;
  240. // 设置表格最大高度
  241. this.questionTableHeight = availableHeight;
  242. console.log('精确计算的表格高度:', this.questionTableHeight);
  243. }
  244. else
  245. {
  246. // 备用计算方式
  247. const availableHeight = window.innerHeight - 65 - 40 - 40;
  248. this.questionTableHeight = availableHeight;
  249. }
  250. });
  251. },
  252. // 更新当前试卷数据的公共方法
  253. UpdateCurrentPaperData()
  254. {
  255. if (this.paperImageList.length > 0 && this.currentIndex < this.paperImageList.length) {
  256. this.currentPaperUrl = this.paperImageList[this.currentIndex].picUrl;
  257. this.currentDrawData = this.paperImageList[this.currentIndex].questionVOS || [];
  258. this.currentDownLoadName = this.pageTitle+'答题卡第'+(this.currentIndex + 1) + '页'; // 重置下载名称
  259. } else {
  260. // 处理边界情况
  261. this.currentPaperUrl = '';
  262. this.currentDrawData = [];
  263. this.currentDownLoadName = '';
  264. }
  265. },
  266. }
  267. }
  268. </script>
  269. <style lang="scss" scoped>
  270. .dialog_paper
  271. {
  272. width: 100%;
  273. height: calc(100vh - 65px);
  274. background: #F0F4FB;
  275. overflow: hidden;
  276. display: flex;
  277. justify-content: space-between;
  278. padding: 20px;
  279. box-sizing: border-box;
  280. .paper_content
  281. {
  282. width: calc(100% - 340px);
  283. height: 100%;
  284. display: flex;
  285. justify-content: flex-start;
  286. .canvas_button
  287. {
  288. width: 48px;
  289. height: 100%;
  290. display: flex;
  291. justify-content: center;
  292. align-items: center;
  293. .button_item
  294. {
  295. width: 48px;
  296. height: 48px;
  297. border-radius: 50%;
  298. background: rgba(0,0,0,0.1);
  299. color:#999999;
  300. font-size: 24px;
  301. line-height: 48px;
  302. text-align: center;
  303. cursor: pointer;
  304. }
  305. .disable_button_item
  306. {
  307. width: 48px;
  308. height: 48px;
  309. border-radius: 50%;
  310. background: rgba(0,0,0,0.1);
  311. color:#C0C4CC;
  312. font-size: 24px;
  313. line-height: 48px;
  314. text-align: center;
  315. }
  316. }
  317. .canvas_image
  318. {
  319. width: calc(100% - 88px - 40px);
  320. height: 100%;
  321. margin: auto;
  322. // background-color: green;
  323. }
  324. }
  325. .paper_question
  326. {
  327. width: 320px;
  328. height: 100%;
  329. background: #FFFFFF;
  330. border-radius: 10px;
  331. border: 1px solid #EBEEF5;
  332. padding: 20px;
  333. box-sizing: border-box;
  334. .question_score
  335. {
  336. color:#F56C6C;
  337. display: flex;
  338. height: 100%;
  339. align-items: center;
  340. justify-content: center;
  341. }
  342. }
  343. }
  344. </style>