refactor(样式): 优化输入框样式和矩阵文本组件

- 调整了 main.scss 和 public.scss 中的样式
-重构了 MatrixText 组件,支持数字和文本输入
- 优化了 Completion 组件的默认值设置
- 修改了验证逻辑,允许空值作为有效答案
This commit is contained in:
陈昱达
2025-05-28 23:19:14 +08:00
parent f4f84e0b68
commit 966e56ad74
8 changed files with 206 additions and 95 deletions

View File

@@ -51,7 +51,7 @@ a,
top: 0;
width: 100%;
// background-color: linear-gradient(to bottom, theme.$theme-color 200px, theme.$nav-color 300px);
background: url("../img/home/nav.png") theme.$nav-color;
background: url('../img/home/nav.png') theme.$nav-color;
color: #000;
& .van-nav-bar__content {

View File

@@ -300,3 +300,12 @@ input {
background: linear-gradient(180deg, #e8fad7 0%, #ffffff 8%);
}
//background: linear-gradient( 180deg, #E8FAD7 0%, #FFFFFF 100%);
.el-input-number__decrease,
.el-input-number__increase {
display: none;
}
.el-input-number .el-input__wrapper,
.el-input-number.is-controls-right .el-input__wrapper {
padding: 0;
}

View File

@@ -12,7 +12,7 @@ import appBridge from '@/assets/js/appBridge';
import VConsole from 'vconsole';
import './assets/css/main.scss';
// 引入 swiper 样式
import 'swiper/css';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';

View File

@@ -58,7 +58,7 @@
import { toRefs, watch } from 'vue';
import { ElInputNumber } from 'element-plus';
import { showFailToast } from 'vant';
const completionValue = defineModel('completionValue', { default: null, type: String });
const completionValue = defineModel('completionValue', { default: '', type: String });
const props = defineProps({
isPreview: {
type: Boolean,

View File

@@ -1,16 +1,40 @@
<template>
<input
type="text"
class="el-input"
style="width: 100%"
:placeholder="element.config.placeholder"
:name="`R${rowIndex + 1}`"
:value="getInputValue(rowIndex, colIndex)"
@change="handleMatrixTextChange(rowIndex, colIndex, $event)"
/>
<div>
<!-- <el-input-number-->
<!-- v-model="inputValueMTX"-->
<!-- style="width: 100%"-->
<!-- v-if="element.config.text_type === 1"-->
<!-- controls-position="right"-->
<!-- @change="(e) => ev"-->
<!-- :max="element.config.max"-->
<!-- @blur="changeValue(rowIndex, colIndex)"-->
<!-- ></el-input-number>-->
<!-- <el-input-number-->
<!-- v-model="inputValueMTX"-->
<!-- style="width: 100%"-->
<!-- v-else-if="element.config.text_type === 2"-->
<!-- controls-position="right"-->
<!-- @change="(e) => handleMatrixTextChange(rowIndex, colIndex, { target: { value: e } })"-->
<!-- :precision="element.config.decimal_few"-->
<!-- :max="element.config.max"-->
<!-- @blur="changeValue(rowIndex, colIndex)"-->
<!-- ></el-input-number>-->
<input
type="text"
class="el-input"
style="width: 100%"
:placeholder="element.config.placeholder"
:name="`R${rowIndex + 1}`"
:value="getInputValue(rowIndex, colIndex)"
@change="handleMatrixTextChange(rowIndex, colIndex, $event)"
/>
</div>
</template>
<script setup lang="ts">
import { ElInputNumber } from 'element-plus';
import { ref } from 'vue';
import { showFailToast } from 'vant';
// 接受获取到的 col row 的索引参数
const rowIndex = defineModel('rowIndex', { required: true, default: 0 });
const colIndex = defineModel('colIndex', { required: true, default: 0 });
@@ -23,10 +47,12 @@ const element = defineModel<question>('element', {
}
});
console.log(element);
const inputValueMTX = ref('');
const emit = defineEmits(['update:matrixAnswer', 'update:rowRecord', 'update:element']);
function ev() {
console.log(1231);
}
function getInputValue(row: number, col: number) {
// console.log(`row: ${row}, col: ${col}`);
// console.log(`rowRecord:`, rowRecord.value);
@@ -39,6 +65,7 @@ function handleMatrixTextChange(row: number, col: number, e: Event) {
const target = e.target as HTMLInputElement;
const inputValue = target.value;
console.log(inputValue, 123);
// 获取 colIndexArray
if (!rowRecord.value[row]) {
// 如果没有对应的row创建一个
@@ -50,6 +77,18 @@ function handleMatrixTextChange(row: number, col: number, e: Event) {
// console.log(`rowRecord:`, rowRecord.value);
}
const changeValue = (rowIndex, colIndex) => {
if (
inputValueMTX.value < element.value.config.min &&
element.value.config.min &&
inputValueMTX.value
) {
inputValueMTX.value = null;
showFailToast('请输入大于' + element.value.config.min + '的数字');
handleMatrixTextChange(rowIndex, colIndex, { target: { value: '' } });
}
};
const emitValue = () => {
emit('update:element', element.value);
};
@@ -57,4 +96,15 @@ const emitValue = () => {
<style scoped lang="scss">
@import '@/assets/css/theme';
input[type='text'] {
width: 100%;
padding: 0 5px;
border: none;
border-radius: 4px;
outline: 1px solid #f4f4f4;
&:focus {
outline: 1px solid $theme-color;
}
}
</style>

View File

@@ -651,8 +651,9 @@ async function answer(callback, callbackBeforePage) {
if ((questions.value.length || !questionsData.value.questions.length) && !props.isTemplate) {
// 表单验证(当前页)
const errors = questions.value.filter((question) => {
const { config, answer, question_type: questionType, error } = question;
const { config, question_type: questionType, error, answer } = question;
console.log(question.answer);
// let answer = question.answer.value ? question.answer.value : question.answer;
// console.log(answer, questionType, error);
// 单独 处理 图文
if (questionType === 6) {
@@ -662,6 +663,15 @@ async function answer(callback, callbackBeforePage) {
let isError = false;
// 如果问题没有答案还有是必须填空的,就往下处理
// 2025/4/1新增 如果有 error 内容, 同样视为有错误
// if (config.is_required === 0) {
// if (!answer && !answer?.value) {
// return;
// }
// }
console.log(answer, ' isError = true;');
if (!answer || error) {
isError = true;
// 各个问题单独处理
@@ -684,11 +694,11 @@ async function answer(callback, callbackBeforePage) {
// 分类题
question.error = translatedText.value.PleaseCategorizeAllOptions;
} else if (!question.error) {
console.log(question);
if (question.config.is_required === 1) {
console.log(question, 23);
if (config.is_required === 1) {
question.error = translatedText.value.ThisIsARequiredQuestion;
} else {
return;
isError = false;
}
}
} else if (
@@ -741,83 +751,108 @@ async function answer(callback, callbackBeforePage) {
isError = true;
question.error = translatedText.value.PleaseUploadAtLeastOneFiles(config.min_number);
} 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;
if (!answer.value && config.is_required === 0) {
isError = false;
return;
}
if (answer.value === null) {
isError = true;
console.log(123123);
question.error = translatedText.value.ThisIsARequiredQuestion;
return;
}
// // 矩阵填空题
switch (config.text_type) {
// 字母
case 3:
if (
!/^[a-zA-Z·~@#¥%…&*()—\-+={}|《》?:“”【】、;‘’,。`!$^()_<>?:",./;'\\[\]]+$/.test(
answer.value
)
) {
isError = true;
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
)
) {
isError = true;
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
)
) {
isError = true;
question.error = translatedText.value.PleaseEnterACorrectEmail;
}
break;
// 手机号
case 6:
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(answer.value)) {
isError = true;
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
)
) {
isError = true;
question.error = translatedText.value.PleaseEnterACorrectID;
}
break;
default:
break;
}
console.log(answer.value?.length, config.text_type, config.min);
// if (![5, 6, 7].includes(config.text_type)) {
if (
answer.value?.length < config.min &&
![1, 2, 5, 6, 7].includes(config.text_type) &&
config.min
) {
isError = true;
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
return;
}
if (
answer.value?.length > config.max &&
![1, 2, 5, 6, 7].includes(config.text_type) &&
config.max
) {
isError = true;
question.error = translatedText.value.PleaseEnterLessCharacters(config.max);
return;
}
// }
if (question.error) isError = true;
} else if (answer && questionType === 8) {
// 矩阵填空题
question.error = '';
if (!answer && config.is_required === 0) {
isError = false;
return false;
}
Object.keys(answer).forEach((key) => {
const value = answer[key];
switch (config.text_type) {
// 字母
case 3:
@@ -826,6 +861,7 @@ async function answer(callback, callbackBeforePage) {
value
)
) {
isError = true;
question.error = translatedText.value.PleaseEnterEnglishLetters;
}
break;
@@ -836,6 +872,7 @@ async function answer(callback, callbackBeforePage) {
value
)
) {
isError = true;
question.error = translatedText.value.PleaseEnterChineseWords;
}
break;
@@ -846,12 +883,14 @@ async function answer(callback, callbackBeforePage) {
value
)
) {
isError = true;
question.error = translatedText.value.PleaseEnterACorrectEmail;
}
break;
// 手机号
case 6:
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value)) {
isError = true;
question.error = translatedText.value.PleaseEnterACorrectPhone;
}
break;
@@ -862,6 +901,7 @@ async function answer(callback, callbackBeforePage) {
value
)
) {
isError = true;
question.error = translatedText.value.PleaseEnterACorrectID;
}
break;
@@ -873,16 +913,23 @@ async function answer(callback, callbackBeforePage) {
if (
!question.error &&
value.length < config.min &&
config.min &&
![1, 2].includes(config.text_type)
) {
isError = true;
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
return false;
}
if (
!question.error &&
value.length > config.max &&
config.max &&
![1, 2].includes(config.text_type)
) {
isError = true;
question.error = translatedText.value.PleaseEnterLessCharacters(config.max);
return false;
}
}
});

View File

@@ -34,18 +34,21 @@ const completionValue = ref<string>(answer.value?.value ?? '');
watch(
() => completionValue.value,
(value) => {
console.log(value, 'update');
// 答案校验,生成最终答案
const { isError } = validateCompletion(question.value, question.value.config!, String(value));
console.log(`isError, question`, isError, question.value);
if (isError) {
// 有错误就不更新
question.value.answer = void 0;
return;
}
// if (isError) {
// 有错误就不更新
question.value.answer = void 0;
// return;
// }
const res = generateAnswer(value);
answer.value = res;
question.value!.answer = res;
// answer emit 提交失效
// emit('changeAnswer', res);
}
@@ -56,6 +59,8 @@ watch(
* @param answer {string}
*/
function generateAnswer(answer: string) {
console.log(answer, 'asjd');
return { value: answer };
}
</script>

View File

@@ -22,7 +22,7 @@ export function validateMinLength(
// 如果包含相应的 text_type 也不处理1是整数2是小数
if ([1, 2].includes(config.text_type)) return;
if (answer.length > Number(config.min)) return;
if (answer.length >= Number(config.min)) return;
return {
isError: true,
errorMessage: translatedText.PleaseEnterMoreCharacters(config.min)