index.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <template>
  2. <div class="header-back">
  3. <m-nav-bar :transparent="true" title="模拟考试" style="color: #ffffff" />
  4. <div class="user-data">
  5. <div class="left">
  6. <m-user-avatar />
  7. <div class="name">
  8. <m-user-name />
  9. <span
  10. >最高成绩<span class="grade">{{ testScoresInfo.maxScore }}</span
  11. >分</span
  12. >
  13. </div>
  14. </div>
  15. <m-button
  16. @click="goMockTest"
  17. class="continue"
  18. width="90px"
  19. height="30px"
  20. text="继续考试"
  21. />
  22. </div>
  23. </div>
  24. <div class="summary content-box">
  25. <div class="item">
  26. <div>
  27. <span class="number">{{ testScoresList.length }}</span
  28. >次
  29. </div>
  30. <div>考试次数</div>
  31. </div>
  32. <div class="item">
  33. <div>
  34. <span class="number">{{ testScoresInfo.avgScore }}</span
  35. >分
  36. </div>
  37. <div>平均成绩</div>
  38. </div>
  39. <div class="item">
  40. <div>
  41. <span class="number">{{ testScoresInfo.forecastScore }}</span
  42. >分
  43. </div>
  44. <div>成绩预测</div>
  45. </div>
  46. </div>
  47. <div class="test-scores content-box">
  48. <table class="table">
  49. <tr>
  50. <th>车型</th>
  51. <th>科目</th>
  52. <th>分数</th>
  53. <th>时间</th>
  54. </tr>
  55. <tr v-for="(item, index) in testScoresList" :key="index">
  56. <td>{{ item.type }}</td>
  57. <td>{{ item.kskm }}</td>
  58. <td>{{ item.score }}</td>
  59. <td>{{ item.createTime }}</td>
  60. </tr>
  61. </table>
  62. </div>
  63. </template>
  64. <script lang="ts">
  65. import { getTestScoresList, getTestScoresInfo } from "@/api";
  66. import { ref, onBeforeMount } from "vue";
  67. import { RouterBus } from "@/hooks";
  68. /**
  69. * 考试成绩数据结构
  70. */
  71. interface TestScores {
  72. createTime: string; //考试时间
  73. kskm: string; //科目
  74. score: number; //分数
  75. type: string; //车型
  76. }
  77. /**
  78. * 模拟考成绩列表
  79. */
  80. const useTestScoresList = () => {
  81. const testScoresList = ref<TestScores[]>([]);
  82. onBeforeMount(async () => {
  83. let res = await getTestScoresList();
  84. testScoresList.value = res.rows;
  85. });
  86. return {
  87. testScoresList,
  88. };
  89. };
  90. /**
  91. * 成绩信息数据结构
  92. */
  93. interface TestScoresInfo {
  94. avgScore: number; //平均成绩
  95. forecastScore: number; //预测成绩
  96. maxScore: number; //最大成绩
  97. }
  98. /**
  99. * 最大成绩,平均成绩,预测成绩
  100. */
  101. const useTestScoresInfo = () => {
  102. const testScoresInfo = ref<TestScoresInfo>({
  103. avgScore: 0,
  104. forecastScore: 0,
  105. maxScore: 0,
  106. });
  107. onBeforeMount(async () => {
  108. let res = await getTestScoresInfo();
  109. testScoresInfo.value = res.data;
  110. });
  111. return {
  112. testScoresInfo,
  113. };
  114. };
  115. </script>
  116. <script lang="ts" setup>
  117. const { testScoresList } = useTestScoresList();
  118. const { testScoresInfo } = useTestScoresInfo();
  119. const { goMockTest } = new RouterBus();
  120. </script>
  121. <style scoped lang="scss">
  122. .header-back {
  123. width: 375px;
  124. padding-bottom: 82px;
  125. background: linear-gradient(180deg, #498ef5 0%, #4da8e6 100%);
  126. border-radius: 0px 0px 82px 82px;
  127. .user-data {
  128. display: flex;
  129. justify-content: space-between;
  130. align-items: center;
  131. padding: 19px 17px 24px;
  132. .left {
  133. display: flex;
  134. justify-content: space-between;
  135. align-items: center;
  136. .name {
  137. display: flex;
  138. flex-direction: column;
  139. font-size: 13px;
  140. color: #ffffff;
  141. justify-content: space-between;
  142. margin-left: 6px;
  143. .grade {
  144. font-size: 24px;
  145. padding: 4px;
  146. }
  147. }
  148. }
  149. .continue {
  150. font-size: 13px;
  151. font-family: PingFang SC;
  152. font-weight: 400;
  153. line-height: 19px;
  154. color: #ffffff;
  155. background: #01c18d;
  156. }
  157. }
  158. }
  159. .content-box {
  160. width: 345px;
  161. background: #ffffff;
  162. box-shadow: 0px 0px 8px rgba(124, 129, 136, 0.2);
  163. border-radius: 10px;
  164. position: relative;
  165. left: 50%;
  166. transform: translateX(-50%);
  167. top: -82px;
  168. margin-top: 10px;
  169. }
  170. .summary {
  171. display: flex;
  172. justify-content: space-around;
  173. padding: 25px 30px;
  174. box-sizing: border-box;
  175. .item {
  176. font-size: 13px;
  177. font-family: PingFang SC;
  178. font-weight: 400;
  179. line-height: 19px;
  180. color: #8a9099;
  181. display: flex;
  182. flex-direction: column;
  183. align-items: center;
  184. .number {
  185. font-size: 24px;
  186. color: #0a1a33;
  187. padding: 4px;
  188. }
  189. }
  190. }
  191. .test-scores {
  192. font-size: 13px;
  193. font-family: PingFang SC;
  194. font-weight: 400;
  195. line-height: 19px;
  196. color: #0a1a33;
  197. padding: 15px;
  198. box-sizing: border-box;
  199. .table {
  200. width: 100%;
  201. border-collapse: collapse;
  202. font-size: 13px;
  203. th {
  204. padding: 5px;
  205. color: #0a1a33;
  206. }
  207. td {
  208. text-align: center;
  209. padding: 5px;
  210. color: #8a9099;
  211. }
  212. tr {
  213. &:nth-of-type(n) {
  214. background: #ffffff;
  215. }
  216. &:nth-of-type(2n) {
  217. background: rgba(73, 142, 245, 0.15);
  218. }
  219. }
  220. }
  221. }
  222. </style>