transcript_single.vue 36 KB

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