diff --git a/apps/client/components/main/QuestionInput/QuestionInput.vue b/apps/client/components/main/QuestionInput/QuestionInput.vue
index 0461f9efd..229e1c18b 100644
--- a/apps/client/components/main/QuestionInput/QuestionInput.vue
+++ b/apps/client/components/main/QuestionInput/QuestionInput.vue
@@ -10,7 +10,22 @@
:class="getWordsClassNames(i)"
:style="{ minWidth: `${inputWidth(w)}ch` }"
>
- {{ userInputWords[i]["userInput"] }}
+
+
+ {{ w }}
+
+
+
+ {{ char.character }}
+
+
+
+
+ {{ userInputWords[i]["userInput"] }}
+
courseStore.currentStatement?.english!,
- setInputCursorPosition,
- getInputCursorPosition,
- inputChangedCallback,
- });
-const { showAnswerTip, hiddenAnswerTip } = useAnswerTip();
+const {
+ inputValue,
+ userInputWords,
+ submitAnswer,
+ setInputValue,
+ handleKeyboardInput,
+ isFixMode,
+ tipWords,
+} = useInput({
+ source: () => courseStore.currentStatement?.english!,
+ setInputCursorPosition,
+ getInputCursorPosition,
+ inputChangedCallback,
+});
+const { showAnswerTip, hiddenAnswerTip, isAnswerTip } = useAnswerTip();
onMounted(() => {
focusInput();
@@ -82,6 +104,7 @@ focusInputWhenWIndowFocus();
watch(
() => inputValue.value,
(val) => {
+ hiddenAnswerTip();
setInputValue(val);
courseTimer.time(String(courseStore.statementIndex));
},
@@ -210,7 +233,7 @@ function handleKeydown(e: KeyboardEvent) {
useSpaceSubmitAnswer: {
enable: isUseSpaceSubmitAnswer(),
rightCallback: handleAnswerRight,
- errorCallback: handleAnswerError,
+ errorCallback: handleAnswerError, // 错误提示
},
});
}
diff --git a/apps/client/composables/main/answerTip.ts b/apps/client/composables/main/answerTip.ts
index 88b7f2987..d0fd08ed3 100644
--- a/apps/client/composables/main/answerTip.ts
+++ b/apps/client/composables/main/answerTip.ts
@@ -1,10 +1,12 @@
import { ref } from "vue";
+import { validateInput } from "./question";
const answerTip = ref(false);
export function useAnswerTip() {
function showAnswerTip() {
answerTip.value = true;
+ validateInput()
}
function hiddenAnswerTip() {
answerTip.value = false;
diff --git a/apps/client/composables/main/question.ts b/apps/client/composables/main/question.ts
index 42d3add21..0fa73e3f8 100644
--- a/apps/client/composables/main/question.ts
+++ b/apps/client/composables/main/question.ts
@@ -1,4 +1,5 @@
import { nextTick, reactive, ref, watchEffect } from "vue";
+import { useCourseStore } from "~/store/course";
interface Word {
text: string;
@@ -32,6 +33,44 @@ export function clearQuestionInput() {
inputValue.value = "";
}
+interface TipWord {
+ noInput: boolean;
+ characters: { incorrect: boolean; character: string }[];
+}
+
+const tipWords = reactive([]);
+
+export function validateInput() {
+ const userInputs = inputValue.value.toLowerCase().split(separator)
+
+ function getUserInput(index: number) {
+ return userInputs[index] || "";
+ }
+
+ function validateCharacter(word: string, index: number) {
+ const userInput = getUserInput(index);
+ const inputCharacters = userInput.split("");
+
+ const overLength = userInput.length > word.length;
+
+ return word
+ .toLowerCase()
+ .split("")
+ .map((character, index) => ({
+ character,
+ incorrect: character !== inputCharacters[index] || overLength,
+ }));
+ }
+
+ const courseStore = useCourseStore();
+ courseStore.words.forEach((word, index) => {
+ tipWords[index] = {
+ noInput: !Boolean(getUserInput(index)),
+ characters: validateCharacter(word, index),
+ };
+ });
+}
+
export function useInput({
source,
setInputCursorPosition,
@@ -354,5 +393,6 @@ export function useInput({
fixFirstIncorrectWord,
resetUserInputWords,
isFixMode,
+ tipWords,
};
}