index.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. <template>
  2. <Container
  3. title="学习本"
  4. bgColor="#f8f8f8"
  5. :scrollStyle="{
  6. padding: 0,
  7. }"
  8. headerColor="#fff"
  9. >
  10. <div class="top">
  11. <div
  12. class="item col left"
  13. :class="currentIndex === 0 && 'select'"
  14. @click="currentIndex = 0"
  15. >
  16. <span>
  17. <span class="primary">{{ info.answer_total }}</span
  18. >/{{ info.topic_total }}
  19. </span>
  20. <span
  21. >正确率<span class="primary">{{ info.accuracy }}</span></span
  22. >
  23. </div>
  24. <div
  25. class="item"
  26. :class="currentIndex === 1 && 'select'"
  27. @click="currentIndex = 1"
  28. >
  29. 考试记录(<span class="primary">{{ info.real_paper_total }}</span
  30. >)
  31. </div>
  32. <div
  33. class="item right"
  34. :class="currentIndex === 2 && 'select'"
  35. @click="currentIndex = 2"
  36. >
  37. 题目收藏(<span class="primary">{{ info.favorite_total }}</span
  38. >)
  39. </div>
  40. </div>
  41. <div class="tab">
  42. <scroll-view class="scroll" scroll-x>
  43. <div class="box">
  44. <div
  45. v-for="(item, index) in info.chapter_infos"
  46. class="item"
  47. :class="{
  48. select: item.id === currentTab,
  49. }"
  50. :key="item.id"
  51. @click="
  52. () => {
  53. currentTab = item.id;
  54. }
  55. "
  56. >
  57. {{ item.name }}
  58. </div>
  59. </div>
  60. </scroll-view>
  61. <div class="select-line" v-if="currentIndex === 0">
  62. <div class="item" :class="{ select: isRight }" @click="isRight = 1">
  63. 答案正确({{ rightTotal }})
  64. </div>
  65. <div class="item" :class="{ select: !isRight }" @click="isRight = 0">
  66. 答案错误({{ errorTotal }})
  67. </div>
  68. </div>
  69. </div>
  70. <div class="context">
  71. <template v-if="currentIndex === 0 && dataList.length">
  72. <QuestionsItem :data="dataList" :isRight="isRight" />
  73. </template>
  74. <template v-else-if="currentIndex === 1 && examList.length">
  75. <div class="card" v-for="item in examList" :key="item.catalogue_id">
  76. <div class="card-header">
  77. <span class="title">{{ item.year }}年真题</span>
  78. <span class="exam-count">已考试{{ item.exam_count }}次</span>
  79. </div>
  80. <div class="card-body">
  81. <span>最低分:{{ item.min_score }}分</span>
  82. <span>最高分:{{ item.max_score }}分</span>
  83. </div>
  84. <div class="footer">
  85. <div class="c-primary" @click="toHistory(item)">再考一次</div>
  86. </div>
  87. </div>
  88. </template>
  89. <template v-else-if="currentIndex === 2 && favoriteList.length">
  90. <QuestionsItem
  91. :data="favoriteList"
  92. :isRight="isRight"
  93. :onClick="toFavorite"
  94. />
  95. </template>
  96. <Empty v-else text="暂无数据"></Empty>
  97. </div>
  98. </Container>
  99. </template>
  100. <script setup>
  101. import Container from "@/components/Container/Container.vue";
  102. import Empty from "@/components/Empty/Empty.vue";
  103. import { ref, watch } from "vue";
  104. import { onShow } from "@dcloudio/uni-app";
  105. import { request } from "../../utils/request";
  106. import QuestionsItem from "../../components/Topic/QuestionsItem.vue";
  107. import { router } from "../../utils/router";
  108. const currentIndex = ref(0);
  109. const currentTab = ref(0);
  110. const isRight = ref(1);
  111. const info = ref({});
  112. const rightTotal = ref(0);
  113. const errorTotal = ref(0);
  114. const dataList = ref([]);
  115. const examList = ref([]);
  116. const favoriteList = ref([]);
  117. const toHistory = (item) => {
  118. router.push({
  119. path: "/pages/real/history",
  120. query: {
  121. id: item.catalogue_id,
  122. },
  123. });
  124. };
  125. const requestTopic = (is_correct, onSucess) => {
  126. request(
  127. "api/question_bank/question_reception/study_book/get_answer_topic_record",
  128. {
  129. chapter_id: currentTab.value,
  130. is_correct,
  131. }
  132. ).then((res) => {
  133. if (onSucess) {
  134. onSucess(res.data.data);
  135. return;
  136. }
  137. if (is_correct) {
  138. rightTotal.value = res.data.total;
  139. dataList.value = res.data.data;
  140. } else {
  141. errorTotal.value = res.data.total;
  142. }
  143. });
  144. };
  145. const requestExamList = () => {
  146. request("api/question_bank/question_reception/real_topic/get_exam_record", {
  147. chapter_id: currentTab.value,
  148. }).then((res) => {
  149. examList.value = res.data;
  150. });
  151. };
  152. const requestFavo = () => {
  153. request(
  154. "api/question_bank/question_reception/favorite/get_user_favorite_list",
  155. {
  156. chapter_id: currentTab.value,
  157. }
  158. ).then((res) => {
  159. favoriteList.value = res.data.data;
  160. });
  161. };
  162. const toFavorite = (item) => {
  163. console.log(item);
  164. };
  165. watch(currentIndex, () => {
  166. switch (currentIndex.value) {
  167. case 1:
  168. requestExamList();
  169. break;
  170. case 2:
  171. requestFavo();
  172. break;
  173. default:
  174. break;
  175. }
  176. });
  177. watch(currentTab, () => {
  178. switch (currentIndex.value) {
  179. case 0:
  180. isRight.value = 1;
  181. requestTopic(isRight.value);
  182. requestTopic(Number(!isRight.value));
  183. break;
  184. case 1:
  185. requestExamList();
  186. break;
  187. case 2:
  188. requestFavo();
  189. break;
  190. default:
  191. break;
  192. }
  193. });
  194. watch(isRight, () => {
  195. dataList.value = [];
  196. requestTopic(isRight.value, (data) => {
  197. dataList.value = data;
  198. });
  199. });
  200. onShow(() => {
  201. request(
  202. "api/question_bank/question_reception/study_book/get_study_record_title"
  203. ).then((res) => {
  204. info.value = res.data;
  205. currentTab.value = res.data.chapter_infos[0].id;
  206. });
  207. });
  208. // 示例数据
  209. </script>
  210. <style scoped lang="scss">
  211. @import "@/uni.scss";
  212. .primary {
  213. color: $primary;
  214. }
  215. .top {
  216. margin: 24rpx 32rpx 0;
  217. display: grid;
  218. grid-template-columns: repeat(3, 1fr);
  219. .item {
  220. border: 1px solid $primary;
  221. display: flex;
  222. align-items: center;
  223. justify-content: center;
  224. height: 113rpx;
  225. background-color: #fff;
  226. font-weight: 500;
  227. font-size: 24rpx;
  228. color: #333333;
  229. }
  230. .item.col {
  231. flex-direction: column;
  232. gap: 12rpx;
  233. }
  234. .item.left {
  235. border-top-left-radius: 24rpx;
  236. }
  237. .item.right {
  238. border-top-right-radius: 24rpx;
  239. }
  240. .select {
  241. border-color: #fff;
  242. }
  243. }
  244. .tab {
  245. background-color: #fff;
  246. .select-line {
  247. display: grid;
  248. grid-template-columns: repeat(2, 1fr);
  249. .item {
  250. display: flex;
  251. align-items: center;
  252. justify-content: center;
  253. padding: 28rpx;
  254. border-bottom: 1px solid #fff;
  255. font-weight: 500;
  256. font-size: 32rpx;
  257. }
  258. .item.select {
  259. color: $primary;
  260. border-color: $primary;
  261. }
  262. }
  263. }
  264. .scroll {
  265. white-space: nowrap;
  266. font-weight: 500;
  267. font-size: 32rpx;
  268. color: #333333;
  269. .box {
  270. padding: 30rpx;
  271. }
  272. .item {
  273. display: inline-flex;
  274. padding: 8rpx 36rpx;
  275. }
  276. .item.select {
  277. border-radius: 200rpx;
  278. background-color: $primary;
  279. color: #fff;
  280. }
  281. }
  282. .context {
  283. padding: 20rpx 32rpx;
  284. display: flex;
  285. flex-direction: column;
  286. gap: 16rpx;
  287. .card {
  288. border-radius: 16rpx;
  289. padding: 16rpx;
  290. background-color: #fff;
  291. display: flex;
  292. flex-direction: column;
  293. .question-header {
  294. display: flex;
  295. justify-content: space-between;
  296. margin-bottom: 12rpx;
  297. color: #999;
  298. .question-type {
  299. font-weight: 500;
  300. font-size: 32rpx;
  301. color: #999999;
  302. border-radius: 8rpx 8rpx 8rpx 8rpx;
  303. border: 1rpx solid #dddddd;
  304. padding: 0 10rpx;
  305. }
  306. .question-date {
  307. color: #999;
  308. font-size: 24rpx;
  309. }
  310. }
  311. .question-text {
  312. font-size: 28rpx;
  313. color: #333;
  314. margin-bottom: 16rpx;
  315. }
  316. .options {
  317. margin-top: 8rpx;
  318. .option {
  319. display: flex;
  320. align-items: center;
  321. margin-bottom: 12rpx;
  322. gap: 14rpx;
  323. .option-select {
  324. width: 51rpx;
  325. height: 51rpx;
  326. display: flex;
  327. align-items: center;
  328. justify-content: center;
  329. border: 1rpx solid #dddddd;
  330. border-radius: 50%;
  331. }
  332. }
  333. }
  334. .footer {
  335. display: flex;
  336. align-items: center;
  337. justify-content: center;
  338. }
  339. .card-header {
  340. display: flex;
  341. justify-content: space-between;
  342. margin-bottom: 12rpx;
  343. .title {
  344. font-weight: bold;
  345. font-size: 28rpx;
  346. color: #333;
  347. }
  348. .exam-count {
  349. color: #999;
  350. font-size: 24rpx;
  351. }
  352. }
  353. .card-body {
  354. display: flex;
  355. justify-content: space-between;
  356. align-items: center;
  357. font-weight: 500;
  358. font-size: 28rpx;
  359. color: #000000;
  360. }
  361. }
  362. }
  363. .c-primary {
  364. padding: 2rpx 10rpx;
  365. border-radius: 4rpx;
  366. border: 1rpx solid $primary;
  367. color: $primary;
  368. font-size: 24rpx;
  369. }
  370. .c-error {
  371. padding: 2rpx 10rpx;
  372. border-radius: 4rpx;
  373. border: 1rpx solid $error;
  374. color: $error;
  375. font-size: 24rpx;
  376. }
  377. </style>