feat: 重构矩阵问卷
- 重构矩阵,现在单选矩阵可以自由左右滚动
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { /* useTemplateRef, */ ref, computed, type Component } from 'vue';
|
import { type Component, computed, defineModel } from 'vue';
|
||||||
import MatrixCheckbox from '@/views/Design/components/Questions/MatrixCheckbox.vue';
|
import MatrixCheckbox from '@/views/Design/components/Questions/MatrixCheckbox.vue';
|
||||||
import MatrixText from '@/views/Design/components/Questions/MatrixText.vue';
|
import MatrixText from '@/views/Design/components/Questions/MatrixText.vue';
|
||||||
import MatrixRadio from '@/views/Design/components/Questions/MatrixRadio.vue';
|
import MatrixRadio from '@/views/Design/components/Questions/MatrixRadio.vue';
|
||||||
@@ -10,6 +10,9 @@ const question = defineModel<question>('element', {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const rowRecord = defineModel<unknown[]>('rowRecord', { required: false, default: () => [] });
|
||||||
|
const isPreview = defineModel<boolean>('isPreview', { required: false, default: false });
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const activeComponent = computed<Component>(() => {
|
const activeComponent = computed<Component>(() => {
|
||||||
switch (question.value.question_type) {
|
switch (question.value.question_type) {
|
||||||
@@ -24,16 +27,19 @@ const activeComponent = computed<Component>(() => {
|
|||||||
|
|
||||||
if (question.value?.list) question.value.options = question.value?.list;
|
if (question.value?.list) question.value.options = question.value?.list;
|
||||||
// 行标签
|
// 行标签
|
||||||
const rows = ref(question.value?.options[0] ?? []);
|
const rows = defineModel<questionOptionType[]>('rows', { required: false, default: () => [] });
|
||||||
|
rows.value.length < 1 && (rows.value = question.value?.options[0] ?? []);
|
||||||
// 列标签
|
// 列标签
|
||||||
const cols = ref(question.value?.options[1] ?? []);
|
const cols = defineModel<questionOptionType[]>('cols', { required: false, default: () => [] });
|
||||||
|
cols.value.length < 1 && (cols.value = question.value?.options[1] ?? []);
|
||||||
|
|
||||||
// console.log(rows.value, cols.value);
|
// console.log(rows.value, cols.value);
|
||||||
// const columnLabels = useTemplateRef<HTMLElement[]>('columnLabels');
|
// const columnLabels = useTemplateRef<HTMLElement[]>('columnLabels');
|
||||||
|
|
||||||
// 注意, element.options 里面的东西是数组,第一项内容是行标签内容,第二项内容是列标签内容
|
// 注意, element.options 里面的东西是数组,第一项内容是行标签内容,第二项内容是列标签内容
|
||||||
// 类型 AI 生成 切勿盲目相信,以实际为准
|
// 类型 AI 生成 切勿盲目相信,以实际为准
|
||||||
/* const props = */ defineProps<{
|
/* const props = */
|
||||||
|
defineProps<{
|
||||||
index: number;
|
index: number;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
}>();
|
}>();
|
||||||
@@ -62,54 +68,16 @@ const emitValue = () => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #input>
|
<template #input>
|
||||||
<!-- <div style="width: 1000px; overflow: scroll">-->
|
<Component
|
||||||
<Component :is="activeComponent" v-model:rows="rows" v-model:cols="cols" />
|
:is="activeComponent"
|
||||||
<!-- </div>-->
|
v-model:rowRecord="rowRecord"
|
||||||
|
v-model:element="question"
|
||||||
|
v-model:rows="rows"
|
||||||
|
v-model:cols="cols"
|
||||||
|
:isPreview="isPreview"
|
||||||
|
style="overflow: scroll; width: 88vw"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<!-- 使用 label 插槽来自定义标题 -->
|
|
||||||
<!-- <template #input>-->
|
|
||||||
<!-- <table class="matrix-table">-->
|
|
||||||
<!-- <thead>-->
|
|
||||||
<!-- <tr>-->
|
|
||||||
<!-- <!– 第一行内容为空 –>-->
|
|
||||||
<!-- <th></th>-->
|
|
||||||
<!-- <!– 第二行内容开始填充 –>-->
|
|
||||||
<!-- <td v-for="col in element.options[1]" :key="col.option" ref="columnLabels">-->
|
|
||||||
<!-- <contenteditable-->
|
|
||||||
<!-- v-model="col.option"-->
|
|
||||||
<!-- :active="active"-->
|
|
||||||
<!-- @blur="emitValue"-->
|
|
||||||
<!-- ></contenteditable>-->
|
|
||||||
<!-- </td>-->
|
|
||||||
<!-- </tr>-->
|
|
||||||
<!-- </thead>-->
|
|
||||||
<!-- <tbody>-->
|
|
||||||
<!-- <tr v-for="row in element.options[0]" :key="row.option">-->
|
|
||||||
<!-- <!– 编辑状态,单次点击出输入框,失焦后关闭 –>-->
|
|
||||||
<!-- <td>-->
|
|
||||||
<!-- <contenteditable-->
|
|
||||||
<!-- v-model="row.option"-->
|
|
||||||
<!-- :active="active"-->
|
|
||||||
<!-- @blur="emitValue"-->
|
|
||||||
<!-- ></contenteditable>-->
|
|
||||||
<!-- </td>-->
|
|
||||||
<!-- <td v-for="col in element.options[1]" :key="col.option" class="td-input">-->
|
|
||||||
<!-- <!– 编辑状态,单次点击出输入框,失焦后关闭 –>-->
|
|
||||||
<!-- <input :id="col.option" :type="tableInputTypeMapping()" :name="row.option" />-->
|
|
||||||
<!-- </td>-->
|
|
||||||
|
|
||||||
<!-- <td v-if="element.config.is_limit_right_content === 1">-->
|
|
||||||
<!-- <contenteditable-->
|
|
||||||
<!-- v-model="row.option_config.limit_right_content"-->
|
|
||||||
<!-- :active="active"-->
|
|
||||||
<!-- @blur="emitValue"-->
|
|
||||||
<!-- >-->
|
|
||||||
<!-- </contenteditable>-->
|
|
||||||
<!-- </td>-->
|
|
||||||
<!-- </tr>-->
|
|
||||||
<!-- </tbody>-->
|
|
||||||
<!-- </table>-->
|
|
||||||
<!-- </template>-->
|
|
||||||
</van-field>
|
</van-field>
|
||||||
</template>
|
</template>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -1,58 +1,82 @@
|
|||||||
<template>
|
<template>
|
||||||
<table class="matrix-table">
|
<!-- <table class="matrix-table">-->
|
||||||
<thead>
|
<!-- <thead>-->
|
||||||
<tr>
|
<!-- <tr>-->
|
||||||
<th></th>
|
<!-- <th></th>-->
|
||||||
<th v-for="col in cols" :key="col.option">
|
<!-- <th v-for="col in cols" :key="col.option">-->
|
||||||
<contenteditable v-model="col.option" :active="active" @blur="emitValue" />
|
<!-- <contenteditable-->
|
||||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
<!-- v-if="col.option"-->
|
||||||
<!-- <input-->
|
<!-- v-model="col.option"-->
|
||||||
<!-- v-if="col.editor"-->
|
<!-- :active="active"-->
|
||||||
<!-- v-model="col.option"-->
|
<!-- @blur="emitValue"-->
|
||||||
<!-- v-focus-->
|
<!-- />-->
|
||||||
<!-- type="text"-->
|
<!-- <van-field v-else placeholder="请输入" v-model="col.option" v-focus />-->
|
||||||
<!-- @focusout="col.editor = false"-->
|
<!-- </th>-->
|
||||||
<!-- @click="handleRowNameChange(col.option!)"-->
|
<!-- </tr>-->
|
||||||
<!-- />-->
|
<!-- </thead>-->
|
||||||
<!-- <span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>-->
|
<!-- <tbody>-->
|
||||||
</th>
|
<!-- <tr v-for="(row, rowIndex) in rows" :key="rowIndex">-->
|
||||||
</tr>
|
<!-- <contenteditable v-model="row.option" :active="active" @blur="emitValue" />-->
|
||||||
</thead>
|
<!-- <td v-for="(col, colIndex) in cols" :key="colIndex">-->
|
||||||
<tbody>
|
<!-- <input-->
|
||||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
<!-- type="radio"-->
|
||||||
<contenteditable v-model="row.option" :active="active" @blur="emitValue" />
|
<!-- class="van-icon matrix-radio"-->
|
||||||
<td v-for="(col, colIndex) in cols" :key="colIndex">
|
<!-- :name="`R${rowIndex + 1}`"-->
|
||||||
<input
|
<!-- :value="`${rowIndex + 1}_${colIndex + 1}`"-->
|
||||||
type="radio"
|
<!-- :checked="isOptionChecked(rowIndex, colIndex)"-->
|
||||||
class="van-icon matrix-radio"
|
<!-- @change="handleMatrixRadioChange(rowIndex, colIndex)"-->
|
||||||
:name="`R${rowIndex + 1}`"
|
<!-- />-->
|
||||||
:value="`${rowIndex + 1}_${colIndex + 1}`"
|
<!-- </td>-->
|
||||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
<!-- </tr>-->
|
||||||
@change="handleMatrixRadioChange(rowIndex, colIndex)"
|
<!-- </tbody>-->
|
||||||
/>
|
<!-- </table>-->
|
||||||
</td>
|
<el-table :data="rows" style="width: 100%">
|
||||||
</tr>
|
<el-table-column width="140">
|
||||||
</tbody>
|
<template #header></template>
|
||||||
</table>
|
<template #default="{ row /*, column, $index*/ }"> <div v-html="row.option"></div></template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column v-for="(col, colIndex) in cols" :key="col.option" width="100">
|
||||||
|
<template #header>
|
||||||
|
<contenteditable
|
||||||
|
v-if="col.option"
|
||||||
|
v-model="col.option"
|
||||||
|
:active="active"
|
||||||
|
@blur="emitValue"
|
||||||
|
/>
|
||||||
|
<van-field v-else v-model="col.option" placeholder="请输入"></van-field>
|
||||||
|
</template>
|
||||||
|
<template #default="{ /*row, column, */ $index: rowIndex }">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
:name="`R${rowIndex + 1}`"
|
||||||
|
:checked="isOptionChecked(rowIndex, colIndex)"
|
||||||
|
@change="handleMatrixRadioChange(rowIndex, colIndex)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// import { defineProps } from 'vue';
|
|
||||||
// import { vFocus } from '@/utils/directives/useVFocus';
|
|
||||||
|
|
||||||
// 记录行和列的索引
|
// 记录行和列的索引
|
||||||
|
// import { getDomText } from '@/utils/utils';
|
||||||
|
|
||||||
const rowRecord = defineModel<number[]>('rowRecord', { required: false, default: () => [] });
|
const rowRecord = defineModel<number[]>('rowRecord', { required: false, default: () => [] });
|
||||||
// const matrixAnswer = defineModel<{ [key: string]: 1 }>('matrixAnswer', { required: false, default: () => ({}) });
|
|
||||||
// 检查 rowRecord 是否存在
|
// 检查 rowRecord 是否存在
|
||||||
// console.log(`rowRecord:`, rowRecord.value);
|
// console.log(`rowRecord:`, rowRecord.value);
|
||||||
|
|
||||||
/* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false });
|
/* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false });
|
||||||
|
|
||||||
const rows = defineModel<number[]>('rows', { required: false, default: () => [] });
|
const rows = defineModel<questionOptionType[]>('rows', { required: false, default: () => [] });
|
||||||
const cols = defineModel<number[]>('cols', { required: false, default: () => [] });
|
const cols = defineModel<questionOptionType[]>('cols', { required: false, default: () => [] });
|
||||||
const active = defineModel<boolean>('active', { required: false, default: true });
|
/* const active = */ defineModel<boolean>('active', { required: false, default: true });
|
||||||
// console.log(rows.value, cols.value);
|
const element = defineModel<question>('element', {
|
||||||
// const emits = defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
required: false,
|
||||||
|
default: () => {
|
||||||
|
/**/
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const emit = defineEmits(['update:matrixAnswer', 'update:rowRecord', 'update:element']);
|
||||||
|
|
||||||
// 判断是否选中
|
// 判断是否选中
|
||||||
const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
|
const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
|
||||||
@@ -93,7 +117,8 @@ function handleMatrixRadioChange(row: number, col: number) {
|
|||||||
// emits('update:matrixAnswer', props.matrixAnswer);
|
// emits('update:matrixAnswer', props.matrixAnswer);
|
||||||
// emits('update:rowRecord', props.rowRecord);
|
// emits('update:rowRecord', props.rowRecord);
|
||||||
// };
|
// };
|
||||||
const emitValue = () => {
|
const emitValue = (val: unknown) => {
|
||||||
|
console.log(val);
|
||||||
emit('update:element', element.value);
|
emit('update:element', element.value);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ const rowRecord = defineModel<string[][]>('rowRecord', { required: false, defaul
|
|||||||
const active = defineModel<boolean>('active', { required: false, default: true });
|
const active = defineModel<boolean>('active', { required: false, default: true });
|
||||||
|
|
||||||
/* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false });
|
/* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false });
|
||||||
const rows = defineModel<number[]>('rows', { required: false, default: () => [] });
|
const rows = defineModel<questionOptionType[]>('rows', { required: false, default: () => [] });
|
||||||
const cols = defineModel<number[]>('cols', { required: false, default: () => [] });
|
const cols = defineModel<questionOptionType[]>('cols', { required: false, default: () => [] });
|
||||||
|
|
||||||
// const emits = defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
const emit = defineEmits(['update:matrixAnswer', 'update:rowRecord', 'update:element']);
|
||||||
|
|
||||||
// const handleRowNameChange = (/* value: string */) => {
|
// const handleRowNameChange = (/* value: string */) => {
|
||||||
// console.log(`row change: ${value}`);
|
// console.log(`row change: ${value}`);
|
||||||
@@ -94,6 +94,9 @@ function handleMatrixTextChange(row: number, col: number, e: Event) {
|
|||||||
// emits('update:matrixAnswer', props.matrixAnswer);
|
// emits('update:matrixAnswer', props.matrixAnswer);
|
||||||
// emits('update:rowRecord', props.rowRecord);
|
// emits('update:rowRecord', props.rowRecord);
|
||||||
// };
|
// };
|
||||||
|
const emitValue = () => {
|
||||||
|
emit('update:element', element.value);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ interface OptionConfigType {
|
|||||||
limit_right_content?: string;
|
limit_right_content?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OptionType {
|
interface questionOptionType {
|
||||||
// 包含 HTML 标签的字符串,例如 "<p>选项1</p>"
|
// 包含 HTML 标签的字符串,例如 "<p>选项1</p>"
|
||||||
option?: string;
|
option?: string;
|
||||||
is_other?: number;
|
is_other?: number;
|
||||||
@@ -34,7 +34,7 @@ type questionsList = {
|
|||||||
relation_last_scope: number;
|
relation_last_scope: number;
|
||||||
relation_first_scope: number;
|
relation_first_scope: number;
|
||||||
relation_question_index: number;
|
relation_question_index: number;
|
||||||
options?: OptionType[];
|
options?: questionOptionType[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type question = {
|
type question = {
|
||||||
|
|||||||
@@ -183,6 +183,7 @@
|
|||||||
v-else-if="question.question_type === 8"
|
v-else-if="question.question_type === 8"
|
||||||
v-model:answer="question.answer"
|
v-model:answer="question.answer"
|
||||||
:list="question.list"
|
:list="question.list"
|
||||||
|
:questionIndex="question.question_index"
|
||||||
:config="question.config"
|
:config="question.config"
|
||||||
:stem="question.stem"
|
:stem="question.stem"
|
||||||
:question="question"
|
:question="question"
|
||||||
@@ -195,6 +196,7 @@
|
|||||||
v-else-if="question.question_type === 9"
|
v-else-if="question.question_type === 9"
|
||||||
v-model:answer="question.answer"
|
v-model:answer="question.answer"
|
||||||
:list="question.list"
|
:list="question.list"
|
||||||
|
:questionIndex="question.question_index"
|
||||||
:config="question.config"
|
:config="question.config"
|
||||||
:stem="question.stem"
|
:stem="question.stem"
|
||||||
:answerSn="questionsData.answer.sn"
|
:answerSn="questionsData.answer.sn"
|
||||||
@@ -669,9 +671,9 @@ async function answer(callback, callbackBeforePage) {
|
|||||||
question.error = translatedText.value.ThisIsARequiredQuestion;
|
question.error = translatedText.value.ThisIsARequiredQuestion;
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
answer &&
|
answer
|
||||||
questionType === 1 &&
|
&& questionType === 1
|
||||||
Object.keys(answer).findIndex((value) => !answer[value]) !== -1
|
&& Object.keys(answer).findIndex((value) => !answer[value]) !== -1
|
||||||
) {
|
) {
|
||||||
// 单选题
|
// 单选题
|
||||||
isError = true;
|
isError = true;
|
||||||
@@ -846,52 +848,52 @@ async function answer(callback, callbackBeforePage) {
|
|||||||
const { value } = answer;
|
const { value } = answer;
|
||||||
const newValue = value.replace(/\n|\r|\r\n/g, '');
|
const newValue = value.replace(/\n|\r|\r\n/g, '');
|
||||||
switch (config.text_type) {
|
switch (config.text_type) {
|
||||||
// 字母
|
// 字母
|
||||||
case 3:
|
case 3:
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const reg =
|
const reg =
|
||||||
/^[a-zA-Z·~!@#¥%…&*()—\-+={}|《》?:“”【】、;‘’,。`!$^()_<>?:",./;'\\[\]]+$/;
|
/^[a-zA-Z·~!@#¥%…&*()—\-+={}|《》?:“”【】、;‘’,。`!$^()_<>?:",./;'\\[\]]+$/;
|
||||||
isError =
|
isError
|
||||||
config.include_mark === 1
|
= config.include_mark === 1
|
||||||
? !reg.test(newValue) || !newValue.length
|
? !reg.test(newValue) || !newValue.length
|
||||||
: !/^[a-zA-Z]+$/.test(newValue) || !newValue.length;
|
: !/^[a-zA-Z]+$/.test(newValue) || !newValue.length;
|
||||||
question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : '';
|
question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : '';
|
||||||
break;
|
break;
|
||||||
// 中文
|
// 中文
|
||||||
case 4:
|
case 4:
|
||||||
isError =
|
isError
|
||||||
config.include_mark === 1
|
= config.include_mark === 1
|
||||||
? !/^(?:[\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]|[a-zA-Z·~!@#¥%…&*()—\-+={}|《》?:“”【】、;‘’,。`!$^()_<>?:",./;'\\[\]])+$/.test(
|
? !/^(?:[\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]|[a-zA-Z·~!@#¥%…&*()—\-+={}|《》?:“”【】、;‘’,。`!$^()_<>?:",./;'\\[\]])+$/.test(
|
||||||
newValue
|
newValue
|
||||||
) || !newValue.length
|
) || !newValue.length
|
||||||
: !/^(?:[\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(
|
: !/^(?:[\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(
|
||||||
newValue
|
newValue
|
||||||
) || !newValue.length;
|
) || !newValue.length;
|
||||||
question.error = isError ? translatedText.value.PleaseEnterChineseWords : '';
|
question.error = isError ? translatedText.value.PleaseEnterChineseWords : '';
|
||||||
break;
|
break;
|
||||||
// 邮箱
|
// 邮箱
|
||||||
case 5:
|
case 5:
|
||||||
isError =
|
isError
|
||||||
!/^(([^<>()[\]\\.,;:\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(
|
= !/^(([^<>()[\]\\.,;:\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(
|
||||||
value
|
value
|
||||||
);
|
);
|
||||||
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
|
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
|
||||||
break;
|
break;
|
||||||
// 手机号
|
// 手机号
|
||||||
case 6:
|
case 6:
|
||||||
isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value);
|
isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value);
|
||||||
question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : '';
|
question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : '';
|
||||||
break;
|
break;
|
||||||
// 身份证号
|
// 身份证号
|
||||||
case 7:
|
case 7:
|
||||||
isError =
|
isError
|
||||||
!/^[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(
|
= !/^[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(
|
||||||
value
|
value
|
||||||
);
|
);
|
||||||
question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
|
question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!isError && value.length < config.min && ![1, 2].includes(config.text_type)) {
|
if (!isError && value.length < config.min && ![1, 2].includes(config.text_type)) {
|
||||||
isError = true;
|
isError = true;
|
||||||
@@ -903,54 +905,54 @@ async function answer(callback, callbackBeforePage) {
|
|||||||
Object.keys(answer).forEach((key) => {
|
Object.keys(answer).forEach((key) => {
|
||||||
const value = answer[key];
|
const value = answer[key];
|
||||||
switch (config.text_type) {
|
switch (config.text_type) {
|
||||||
// 字母
|
// 字母
|
||||||
case 3:
|
case 3:
|
||||||
if (
|
if (
|
||||||
!/^[a-zA-Z·~!@#¥%…&*()—\-+={}|《》?:“”【】、;‘’,。`!$^()_<>?:",./;'\\[\]]+$/.test(
|
!/^[a-zA-Z·~!@#¥%…&*()—\-+={}|《》?:“”【】、;‘’,。`!$^()_<>?:",./;'\\[\]]+$/.test(
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
question.error = translatedText.value.PleaseEnterEnglishLetters;
|
question.error = translatedText.value.PleaseEnterEnglishLetters;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// 中文
|
// 中文
|
||||||
case 4:
|
case 4:
|
||||||
if (
|
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(
|
!/^(?:[\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(
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
question.error = translatedText.value.PleaseEnterChineseWords;
|
question.error = translatedText.value.PleaseEnterChineseWords;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// 邮箱
|
// 邮箱
|
||||||
case 5:
|
case 5:
|
||||||
if (
|
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(
|
!/^(([^<>()[\]\\.,;:\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(
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
question.error = translatedText.value.PleaseEnterACorrectEmail;
|
question.error = translatedText.value.PleaseEnterACorrectEmail;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// 手机号
|
// 手机号
|
||||||
case 6:
|
case 6:
|
||||||
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value)) {
|
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value)) {
|
||||||
question.error = translatedText.value.PleaseEnterACorrectPhone;
|
question.error = translatedText.value.PleaseEnterACorrectPhone;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// 身份证号
|
// 身份证号
|
||||||
case 7:
|
case 7:
|
||||||
if (
|
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(
|
!/^[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(
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
question.error = translatedText.value.PleaseEnterACorrectID;
|
question.error = translatedText.value.PleaseEnterACorrectID;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!question.error && value.length < config.min && ![1, 2].includes(config.text_type)) {
|
if (!question.error && value.length < config.min && ![1, 2].includes(config.text_type)) {
|
||||||
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
|
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
|
||||||
@@ -1027,14 +1029,14 @@ async function answer(callback, callbackBeforePage) {
|
|||||||
currentQuestions.forEach((question, index) => {
|
currentQuestions.forEach((question, index) => {
|
||||||
if (index >= warnStart && index < warnEnd) {
|
if (index >= warnStart && index < warnEnd) {
|
||||||
if (repeat.repeat_type) {
|
if (repeat.repeat_type) {
|
||||||
question.warning =
|
question.warning
|
||||||
translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
|
= translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
|
||||||
repeat.allow_repeat_num,
|
repeat.allow_repeat_num,
|
||||||
repeat.repeat_type
|
repeat.repeat_type
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
question.error =
|
question.error
|
||||||
translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
|
= translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
|
||||||
repeat.allow_repeat_num,
|
repeat.allow_repeat_num,
|
||||||
repeat.repeat_type
|
repeat.repeat_type
|
||||||
);
|
);
|
||||||
@@ -1381,8 +1383,8 @@ function updateAnswer(auto) {
|
|||||||
const evt1 = {};
|
const evt1 = {};
|
||||||
|
|
||||||
if ([1].includes(question.question_type)) {
|
if ([1].includes(question.question_type)) {
|
||||||
evt1.value =
|
evt1.value
|
||||||
Object.keys(question.answer)
|
= Object.keys(question.answer)
|
||||||
.map((key) => (question.answer[key] ? key : undefined))
|
.map((key) => (question.answer[key] ? key : undefined))
|
||||||
.filter((i) => !!i)?.[0] || undefined;
|
.filter((i) => !!i)?.[0] || undefined;
|
||||||
evt1.options = question.list.flatMap((i) => i.options);
|
evt1.options = question.list.flatMap((i) => i.options);
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<matrix-radio
|
<MartrixQuestion
|
||||||
v-model:rowRecord="rowRecord"
|
v-model:rowRecord="rowRecord"
|
||||||
v-model:matrix-radio-answer="answer!"
|
|
||||||
:rows="rows"
|
:rows="rows"
|
||||||
:cols="cols"
|
:cols="cols"
|
||||||
|
:index="questionIndex"
|
||||||
|
:element="question"
|
||||||
:is-preview="true"
|
:is-preview="true"
|
||||||
></matrix-radio>
|
:active="false"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import matrixRadio from '@/views/Design/components/Questions/MatrixRadio.vue';
|
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
import MartrixQuestion from '@/views/Design/components/Questions/MartrixQuestion.vue';
|
||||||
// const questionType = defineModel<number>('questionType', { required: false });
|
// const questionType = defineModel<number>('questionType', { required: false });
|
||||||
|
|
||||||
// 矩阵单选的答案类型
|
// 矩阵单选的答案类型
|
||||||
@@ -23,6 +26,8 @@ type answerType = {
|
|||||||
// const list = defineModel<questionsList[]>('list', { required: false });
|
// const list = defineModel<questionsList[]>('list', { required: false });
|
||||||
// const config = defineModel<OptionConfigType>('config', { required: false });
|
// const config = defineModel<OptionConfigType>('config', { required: false });
|
||||||
const question = defineModel<question>('question');
|
const question = defineModel<question>('question');
|
||||||
|
const questionIndex = defineModel<number>('questionIndex', { required: false, default: 0 });
|
||||||
|
// console.log(question.value);
|
||||||
const emit = defineEmits(['changeAnswer', 'previous', 'next']);
|
const emit = defineEmits(['changeAnswer', 'previous', 'next']);
|
||||||
// 示例
|
// 示例
|
||||||
// {
|
// {
|
||||||
|
|||||||
Reference in New Issue
Block a user