question_report.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. <template>
  2. <view>
  3. <nav-bar title="试卷报告"></nav-bar>
  4. <view
  5. :class="
  6. reportStatus == 0
  7. ? 'redBtn'
  8. : reportStatus == 1
  9. ? 'greenBtn'
  10. : 'disNone'
  11. "
  12. v-if="reportStatus !== null"
  13. >
  14. {{
  15. reportStatus == 0 ? "测试未通过" : reportStatus == 1 ? "测试通过" : ""
  16. }}
  17. </view>
  18. <view class="top">
  19. <view class="box">
  20. <view class="left">
  21. <view
  22. >{{
  23. (
  24. (rightQuestionNum / (rightQuestionNum + doWrongQuestionNum)) *
  25. 100
  26. ).toFixed(0)
  27. }}%</view
  28. >
  29. <view>正确率</view>
  30. <view>不含简答/案例题</view>
  31. </view>
  32. <view class="right">
  33. <view class="flex up">
  34. <!-- <u-icon name="checkmark" color="#16D48B" size="48" style="margin-right: 14rpx;"></u-icon> -->
  35. <image
  36. class="right_num"
  37. src="/static/right_num.png"
  38. mode="widthFix"
  39. ></image>
  40. <view class="text">正确题数</view>
  41. <text class="green">{{ rightQuestionNum }}</text>
  42. </view>
  43. <view class="flex up">
  44. <!-- <u-icon name="checkmark" color="#16D48B" size="48" style="margin-right: 14rpx;"></u-icon> -->
  45. <image
  46. class="right_num"
  47. src="/static/out_num.png"
  48. mode="widthFix"
  49. ></image>
  50. <view class="text">少选题数</view>
  51. <text class="yellow">{{ lessQuestionNum }}</text>
  52. </view>
  53. <view class="flex down">
  54. <!-- <u-icon name="close" color="#FF3B30" size="38" style="margin-right: 26rpx;"></u-icon> -->
  55. <image
  56. class="right_num"
  57. src="/static/wrong_num.png"
  58. mode="widthFix"
  59. ></image>
  60. <view class="text">错误题数</view>
  61. <text class="red">{{ doWrongQuestionNum }}</text>
  62. </view>
  63. </view>
  64. </view>
  65. <view class="dis_fst">
  66. <navigator
  67. v-if="doWrongQuestionNum != 0"
  68. :url="
  69. '/pages2/bank/questionBankWrongExplain?recordId=' +
  70. reportdata.recordId +
  71. '&id=' +
  72. reportdata.examId +
  73. '&courseType=2'
  74. "
  75. >
  76. <view class="btnACs">错题解析</view>
  77. </navigator>
  78. <navigator
  79. :url="
  80. '/pages2/bank/questionBankAllExplain?id=' +
  81. reportdata.examId +
  82. '&goodsid=' +
  83. reportdata.goodsId +
  84. '&moduleId=' +
  85. reportdata.moduleId +
  86. '&chapterId=' +
  87. reportdata.chapterId +
  88. '&recordId=' +
  89. reportdata.recordId +
  90. '&courseType=2'
  91. "
  92. >
  93. <view class="btnACs">全部解析</view>
  94. </navigator>
  95. <view
  96. class="btnACs"
  97. v-if="reportStatus == 1 || bankType == 1"
  98. @click="
  99. doRepeat(
  100. reportdata.examId,
  101. reportdata.goodsId,
  102. reportdata.moduleId,
  103. reportdata.chapterId
  104. )
  105. "
  106. >重新做题</view
  107. >
  108. <navigator v-if="isBackVideo" open-type="navigateBack">
  109. <view class="btnACs">返回学习</view>
  110. </navigator>
  111. <!-- <view class="btnACs" v-if="nextExamId" @click="backBank">继续做题</view> -->
  112. </view>
  113. </view>
  114. <view class="bottom">
  115. <view class="circle-wrap">
  116. <view class="circle-list">
  117. <view class="item" v-show="totalScore">
  118. <view class="title">
  119. 试卷得分
  120. <text>(不含简答和案例题)</text>
  121. </view>
  122. <canvas class="canvas" canvas-id="Canvas1"></canvas>
  123. </view>
  124. <view class="item" v-show="examTime">
  125. <view class="title">答题时长</view>
  126. <canvas canvas-id="Canvas2"></canvas>
  127. </view>
  128. </view>
  129. </view>
  130. </view>
  131. <view v-if="courseList.length" class="course_list">
  132. <view class="titles">
  133. <image class="code" src="@/static/learn/act_icon.png"></image>
  134. <text class="title">推荐课程</text>
  135. </view>
  136. <view
  137. class="list_item"
  138. v-for="(item, index) in courseList"
  139. :key="index"
  140. @click="toBuy(item)"
  141. >
  142. <view class="course_content">
  143. <view class="c_title">{{ item.goodsName }}</view>
  144. <view class="c_downs">
  145. <view class="img">
  146. <image :src="$method.splitImgHost(item.coverUrl, true)"></image>
  147. <view class="time" v-if="item.year">{{
  148. item.year ? item.year : ""
  149. }}</view>
  150. </view>
  151. <view class="text">
  152. <view class="desc">
  153. <view class="left">
  154. <text class="mon_t">¥ {{ item.standPrice }}</text>
  155. <!-- <text class="sale">/限时优惠</text> -->
  156. <text v-if="item.linePrice" class="sale"> ¥ </text>
  157. <text v-if="item.linePrice" class="price_line"
  158. >&nbsp;{{ item.linePrice }}</text
  159. >
  160. </view>
  161. <view class="right">
  162. <view class="regiser_row" v-if="!hideBuyState">立即购买</view>
  163. </view>
  164. </view>
  165. <view v-if="item.buyUserNum" class="joins">
  166. <!-- <image class="people" src="/static/index/people.png"></image> -->
  167. <!-- 为0时,不显示 -->
  168. <view class="people">{{ item.buyUserNum }}人参与</view>
  169. </view>
  170. </view>
  171. </view>
  172. </view>
  173. </view>
  174. </view>
  175. </view>
  176. </template>
  177. <script>
  178. import { mapGetters } from "vuex";
  179. export default {
  180. data() {
  181. return {
  182. id: "",
  183. hideBtns: false,
  184. examData: {},
  185. examId: "",
  186. context1: null,
  187. context2: null,
  188. rightQuestionNum: "",
  189. // doWrongQuestionNum:'',
  190. score: "",
  191. totalScore: "",
  192. doTime: "",
  193. examTime: "",
  194. reportStatus: null,
  195. lessQuestionNum: 0,
  196. courseList: [],
  197. pageNum: 1,
  198. pageSize: 10,
  199. total: 0,
  200. recordId: "",
  201. reportdata: {},
  202. examType: 0, // 3-模块,1-章,2-节
  203. orderGoodsId: "",
  204. bankType: "",
  205. isBackVideo: "",
  206. };
  207. },
  208. onPullDownRefresh() {
  209. this.pageNum = 1;
  210. this.courseList = [];
  211. this.getcourList();
  212. // this.timer = setTimeout(function() {
  213. // uni.stopPullDownRefresh()
  214. // }, 500)
  215. },
  216. onReachBottom() {
  217. console.log(this.total, "total");
  218. console.log(this.courseList.length, "length");
  219. if (this.courseList.length < this.total) {
  220. this.pageNum++;
  221. this.getcourList();
  222. }
  223. },
  224. onUnload() {},
  225. computed: {
  226. ...mapGetters(["userInfo", "hideBuyState"]),
  227. doWrongQuestionNum() {
  228. let value =
  229. this.reportdata.totalQuestionNum -
  230. this.reportdata.rightQuestionNum -
  231. this.reportdata.lessQuestionNum;
  232. return value > 0 ? value : 0;
  233. },
  234. },
  235. async onShow() {
  236. this.pageNum = 1;
  237. this.courseList = [];
  238. this.getcourList();
  239. },
  240. async onLoad(option) {
  241. this.examType = option.type;
  242. this.recordId = option.recordId;
  243. this.examId = option.examId;
  244. this.orderGoodsId = option.orderGoodsId;
  245. this.bankType = option.bankType;
  246. this.isBackVideo = option.isBackVideo;
  247. this.bankReport();
  248. },
  249. methods: {
  250. getCanvas() {
  251. this.$method.getCanvas(this).then(({ systemInfo }) => {
  252. var caculateX = systemInfo.screenWidth / 750;
  253. if (this.totalScore) {
  254. var context1 = uni.createCanvasContext("Canvas1");
  255. this.context1 = context1;
  256. context1.setStrokeStyle("#EEEEEE");
  257. context1.setLineWidth(caculateX * 20);
  258. context1.arc(
  259. caculateX * 90,
  260. caculateX * 90,
  261. caculateX * 80,
  262. 0,
  263. 2 * Math.PI,
  264. true
  265. );
  266. context1.stroke();
  267. context1.beginPath();
  268. context1.setStrokeStyle("#32D74B");
  269. context1.setFillStyle("#32D74B");
  270. context1.setTextAlign("center");
  271. context1.setTextBaseline("middle");
  272. context1.setLineCap("round");
  273. context1.setFontSize(caculateX * 64);
  274. context1.fillText(
  275. this.score,
  276. caculateX * 90,
  277. caculateX * 90,
  278. caculateX * 180
  279. );
  280. context1.setFillStyle("#999999");
  281. context1.setFontSize(caculateX * 20);
  282. context1.fillText(
  283. `满分${this.totalScore}`,
  284. caculateX * 90,
  285. caculateX * 130,
  286. caculateX * 180
  287. );
  288. context1.arc(
  289. caculateX * 90,
  290. caculateX * 90,
  291. caculateX * 80,
  292. -Math.PI / 2,
  293. -Math.PI / 2 + (this.score / this.totalScore) * 2 * Math.PI,
  294. false
  295. );
  296. context1.stroke();
  297. context1.draw();
  298. }
  299. if (this.examTime) {
  300. var context2 = uni.createCanvasContext("Canvas2");
  301. this.context2 = context2;
  302. context2.setStrokeStyle("#EEEEEE");
  303. context2.setLineWidth(caculateX * 20);
  304. context2.arc(
  305. caculateX * 90,
  306. caculateX * 90,
  307. caculateX * 80,
  308. 0,
  309. 2 * Math.PI,
  310. true
  311. );
  312. context2.stroke();
  313. context2.beginPath();
  314. context2.setStrokeStyle("#007AFF");
  315. context2.setFillStyle("#007AFF");
  316. context2.setTextAlign("center");
  317. context2.setTextBaseline("middle");
  318. context2.setLineCap("round");
  319. context2.setFontSize(caculateX * 64);
  320. context2.fillText(
  321. `${this.doTime}'`,
  322. caculateX * 90,
  323. caculateX * 90,
  324. caculateX * 180
  325. );
  326. context2.setFillStyle("#999999");
  327. context2.setFontSize(caculateX * 20);
  328. context2.fillText(
  329. `限时${this.examTime}'`,
  330. caculateX * 90,
  331. caculateX * 130,
  332. caculateX * 180
  333. );
  334. context2.arc(
  335. caculateX * 90,
  336. caculateX * 90,
  337. caculateX * 80,
  338. -Math.PI / 2,
  339. -Math.PI / 2 + (this.doTime / this.examTime) * 2 * Math.PI,
  340. false
  341. );
  342. context2.stroke();
  343. context2.draw();
  344. }
  345. });
  346. },
  347. getcourList() {
  348. this.$http({
  349. url: "/apply/recommend/goodsList",
  350. method: "post",
  351. data: {
  352. examId: this.examId,
  353. pageNum: this.pageNum,
  354. pageSize: this.pageSize,
  355. },
  356. }).then((res) => {
  357. if (res.data.code == 200) {
  358. this.courseList.push(...(res.data.rows || []));
  359. this.total = res.data.total;
  360. }
  361. });
  362. },
  363. toBuy(item) {
  364. // if (item.goodsType == 1) {
  365. // uni.navigateTo({
  366. // url: '/pages3/course/detail?id='+item.goodsId
  367. // })
  368. // } else
  369. if (item.goodsType == 2) {
  370. uni.navigateTo({
  371. url: "/pages2/bank/detail?id=" + item.goodsId,
  372. });
  373. } else {
  374. // /pages5/liveDetail/index
  375. uni.navigateTo({
  376. url:
  377. "/pages3/course/detail?id=" +
  378. item.goodsId +
  379. "&goodsType=" +
  380. item.goodsType,
  381. });
  382. }
  383. },
  384. bankReport() {
  385. this.$api.bankReportData(this.recordId).then((res) => {
  386. this.reportdata = res.data.data;
  387. // console.log('reportdata:', this.reportdata)
  388. const {
  389. examTime,
  390. doTime,
  391. reportStatus,
  392. rightQuestionNum,
  393. performance,
  394. lessQuestionNum,
  395. totalScore,
  396. } = this.reportdata;
  397. this.examTime = examTime;
  398. this.doTime = doTime;
  399. this.reportStatus = reportStatus;
  400. this.rightQuestionNum = rightQuestionNum;
  401. // this.doWrongQuestionNum = +option.doWrongQuestionNum;
  402. this.score = performance;
  403. this.lessQuestionNum = lessQuestionNum;
  404. this.totalScore = totalScore;
  405. this.getCanvas();
  406. });
  407. },
  408. /**
  409. * 去做题
  410. */
  411. async doRepeat(examId, goodsId, moduleId = 0, chapterId = 0) {
  412. let count = await this.bankRecordDoNum();
  413. let answerNum = await this.getExamDetail(examId);
  414. //超过答题次数
  415. if (answerNum > 0 && count >= answerNum) {
  416. this.$u.toast("该试卷只能答题" + answerNum + "次!");
  417. return;
  418. }
  419. // answerNum==0没有答题次数限制
  420. if (answerNum == 0 || (answerNum - count > 0 && answerNum > 0)) {
  421. const { courseId, gradeId, sectionId } = this.reportdata;
  422. uni.redirectTo({
  423. url:
  424. "/pages2/class/questionBank?courseId=" +
  425. courseId +
  426. "&gradeId=" +
  427. gradeId +
  428. "&isFromVideo=1&id=" +
  429. examId +
  430. "&goodsid=" +
  431. goodsId +
  432. "&moduleId=" +
  433. moduleId +
  434. "&chapterId=" +
  435. chapterId +
  436. "&sectionId=" +
  437. sectionId +
  438. "&orderGoodsId=" +
  439. this.orderGoodsId +
  440. "&type=" +
  441. this.examType +
  442. "&learning=" +
  443. this.reportStatus,
  444. });
  445. }
  446. },
  447. /**
  448. * 获取试卷已做的次数
  449. */
  450. bankRecordDoNum() {
  451. return new Promise((resolve) => {
  452. this.$api
  453. .bankRecordDoNum({
  454. goodsId: this.reportdata.goodsId,
  455. gradeId: this.reportdata.gradeId,
  456. chapterId: this.reportdata.chapterId || 0,
  457. courseId: this.reportdata.courseId,
  458. moduleId: this.reportdata.moduleId || 0,
  459. examId: this.reportdata.examId,
  460. })
  461. .then((res) => {
  462. resolve(res.data.data);
  463. });
  464. });
  465. },
  466. /**
  467. * @param {Object} exam_id
  468. * 获取试卷可以做的次数
  469. */
  470. getExamDetail(exam_id) {
  471. return new Promise((resolve) => {
  472. this.$api.getExamDetail(exam_id).then((res) => {
  473. resolve(res.data.data.answerNum);
  474. });
  475. });
  476. },
  477. },
  478. };
  479. </script>
  480. <style>
  481. page {
  482. background-color: #eaeef1;
  483. }
  484. </style>
  485. <style lang="scss" scope>
  486. @import "../../pages5/examReport/indexCourseList.scss";
  487. .disNone {
  488. display: none;
  489. }
  490. .greenBtn {
  491. margin: 16rpx 16rpx 0;
  492. height: 80rpx;
  493. line-height: 80rpx;
  494. text-align: center;
  495. background-color: #f7fff8;
  496. border-radius: 16rpx;
  497. color: #34c759;
  498. font-weight: bold;
  499. font-size: 30rpx;
  500. }
  501. .redBtn {
  502. margin: 16rpx 16rpx 0;
  503. height: 80rpx;
  504. line-height: 80rpx;
  505. text-align: center;
  506. background-color: #fff3f2;
  507. border-radius: 16rpx;
  508. color: #ff3b30;
  509. font-weight: bold;
  510. font-size: 30rpx;
  511. }
  512. .dis_fst {
  513. margin-top: 40rpx;
  514. display: flex;
  515. align-items: center;
  516. justify-content: space-around;
  517. }
  518. .btnACs {
  519. height: 48rpx;
  520. width: 160rpx;
  521. text-align: center;
  522. line-height: 48rpx;
  523. border: 1rpx solid #007aff;
  524. border-radius: 16rpx;
  525. color: #007aff;
  526. font-size: 24rpx;
  527. }
  528. .top {
  529. margin: 16rpx 16rpx 0;
  530. border-radius: 16rpx;
  531. padding: 40rpx 24rpx 16rpx;
  532. background: #fff;
  533. .title {
  534. font-size: 32rpx;
  535. font-weight: bold;
  536. color: #333333;
  537. }
  538. .desc {
  539. margin-top: 20rpx;
  540. font-size: 24rpx;
  541. color: #999999;
  542. }
  543. .box {
  544. margin-top: 30rpx;
  545. display: flex;
  546. .left {
  547. width: 250rpx;
  548. height: 176rpx;
  549. background: #f5f5f5;
  550. border-radius: 16rpx;
  551. display: flex;
  552. align-items: center;
  553. justify-content: center;
  554. flex-direction: column;
  555. margin-right: 16rpx;
  556. view {
  557. text-align: center;
  558. &:nth-of-type(1) {
  559. font-size: 60rpx;
  560. font-weight: bold;
  561. color: #007aff;
  562. }
  563. &:nth-of-type(2) {
  564. font-size: 32rpx;
  565. font-weight: bold;
  566. color: #333333;
  567. }
  568. &:nth-of-type(3) {
  569. font-size: 24rpx;
  570. color: #999999;
  571. }
  572. }
  573. }
  574. .right {
  575. flex: 1;
  576. display: flex;
  577. flex-direction: column;
  578. justify-content: space-between;
  579. .flex {
  580. background: #f5f5f5;
  581. display: flex;
  582. height: 80rpx;
  583. align-items: center;
  584. padding: 0 40rpx;
  585. border-radius: 16rpx;
  586. image {
  587. margin-right: 28rpx;
  588. &.right_num {
  589. width: 26rpx;
  590. }
  591. &.out_num {
  592. width: 38rpx;
  593. }
  594. &.wrong_num {
  595. width: 30rpx;
  596. }
  597. }
  598. .text {
  599. flex: 1;
  600. font-size: 30rpx;
  601. color: #666666;
  602. }
  603. text {
  604. font-size: 48rpx;
  605. color: #e12626;
  606. &.red {
  607. color: #ff3b30;
  608. }
  609. &.green {
  610. color: #36c75a;
  611. }
  612. &.yellow {
  613. color: #ffc53d;
  614. }
  615. }
  616. }
  617. }
  618. }
  619. }
  620. .bottom {
  621. .circle-wrap {
  622. .circle-list {
  623. display: flex;
  624. .item {
  625. padding: 20rpx;
  626. border-radius: 16rpx;
  627. background: #fff;
  628. margin: 16rpx;
  629. flex: 1;
  630. .title {
  631. font-weight: bold;
  632. font-size: 30rpx;
  633. line-height: 24rpx;
  634. color: #333333;
  635. text {
  636. font-size: 20rpx;
  637. color: #999999;
  638. }
  639. }
  640. canvas {
  641. margin: 36rpx auto 0;
  642. width: 180rpx;
  643. height: 180rpx;
  644. }
  645. .text {
  646. text-align: center;
  647. margin-top: 16rpx;
  648. font-size: 24rpx;
  649. color: #333333;
  650. }
  651. }
  652. }
  653. }
  654. }
  655. </style>