transcript_single.vue 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052
  1. <template>
  2. <div class="page_report">
  3. <div class="report_module">
  4. <div class="module_title">
  5. <div class="title_left">我的成绩</div>
  6. </div>
  7. <div class="module_table">
  8. <div
  9. class="subject_score"
  10. v-loading="subjectLoading"
  11. :element-loading-text="loadingText"
  12. element-loading-spinner="el-icon-loading"
  13. element-loading-background="#ffffff"
  14. >
  15. <div class="subject_score_chart" style="height: 250px; overflow: hidden">
  16. <GaugeChart
  17. v-if="!subjectLoading && subjectData.levelValue"
  18. :data="subjectData.levelValue"
  19. :gradeName="subjectData.gradeName"
  20. :subjectName="subjectData.subjectName"
  21. :fullScore="subjectData.fullScore"
  22. :chartData="subjectData.levelData"
  23. ></GaugeChart>
  24. <!-- <el-button class="button_editor"
  25. :disabled="!subjectData?.data?.imgUrlList || subjectData?.data?.imgUrlList == '-'">查看答题卡</el-button> -->
  26. <div class="module_chart no_content_data" style="height: 240px; min-height: 240px" v-else>
  27. <span>暂无数据</span>
  28. </div>
  29. </div>
  30. <div class="subject_score_content">
  31. <div class="score_item">
  32. <span class="title">班级</span>
  33. <span class="value">{{ subjectData?.data?.className ?? '-' }}</span>
  34. </div>
  35. <!-- 0-显示,1-不显示 -->
  36. <div class="score_item" v-if="subjectData?.data?.scoreStatus === 0">
  37. <span class="title">原始分</span>
  38. <span class="value">
  39. <!-- * 1-得分显示分数,小题分显示分数,2-得分显示分数,小题分显示对错
  40. * 3-得分显示对错,小题分显示分数,4-得分显示对错,小题分显示对错
  41. * 5-得分显示等级,小题分显示分数,6-得分显示等级,小题分显示对错 -->
  42. <template
  43. v-if="
  44. (subjectData.data.studentOpenness == 3 || subjectData.data.studentOpenness == 4) && subjectData?.data?.score
  45. "
  46. >
  47. <img
  48. v-if="subjectData?.data?.fullScore == subjectData?.data?.score"
  49. src="@/assets/stuIcon/icon_right.png"
  50. />
  51. <img v-else-if="subjectData?.data?.score === 0" src="@/assets/stuIcon/icon_error.png" />
  52. <img v-else src="@/assets/stuIcon/icon_half_right.png" />
  53. </template>
  54. <template v-else>{{ subjectData?.data?.score ?? '-' }}</template>
  55. </span>
  56. </div>
  57. <div class="score_item" v-if="subjectData?.data?.rateScoreStatus === 0">
  58. <span class="title">赋分</span>
  59. <span class="value">{{ subjectData?.data?.rateScore ?? '-' }}</span>
  60. </div>
  61. <div class="score_item" v-if="subjectData?.data?.classRankStatus === 0">
  62. <span class="title">班排</span>
  63. <span class="value">{{ subjectData?.data?.classRank ?? '-' }}</span>
  64. </div>
  65. <div class="score_item" v-if="subjectData?.data?.schoolRankStatus === 0">
  66. <span class="title">年排</span>
  67. <span class="value">{{ subjectData?.data?.schoolRank ?? '-' }}</span>
  68. </div>
  69. <div class="score_item" v-if="subjectData?.data?.examRankStatus === 0 && schoolType == 2">
  70. <span class="title">联排</span>
  71. <span class="value">{{ subjectData?.data?.examRank ?? '-' }}</span>
  72. </div>
  73. <div class="score_item" v-if="subjectData?.data?.rateScoreStatus === 0">
  74. <span class="title">赋分等级</span>
  75. <span class="value">{{ subjectData?.data?.rateScoreName ?? '-' }}</span>
  76. </div>
  77. <div class="score_item" v-if="subjectData?.data?.standardScoreStatus === 0">
  78. <span class="title">标准分</span>
  79. <span class="value">{{ subjectData?.data?.standardScore ?? '-' }}</span>
  80. </div>
  81. <div class="score_item" v-if="subjectData?.data?.gradeNameStatus === 0">
  82. <span class="title">学业等级</span>
  83. <span class="value">{{ subjectData?.data?.gradeName ?? '-' }}</span>
  84. </div>
  85. <div class="score_item" v-if="subjectData?.data?.scoreRateStatus === 0">
  86. <span class="title">得分率</span>
  87. <span class="value">{{ subjectData?.data?.scoreRate ?? '-' }}</span>
  88. </div>
  89. <div class="score_item" v-if="subjectData?.data?.classMaxScoreStatus === 0">
  90. <span class="title">班级最高分</span>
  91. <span class="value">{{ subjectData?.data?.classMaxScore ?? '-' }}</span>
  92. </div>
  93. <div class="score_item" v-if="subjectData?.data?.gradeMaxScoreStatus === 0">
  94. <span class="title">年级最高分</span>
  95. <span class="value">{{ subjectData?.data?.gradeMaxScore ?? '-' }}</span>
  96. </div>
  97. <div class="score_item" v-if="subjectData?.data?.examMaxScoreStatus === 0">
  98. <span class="title">联校最高分</span>
  99. <span class="value">{{ subjectData?.data?.examMaxScore ?? '-' }}</span>
  100. </div>
  101. <div class="score_item" v-if="subjectData?.data?.classAvgScoreStatus === 0">
  102. <span class="title">班级均分</span>
  103. <span class="value">{{ subjectData?.data?.classAvgScore ?? '-' }}</span>
  104. </div>
  105. <div class="score_item" v-if="subjectData?.data?.gradeAvgScoreStatus === 0">
  106. <span class="title">年级均分</span>
  107. <span class="value">{{ subjectData?.data?.gradeAvgScore ?? '-' }}</span>
  108. </div>
  109. <div class="score_item" v-if="subjectData?.data?.examAvgScoreStatus === 0">
  110. <span class="title">联校均分</span>
  111. <span class="value">{{ subjectData?.data?.examAvgScore ?? '-' }}</span>
  112. </div>
  113. </div>
  114. </div>
  115. <div class="page_jg_20"></div>
  116. </div>
  117. </div>
  118. <div class="report_module" v-if="isHidden">
  119. <div class="module_title">
  120. <div class="title_left">总结建议</div>
  121. </div>
  122. <div class="module_describe suggestion">
  123. <ExpandableText :isExpanded="false" :shouldShowButton="false" v-html="suggestionData"></ExpandableText>
  124. </div>
  125. </div>
  126. <!-- 答题卡 -->
  127. <div class="report_module">
  128. <div class="module_title">
  129. <div class="title_left">{{ getSubjectName }}答题卡 ({{ answerCard.paperImageList.length }}页)</div>
  130. </div>
  131. <div class="module_table">
  132. <div class="answer_sheet" v-if="answerCard.paperImageList.length">
  133. <div class="item" v-for="(item, index) in answerCard.paperImageList">
  134. <PaperImage :imageIndex="index" :paperImgUrl="item.picUrl" :drawData="item.questionVOS || []"></PaperImage>
  135. <div class="item_hover">
  136. <div class="show_view" @click="OpenStudentPaper(index)">
  137. <img src="@/assets/icon/pic_show_view.png" />
  138. <span>查看</span>
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. <div
  144. class="module_chart no_content_data"
  145. v-loading="answerCard.loading"
  146. :element-loading-text="loadingText"
  147. element-loading-spinner="el-icon-loading"
  148. element-loading-background="#ffffff"
  149. v-else
  150. >
  151. <span>暂无答题卡</span>
  152. </div>
  153. <div class="page_jg_20"></div>
  154. </div>
  155. </div>
  156. <!-- 小题分析图 -->
  157. <template v-for="group in groupData.groupName">
  158. <div class="report_module">
  159. <div class="module_title" style="position: relative">
  160. <div class="title_left">{{ group.name }}分析图</div>
  161. <div class="title_right">
  162. <div class="echart_type">
  163. <span
  164. class="chart_icon_item"
  165. v-for="item in groupData.chartTypeList"
  166. :key="item.value"
  167. :class="groupData[group.value].chartType == item.value ? `${item.value}_cur` : item.value"
  168. @click="ChangeChartType(group.value, item.value)"
  169. >{{ item.label }}</span
  170. >
  171. </div>
  172. </div>
  173. </div>
  174. <div class="module_chart" v-if="groupData[group.value].tableData.length > 0">
  175. <BarChart
  176. v-if="groupData[group.value].chartType == 'vertical_bar'"
  177. :datax="groupData[group.value].datax"
  178. typeName="得分率"
  179. :datay="groupData[group.value].datay"
  180. unit="%"
  181. ></BarChart>
  182. <RadarCharts
  183. v-else
  184. :data="groupData[group.value].radarChartData"
  185. :showCheckBox="false"
  186. :showLegend="false"
  187. :openShowAllLegend="false"
  188. >
  189. </RadarCharts>
  190. </div>
  191. <div
  192. class="module_chart no_content_data"
  193. v-loading="groupData[group.value].loading"
  194. :element-loading-text="loadingText"
  195. element-loading-spinner="el-icon-loading"
  196. element-loading-background="#ffffff"
  197. v-else
  198. >
  199. <span>暂无数据</span>
  200. </div>
  201. <div class="page_jg_20"></div>
  202. </div>
  203. <!-- 小题分析表 -->
  204. <div class="report_module">
  205. <div class="module_title">
  206. <div class="title_left">{{ group.name }}分析表</div>
  207. </div>
  208. <div class="module_table">
  209. <el-table
  210. :data="smallQuestionTableData(group.value)"
  211. v-loading="groupData[group.value].loading"
  212. :element-loading-text="loadingText"
  213. element-loading-spinner="el-icon-loading"
  214. element-loading-background="#ffffff"
  215. border
  216. stripe
  217. align="left"
  218. >
  219. <el-table-column
  220. v-for="title in groupData[group.value].titleData"
  221. :key="title.prop"
  222. align="center"
  223. :label="title.name"
  224. show-overflow-tooltip
  225. >
  226. <template slot-scope="scope">
  227. <template v-if="title.prop == 'score'">
  228. <!-- * 1-得分显示分数,小题分显示分数,2-得分显示分数,小题分显示对错
  229. * 3-得分显示对错,小题分显示分数,4-得分显示对错,小题分显示对错
  230. * 5-得分显示等级,小题分显示分数,6-得分显示等级,小题分显示对错 -->
  231. <template
  232. v-if="
  233. groupData[group.value].studentOpenness == 2 ||
  234. groupData[group.value].studentOpenness == 4 ||
  235. groupData[group.value].studentOpenness == 6
  236. "
  237. >
  238. <img v-if="scope.row.fullScore == scope.row.score" src="@/assets/stuIcon/icon_right.png" />
  239. <img v-else-if="scope.row.score == 0" src="@/assets/stuIcon/icon_error.png" />
  240. <img v-else src="@/assets/stuIcon/icon_half_right.png" />
  241. </template>
  242. <template v-else>{{ scope.row.score || '-' }}</template>
  243. </template>
  244. <!-- 包含小题 -->
  245. <template
  246. v-else-if="
  247. title.prop == 'smallQuestionNames' &&
  248. scope?.row?.[title.prop] &&
  249. Object.prototype.toString.call(scope.row[title.prop]) == '[object Array]'
  250. "
  251. >{{ scope.row[title.prop].join('、') }}</template
  252. >
  253. <template v-else-if="title.prop == 'difficultyName'"
  254. ><span :class="GetDifficultyClass(scope.row[title.prop])"></span
  255. ><span>{{ GetDifficultyName(scope.row[title.prop]) }}</span></template
  256. >
  257. <template v-else>{{ scope.row[title.prop] || '-' }}</template>
  258. </template>
  259. </el-table-column>
  260. </el-table>
  261. <div
  262. class="page_pagination"
  263. style="margin-top: 10px; padding-bottom: 10px"
  264. v-if="groupData[group.value].total > 10"
  265. >
  266. <el-pagination
  267. @current-change="value => QuestionChangePage(value, group.value)"
  268. layout="prev, pager, next"
  269. :current-page="groupData[group.value].pageNum"
  270. :page-size="groupData[group.value].pageSize"
  271. :total="groupData[group.value].total"
  272. >
  273. </el-pagination>
  274. </div>
  275. <div v-else class="page_jg_20"></div>
  276. </div>
  277. </div>
  278. </template>
  279. <div class="report_module" v-if="true">
  280. <div class="module_title">
  281. <div class="title_left">历次考试分析</div>
  282. <div class="title_right report_button">
  283. <div class="module_tab">
  284. <div
  285. class="tab_item"
  286. v-for="item in historyExamData.selectNames"
  287. :class="historyExamData.selectVal == item.prop ? 'tab_active' : ''"
  288. :key="item.prop"
  289. @click="ChangeSelectVal(item.prop, item.name)"
  290. >
  291. {{ item.name }}
  292. </div>
  293. </div>
  294. </div>
  295. </div>
  296. <div class="module_chart" v-if="historyExamData.chartData.length > 0">
  297. <LineChart
  298. :extraText="false"
  299. :showCheckBox="false"
  300. :showMarkPoint="false"
  301. :showBackground="false"
  302. :markNumber="historyExamData.markNumber"
  303. :datax="historyExamData.datax"
  304. :datay="historyExamData.datay"
  305. :title="historyExamData.title"
  306. :legendList="historyExamData.title"
  307. :yInverse="
  308. historyExamData.selectVal == 'examRank' || historyExamData.selectVal == 'schoolRank' ? true : false
  309. "
  310. :tooltipData="historyExamData.tooltipData"
  311. ></LineChart>
  312. </div>
  313. <div
  314. class="module_chart no_content_data"
  315. v-loading="historyExamLoading"
  316. :element-loading-text="loadingText"
  317. element-loading-spinner="el-icon-loading"
  318. element-loading-background="#ffffff"
  319. v-else
  320. >
  321. <span>暂无数据</span>
  322. </div>
  323. <div class="page_jg_20"></div>
  324. </div>
  325. <GotoTop></GotoTop>
  326. <!-- 学生答题卡预览组件 -->
  327. <StudentPaper
  328. v-model="showStudentPaperDialog"
  329. :paperInfo="{ examId: reportParam.examId, subjectCode: reportParam.subjectCode }"
  330. :currentPageIndex="currentPageIndex"
  331. :pageTitle="paperTitle"
  332. ></StudentPaper>
  333. </div>
  334. </template>
  335. <script>
  336. import PaperImage from '@/components/PaperImageSmall.vue' //学生试卷组件
  337. import StudentPaper from '@/components/StudentPaper.vue' //学生答题卡预览组件
  338. import BarChart from '@/views/analysisReport/components/dCharts/barChart' //单柱状图组件
  339. import RadarCharts from '@/views/analysisReport/components/dCharts/radarCharts' //雷达图
  340. import ExpandableText from '@/views/analysisReport/components/ExpandableText' //文本内容展开收缩组件
  341. import LineChart from '@/views/analysisReport/components/dCharts/lineChart' //折线图
  342. import GaugeChart from '@/views/analysisReport/components/dCharts/GaugeChart'
  343. import GotoTop from '@/views/analysisReport/components/GotoTop' //分析报告页面底部回到顶部组件
  344. import { mapGetters } from 'vuex'
  345. export default {
  346. name: 'subjectQuality',
  347. props: {},
  348. components: {
  349. PaperImage,
  350. StudentPaper,
  351. BarChart,
  352. RadarCharts,
  353. ExpandableText,
  354. LineChart,
  355. GaugeChart,
  356. GotoTop
  357. },
  358. data() {
  359. return {
  360. subjectData: {
  361. data: {},
  362. levelData: [],
  363. gradeName: '',
  364. levelValue: 0,
  365. fullScore: '', //满分
  366. subjectName: '', //科目名称
  367. chartData: []
  368. },
  369. answerCard: {
  370. //答题卡
  371. studentCode:'',
  372. loading: false,
  373. paperImageList: [] //答题卡图片
  374. },
  375. showStudentPaperDialog: false, //显示答题卡弹框
  376. paperTitle: '', //答题卡弹框标题
  377. currentPageIndex: 0, //当前选中的答题卡第几页
  378. groupData: {
  379. groupName: [
  380. {
  381. name: '小题',
  382. value: 'smallQuestionData'
  383. }
  384. ],
  385. chartTypeList: [
  386. {
  387. label: '柱状图',
  388. value: 'vertical_bar'
  389. },
  390. {
  391. label: '雷达图',
  392. value: 'radar_chart'
  393. }
  394. ],
  395. smallQuestionData: {
  396. studentOpenness: '',
  397. loading: false,
  398. chartType: 'vertical_bar', //默认显示折线图柱状图line_bar_chart
  399. total: 0,
  400. pageNum: 1,
  401. pageSize: 10,
  402. tableData: [],
  403. titleData: [],
  404. datax: [], //x轴数据
  405. datay: [], //y轴数据
  406. radarChartData: []
  407. },
  408. bigQuestionData: {
  409. studentOpenness: '',
  410. loading: false,
  411. chartType: 'vertical_bar', //默认显示折线图柱状图line_bar_chart
  412. total: 0,
  413. pageNum: 1,
  414. pageSize: 10,
  415. tableData: [],
  416. titleData: [],
  417. datax: [], //x轴数据
  418. datay: [], //y轴数据
  419. radarChartData: []
  420. },
  421. knowledgePointQuestionData: {
  422. studentOpenness: '',
  423. loading: false,
  424. chartType: 'vertical_bar', //默认显示折线图柱状图line_bar_chart
  425. total: 0,
  426. pageNum: 1,
  427. pageSize: 10,
  428. tableData: [],
  429. titleData: [],
  430. datax: [], //x轴数据
  431. datay: [], //y轴数据
  432. radarChartData: []
  433. },
  434. abilityQuestionData: {
  435. studentOpenness: '',
  436. loading: false,
  437. chartType: 'vertical_bar', //默认显示折线图柱状图line_bar_chart
  438. total: 0,
  439. pageNum: 1,
  440. pageSize: 10,
  441. tableData: [],
  442. titleData: [],
  443. datax: [], //x轴数据
  444. datay: [], //y轴数据
  445. radarChartData: []
  446. }
  447. },
  448. subjectLoading: true, //加载状态
  449. historyExamLoading: false,
  450. loadingText: '加载中,请稍后……',
  451. historyExamData: {
  452. chartData: [],
  453. datax: [],
  454. datay: [],
  455. title: [],
  456. colors: ['#5470C6'],
  457. markNumber: [],
  458. selectNames: [],
  459. selectVal: 'standardScore'
  460. }, //线面积图
  461. suggestionData: null,
  462. suggestionUpSubjectData:[],//总结建议优势
  463. suggestionDownSubjectData:[],//总结建议劣势
  464. }
  465. },
  466. watch: {
  467. reportParam() {
  468. this.PageInit() //初始加载数据
  469. } //监听筛选数据变化
  470. },
  471. computed: {
  472. ...mapGetters(['userInfo']),
  473. reportParam() {
  474. return {
  475. examLevel: this.$store.state.report.filterObject.examLevel, //1-联考 2-单校
  476. contrastExamIds: this.$store.state.report.filterObject.contrastExamIds, //多次考试任务对比ID,不包含当前任务ID
  477. examId: this.$store.state.report.filterObject.examId, //考试id
  478. subjectCode: this.$store.state.report.filterObject.subjectCode, //科目code
  479. subjectGroupType: this.$store.state.report.filterObject.subjectGroupType, //是否为组合科目 1为组合科目 0为非组合科目
  480. isTotal: this.$store.state.report.filterObject.isTotal //是否为总分科目 1为总分 0为非总分
  481. }
  482. }, //分析报告公共参数变量
  483. smallQuestionTableData() {
  484. return function (group) {
  485. const { tableData, pageSize, pageNum } = this.groupData[group]
  486. const start = (pageNum - 1) * pageSize
  487. const end = start + pageSize
  488. return tableData.slice(start, end)
  489. }
  490. },
  491. getSubjectName() {
  492. return this.$store.state.report.filterObject.subjectName
  493. }, //科目名称
  494. pageName() {
  495. return this.$store.state.report.examSelectItem.examName
  496. }, //考试名称
  497. schoolType() {
  498. return sessionStorage.getItem('schoolType') //1:单校 2:联校
  499. },
  500. isHidden(){
  501. if(this.suggestionUpSubjectData.length || this.suggestionDownSubjectData.length){
  502. return true
  503. }else{
  504. return false
  505. }
  506. }
  507. },
  508. created() {},
  509. mounted() {
  510. this.PageInit() //页面初始加载数据
  511. },
  512. methods: {
  513. PageInit() {
  514. this.initData()
  515. this.QueryOneSubjectData() //学生端查询单科-我的成绩
  516. this.FindStudentCard() //查询学生答题卡带批阅痕迹的(单校)
  517. this.QueryOneSubjectSmallQuestionData() //学生端查询单科-小题分析(表格-图表)
  518. this.QueryOneSubjectHistoryExamData() //学生端查询单科-历次查询
  519. this.QueryOneSubjectSuggestionData() //学生端查询单科-总结建议
  520. },
  521. initData() {
  522. this.groupData.groupName = [
  523. {
  524. name: '小题',
  525. value: 'smallQuestionData'
  526. }
  527. ]
  528. this.suggestionData = null
  529. Object.keys(this.groupData).forEach(key => {
  530. if (key != 'groupName' || key != 'chartTypeList') {
  531. this.groupData[key].chartType = 'vertical_bar'
  532. this.groupData[key].total = 0
  533. this.groupData[key].pageNum = 1
  534. this.groupData[key].pageSize = 10
  535. }
  536. })
  537. },
  538. //学生端查询单科-我的成绩
  539. QueryOneSubjectData() {
  540. this.subjectLoading = true
  541. this.$api.reportStudent
  542. .queryOneSubjectData(this.reportParam)
  543. .then(res => {
  544. if (res.code == 200 && res.data) {
  545. this.subjectData.data = res.data
  546. const academicLevelData = res.data.academicLevelData
  547. const examAcademicLevelList = (academicLevelData.examAcademicLevelList || []).reverse()
  548. this.subjectData.levelData = examAcademicLevelList.map(item => ({
  549. label: item.gradeName,
  550. range: this.getMiddleNumber(
  551. academicLevelData.scoreType == 1
  552. ? [Number(item.endScore), Number(item.startScore)]
  553. : [Number(item.startScore), Number(item.endScore)]
  554. ),
  555. value: academicLevelData.scoreType == 1 ? Number(item.startScore) : Number(item.Number(item.endScore)) //1 按分数
  556. }))
  557. const gradeName = this.subjectData.levelData.find(item => item.label == res.data.gradeName)
  558. this.subjectData.levelValue = gradeName ? gradeName.range : 0
  559. this.subjectData.gradeName = res.data.gradeName //等级
  560. this.subjectData.fullScore = res.data.fullScore //满分
  561. this.subjectData.subjectName = res.data.subjectName //科目名称
  562. } else {
  563. this.subjectData.data = {}
  564. this.subjectData.levelData = []
  565. this.subjectData.levelValue = 0
  566. this.subjectData.gradeName = ''
  567. this.subjectData.fullScore = '' //满分
  568. this.subjectData.subjectName = '' //科目名称
  569. }
  570. })
  571. .finally(() => {
  572. this.subjectLoading = false
  573. })
  574. },
  575. //查询学生答题卡带批阅痕迹的
  576. FindStudentCard() {
  577. this.answerCard.loading = true
  578. this.$api.reportStudent
  579. .findStudentCard({
  580. examId: this.reportParam.examId, //考试ID
  581. subjectCode: this.reportParam.subjectCode //科目code
  582. })
  583. .then(res => {
  584. if (res.code == 200 && res.data) {
  585. this.answerCard.paperImageList = res?.data?.pageVOS || [];
  586. this.answerCard.studentCode = res?.data?.studentCode ?? ''
  587. //先添加总分数据
  588. let totalScore = {
  589. questionName: '总分',
  590. fullScore: res?.data?.fullScore || 150,
  591. score: res?.data?.levelName ?? res?.data?.totalScore,
  592. displayType: res.data.displayType, //显示类型 0-分数 1-对错 2-等级
  593. displayName: res.data.displayName, //显示值
  594. correctType: res.data.correctType, //显示对错的时候 0-错 1-半对 2-全对
  595. questionAnswer: '',
  596. answer: '',
  597. samplingPosition: '{"x":195,"y":247,"page":1}'
  598. }
  599. if (this.answerCard.paperImageList.length > 0 && this.answerCard.paperImageList[0].questionVOS) {
  600. this.answerCard.paperImageList[0].questionVOS.unshift(totalScore)
  601. }
  602. } else {
  603. this.answerCard.paperImageList = []
  604. this.answerCard.studentCode = '';
  605. }
  606. })
  607. .finally(() => {
  608. this.answerCard.loading = false
  609. })
  610. },
  611. //答题卡预览
  612. OpenStudentPaper(index) {
  613. this.currentPageIndex = index //当选选中的第几页
  614. this.paperTitle = `${this.pageName}_${this.userInfo.userName}【${this.answerCard.studentCode}】`
  615. this.showStudentPaperDialog = true
  616. },
  617. getMiddleNumber(arr) {
  618. return parseInt((arr[0] + arr[1]) / 2)
  619. },
  620. //学生端查询单科-小题分析(表格-图表)
  621. QueryOneSubjectSmallQuestionData() {
  622. this.groupData.smallQuestionData.loading = true
  623. this.$api.reportStudent
  624. .queryOneSubjectSmallQuestionData(this.reportParam)
  625. .then(res => {
  626. if (res.code == 200 && res.data) {
  627. const tableData = res.data.tableData || []
  628. const titleData = res.data.titleData || []
  629. const studentOpenness = res.data?.studentOpenness ?? ''
  630. this.TableChartData(tableData, titleData, studentOpenness, 'smallQuestionData')
  631. } else {
  632. this.groupData.smallQuestionData.tableData = []
  633. this.groupData.smallQuestionData.titleData = []
  634. this.groupData.smallQuestionData.total = 0
  635. this.groupData.smallQuestionData.datax = []
  636. this.groupData.smallQuestionData.datay = []
  637. this.groupData.smallQuestionData.studentOpenness = ''
  638. }
  639. this.QueryOneSubjectGroupQuestionData() //学生端查询单科-大题分析,知识点分析,能力要素分析
  640. })
  641. .finally(() => {
  642. this.groupData.smallQuestionData.loading = false
  643. })
  644. },
  645. GetDifficultyClass(val) {
  646. if (val == 1) {
  647. return 'difficulty easy'
  648. } else if (val == 2) {
  649. return 'difficulty relatively_easy'
  650. } else if (val == 3) {
  651. return 'difficulty general'
  652. } else if (val == 4) {
  653. return 'difficulty more_difficult'
  654. } else if (val == 5) {
  655. return 'difficulty difficult'
  656. } else {
  657. return ''
  658. }
  659. },
  660. GetDifficultyName(val) {
  661. if (val == 1) {
  662. return '容易'
  663. } else if (val == 2) {
  664. return '较易'
  665. } else if (val == 3) {
  666. return '一般'
  667. } else if (val == 4) {
  668. return '较难'
  669. } else if (val == 5) {
  670. return '困难'
  671. } else {
  672. return '-'
  673. }
  674. },
  675. //处理数据
  676. TableChartData(tableData, titleData, studentOpenness, type) {
  677. this.groupData[type].studentOpenness = studentOpenness
  678. this.groupData[type].tableData = tableData
  679. this.groupData[type].titleData = titleData
  680. this.groupData[type].total = tableData.length
  681. //分析图
  682. this.groupData[type].datax = []
  683. this.groupData[type].datay = []
  684. const radarChartData = []
  685. tableData.forEach(item => {
  686. this.groupData[type].datax.push(item.questionName)
  687. const scoreRate = item?.scoreRate ?? ''
  688. this.groupData[type].datay.push(scoreRate)
  689. radarChartData.push([item.questionName, scoreRate])
  690. })
  691. //雷达图
  692. this.groupData[type].radarChartData = [['group', '得分率'], ...radarChartData]
  693. },
  694. QuestionChangePage(value, group) {
  695. this.groupData[group].pageNum = value
  696. },
  697. ChangeChartType(prop, value) {
  698. this.groupData[prop].chartType = value
  699. },
  700. //学生端查询单科-大题分析,知识点分析,能力要素分析
  701. QueryOneSubjectGroupQuestionData() {
  702. this.groupData.bigQuestionData.loading = true
  703. this.groupData.knowledgePointQuestionData.loading = true
  704. this.groupData.abilityQuestionData.loading = true
  705. this.$api.reportStudent
  706. .queryOneSubjectGroupQuestionData(this.reportParam)
  707. .then(res => {
  708. if (res.code == 200 && res.data) {
  709. const { bigQuestion, knowledgePointQuestion, abilityQuestion } = res.data
  710. if (bigQuestion && bigQuestion?.tableData?.length > 0) {
  711. this.groupData.groupName.push({
  712. name: '大题',
  713. value: 'bigQuestionData'
  714. })
  715. const tableData = bigQuestion.tableData || []
  716. const titleData = bigQuestion.titleData || []
  717. const studentOpenness = bigQuestion?.studentOpenness ?? ''
  718. this.TableChartData(tableData, titleData, studentOpenness, 'bigQuestionData')
  719. }
  720. if (knowledgePointQuestion && knowledgePointQuestion?.tableData?.length > 0) {
  721. this.groupData.groupName.push({
  722. name: '知识点',
  723. value: 'knowledgePointQuestionData'
  724. })
  725. const tableData = knowledgePointQuestion.tableData || []
  726. const titleData = knowledgePointQuestion.titleData || []
  727. const studentOpenness = knowledgePointQuestion?.studentOpenness ?? ''
  728. this.TableChartData(tableData, titleData, studentOpenness, 'knowledgePointQuestionData')
  729. }
  730. if (abilityQuestion && abilityQuestion?.tableData?.length > 0) {
  731. this.groupData.groupName.push({
  732. name: '能力要素',
  733. value: 'abilityQuestionData'
  734. })
  735. const tableData = abilityQuestion.tableData || []
  736. const titleData = abilityQuestion.titleData || []
  737. const studentOpenness = abilityQuestion?.studentOpenness ?? ''
  738. this.TableChartData(tableData, titleData, studentOpenness, 'abilityQuestionData')
  739. }
  740. } else {
  741. this.groupData.bigQuestionData.tableData = []
  742. this.groupData.bigQuestionData.titleData = []
  743. this.groupData.bigQuestionData.total = 0
  744. this.groupData.bigQuestionData.datax = []
  745. this.groupData.bigQuestionData.datay = []
  746. this.groupData.bigQuestionData.studentOpenness = ''
  747. this.groupData.knowledgePointQuestionData.tableData = []
  748. this.groupData.knowledgePointQuestionData.titleData = []
  749. this.groupData.knowledgePointQuestionData.total = 0
  750. this.groupData.knowledgePointQuestionData.datax = []
  751. this.groupData.knowledgePointQuestionData.datay = []
  752. this.groupData.knowledgePointQuestionData.studentOpenness = ''
  753. this.groupData.abilityQuestionData.tableData = []
  754. this.groupData.abilityQuestionData.titleData = []
  755. this.groupData.abilityQuestionData.total = 0
  756. this.groupData.abilityQuestionData.datax = []
  757. this.groupData.abilityQuestionData.datay = []
  758. this.groupData.abilityQuestionData.studentOpenness = ''
  759. }
  760. this.QueryOneSubjectCustomGroupQuestion() //学生端查询单科-自定义分组
  761. })
  762. .finally(() => {
  763. this.groupData.bigQuestionData.loading = false
  764. this.groupData.knowledgePointQuestionData.loading = false
  765. this.groupData.abilityQuestionData.loading = false
  766. })
  767. },
  768. //学生端查询单科-自定义分组
  769. QueryOneSubjectCustomGroupQuestion() {
  770. this.$api.reportStudent.queryOneSubjectCustomGroupQuestion(this.reportParam).then(res => {
  771. if (res.code == 200 && res.data) {
  772. const customQuestionData = res?.data?.customQuestionData ?? []
  773. if (customQuestionData && customQuestionData.length > 0) {
  774. customQuestionData.forEach((item, index) => {
  775. this.groupData.groupName.push({
  776. name: item.customName,
  777. value: `customQuestionData${index}`
  778. })
  779. this.$set(this.groupData, `customQuestionData${index}`, {
  780. studentOpenness: '',
  781. loading: false,
  782. chartType: 'vertical_bar', //默认显示折线图柱状图line_bar_chart
  783. total: 0,
  784. pageNum: 1,
  785. pageSize: 10,
  786. tableData: [],
  787. titleData: [],
  788. datax: [], //x轴数据
  789. datay: [], //y轴数据
  790. radarChartData: []
  791. })
  792. const tableData = item?.questionData?.tableData || []
  793. const titleData = item?.questionData?.titleData || []
  794. const studentOpenness = res.data?.studentOpenness ?? ''
  795. this.TableChartData(tableData, titleData, studentOpenness, `customQuestionData${index}`)
  796. })
  797. }
  798. }
  799. })
  800. },
  801. //学生端查询单科-历次查询
  802. QueryOneSubjectHistoryExamData() {
  803. this.historyExamLoading = true
  804. this.$api.reportStudent
  805. .queryOneSubjectHistoryExamData(this.reportParam)
  806. .then(res => {
  807. if (res.code == 200 && res.data) {
  808. const detailData = (res.data?.detailData || []).reverse()
  809. this.historyExamData.chartData = detailData
  810. this.historyExamData.selectNames = res.data.selectNames || []
  811. this.historyExamData.selectVal = this.historyExamData?.selectNames?.[0]?.prop ?? ''
  812. this.historyExamData.datax = []
  813. let datay = [],
  814. tooltipData = []
  815. detailData.forEach(item => {
  816. this.historyExamData.datax.push(item.examName)
  817. datay.push(item[this.historyExamData.selectVal])
  818. tooltipData.push({
  819. name: this.historyExamData?.selectNames?.[0]?.name ?? '',
  820. value: item[this.historyExamData.selectVal]
  821. })
  822. })
  823. this.historyExamData.datay = [datay]
  824. this.historyExamData.tooltipData = [tooltipData]
  825. } else {
  826. this.historyExamData.chartData = []
  827. this.historyExamData.datax = []
  828. this.historyExamData.datay = []
  829. this.historyExamData.selectNames = []
  830. this.historyExamData.tooltipData = []
  831. this.historyExamData.selectVal = ''
  832. }
  833. })
  834. .finally(() => {
  835. this.historyExamLoading = false
  836. })
  837. },
  838. ChangeSelectVal(prop, name) {
  839. this.historyExamData.selectVal = prop
  840. let datay = [],
  841. tooltipData = []
  842. this.historyExamData.chartData.forEach(item => {
  843. datay.push(item[prop])
  844. tooltipData.push({
  845. name: name,
  846. value: item[prop]
  847. })
  848. })
  849. this.historyExamData.datay = [datay]
  850. this.historyExamData.tooltipData = [tooltipData]
  851. },
  852. //学生端查询单科-总结建议
  853. QueryOneSubjectSuggestionData() {
  854. this.$api.reportStudent.queryOneSubjectSuggestionData(this.reportParam).then(res => {
  855. if (res.code == 200 && res.data) {
  856. const data = res.data
  857. //* 1-得分显示分数,小题分显示分数,2-得分显示分数,小题分显示对错
  858. //* 3-得分显示对错,小题分显示分数,4-得分显示对错,小题分显示对错
  859. //* 5-得分显示等级,小题分显示分数,6-得分显示等级,小题分显示对错
  860. this.suggestionUpSubjectData = data.upSubjectData
  861. this.suggestionDownSubjectData = data.downSubjectData
  862. const upSubjectData = data.upSubjectData
  863. .map(item => {
  864. if (data.studentOpenness == 1 || data.studentOpenness == 2) {
  865. return `${item.subjectName}得分<span style="color: #3BA272;">${item.score}</span>分`
  866. } else {
  867. return `${item.subjectName}标准分为<span style="color: #3BA272;">${item.score}</span>`
  868. }
  869. })
  870. .join('、')
  871. const downSubjectData = data.downSubjectData
  872. .map(item => {
  873. if (data.studentOpenness == 1 || data.studentOpenness == 2) {
  874. return `${item.subjectName}得分<span style="color: #EE6666;">${item.score}</span>分`
  875. } else {
  876. return `${item.subjectName}标准分为<span style="color: #EE6666;">${item.score}</span>`
  877. }
  878. })
  879. .join('、')
  880. if (data.studentName) {
  881. this.suggestionData = `${data.studentName}同学,本次考试`
  882. }
  883. if (upSubjectData) {
  884. this.suggestionData += `${upSubjectData},是你的优势学科,建议通过提分练习进行强化,继续保持这类学科的优势性!`
  885. }
  886. if (downSubjectData) {
  887. this.suggestionData += `${downSubjectData},是你的劣势学科,建议先加强学习,熟练掌握薄弱知识点的基础,然后通过提分练习进行巩固和强化,争取下次考试获得更优异的成绩!`
  888. }
  889. } else {
  890. this.suggestionData = null
  891. }
  892. })
  893. }
  894. }
  895. }
  896. </script>
  897. <style lang="scss" scoped>
  898. .module_tab {
  899. width: auto !important;
  900. height: auto !important;
  901. padding: 0 10px !important;
  902. .tab_item {
  903. padding-bottom: 0 !important;
  904. &.tab_active {
  905. border-bottom: 0 !important;
  906. }
  907. }
  908. }
  909. .subject_score {
  910. display: flex;
  911. width: 100%;
  912. .subject_score_chart {
  913. width: 40%;
  914. position: relative;
  915. .button_editor {
  916. position: absolute;
  917. left: 50%;
  918. top: 62%;
  919. transform: translate(-50%, 0);
  920. color: #2e64fa;
  921. border: 1px solid #2e64fa;
  922. }
  923. }
  924. .subject_score_content {
  925. width: 60%;
  926. display: flex;
  927. flex-wrap: wrap;
  928. gap: 12px 15px;
  929. align-content: flex-start;
  930. /* 元素之间的间隔 */
  931. .score_item {
  932. width: calc((100% - 15px * 4) / 5);
  933. height: 98px;
  934. background: #f8f9fd;
  935. border-radius: 5px;
  936. border: 1px solid #ebeef5;
  937. padding: 10px 2px;
  938. box-sizing: border-box;
  939. display: flex;
  940. flex-direction: column;
  941. justify-content: center;
  942. span {
  943. display: flex;
  944. justify-content: center;
  945. &.title {
  946. font-weight: 400;
  947. color: #999999;
  948. }
  949. &.value {
  950. font-weight: 500;
  951. font-size: 20px;
  952. color: #333333;
  953. margin-top: 10px;
  954. }
  955. }
  956. }
  957. }
  958. }
  959. .module_describe {
  960. &.suggestion {
  961. padding-top: 0 !important;
  962. }
  963. }
  964. .answer_sheet {
  965. display: flex;
  966. flex-wrap: wrap;
  967. width: 100%;
  968. gap: 20px;
  969. .item {
  970. width: calc((100% - 20px * 3) / 4);
  971. padding: 9px;
  972. height: 200px;
  973. background: #f8f9fd;
  974. border-radius: 10px;
  975. border: 1px solid #ebeef5;
  976. box-sizing: border-box;
  977. position: relative;
  978. cursor: pointer;
  979. &:hover {
  980. .item_hover {
  981. display: flex;
  982. justify-content: center;
  983. align-items: center;
  984. .show_view {
  985. width: 80px;
  986. height: 40px;
  987. background: #ffffff;
  988. border-radius: 4px;
  989. display: flex;
  990. justify-content: center;
  991. align-items: center;
  992. img {
  993. width: 20px;
  994. height: 20px;
  995. margin-right: 6px;
  996. }
  997. span {
  998. font-weight: 400;
  999. font-size: 14px;
  1000. color: #606266;
  1001. }
  1002. }
  1003. }
  1004. }
  1005. .item_hover {
  1006. display: none;
  1007. position: absolute;
  1008. left: 0;
  1009. top: 0;
  1010. width: 100%;
  1011. height: 100%;
  1012. background: rgba(0, 0, 0, 0.2);
  1013. border-radius: 10px;
  1014. z-index: 99;
  1015. }
  1016. }
  1017. }
  1018. .difficulty {
  1019. width: 6px;
  1020. height: 6px;
  1021. display: inline-flex;
  1022. border-radius: 50%;
  1023. margin-right: 4px;
  1024. &.easy {
  1025. background: #3ba272;
  1026. }
  1027. &.relatively_easy {
  1028. background: #fac858;
  1029. }
  1030. &.general {
  1031. background: #5470c6;
  1032. }
  1033. &.more_difficult {
  1034. background: #ea7acb;
  1035. }
  1036. &.difficult {
  1037. background: #ee6666;
  1038. }
  1039. }
  1040. </style>