transcript_single.vue 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  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="false">
  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. loading: false,
  372. paperImageList: [] //答题卡图片
  373. },
  374. showStudentPaperDialog: false, //显示答题卡弹框
  375. paperTitle: '', //答题卡弹框标题
  376. currentPageIndex: 0, //当前选中的答题卡第几页
  377. groupData: {
  378. groupName: [
  379. {
  380. name: '小题',
  381. value: 'smallQuestionData'
  382. }
  383. ],
  384. chartTypeList: [
  385. {
  386. label: '柱状图',
  387. value: 'vertical_bar'
  388. },
  389. {
  390. label: '雷达图',
  391. value: 'radar_chart'
  392. }
  393. ],
  394. smallQuestionData: {
  395. studentOpenness: '',
  396. loading: false,
  397. chartType: 'vertical_bar', //默认显示折线图柱状图line_bar_chart
  398. total: 0,
  399. pageNum: 1,
  400. pageSize: 10,
  401. tableData: [],
  402. titleData: [],
  403. datax: [], //x轴数据
  404. datay: [], //y轴数据
  405. radarChartData: []
  406. },
  407. bigQuestionData: {
  408. studentOpenness: '',
  409. loading: false,
  410. chartType: 'vertical_bar', //默认显示折线图柱状图line_bar_chart
  411. total: 0,
  412. pageNum: 1,
  413. pageSize: 10,
  414. tableData: [],
  415. titleData: [],
  416. datax: [], //x轴数据
  417. datay: [], //y轴数据
  418. radarChartData: []
  419. },
  420. knowledgePointQuestionData: {
  421. studentOpenness: '',
  422. loading: false,
  423. chartType: 'vertical_bar', //默认显示折线图柱状图line_bar_chart
  424. total: 0,
  425. pageNum: 1,
  426. pageSize: 10,
  427. tableData: [],
  428. titleData: [],
  429. datax: [], //x轴数据
  430. datay: [], //y轴数据
  431. radarChartData: []
  432. },
  433. abilityQuestionData: {
  434. studentOpenness: '',
  435. loading: false,
  436. chartType: 'vertical_bar', //默认显示折线图柱状图line_bar_chart
  437. total: 0,
  438. pageNum: 1,
  439. pageSize: 10,
  440. tableData: [],
  441. titleData: [],
  442. datax: [], //x轴数据
  443. datay: [], //y轴数据
  444. radarChartData: []
  445. }
  446. },
  447. subjectLoading: true, //加载状态
  448. historyExamLoading: false,
  449. loadingText: '加载中,请稍后……',
  450. historyExamData: {
  451. chartData: [],
  452. datax: [],
  453. datay: [],
  454. title: [],
  455. colors: ['#5470C6'],
  456. markNumber: [],
  457. selectNames: [],
  458. selectVal: 'standardScore'
  459. }, //线面积图
  460. suggestionData: null,
  461. suggestionUpSubjectData:[],//总结建议优势
  462. suggestionDownSubjectData:[],//总结建议劣势
  463. }
  464. },
  465. watch: {
  466. reportParam() {
  467. this.PageInit() //初始加载数据
  468. } //监听筛选数据变化
  469. },
  470. computed: {
  471. ...mapGetters(['userInfo']),
  472. reportParam() {
  473. return {
  474. examLevel: this.$store.state.report.filterObject.examLevel, //1-联考 2-单校
  475. contrastExamIds: this.$store.state.report.filterObject.contrastExamIds, //多次考试任务对比ID,不包含当前任务ID
  476. examId: this.$store.state.report.filterObject.examId, //考试id
  477. subjectCode: this.$store.state.report.filterObject.subjectCode, //科目code
  478. subjectGroupType: this.$store.state.report.filterObject.subjectGroupType, //是否为组合科目 1为组合科目 0为非组合科目
  479. isTotal: this.$store.state.report.filterObject.isTotal //是否为总分科目 1为总分 0为非总分
  480. }
  481. }, //分析报告公共参数变量
  482. smallQuestionTableData() {
  483. return function (group) {
  484. const { tableData, pageSize, pageNum } = this.groupData[group]
  485. const start = (pageNum - 1) * pageSize
  486. const end = start + pageSize
  487. return tableData.slice(start, end)
  488. }
  489. },
  490. getSubjectName() {
  491. return this.$store.state.report.filterObject.subjectName
  492. }, //科目名称
  493. pageName() {
  494. return this.$store.state.report.examSelectItem.examName
  495. }, //考试名称
  496. schoolType() {
  497. return sessionStorage.getItem('schoolType') //1:单校 2:联校
  498. },
  499. isHidden(){
  500. if(this.suggestionUpSubjectData.length || this.suggestionDownSubjectData.length){
  501. return true
  502. }else{
  503. return false
  504. }
  505. }
  506. },
  507. created() {},
  508. mounted() {
  509. this.PageInit() //页面初始加载数据
  510. },
  511. methods: {
  512. PageInit() {
  513. this.initData()
  514. this.QueryOneSubjectData() //学生端查询单科-我的成绩
  515. this.FindStudentCard() //查询学生答题卡带批阅痕迹的(单校)
  516. this.QueryOneSubjectSmallQuestionData() //学生端查询单科-小题分析(表格-图表)
  517. this.QueryOneSubjectHistoryExamData() //学生端查询单科-历次查询
  518. this.QueryOneSubjectSuggestionData() //学生端查询单科-总结建议
  519. },
  520. initData() {
  521. this.groupData.groupName = [
  522. {
  523. name: '小题',
  524. value: 'smallQuestionData'
  525. }
  526. ]
  527. this.suggestionData = null
  528. Object.keys(this.groupData).forEach(key => {
  529. if (key != 'groupName' || key != 'chartTypeList') {
  530. this.groupData[key].chartType = 'vertical_bar'
  531. this.groupData[key].total = 0
  532. this.groupData[key].pageNum = 1
  533. this.groupData[key].pageSize = 10
  534. }
  535. })
  536. },
  537. //学生端查询单科-我的成绩
  538. QueryOneSubjectData() {
  539. this.subjectLoading = true
  540. this.$api.reportStudent
  541. .queryOneSubjectData(this.reportParam)
  542. .then(res => {
  543. if (res.code == 200 && res.data) {
  544. this.subjectData.data = res.data
  545. const academicLevelData = res.data.academicLevelData
  546. const examAcademicLevelList = (academicLevelData.examAcademicLevelList || []).reverse()
  547. this.subjectData.levelData = examAcademicLevelList.map(item => ({
  548. label: item.gradeName,
  549. range: this.getMiddleNumber(
  550. academicLevelData.scoreType == 1
  551. ? [Number(item.endScore), Number(item.startScore)]
  552. : [Number(item.startScore), Number(item.endScore)]
  553. ),
  554. value: academicLevelData.scoreType == 1 ? Number(item.startScore) : Number(item.Number(item.endScore)) //1 按分数
  555. }))
  556. const gradeName = this.subjectData.levelData.find(item => item.label == res.data.gradeName)
  557. this.subjectData.levelValue = gradeName ? gradeName.range : 0
  558. this.subjectData.gradeName = res.data.gradeName //等级
  559. this.subjectData.fullScore = res.data.fullScore //满分
  560. this.subjectData.subjectName = res.data.subjectName //科目名称
  561. } else {
  562. this.subjectData.data = {}
  563. this.subjectData.levelData = []
  564. this.subjectData.levelValue = 0
  565. this.subjectData.gradeName = ''
  566. this.subjectData.fullScore = '' //满分
  567. this.subjectData.subjectName = '' //科目名称
  568. }
  569. })
  570. .finally(() => {
  571. this.subjectLoading = false
  572. })
  573. },
  574. //查询学生答题卡带批阅痕迹的
  575. FindStudentCard() {
  576. this.answerCard.loading = true
  577. this.$api.reportStudent
  578. .findStudentCard({
  579. examId: this.reportParam.examId, //考试ID
  580. subjectCode: this.reportParam.subjectCode //科目code
  581. })
  582. .then(res => {
  583. if (res.code == 200 && res.data) {
  584. this.answerCard.paperImageList = res.data.pageVOS || []
  585. //先添加总分数据
  586. let totalScore = {
  587. questionName: '总分',
  588. fullScore: res?.data?.fullScore || 150,
  589. score: res?.data?.levelName ?? res?.data?.totalScore,
  590. displayType: res.data.displayType, //显示类型 0-分数 1-对错 2-等级
  591. displayName: res.data.displayName, //显示值
  592. correctType: res.data.correctType, //显示对错的时候 0-错 1-半对 2-全对
  593. questionAnswer: '',
  594. answer: '',
  595. samplingPosition: '{"x":195,"y":247,"page":1}'
  596. }
  597. if (this.answerCard.paperImageList.length > 0 && this.answerCard.paperImageList[0].questionVOS) {
  598. this.answerCard.paperImageList[0].questionVOS.unshift(totalScore)
  599. }
  600. } else {
  601. this.answerCard.paperImageList = []
  602. }
  603. })
  604. .finally(() => {
  605. this.answerCard.loading = false
  606. })
  607. },
  608. //答题卡预览
  609. OpenStudentPaper(index) {
  610. this.currentPageIndex = index //当选选中的第几页
  611. this.paperTitle = `${this.pageName}_${this.userInfo.userName}【${this.userInfo.registrationCode}】`
  612. this.showStudentPaperDialog = true
  613. },
  614. getMiddleNumber(arr) {
  615. return parseInt((arr[0] + arr[1]) / 2)
  616. },
  617. //学生端查询单科-小题分析(表格-图表)
  618. QueryOneSubjectSmallQuestionData() {
  619. this.groupData.smallQuestionData.loading = true
  620. this.$api.reportStudent
  621. .queryOneSubjectSmallQuestionData(this.reportParam)
  622. .then(res => {
  623. if (res.code == 200 && res.data) {
  624. const tableData = res.data.tableData || []
  625. const titleData = res.data.titleData || []
  626. const studentOpenness = res.data?.studentOpenness ?? ''
  627. this.TableChartData(tableData, titleData, studentOpenness, 'smallQuestionData')
  628. } else {
  629. this.groupData.smallQuestionData.tableData = []
  630. this.groupData.smallQuestionData.titleData = []
  631. this.groupData.smallQuestionData.total = 0
  632. this.groupData.smallQuestionData.datax = []
  633. this.groupData.smallQuestionData.datay = []
  634. this.groupData.smallQuestionData.studentOpenness = ''
  635. }
  636. this.QueryOneSubjectGroupQuestionData() //学生端查询单科-大题分析,知识点分析,能力要素分析
  637. })
  638. .finally(() => {
  639. this.groupData.smallQuestionData.loading = false
  640. })
  641. },
  642. GetDifficultyClass(val) {
  643. if (val == 1) {
  644. return 'difficulty easy'
  645. } else if (val == 2) {
  646. return 'difficulty relatively_easy'
  647. } else if (val == 3) {
  648. return 'difficulty general'
  649. } else if (val == 4) {
  650. return 'difficulty more_difficult'
  651. } else if (val == 5) {
  652. return 'difficulty difficult'
  653. } else {
  654. return ''
  655. }
  656. },
  657. GetDifficultyName(val) {
  658. if (val == 1) {
  659. return '容易'
  660. } else if (val == 2) {
  661. return '较易'
  662. } else if (val == 3) {
  663. return '一般'
  664. } else if (val == 4) {
  665. return '较难'
  666. } else if (val == 5) {
  667. return '困难'
  668. } else {
  669. return '-'
  670. }
  671. },
  672. //处理数据
  673. TableChartData(tableData, titleData, studentOpenness, type) {
  674. this.groupData[type].studentOpenness = studentOpenness
  675. this.groupData[type].tableData = tableData
  676. this.groupData[type].titleData = titleData
  677. this.groupData[type].total = tableData.length
  678. //分析图
  679. this.groupData[type].datax = []
  680. this.groupData[type].datay = []
  681. const radarChartData = []
  682. tableData.forEach(item => {
  683. this.groupData[type].datax.push(item.questionName)
  684. const scoreRate = item?.scoreRate ?? ''
  685. this.groupData[type].datay.push(scoreRate)
  686. radarChartData.push([item.questionName, scoreRate])
  687. })
  688. //雷达图
  689. this.groupData[type].radarChartData = [['group', '得分率'], ...radarChartData]
  690. },
  691. QuestionChangePage(value, group) {
  692. this.groupData[group].pageNum = value
  693. },
  694. ChangeChartType(prop, value) {
  695. this.groupData[prop].chartType = value
  696. },
  697. //学生端查询单科-大题分析,知识点分析,能力要素分析
  698. QueryOneSubjectGroupQuestionData() {
  699. this.groupData.bigQuestionData.loading = true
  700. this.groupData.knowledgePointQuestionData.loading = true
  701. this.groupData.abilityQuestionData.loading = true
  702. this.$api.reportStudent
  703. .queryOneSubjectGroupQuestionData(this.reportParam)
  704. .then(res => {
  705. if (res.code == 200 && res.data) {
  706. const { bigQuestion, knowledgePointQuestion, abilityQuestion } = res.data
  707. if (bigQuestion && bigQuestion?.tableData?.length > 0) {
  708. this.groupData.groupName.push({
  709. name: '大题',
  710. value: 'bigQuestionData'
  711. })
  712. const tableData = bigQuestion.tableData || []
  713. const titleData = bigQuestion.titleData || []
  714. const studentOpenness = bigQuestion?.studentOpenness ?? ''
  715. this.TableChartData(tableData, titleData, studentOpenness, 'bigQuestionData')
  716. }
  717. if (knowledgePointQuestion && knowledgePointQuestion?.tableData?.length > 0) {
  718. this.groupData.groupName.push({
  719. name: '知识点',
  720. value: 'knowledgePointQuestionData'
  721. })
  722. const tableData = knowledgePointQuestion.tableData || []
  723. const titleData = knowledgePointQuestion.titleData || []
  724. const studentOpenness = knowledgePointQuestion?.studentOpenness ?? ''
  725. this.TableChartData(tableData, titleData, studentOpenness, 'knowledgePointQuestionData')
  726. }
  727. if (abilityQuestion && abilityQuestion?.tableData?.length > 0) {
  728. this.groupData.groupName.push({
  729. name: '能力要素',
  730. value: 'abilityQuestionData'
  731. })
  732. const tableData = abilityQuestion.tableData || []
  733. const titleData = abilityQuestion.titleData || []
  734. const studentOpenness = abilityQuestion?.studentOpenness ?? ''
  735. this.TableChartData(tableData, titleData, studentOpenness, 'abilityQuestionData')
  736. }
  737. } else {
  738. this.groupData.bigQuestionData.tableData = []
  739. this.groupData.bigQuestionData.titleData = []
  740. this.groupData.bigQuestionData.total = 0
  741. this.groupData.bigQuestionData.datax = []
  742. this.groupData.bigQuestionData.datay = []
  743. this.groupData.bigQuestionData.studentOpenness = ''
  744. this.groupData.knowledgePointQuestionData.tableData = []
  745. this.groupData.knowledgePointQuestionData.titleData = []
  746. this.groupData.knowledgePointQuestionData.total = 0
  747. this.groupData.knowledgePointQuestionData.datax = []
  748. this.groupData.knowledgePointQuestionData.datay = []
  749. this.groupData.knowledgePointQuestionData.studentOpenness = ''
  750. this.groupData.abilityQuestionData.tableData = []
  751. this.groupData.abilityQuestionData.titleData = []
  752. this.groupData.abilityQuestionData.total = 0
  753. this.groupData.abilityQuestionData.datax = []
  754. this.groupData.abilityQuestionData.datay = []
  755. this.groupData.abilityQuestionData.studentOpenness = ''
  756. }
  757. this.QueryOneSubjectCustomGroupQuestion() //学生端查询单科-自定义分组
  758. })
  759. .finally(() => {
  760. this.groupData.bigQuestionData.loading = false
  761. this.groupData.knowledgePointQuestionData.loading = false
  762. this.groupData.abilityQuestionData.loading = false
  763. })
  764. },
  765. //学生端查询单科-自定义分组
  766. QueryOneSubjectCustomGroupQuestion() {
  767. this.$api.reportStudent.queryOneSubjectCustomGroupQuestion(this.reportParam).then(res => {
  768. if (res.code == 200 && res.data) {
  769. const customQuestionData = res?.data?.customQuestionData ?? []
  770. if (customQuestionData && customQuestionData.length > 0) {
  771. customQuestionData.forEach((item, index) => {
  772. this.groupData.groupName.push({
  773. name: item.customName,
  774. value: `customQuestionData${index}`
  775. })
  776. this.$set(this.groupData, `customQuestionData${index}`, {
  777. studentOpenness: '',
  778. loading: false,
  779. chartType: 'vertical_bar', //默认显示折线图柱状图line_bar_chart
  780. total: 0,
  781. pageNum: 1,
  782. pageSize: 10,
  783. tableData: [],
  784. titleData: [],
  785. datax: [], //x轴数据
  786. datay: [], //y轴数据
  787. radarChartData: []
  788. })
  789. const tableData = item?.questionData?.tableData || []
  790. const titleData = item?.questionData?.titleData || []
  791. const studentOpenness = res.data?.studentOpenness ?? ''
  792. this.TableChartData(tableData, titleData, studentOpenness, `customQuestionData${index}`)
  793. })
  794. }
  795. }
  796. })
  797. },
  798. //学生端查询单科-历次查询
  799. QueryOneSubjectHistoryExamData() {
  800. this.historyExamLoading = true
  801. this.$api.reportStudent
  802. .queryOneSubjectHistoryExamData(this.reportParam)
  803. .then(res => {
  804. if (res.code == 200 && res.data) {
  805. const detailData = (res.data?.detailData || []).reverse()
  806. this.historyExamData.chartData = detailData
  807. this.historyExamData.selectNames = res.data.selectNames || []
  808. this.historyExamData.selectVal = this.historyExamData?.selectNames?.[0]?.prop ?? ''
  809. this.historyExamData.datax = []
  810. let datay = [],
  811. tooltipData = []
  812. detailData.forEach(item => {
  813. this.historyExamData.datax.push(item.examName)
  814. datay.push(item[this.historyExamData.selectVal])
  815. tooltipData.push({
  816. name: this.historyExamData?.selectNames?.[0]?.name ?? '',
  817. value: item[this.historyExamData.selectVal]
  818. })
  819. })
  820. this.historyExamData.datay = [datay]
  821. this.historyExamData.tooltipData = [tooltipData]
  822. } else {
  823. this.historyExamData.chartData = []
  824. this.historyExamData.datax = []
  825. this.historyExamData.datay = []
  826. this.historyExamData.selectNames = []
  827. this.historyExamData.tooltipData = []
  828. this.historyExamData.selectVal = ''
  829. }
  830. })
  831. .finally(() => {
  832. this.historyExamLoading = false
  833. })
  834. },
  835. ChangeSelectVal(prop, name) {
  836. this.historyExamData.selectVal = prop
  837. let datay = [],
  838. tooltipData = []
  839. this.historyExamData.chartData.forEach(item => {
  840. datay.push(item[prop])
  841. tooltipData.push({
  842. name: name,
  843. value: item[prop]
  844. })
  845. })
  846. this.historyExamData.datay = [datay]
  847. this.historyExamData.tooltipData = [tooltipData]
  848. },
  849. //学生端查询单科-总结建议
  850. QueryOneSubjectSuggestionData() {
  851. this.$api.reportStudent.queryOneSubjectSuggestionData(this.reportParam).then(res => {
  852. if (res.code == 200 && res.data) {
  853. const data = res.data
  854. //* 1-得分显示分数,小题分显示分数,2-得分显示分数,小题分显示对错
  855. //* 3-得分显示对错,小题分显示分数,4-得分显示对错,小题分显示对错
  856. //* 5-得分显示等级,小题分显示分数,6-得分显示等级,小题分显示对错
  857. this.suggestionUpSubjectData = data.upSubjectData
  858. this.suggestionDownSubjectData = data.downSubjectData
  859. const upSubjectData = data.upSubjectData
  860. .map(item => {
  861. if (data.studentOpenness == 1 || data.studentOpenness == 2) {
  862. return `${item.subjectName}得分<span style="color: #3BA272;">${item.score}</span>分`
  863. } else {
  864. return `${item.subjectName}标准分为<span style="color: #3BA272;">${item.score}</span>`
  865. }
  866. })
  867. .join('、')
  868. const downSubjectData = data.downSubjectData
  869. .map(item => {
  870. if (data.studentOpenness == 1 || data.studentOpenness == 2) {
  871. return `${item.subjectName}得分<span style="color: #EE6666;">${item.score}</span>分`
  872. } else {
  873. return `${item.subjectName}标准分为<span style="color: #EE6666;">${item.score}</span>`
  874. }
  875. })
  876. .join('、')
  877. if (data.studentName) {
  878. this.suggestionData = `${data.studentName}同学,本次考试`
  879. }
  880. if (upSubjectData) {
  881. this.suggestionData += `${upSubjectData},是你的优势学科,建议通过提分练习进行强化,继续保持这类学科的优势性!`
  882. }
  883. if (downSubjectData) {
  884. this.suggestionData += `${downSubjectData},是你的劣势学科,建议先加强学习,熟练掌握薄弱知识点的基础,然后通过提分练习进行巩固和强化,争取下次考试获得更优异的成绩!`
  885. }
  886. } else {
  887. this.suggestionData = null
  888. }
  889. })
  890. }
  891. }
  892. }
  893. </script>
  894. <style lang="scss" scoped>
  895. .module_tab {
  896. width: auto !important;
  897. height: auto !important;
  898. padding: 0 10px !important;
  899. .tab_item {
  900. padding-bottom: 0 !important;
  901. &.tab_active {
  902. border-bottom: 0 !important;
  903. }
  904. }
  905. }
  906. .subject_score {
  907. display: flex;
  908. width: 100%;
  909. .subject_score_chart {
  910. width: 40%;
  911. position: relative;
  912. .button_editor {
  913. position: absolute;
  914. left: 50%;
  915. top: 62%;
  916. transform: translate(-50%, 0);
  917. color: #2e64fa;
  918. border: 1px solid #2e64fa;
  919. }
  920. }
  921. .subject_score_content {
  922. width: 60%;
  923. display: flex;
  924. flex-wrap: wrap;
  925. gap: 12px 15px;
  926. align-content: flex-start;
  927. /* 元素之间的间隔 */
  928. .score_item {
  929. width: calc((100% - 15px * 4) / 5);
  930. height: 98px;
  931. background: #f8f9fd;
  932. border-radius: 5px;
  933. border: 1px solid #ebeef5;
  934. padding: 10px 2px;
  935. box-sizing: border-box;
  936. display: flex;
  937. flex-direction: column;
  938. justify-content: center;
  939. span {
  940. display: flex;
  941. justify-content: center;
  942. &.title {
  943. font-weight: 400;
  944. color: #999999;
  945. }
  946. &.value {
  947. font-weight: 500;
  948. font-size: 20px;
  949. color: #333333;
  950. margin-top: 10px;
  951. }
  952. }
  953. }
  954. }
  955. }
  956. .module_describe {
  957. &.suggestion {
  958. padding-top: 0 !important;
  959. }
  960. }
  961. .answer_sheet {
  962. display: flex;
  963. flex-wrap: wrap;
  964. width: 100%;
  965. gap: 20px;
  966. .item {
  967. width: calc((100% - 20px * 3) / 4);
  968. padding: 9px;
  969. height: 200px;
  970. background: #f8f9fd;
  971. border-radius: 10px;
  972. border: 1px solid #ebeef5;
  973. box-sizing: border-box;
  974. position: relative;
  975. cursor: pointer;
  976. &:hover {
  977. .item_hover {
  978. display: flex;
  979. justify-content: center;
  980. align-items: center;
  981. .show_view {
  982. width: 80px;
  983. height: 40px;
  984. background: #ffffff;
  985. border-radius: 4px;
  986. display: flex;
  987. justify-content: center;
  988. align-items: center;
  989. img {
  990. width: 20px;
  991. height: 20px;
  992. margin-right: 6px;
  993. }
  994. span {
  995. font-weight: 400;
  996. font-size: 14px;
  997. color: #606266;
  998. }
  999. }
  1000. }
  1001. }
  1002. .item_hover {
  1003. display: none;
  1004. position: absolute;
  1005. left: 0;
  1006. top: 0;
  1007. width: 100%;
  1008. height: 100%;
  1009. background: rgba(0, 0, 0, 0.2);
  1010. border-radius: 10px;
  1011. z-index: 99;
  1012. }
  1013. }
  1014. }
  1015. .difficulty {
  1016. width: 6px;
  1017. height: 6px;
  1018. display: inline-flex;
  1019. border-radius: 50%;
  1020. margin-right: 4px;
  1021. &.easy {
  1022. background: #3ba272;
  1023. }
  1024. &.relatively_easy {
  1025. background: #fac858;
  1026. }
  1027. &.general {
  1028. background: #5470c6;
  1029. }
  1030. &.more_difficult {
  1031. background: #ea7acb;
  1032. }
  1033. &.difficult {
  1034. background: #ee6666;
  1035. }
  1036. }
  1037. </style>