Pārlūkot izejas kodu

新增题目列表预览

wyling007 3 gadi atpakaļ
vecāks
revīzija
1656686f6b

+ 106 - 0
src/components/m-exercise/components/subjectChangePopup.vue

@@ -0,0 +1,106 @@
+<template>
+	<div>
+		<van-cell center>
+			<template #title>
+				<div style="margin-top: 5px">
+					<span class="flex-center">
+						<m-icon type="dui" class="icon-size" />
+						<span style="margin-left: 5px">{{ trueNum }}</span>
+					</span>
+					<span class="flex-center" style="margin-left: 21px">
+						<m-icon type="cuo" class="icon-size" />
+						<span style="margin-left: 5px">{{ falseNum }}</span>
+					</span>
+				</div>
+			</template>
+			<!-- 使用 right-icon 插槽来自定义右侧图标 -->
+			<template #right-icon>
+				<div class="flex-center">
+					<m-icon type="zongtishu" class="icon-size" />
+					<span style="margin-left: 5px">{{ currentSubjectIndex + 1 }}/{{ subjectList.length }}</span>
+				</div>
+			</template>
+		</van-cell>
+		<div class="list-box">
+			<span @click="changeCurrentSubjectIndex(index)" class="item" :class="subjectClass(item, index)" v-for="(item, index) in subjectList">{{ index + 1 }}</span>
+		</div>
+	</div>
+</template>
+
+<script setup lang="ts">
+	const props = defineProps<{
+		trueNum: number;
+		falseNum: number;
+		currentSubjectIndex: number;
+		subjectList: any[];
+	}>();
+
+	const emit = defineEmits<{
+		(event: "update:currentSubjectIndex", id: number): void;
+	}>();
+
+	const subjectClass = (item: any, index: number) => {
+		if (index === props.currentSubjectIndex) {
+			return "select";
+		}
+		if (item.isTrue == null) {
+			return "";
+		}
+		if (item.isTrue) {
+			return "true";
+		} else {
+			return "false";
+		}
+	};
+
+	const changeCurrentSubjectIndex = (index: number) => {
+		emit("update:currentSubjectIndex", index);
+	};
+</script>
+
+<style lang="scss" scoped>
+	.false {
+		background: rgba(255, 219, 220, 0.39);
+		border: 1px solid #ff4d53 !important;
+	}
+	.true {
+		background: rgba(204, 243, 232, 0.39);
+		border: 1px solid #01c18d !important;
+	}
+	.select {
+		background: rgba(138, 144, 153, 0.08);
+		border: 1px solid #bfbfbf;
+	}
+	.icon-size {
+		font-size: 22px;
+	}
+	.flex-center {
+		display: inline-flex;
+		justify-content: center;
+		align-items: center;
+	}
+	.list-box {
+		display: flex;
+		justify-content: space-around;
+		align-items: center;
+		height: 60vh;
+		flex-wrap: wrap;
+		overflow: auto;
+		.item {
+			width: 38px;
+			height: 38px;
+			border-radius: 50%;
+			border: 1px solid #bfbfbf;
+			font-size: 17px;
+			font-family: PingFang SC;
+			font-weight: 500;
+			line-height: 24px;
+			color: #5c6066;
+			letter-spacing: 0.2800000011920929px;
+			display: flex;
+			justify-content: center;
+			align-items: center;
+			margin: 10px;
+		}
+	}
+</style>

+ 9 - 2
src/components/m-exercise/index.vue

@@ -167,6 +167,10 @@
 		</van-cell>
 	</van-popup>
 	<!-- 设置操作栏end -->
+	<!-- 底部弹出题目选择栏 -->
+	<van-popup v-model:show="showSubjectChangePopup" position="bottom">
+		<subjectChangePopup :trueNum="trueNum" :falseNum="falseNum" v-model:currentSubjectIndex="currentSubjectIndex" :subjectList="subjectList" />
+	</van-popup>
 	<!-- 底部操作栏 -->
 	<van-tabbar placeholder route>
 		<van-tabbar-item @click="lastSubject"
@@ -187,7 +191,7 @@
 				<m-icon type="cuo" />
 			</template>
 		</van-tabbar-item>
-		<van-tabbar-item
+		<van-tabbar-item @click="showSubjectChangePopup = true"
 			>{{ currentSubjectIndex + 1 }}/{{ subjectTotal }}
 			<template #icon>
 				<m-icon type="zongtishu" />
@@ -211,6 +215,7 @@
 
 <script lang="ts" setup>
 	import { ref, defineProps } from "vue";
+	import subjectChangePopup from "./components/subjectChangePopup.vue";
 	import { useTopicMode, useAudioSet, useSubjectShowLogic } from "@/hooks/exercise";
 	import { RouterBus } from "@/hooks";
 	const {
@@ -230,9 +235,11 @@
 	const setShow = ref(false);
 	/**答题音效 */
 	const isSoundEffect = ref(true);
+	// 显示题目选择栏
+	const showSubjectChangePopup = ref(false);
 
 	//题目展示逻辑
-	const { currentSubject, currentSubjectIndex, subjectTotal, nextSubject, lastSubject, trueNum, falseNum, isJumpNext, userAnswerChange, addCurrentQuestion, skillsShow, officialShow } = useSubjectShowLogic(props.listType);
+	const { subjectList, currentSubject, currentSubjectIndex, subjectTotal, nextSubject, lastSubject, trueNum, falseNum, isJumpNext, userAnswerChange, addCurrentQuestion, skillsShow, officialShow } = useSubjectShowLogic(props.listType);
 
 	//音频模块
 	const { aotuPlayFlag, subjectAudioPlay, aotuPlaySet } = useAudioSet(currentSubject);

+ 68 - 68
src/hooks/exercise/audio.ts

@@ -1,78 +1,78 @@
-import { Howl } from 'howler';
-import { ref, watch, ComputedRef } from 'vue';
+import { Howl } from "howler";
+import { ref, watch, ComputedRef } from "vue";
 
 /**语音设置 */
 export function useAudioSet(currentSubject: ComputedRef<any>) {
-    const aotuPlayFlag = ref(false);
+	const aotuPlayFlag = ref(false);
 
-    let sound: Howl;
-    /**
-     * 播放音频
-     * @param audioUrl
-     */
-    const audioPlay = (audioUrl: string | string[]) => {
-        audioPause();
-        sound = new Howl({
-            src: audioUrl,
-        });
-        sound.once('load', function () {
-            sound.play();
-        });
-        if (typeof audioUrl === 'object') {
-            sound.once('end', () => {
-                sound = new Howl({
-                    src: audioUrl[1],
-                });
-                sound.once('load', function () {
-                    sound.play();
-                });
-            });
-        }
-    };
+	let sound: Howl;
+	/**
+	 * 播放音频
+	 * @param audioUrl
+	 */
+	const audioPlay = (audioUrl: string | string[]) => {
+		audioPause();
+		sound = new Howl({
+			src: audioUrl,
+		});
+		sound.once("load", function () {
+			sound.play();
+		});
+		if (typeof audioUrl === "object") {
+			sound.once("end", () => {
+				sound = new Howl({
+					src: audioUrl[1],
+				});
+				sound.once("load", function () {
+					sound.play();
+				});
+			});
+		}
+	};
 
-    /**
-     * 读题
-     */
-    const subjectAudioPlay = (type: '读题' | '读官方解释' | '读技巧解释' | '读题+答案') => {
-        switch (type) {
-            case '读题':
-                audioPlay(currentSubject.value.issuemp3);
-                break;
-            case '读官方解释':
-                audioPlay(currentSubject.value.explainjsmp3);
-                break;
-            case '读技巧解释':
-                audioPlay(currentSubject.value.explainMp3);
-                break;
-            case '读题+答案':
-                audioPlay([currentSubject.value.issuemp3, currentSubject.value.answermp3]);
-                break;
-            default:
-                break;
-        }
-    };
+	/**
+	 * 读题
+	 */
+	const subjectAudioPlay = (type: "读题" | "读官方解释" | "读技巧解释" | "读题+答案") => {
+		switch (type) {
+			case "读题":
+				currentSubject.value.issuemp3 && audioPlay(currentSubject.value.issuemp3);
+				break;
+			case "读官方解释":
+				currentSubject.value.explainjsmp3 && audioPlay(currentSubject.value.explainjsmp3);
+				break;
+			case "读技巧解释":
+				currentSubject.value.explainMp3 && audioPlay(currentSubject.value.explainMp3);
+				break;
+			case "读题+答案":
+				currentSubject.value.issuemp3 && currentSubject.value.answermp3 && audioPlay([currentSubject.value.issuemp3, currentSubject.value.answermp3]);
+				break;
+			default:
+				break;
+		}
+	};
 
-    /**
-     * 停止播放
-     */
-    const audioPause = () => {
-        sound && sound.pause();
-    };
+	/**
+	 * 停止播放
+	 */
+	const audioPause = () => {
+		sound && sound.pause();
+	};
 
-    //音频模块end
-    const aotuPlaySet = () => {
-        aotuPlayFlag.value = !aotuPlayFlag.value;
-        aotuPlayFlag.value ? subjectAudioPlay('读题') : audioPause();
-    };
+	//音频模块end
+	const aotuPlaySet = () => {
+		aotuPlayFlag.value = !aotuPlayFlag.value;
+		aotuPlayFlag.value ? subjectAudioPlay("读题") : audioPause();
+	};
 
-    //自动读题
-    watch(currentSubject, () => {
-        if (aotuPlayFlag.value) subjectAudioPlay('读题'); //自动读题
-    });
+	//自动读题
+	watch(currentSubject, () => {
+		if (aotuPlayFlag.value) subjectAudioPlay("读题"); //自动读题
+	});
 
-    return {
-        aotuPlayFlag,
-        aotuPlaySet,
-        subjectAudioPlay,
-    };
+	return {
+		aotuPlayFlag,
+		aotuPlaySet,
+		subjectAudioPlay,
+	};
 }

+ 1 - 0
src/hooks/exercise/index.ts

@@ -46,5 +46,6 @@ export const useSubjectShowLogic = (type: ExerciseType.ListType) => {
 		addCurrentQuestion,
 		skillsShow,
 		officialShow,
+		subjectList,
 	};
 };

+ 6 - 6
src/hooks/exercise/list.ts

@@ -1,13 +1,13 @@
-import { ref, onBeforeMount, computed } from 'vue';
-import { useRoute } from 'vue-router';
-import * as API from '@/api';
+import { ref, onBeforeMount, computed } from "vue";
+import { useRoute } from "vue-router";
+import * as API from "@/api";
 
 /**获取题目列表 */
 export const useSubjectList = (type: ExerciseType.ListType) => {
 	const subjectList = ref<any[]>([]); //题目列表
 	const subjectTotal = ref(0); //题目总数
 	const pageNum = ref(1); //当前请求页码
-	const pageSize = ref(100); //当前请求每页数据
+	const pageSize = ref(10000); //当前请求每页数据
 	const query = useRoute().query; //路由query参数
 	onBeforeMount(async () => {
 		const res = await API.getTopicList(
@@ -16,7 +16,7 @@ export const useSubjectList = (type: ExerciseType.ListType) => {
 				pageNum: pageNum.value,
 				pageSize: pageSize.value,
 			},
-			type !== 'free'
+			type !== "free"
 		);
 		subjectList.value = res.list;
 		subjectTotal.value = res.total;
@@ -31,7 +31,7 @@ export const useSubjectList = (type: ExerciseType.ListType) => {
 				pageNum: pageNum.value,
 				pageSize: pageSize.value,
 			},
-			type !== 'free'
+			type !== "free"
 		);
 		subjectList.value = subjectList.value.concat(res.list);
 	};