transcript_single.vue 45 KB

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