feat(Design): 完善填空题输入类型并添加验证

- 新增数字和小数填空类型
- 添加输入限制和验证功能
- 优化文本类型填空的验证逻辑
- 修复了一些与填空题相关的小问题
This commit is contained in:
陈昱达
2025-05-28 21:09:01 +08:00
parent e3269c555d
commit f4f84e0b68
2 changed files with 149 additions and 11 deletions

View File

@@ -18,22 +18,47 @@
></contenteditable> ></contenteditable>
</template> </template>
<template #input> <template #input>
<textarea <el-input-number
v-if="!element.config.line_height || element.config.line_height != 0"
v-model="completionValue" v-model="completionValue"
v-if="element.config.text_type === 1"
type="number"
class="other_input" class="other_input"
:placeholder="element.config.placeholder" controls-position="right"
:rows="element.config.line_height" :max="element.config.max"
></textarea> @blur="changeValue"
style="padding: 0; background: #fff"
></el-input-number>
<el-input-number
v-model="completionValue"
v-else-if="element.config.text_type === 2"
:precision="element.config.decimal_few"
:max="element.config.max"
type="number"
controls-position="right"
class="other_input"
@blur="changeValue"
style="padding: 0; background: #fff"
></el-input-number>
<div v-else style="width: 92%">
<textarea
v-if="!element.config.line_height || element.config.line_height != 0"
v-model="completionValue"
class="other_input"
:placeholder="element.config.placeholder"
:rows="element.config.line_height"
></textarea>
</div>
</template> </template>
</van-field> </van-field>
</div> </div>
</template> </template>
<script setup> <script setup>
import { toRefs } from 'vue'; import { toRefs, watch } from 'vue';
import { ElInputNumber } from 'element-plus';
const completionValue = defineModel('completionValue', { default: '', type: String }); import { showFailToast } from 'vant';
const completionValue = defineModel('completionValue', { default: null, type: String });
const props = defineProps({ const props = defineProps({
isPreview: { isPreview: {
type: Boolean, type: Boolean,
@@ -58,12 +83,33 @@ const errorMessage = defineModel('errorMessage', {
type: String, type: String,
default: '' default: ''
}); });
// 创建一个本地副本以保存更改 // 创建一个本地副本以保存更改
const emit = defineEmits(['update:element']); const emit = defineEmits(['update:element']);
const { element } = toRefs(props); const { element } = toRefs(props);
const emitValue = () => { const emitValue = () => {
emit('update:element', element.value); emit('update:element', element.value);
}; };
watch(
() => completionValue.value,
() => {
if (!completionValue.value) {
completionValue.value = null;
}
}
);
const changeValue = (values) => {
console.log(element.value.config);
if (
completionValue.value < element.value.config.min &&
element.value.config.min &&
completionValue.value
) {
completionValue.value = null;
showFailToast('请输入大于' + element.value.config.min + '的数字');
}
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -658,6 +658,7 @@ async function answer(callback, callbackBeforePage) {
if (questionType === 6) { if (questionType === 6) {
return; return;
} }
let isError = false; let isError = false;
// 如果问题没有答案还有是必须填空的,就往下处理 // 如果问题没有答案还有是必须填空的,就往下处理
// 2025/4/1新增 如果有 error 内容, 同样视为有错误 // 2025/4/1新增 如果有 error 内容, 同样视为有错误
@@ -683,7 +684,12 @@ async function answer(callback, callbackBeforePage) {
// 分类题 // 分类题
question.error = translatedText.value.PleaseCategorizeAllOptions; question.error = translatedText.value.PleaseCategorizeAllOptions;
} else if (!question.error) { } else if (!question.error) {
question.error = translatedText.value.ThisIsARequiredQuestion; console.log(question);
if (question.config.is_required === 1) {
question.error = translatedText.value.ThisIsARequiredQuestion;
} else {
return;
}
} }
} else if ( } else if (
answer && answer &&
@@ -735,6 +741,78 @@ async function answer(callback, callbackBeforePage) {
isError = true; isError = true;
question.error = translatedText.value.PleaseUploadAtLeastOneFiles(config.min_number); question.error = translatedText.value.PleaseUploadAtLeastOneFiles(config.min_number);
} else if (answer && questionType === 4) { } else if (answer && questionType === 4) {
// 矩阵填空题
question.error = '';
if (question.config.is_required === 1 || answer.value) {
switch (config.text_type) {
// 字母
case 3:
if (
!/^[a-zA-Z·~@#¥%…&*()—\-+={}|《》?:“”【】、;‘’,。`!$^()_<>?:",./;'\\[\]]+$/.test(
answer.value
)
) {
question.error = translatedText.value.PleaseEnterEnglishLetters;
}
break;
// 中文
case 4:
if (
!/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~@#¥%…&*()—\-+={}|《》?:“”【】、;‘’,。`!$^()_<>?:",./;'\\[\]])+$/.test(
answer.value
)
) {
question.error = translatedText.value.PleaseEnterChineseWords;
}
break;
// 邮箱
case 5:
if (
!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
answer.value
)
) {
question.error = translatedText.value.PleaseEnterACorrectEmail;
}
break;
// 手机号
case 6:
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(answer.value)) {
question.error = translatedText.value.PleaseEnterACorrectPhone;
}
break;
// 身份证号
case 7:
if (
!/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(
answer.value
)
) {
question.error = translatedText.value.PleaseEnterACorrectID;
}
break;
default:
break;
}
if (![5, 6, 7].includes(config.text_type)) {
if (
!question.error &&
answer.value.length < config.min &&
![1, 2].includes(config.text_type)
) {
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
}
if (
!question.error &&
answer.value.length > config.max &&
![1, 2].includes(config.text_type)
) {
question.error = translatedText.value.PleaseEnterLessCharacters(config.max);
}
}
if (question.error) isError = true;
}
} else if (answer && questionType === 8) { } else if (answer && questionType === 8) {
// 矩阵填空题 // 矩阵填空题
question.error = ''; question.error = '';
@@ -790,8 +868,22 @@ async function answer(callback, callbackBeforePage) {
default: default:
break; break;
} }
if (!question.error && value.length < config.min && ![1, 2].includes(config.text_type)) {
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min); if (![5, 6, 7].includes(config.text_type)) {
if (
!question.error &&
value.length < config.min &&
![1, 2].includes(config.text_type)
) {
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
}
if (
!question.error &&
value.length > config.max &&
![1, 2].includes(config.text_type)
) {
question.error = translatedText.value.PleaseEnterLessCharacters(config.max);
}
} }
}); });
if (question.error) isError = true; if (question.error) isError = true;