Merge remote-tracking branch 'origin/feature/feature-20250331-h5' into feature/feature-20250331-h5
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# .env.development
|
||||
VITE_APP_BASEURL=http://192.168.8.165:15011/
|
||||
VITE_APP_BASEURL=https://yls-api-uat.dctest.digitalyili.com/
|
||||
VITE_APP_ENV=development
|
||||
VITE_APP_CURRENTMODE=dev
|
||||
VITE_APP_BASEOSS=https://diaoyan-files.automark.cc
|
||||
|
||||
4
auto-imports.d.ts
vendored
4
auto-imports.d.ts
vendored
@@ -5,4 +5,6 @@
|
||||
// Generated by unplugin-auto-import
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {}
|
||||
declare global {
|
||||
|
||||
}
|
||||
|
||||
5
components.d.ts
vendored
5
components.d.ts
vendored
@@ -8,6 +8,7 @@ export {}
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
Contenteditable: typeof import('./src/components/contenteditable.vue')['default']
|
||||
RichText: typeof import('./src/components/RichText.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
VanActionSheet: typeof import('vant/es')['ActionSheet']
|
||||
@@ -16,18 +17,14 @@ declare module 'vue' {
|
||||
VanCellGroup: typeof import('vant/es')['CellGroup']
|
||||
VanCheckbox: typeof import('vant/es')['Checkbox']
|
||||
VanCheckboxGroup: typeof import('vant/es')['CheckboxGroup']
|
||||
VanCol: typeof import('vant/es')['Col']
|
||||
VanDivider: typeof import('vant/es')['Divider']
|
||||
VanField: typeof import('vant/es')['Field']
|
||||
VanGrid: typeof import('vant/es')['Grid']
|
||||
VanGridItem: typeof import('vant/es')['GridItem']
|
||||
VanIcon: typeof import('vant/es')['Icon']
|
||||
VanNavBar: typeof import('vant/es')['NavBar']
|
||||
VanPicker: typeof import('vant/es')['Picker']
|
||||
VanPopup: typeof import('vant/es')['Popup']
|
||||
VanRadio: typeof import('vant/es')['Radio']
|
||||
VanRadioGroup: typeof import('vant/es')['RadioGroup']
|
||||
VanRow: typeof import('vant/es')['Row']
|
||||
VanSearch: typeof import('vant/es')['Search']
|
||||
VanStepper: typeof import('vant/es')['Stepper']
|
||||
VanSwitch: typeof import('vant/es')['Switch']
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<template>
|
||||
<div v-if="isPreview"
|
||||
v-html="nodes"
|
||||
style="min-width: 22px"
|
||||
:class="isMobile ? 'mobile-text' : ''"
|
||||
@click="onClick"></div>
|
||||
<div
|
||||
v-if="isPreview"
|
||||
style="min-width: 22px"
|
||||
:class="isMobile ? 'mobile-text' : ''"
|
||||
@click="onClick"
|
||||
v-html="nodes"
|
||||
></div>
|
||||
<div v-else v-html="nodes"></div>
|
||||
</template>
|
||||
|
||||
@@ -32,8 +34,8 @@ export default defineComponent({
|
||||
onClick(evt) {
|
||||
const targetTagName = (evt.target || evt.srcElement).tagName || '';
|
||||
if (targetTagName.toLowerCase() === 'img') {
|
||||
evt.stopPropagation()
|
||||
evt.cancelBubble = true
|
||||
evt.stopPropagation();
|
||||
evt.cancelBubble = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const surveyQuestion = 'https://yls-api-uat.dctest.digitalyili.com/api/console/surveys/RWNK9BYp/questions';
|
||||
export const surveyQuestion = 'https://yls-api-uat.dctest.digitalyili.com/api/console/surveys/RWNK9BYp/questions';
|
||||
@@ -49,7 +49,7 @@ const router = createRouter({
|
||||
path: '/preview',
|
||||
name: 'preview',
|
||||
meta: {},
|
||||
component: ()=> import ( '@/views/Survey/views/Preview/Index.vue')
|
||||
component: () => import('@/views/Survey/views/Preview/Index.vue')
|
||||
},
|
||||
{
|
||||
path: '/create',
|
||||
|
||||
@@ -31,7 +31,7 @@ export const useQuestionStore = defineStore('questionStore', () => {
|
||||
|
||||
// 作用未知
|
||||
const l = ref({});
|
||||
// 主题颜色
|
||||
// 主题颜色
|
||||
const themeColor = ref({});
|
||||
|
||||
return {
|
||||
@@ -44,7 +44,8 @@ export const useQuestionStore = defineStore('questionStore', () => {
|
||||
loading,
|
||||
prevLoading,
|
||||
localPageTimer,
|
||||
questions,showPage
|
||||
questions,
|
||||
showPage
|
||||
|
||||
};
|
||||
});
|
||||
@@ -8,4 +8,3 @@ export const vFocus: Directive = {
|
||||
el.focus();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ service.interceptors.request.use(
|
||||
service.interceptors.response.use(
|
||||
(response) => {
|
||||
if (
|
||||
response.status === 200 ||
|
||||
response.status === 201 ||
|
||||
response.status === 202 ||
|
||||
response.status === 204
|
||||
response.status === 200
|
||||
|| response.status === 201
|
||||
|| response.status === 202
|
||||
|| response.status === 204
|
||||
) {
|
||||
if (response.config.method === 'put') {
|
||||
// message.success('保存中...');
|
||||
|
||||
@@ -335,6 +335,9 @@ const actionFun = {
|
||||
|
||||
// emit 事件
|
||||
const saveQueItem = (logics, questions, survey) => {
|
||||
// questions.map((item, index) => {
|
||||
// item.title = index + 1;
|
||||
// });
|
||||
saveQuestion({
|
||||
sn: route.query.sn,
|
||||
data: {
|
||||
|
||||
@@ -11,7 +11,12 @@
|
||||
<div class="flex flex-start">操作选项</div>
|
||||
</template>
|
||||
<van-cell-group :border="false" class="ml10">
|
||||
<van-cell title="此题必答" :border="false" label-align="left">
|
||||
<van-cell
|
||||
v-if="![6].includes(activeQuestion.question_type)"
|
||||
title="此题必答"
|
||||
:border="false"
|
||||
label-align="left"
|
||||
>
|
||||
<template #right-icon>
|
||||
<van-switch
|
||||
v-model="activeQuestion.config.is_required"
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
size="0.5rem"
|
||||
@change="emit('saveOption')"
|
||||
></van-switch>
|
||||
</template>
|
||||
</van-field>
|
||||
@@ -71,7 +72,7 @@
|
||||
|
||||
<van-cell
|
||||
v-if="![5, 6, 7].includes(actionQuestion.config.text_type)"
|
||||
title="字数限制"
|
||||
:title="`${[1, 2].includes(actionQuestion.config.text_type) ? '数值限制' : '字数限制'}`"
|
||||
:border="false"
|
||||
label-align="left"
|
||||
>
|
||||
@@ -130,6 +131,7 @@
|
||||
v-model="actionQuestion.config.line_type"
|
||||
icon-size="0.4rem"
|
||||
direction="horizontal"
|
||||
@change="emit('saveOption')"
|
||||
>
|
||||
<van-radio :name="0">单行</van-radio>
|
||||
<van-radio :name="1">多行</van-radio>
|
||||
@@ -165,7 +167,7 @@
|
||||
label-align="left"
|
||||
input-align="right"
|
||||
class="action-field"
|
||||
placeholder="不限"
|
||||
placeholder=""
|
||||
@blur="emit('saveOption')"
|
||||
@update:model-value="
|
||||
(value) => {
|
||||
@@ -239,6 +241,7 @@ const selectText = (textType) => {
|
||||
const confirm = ({ selectedValues }) => {
|
||||
actionQuestion.value.config.text_type = Number(selectedValues[0]);
|
||||
selectTextTypeModel.value = false;
|
||||
emit('saveOption');
|
||||
};
|
||||
|
||||
const actionQuestion = computed({
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
></contenteditable>
|
||||
</template>
|
||||
<template #input>
|
||||
<div contenteditable="true" class="input other_input"></div>
|
||||
<textarea
|
||||
class="other_input"
|
||||
:placeholder="element.config.placeholder"
|
||||
:rows="element.config.line_height"
|
||||
></textarea>
|
||||
</template>
|
||||
</van-field>
|
||||
</div>
|
||||
@@ -45,7 +49,6 @@ const props = defineProps({
|
||||
// 创建一个本地副本以保存更改
|
||||
const emit = defineEmits(['update:element']);
|
||||
const { element } = toRefs(props);
|
||||
|
||||
const emitValue = () => {
|
||||
emit('update:element', element.value);
|
||||
};
|
||||
@@ -55,7 +58,7 @@ const emitValue = () => {
|
||||
.cont {
|
||||
.other_input {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
min-height: 40px;
|
||||
margin-bottom: 10px;
|
||||
padding: 3px 5px;
|
||||
border: 1px solid #ccc;
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
<template>
|
||||
<table class="matrix-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td v-for="col in columns" :key="col.option">
|
||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||||
<input
|
||||
v-if="col.editor"
|
||||
v-model="col.option"
|
||||
v-focus
|
||||
type="text"
|
||||
@focusout="col.editor = false"
|
||||
@click="handleRowNameChange(col.option!)"
|
||||
/>
|
||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td v-for="col in columns" :key="col.option">
|
||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||||
<input
|
||||
v-if="col.editor"
|
||||
v-model="col.option"
|
||||
v-focus
|
||||
type="text"
|
||||
@focusout="col.editor = false"
|
||||
@click="handleRowNameChange(col.option!)"
|
||||
/>
|
||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option" />
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
||||
<th v-html="row.option"/>
|
||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
||||
<input
|
||||
type="checkbox"
|
||||
:value="`${rowIndex + 1}_${colIndex + 1}`"
|
||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
||||
@change="handleColNameChange(row.option, col.option, $event)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
||||
<th v-html="row.option" />
|
||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
||||
<input
|
||||
type="checkbox"
|
||||
:value="`${rowIndex + 1}_${colIndex + 1}`"
|
||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
||||
@change="handleColNameChange(row.option, col.option, $event)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, defineProps, defineEmits } from 'vue';
|
||||
import {vFocus} from '@/utils/directives/useVFocus';
|
||||
import { defineProps } from 'vue';
|
||||
import { vFocus } from '@/utils/directives/useVFocus';
|
||||
|
||||
const props = defineProps<{
|
||||
rows: { option: string }[];
|
||||
columns: { option: string, editor?: boolean }[];
|
||||
columns: { option: string; editor?: boolean }[];
|
||||
questionType: number;
|
||||
matrixAnswer: { [key: string]: any };
|
||||
rowRecord: (number | string)[];
|
||||
rowRecord:(number | string)[];
|
||||
}>();
|
||||
|
||||
const emits = defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
||||
/* const emits = */ defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
||||
|
||||
const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
|
||||
const key = `R${rowIndex + 1}_C${colIndex + 1}`;
|
||||
@@ -57,31 +57,32 @@ const handleRowNameChange = (value: string) => {
|
||||
// 你可以在这里添加其他逻辑
|
||||
};
|
||||
|
||||
const handleColNameChange = (rowOption: string, colOption: string, e: Event) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
const col = props.columns.findIndex(option => option.option === colOption);
|
||||
const row = props.rows.findIndex(option => option.option === rowOption);
|
||||
|
||||
if (props.questionType === 10) {
|
||||
if (target.checked) {
|
||||
props.rowRecord[col] = (props.rowRecord[col] || []).concat(row + 1);
|
||||
} else {
|
||||
props.rowRecord[col] = (props.rowRecord[col] || []).filter(item => item !== row + 1);
|
||||
}
|
||||
props.matrixAnswer = {};
|
||||
props.rows.forEach((rowOption, rowIndex) => {
|
||||
const colOptions = props.rowRecord[rowIndex];
|
||||
if (colOptions) {
|
||||
colOptions.forEach((col: any) => {
|
||||
props.matrixAnswer[`R${rowIndex + 1}_C${col}`] = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
emits('update:matrixAnswer', props.matrixAnswer);
|
||||
emits('update:rowRecord', props.rowRecord);
|
||||
};
|
||||
// const handleColNameChange = (rowOption: string, colOption: string, e: Event) => {
|
||||
// const target = e.target as HTMLInputElement;
|
||||
// const col = props.columns.findIndex(option => option.option === colOption);
|
||||
// const row = props.rows.findIndex(option => option.option === rowOption);
|
||||
//
|
||||
// if (props.questionType === 10) {
|
||||
// if (target.checked) {
|
||||
// props.rowRecord[col] = (props.rowRecord[col] || []).concat(row + 1);
|
||||
// } else {
|
||||
// props.rowRecord[col] = (props.rowRecord[col] || []).filter(item => item !== row + 1);
|
||||
// }
|
||||
// const newMatrixAnswer: { [key: string]: boolean } = {};
|
||||
// const newRowRecord: (number | string)[] = [...props.rowRecord];
|
||||
// props.rows.forEach((rowOption, rowIndex) => {
|
||||
// const colOptions = newRowRecord[rowIndex];
|
||||
// if (colOptions) {
|
||||
// colOptions.forEach((col: any) => {
|
||||
// newMatrixAnswer[`R${rowIndex + 1}_C${col}`] = true;
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// emits('update:matrixAnswer', newMatrixAnswer);
|
||||
// emits('update:rowRecord', newRowRecord);
|
||||
// };
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -96,4 +97,4 @@ const handleColNameChange = (rowOption: string, colOption: string, e: Event) =>
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,79 +1,79 @@
|
||||
<template>
|
||||
<table class="matrix-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td v-for="col in columns" :key="col.option">
|
||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||||
<input
|
||||
v-if="col.editor"
|
||||
v-model="col.option"
|
||||
v-focus
|
||||
type="text"
|
||||
@focusout="col.editor = false"
|
||||
@click="handleRowNameChange(col.option!)"
|
||||
/>
|
||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td v-for="col in columns" :key="col.option">
|
||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||||
<input
|
||||
v-if="col.editor"
|
||||
v-model="col.option"
|
||||
v-focus
|
||||
type="text"
|
||||
@focusout="col.editor = false"
|
||||
@click="handleRowNameChange(col.option!)"
|
||||
/>
|
||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
||||
<th v-html="row.option"></th>
|
||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
||||
<input
|
||||
type="radio"
|
||||
:name="`R${rowIndex + 1}`"
|
||||
:value="`${rowIndex + 1}_${colIndex + 1}`"
|
||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
||||
@change="handleColNameChange(row.option, col.option, $event)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
||||
<th v-html="row.option"></th>
|
||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
||||
<input
|
||||
type="radio"
|
||||
:name="`R${rowIndex + 1}`"
|
||||
:value="`${rowIndex + 1}_${colIndex + 1}`"
|
||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
||||
@change="handleColNameChange(row.option, col.option, $event)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, defineProps, defineEmits } from 'vue';
|
||||
import {vFocus} from '@/utils/directives/useVFocus';
|
||||
import { defineProps } from 'vue';
|
||||
import { vFocus } from '@/utils/directives/useVFocus';
|
||||
|
||||
let props = defineProps<{
|
||||
const props = defineProps<{
|
||||
rows: { option: string }[];
|
||||
columns: { option: string, editor?: boolean }[];
|
||||
columns: { option: string; editor?: boolean }[];
|
||||
questionType: number;
|
||||
matrixAnswer: { [key: string]: any };
|
||||
rowRecord: (number | string)[];
|
||||
rowRecord:(number | string)[];
|
||||
}>();
|
||||
|
||||
const emits = defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
||||
/* const emits = */ defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
||||
|
||||
const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
|
||||
const key = `R${rowIndex + 1}_C${colIndex + 1}`;
|
||||
return !!props.matrixAnswer[key];
|
||||
};
|
||||
|
||||
const handleRowNameChange = (value: string) => {
|
||||
console.log(`row change: ${value}`);
|
||||
const handleRowNameChange = (/* value: string */) => {
|
||||
// console.log(`row change: ${value}`);
|
||||
// 你可以在这里添加其他逻辑
|
||||
};
|
||||
|
||||
const handleColNameChange = (rowOption: string, colOption: string, e: Event) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
const col = props.columns.findIndex(option => option.option === colOption);
|
||||
const row = props.rows.findIndex(option => option.option === rowOption);
|
||||
|
||||
if (props.questionType === 9) {
|
||||
props.rowRecord[col] = row + 1;
|
||||
props.matrixAnswer = {};
|
||||
props.rowRecord.forEach((row, index) => {
|
||||
props.matrixAnswer[`${index + 1}_${row}`] = 1;
|
||||
});
|
||||
}
|
||||
|
||||
emits('update:matrixAnswer', props.matrixAnswer);
|
||||
emits('update:rowRecord', props.rowRecord);
|
||||
};
|
||||
// const handleColNameChange = (rowOption: string, colOption: string) => {
|
||||
// // const target = e.target as HTMLInputElement;
|
||||
// const col = props.columns.findIndex((option) => option.option === colOption);
|
||||
// const row = props.rows.findIndex((option) => option.option === rowOption);
|
||||
//
|
||||
// if (props.questionType === 9) {
|
||||
// props.rowRecord[col] = row + 1;
|
||||
// props.matrixAnswer = {};
|
||||
// props.rowRecord.forEach((row, index) => {
|
||||
// props.matrixAnswer[`${index + 1}_${row}`] = 1;
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// emits('update:matrixAnswer', props.matrixAnswer);
|
||||
// emits('update:rowRecord', props.rowRecord);
|
||||
// };
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -88,4 +88,4 @@ const handleColNameChange = (rowOption: string, colOption: string, e: Event) =>
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,56 +1,62 @@
|
||||
<template>
|
||||
<table class="matrix-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td v-for="col in columns" :key="col.option">
|
||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||||
<input
|
||||
v-if="col.editor"
|
||||
v-model="col.option"
|
||||
v-focus
|
||||
type="text"
|
||||
@focusout="col.editor = false"
|
||||
@click="handleRowNameChange(col.option!)"
|
||||
/>
|
||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td v-for="col in columns" :key="col.option">
|
||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||||
<input
|
||||
v-if="col.editor"
|
||||
v-model="col.option"
|
||||
v-focus
|
||||
type="text"
|
||||
@focusout="col.editor = false"
|
||||
@click="handleRowNameChange(col.option!)"
|
||||
/>
|
||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
||||
<th v-html="row.option"></th>
|
||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
||||
<input
|
||||
type="text"
|
||||
:value="matrixAnswer[`${rowIndex + 1}_${colIndex + 1}`]"
|
||||
@change="handleColNameChange(row.option, col.option, $event, rowIndex, colIndex)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
||||
<th v-html="row.option"></th>
|
||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
||||
<input
|
||||
type="text"
|
||||
:value="matrixAnswer[`${rowIndex + 1}_${colIndex + 1}`]"
|
||||
@change="handleColNameChange(row.option, col.option, $event, rowIndex, colIndex)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, defineProps, defineEmits } from 'vue';
|
||||
import {vFocus } from "@/utils/directives/useVFocus"
|
||||
import { defineProps, defineEmits } from 'vue';
|
||||
import { vFocus } from '@/utils/directives/useVFocus';
|
||||
|
||||
const props = defineProps<{
|
||||
rows: { option: string }[];
|
||||
columns: { option: string, editor?: boolean }[];
|
||||
columns: { option: string; editor?: boolean }[];
|
||||
questionType: number;
|
||||
matrixAnswer: { [key: string]: any };
|
||||
}>();
|
||||
|
||||
const emits = defineEmits(['update:matrixAnswer']);
|
||||
|
||||
const handleRowNameChange = (value: string) => {
|
||||
console.log(`row change: ${value}`);
|
||||
const handleRowNameChange = (/* value: string */) => {
|
||||
// console.log(`row change: ${value}`);
|
||||
// 你可以在这里添加其他逻辑
|
||||
};
|
||||
|
||||
const handleColNameChange = (rowOption: string, colOption: string, e: Event, rowIndex: number, colIndex: number) => {
|
||||
const handleColNameChange = (
|
||||
rowOption: string,
|
||||
colOption: string,
|
||||
e: Event,
|
||||
rowIndex: number,
|
||||
colIndex: number
|
||||
) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
const key = `R${rowIndex + 1}_C${colIndex + 1}`;
|
||||
const newMatrixAnswer = { ...props.matrixAnswer, [key]: target.value };
|
||||
@@ -71,4 +77,4 @@ const handleColNameChange = (rowOption: string, colOption: string, e: Event, row
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -10,12 +10,7 @@
|
||||
{{ index + 1 }}
|
||||
</template>
|
||||
<template #label>
|
||||
<div
|
||||
:contenteditable="active"
|
||||
class="van-field"
|
||||
@blur="saveStem($event, element)"
|
||||
v-html="element.stem"
|
||||
></div>
|
||||
<contenteditable v-model="element.stem" :active="active" @blur="saveStem"></contenteditable>
|
||||
</template>
|
||||
<template #input>
|
||||
<div v-for="(optionItem, optionItemIndex) in element.options" :key="optionItemIndex">
|
||||
@@ -38,7 +33,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import RateCharacter from './RateCharacter.vue';
|
||||
|
||||
const props = defineProps({
|
||||
@@ -56,23 +51,11 @@ const props = defineProps({
|
||||
sn: { type: String, default: '' },
|
||||
questionType: { type: [String, Number], default: 4 }
|
||||
});
|
||||
|
||||
const answerValue = ref()
|
||||
// NPS 的答案
|
||||
const NPSAnswer = ref({
|
||||
'question_index': props.index,
|
||||
'answer': {
|
||||
'1': answerValue.value
|
||||
}
|
||||
});
|
||||
|
||||
const element = ref(props.element);
|
||||
const { element } = toRefs(props);
|
||||
const chooseId = ref('');
|
||||
// 创建一个本地副本以保存更改
|
||||
const localElement = ref({ ...props.element });
|
||||
|
||||
const saveStem = (e) => {
|
||||
localElement.value.stem = e.target.innerHTML;
|
||||
const emit = defineEmits(['update:element']);
|
||||
const saveStem = () => {
|
||||
emit('update:element', element.value);
|
||||
};
|
||||
|
||||
const chooseOption = (item) => {
|
||||
@@ -90,4 +73,4 @@ const chooseOption = (item) => {
|
||||
justify-content: space-between;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -11,15 +11,18 @@
|
||||
{{ index + 1 }}
|
||||
</template>
|
||||
<template #label>
|
||||
<contenteditable v-model="element.stem" :active="active"></contenteditable>
|
||||
<!-- <div v-html="element.stem" v-else></div>-->
|
||||
<contenteditable
|
||||
v-model="element.stem"
|
||||
:active="active"
|
||||
@blur="emitValue"
|
||||
></contenteditable>
|
||||
</template>
|
||||
</van-field>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import contenteditable from '@/components/contenteditable.vue';
|
||||
import { ref } from 'vue';
|
||||
import { toRefs } from 'vue';
|
||||
const props = defineProps({
|
||||
element: {
|
||||
type: Object,
|
||||
@@ -39,6 +42,11 @@ const props = defineProps({
|
||||
}
|
||||
});
|
||||
|
||||
const element = ref(props.element);
|
||||
const { element } = toRefs(props);
|
||||
|
||||
const emit = defineEmits(['update:element']);
|
||||
const emitValue = () => {
|
||||
emit('update:element', element.value);
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -11,16 +11,18 @@
|
||||
<!-- <img v-if="styleInfo.head_img_status && styleInfo.head_img_url" width="100%" class="head-img"-->
|
||||
<!-- :src="styleInfo.head_img_url" />-->
|
||||
<!-- LOGO -->
|
||||
<van-cell-group>
|
||||
|
||||
</van-cell-group>
|
||||
<van-cell-group> </van-cell-group>
|
||||
<div
|
||||
v-if="styleInfo.logo_status && styleInfo.logo_url"
|
||||
class="example-logo"
|
||||
:style="[
|
||||
{
|
||||
'justify-content':
|
||||
styleInfo.logo_site === 1 ? 'flex-start' : styleInfo.logo_site === 2 ? 'center' : 'flex-end'
|
||||
styleInfo.logo_site === 1
|
||||
? 'flex-start'
|
||||
: styleInfo.logo_site === 2
|
||||
? 'center'
|
||||
: 'flex-end'
|
||||
},
|
||||
{ 'padding-left': styleInfo.logo_site === 1 ? '20px' : '' },
|
||||
{ 'padding-right': styleInfo.logo_site === 3 ? '20px' : '' },
|
||||
@@ -52,8 +54,8 @@
|
||||
/>
|
||||
<!-- 问卷名和描述 -->
|
||||
<q-first
|
||||
isMobile
|
||||
v-else-if="page === 0"
|
||||
isMobile
|
||||
:title="questionsData?.survey?.title"
|
||||
:desc="questionsData?.survey?.introduction"
|
||||
:questions="questionsData?.questions"
|
||||
@@ -64,21 +66,21 @@
|
||||
/>
|
||||
<!-- 题-mobile -->
|
||||
<question
|
||||
v-for="question in questions"
|
||||
v-else
|
||||
:id="'questionIndex' + question.question_index"
|
||||
:key="question.question_index"
|
||||
class="question"
|
||||
:tip="question.tip"
|
||||
:stem="question.stem"
|
||||
:title="question.title"
|
||||
:error="question.error"
|
||||
:warning="question.warning"
|
||||
v-for="question in questions"
|
||||
:key="question.question_index"
|
||||
:questions="questionsData.questions"
|
||||
:questionType="question.question_type"
|
||||
:questionIndex="question.question_index"
|
||||
:showTitle="styleInfo.is_question_number && true"
|
||||
isMobile
|
||||
:id="'questionIndex' + question.question_index"
|
||||
:isAnswer="isAnswer"
|
||||
>
|
||||
<!-- 单选题 -->
|
||||
@@ -476,11 +478,15 @@
|
||||
"
|
||||
:buttonTextColor="styleInfo.button_text_color"
|
||||
:buttonColor="styleInfo.button_color"
|
||||
@previous="previous"
|
||||
@next="next"
|
||||
:nextText="localPageTimer.is_show && localPageTimer.short_time ? `${localPageTimer.short_time}S` : ''"
|
||||
:nextText="
|
||||
localPageTimer.is_show && localPageTimer.short_time
|
||||
? `${localPageTimer.short_time}S`
|
||||
: ''
|
||||
"
|
||||
:nextDisabled="localPageTimer.short_time"
|
||||
isMobile
|
||||
@previous="previous"
|
||||
@next="next"
|
||||
/>
|
||||
</div>
|
||||
<LangTranslate
|
||||
@@ -492,19 +498,9 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import questions from './js/questions';
|
||||
import { defineComponent } from 'vue';
|
||||
import LangTranslate from './components/LangTranslate.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: { LangTranslate },
|
||||
...questions
|
||||
});
|
||||
</script>
|
||||
|
||||
<script setup>
|
||||
import { useTemplateRef, watch } from 'vue';
|
||||
import { useTemplateRef } from 'vue';
|
||||
import LangTranslate from './components/LangTranslate.vue';
|
||||
import QLast from '@/views/Survey/views/Preview/components/questions/QLast.vue';
|
||||
import Question from '@/views/Survey/views/Preview/components/questions/Question.vue';
|
||||
import QFirst from '@/views/Survey/views/Preview/components/questions/QFirst.vue';
|
||||
@@ -513,9 +509,13 @@ import { storeToRefs } from 'pinia';
|
||||
import { useQuestionStore } from '@/stores/Questions/useQuestionStore';
|
||||
import ProgressBar from './components/ProcessBar/Index.vue';
|
||||
import { AnswerApi } from './js/api';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { getLanguage } from '@/views/Survey/views/Preview/js/language';
|
||||
|
||||
// export default defineComponent({
|
||||
// components: { LangTranslate },
|
||||
// ...questions
|
||||
// });
|
||||
|
||||
// scrollbar
|
||||
const scrollbar = useTemplateRef('scrollbar');
|
||||
@@ -526,7 +526,7 @@ const {
|
||||
page,
|
||||
pages,
|
||||
l,
|
||||
themeColor, showPage,
|
||||
showPage,
|
||||
loading,
|
||||
prevLoading,
|
||||
localPageTimer,
|
||||
@@ -573,7 +573,7 @@ async function getQuestions() {
|
||||
|
||||
// 获取 DOM 的内容
|
||||
function getDomString(htmlString) {
|
||||
if (typeof htmlString !== 'string') return
|
||||
if (typeof htmlString !== 'string') return;
|
||||
const match = htmlString.match(/<.*>(.*?)<\/.*>/);
|
||||
if (match) return match[1];
|
||||
}
|
||||
@@ -629,9 +629,13 @@ async function answer(callback, callbackBeforePage) {
|
||||
if (questionType === 10) {
|
||||
// 矩阵多选题
|
||||
if (question.config.is_change_row_cell) {
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerColumn(config.min_select || 1);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerColumn(
|
||||
config.min_select || 1
|
||||
);
|
||||
} else {
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerLine(config.min_select || 1);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerLine(
|
||||
config.min_select || 1
|
||||
);
|
||||
}
|
||||
} else if (questionType === 12) {
|
||||
// 图片显示题,如果开启了仅显示并且开启了单图显示时长,需要确保用户每一个图片都点开看过了才能下一页
|
||||
@@ -645,7 +649,11 @@ async function answer(callback, callbackBeforePage) {
|
||||
} else if (!question.error) {
|
||||
question.error = translatedText.value.ThisIsARequiredQuestion;
|
||||
}
|
||||
} else if (answer && questionType === 1 && Object.keys(answer).findIndex((value) => !answer[value]) !== -1) {
|
||||
} else if (
|
||||
answer
|
||||
&& questionType === 1
|
||||
&& Object.keys(answer).findIndex((value) => !answer[value]) !== -1
|
||||
) {
|
||||
// 单选题
|
||||
isError = true;
|
||||
question.error = translatedText.value.PleaseInputAValue;
|
||||
@@ -676,23 +684,28 @@ async function answer(callback, callbackBeforePage) {
|
||||
// 选项分组最少选项数量
|
||||
config.option_groups?.option_group.some((optionGroup) => {
|
||||
const { min, title } = optionGroup;
|
||||
const select = optionGroup.groups.filter((groups) => Object.keys(answer).includes(groups.option_key));
|
||||
const select = optionGroup.groups.filter((groups) =>
|
||||
Object.keys(answer).includes(groups.option_key)
|
||||
);
|
||||
if (title && select.length < min) {
|
||||
// 判断隐藏选项
|
||||
question.hideOptionsSet = new Set(question.hideOptions);
|
||||
const options = question.list.flatMap((list) =>
|
||||
list.options
|
||||
.filter(({ option_key }) =>
|
||||
.filter(({ option_key: optionKey }) =>
|
||||
optionGroup.groups.some(
|
||||
({ option_key: groupKey }) =>
|
||||
groupKey === option_key && !question.hideOptionsSet.has(groupKey)
|
||||
groupKey === optionKey && !question.hideOptionsSet.has(groupKey)
|
||||
)
|
||||
)
|
||||
.map(({ option_key }) => option_key)
|
||||
.map(({ option_key: optionKey }) => optionKey)
|
||||
);
|
||||
if (options.length >= min) {
|
||||
isError = true;
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsInTitleGroup(min, title);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsInTitleGroup(
|
||||
min,
|
||||
title
|
||||
);
|
||||
}
|
||||
}
|
||||
return isError;
|
||||
@@ -700,10 +713,18 @@ async function answer(callback, callbackBeforePage) {
|
||||
}
|
||||
} else if (answer && questionType === 10) {
|
||||
// 矩阵多选题,列分组时,校验选项数量
|
||||
const cellGroups = (config?.cell_option_groups?.option_group || []).filter((i) => i.groups?.length);
|
||||
const cellGroups = (config?.cell_option_groups?.option_group || []).filter(
|
||||
(i) => i.groups?.length
|
||||
);
|
||||
if (cellGroups.length) {
|
||||
const rows = question.list.reduce((p, c) => [...p, ...(c.type === 1 ? c.options || [] : [])], []);
|
||||
const cols = question.list.reduce((p, c) => [...p, ...(c.type === 2 ? c.options || [] : [])], []);
|
||||
const rows = question.list.reduce(
|
||||
(p, c) => [...p, ...(c.type === 1 ? c.options || [] : [])],
|
||||
[]
|
||||
);
|
||||
const cols = question.list.reduce(
|
||||
(p, c) => [...p, ...(c.type === 2 ? c.options || [] : [])],
|
||||
[]
|
||||
);
|
||||
const freeCols = cols.filter(
|
||||
(col) => !cellGroups.some((g) => g.groups.find((c) => c.option_key === col.option_key))
|
||||
);
|
||||
@@ -715,7 +736,9 @@ async function answer(callback, callbackBeforePage) {
|
||||
});
|
||||
});
|
||||
});
|
||||
arr.forEach((a, idx) => a.push(freeCols.map((col) => `${rows[idx].option_key}_${col.option_key}`)));
|
||||
arr.forEach((a, idx) =>
|
||||
a.push(freeCols.map((col) => `${rows[idx].option_key}_${col.option_key}`))
|
||||
);
|
||||
const answered = Object.keys(answer);
|
||||
|
||||
cellGroups.forEach((group, idx) => {
|
||||
@@ -754,13 +777,17 @@ async function answer(callback, callbackBeforePage) {
|
||||
}
|
||||
return p;
|
||||
},
|
||||
question.list.filter((i) => i.type === 1).flatMap((i) => i.options.map((i) => 0))
|
||||
question.list.filter((i) => i.type === 1).flatMap((i) => i.options.map(() => 0))
|
||||
);
|
||||
if (minSelect && minSelect > Math.max(...perLineSelectedCount)) {
|
||||
if (question.config.is_change_row_cell) {
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerColumn(config.min_select || 1);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerColumn(
|
||||
config.min_select || 1
|
||||
);
|
||||
} else {
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerLine(config.min_select || 1);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerLine(
|
||||
config.min_select || 1
|
||||
);
|
||||
}
|
||||
isError = true;
|
||||
}
|
||||
@@ -798,44 +825,48 @@ async function answer(callback, callbackBeforePage) {
|
||||
question.error = '';
|
||||
// 填空题
|
||||
const { value } = answer;
|
||||
let newValue = value.replace(/\n|\r|\r\n/g, '');
|
||||
const newValue = value.replace(/\n|\r|\r\n/g, '');
|
||||
switch (config.text_type) {
|
||||
case 3: // 字母
|
||||
isError = config.include_mark == 1
|
||||
? !/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]]+$/.test(
|
||||
newValue
|
||||
) || !newValue.length
|
||||
case 3: // 字母
|
||||
isError
|
||||
= config.include_mark === 1
|
||||
? !/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
|
||||
newValue
|
||||
) || !newValue.length
|
||||
: !/^[a-zA-Z]+$/.test(newValue) || !newValue.length;
|
||||
question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : '';
|
||||
break;
|
||||
case 4: // 中文
|
||||
isError = 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]|[·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]])+$/.test(
|
||||
newValue
|
||||
) || !newValue.length
|
||||
question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : '';
|
||||
break;
|
||||
case 4: // 中文
|
||||
isError
|
||||
= 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]|[·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test(
|
||||
newValue
|
||||
) || !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(
|
||||
newValue
|
||||
) || !newValue.length;
|
||||
question.error = isError ? translatedText.value.PleaseEnterChineseWords : '';
|
||||
break;
|
||||
case 5: // 邮箱
|
||||
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(
|
||||
newValue
|
||||
) || !newValue.length;
|
||||
question.error = isError ? translatedText.value.PleaseEnterChineseWords : '';
|
||||
break;
|
||||
case 5: // 邮箱
|
||||
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(
|
||||
value
|
||||
);
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
|
||||
break;
|
||||
case 6: // 手机号
|
||||
isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value);
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : '';
|
||||
break;
|
||||
case 7: // 身份证号
|
||||
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(
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
|
||||
break;
|
||||
case 6: // 手机号
|
||||
isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value);
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : '';
|
||||
break;
|
||||
case 7: // 身份证号
|
||||
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(
|
||||
value
|
||||
);
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!isError && value.length < config.min && ![1, 2].includes(config.text_type)) {
|
||||
isError = true;
|
||||
@@ -847,42 +878,49 @@ async function answer(callback, callbackBeforePage) {
|
||||
Object.keys(answer).forEach((key) => {
|
||||
const value = answer[key];
|
||||
switch (config.text_type) {
|
||||
case 3: // 字母
|
||||
if (
|
||||
!/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]]+$/.test(
|
||||
value
|
||||
)
|
||||
case 3: // 字母
|
||||
if (
|
||||
!/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
value
|
||||
)
|
||||
question.error = translatedText.value.PleaseEnterACorrectEmail;
|
||||
break;
|
||||
case 6: // 手机号
|
||||
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(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(value)
|
||||
) {
|
||||
question.error = translatedText.value.PleaseEnterACorrectEmail;
|
||||
}
|
||||
break;
|
||||
case 6: // 手机号
|
||||
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(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(
|
||||
value
|
||||
)
|
||||
question.error = translatedText.value.PleaseEnterACorrectID;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
) {
|
||||
question.error = translatedText.value.PleaseEnterACorrectID;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!question.error && value.length < config.min && ![1, 2].includes(config.text_type)) {
|
||||
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
|
||||
@@ -937,89 +975,93 @@ async function answer(callback, callbackBeforePage) {
|
||||
});
|
||||
});
|
||||
}
|
||||
// 质量控制(选择题)
|
||||
const allPages = pages.value.flatMap((currentPages) => currentPages);
|
||||
const allQuestions = allPages.map((questionIndex) => {
|
||||
return questionsData.value.questions.find((question) => question.question_index === questionIndex);
|
||||
});
|
||||
const repeat = questionsData.value.survey.repeat_list?.find((repeat) =>
|
||||
repeat.question_indexes.find(({ first_index, last_index }) => {
|
||||
const firstIndex = allPages.findIndex((questionIndex) => questionIndex === first_index);
|
||||
const lastIndex = allPages.findIndex((questionIndex) => questionIndex === last_index);
|
||||
const currentQuestions = allQuestions
|
||||
.slice(firstIndex, lastIndex + 1)
|
||||
.filter((currentQuestions) => currentQuestions.question_type === repeat.question_type);
|
||||
const answerIndexes = currentQuestions.map((question) => question.answerIndex);
|
||||
return hasNConsecutiveNumbers(
|
||||
answerIndexes,
|
||||
repeat.allow_repeat_num + 1,
|
||||
(warnStart, warnEnd) => {
|
||||
currentQuestions.forEach((question, index) => {
|
||||
if (index >= warnStart && index < warnEnd) {
|
||||
if (repeat.repeat_type) {
|
||||
question.warning = translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
|
||||
repeat.allow_repeat_num,
|
||||
repeat.repeat_type
|
||||
);
|
||||
} else {
|
||||
question.error = translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
|
||||
repeat.allow_repeat_num,
|
||||
repeat.repeat_type
|
||||
);
|
||||
}
|
||||
} else {
|
||||
question.warning = '';
|
||||
question.error = '';
|
||||
}
|
||||
});
|
||||
},
|
||||
() => {
|
||||
currentQuestions.forEach((question) => {
|
||||
question.warning = '';
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
);
|
||||
if (repeat) {
|
||||
await new Promise((resolve) => {
|
||||
Modal[repeat.repeat_type ? 'confirm' : 'info']({
|
||||
class: 'custom-modal custom-modal-title-notice',
|
||||
title: translatedText.value.PleaseAnswerCarefully,
|
||||
content: repeat.alert_text,
|
||||
cancelText: translatedText.value.ContinueAnswer,
|
||||
okText: translatedText.value.ReviseAnswer,
|
||||
onCancel: () => {
|
||||
questions.value.forEach((question) => (question.answerIndex = ''));
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
// 判断是作答还是预览
|
||||
if (!props.isAnswer) {
|
||||
loading.value = true;
|
||||
try {
|
||||
// 模拟接口
|
||||
const data = answerMock(questionsData.value, page.value);
|
||||
console.log('模拟作答数据', data);
|
||||
// 更新答案
|
||||
updateAnswer(data.answer_info_autofill);
|
||||
// 更新分页数组
|
||||
questionsData.value.answer.pages = data.pages;
|
||||
// 选项隐藏
|
||||
hideOptions(data.hide_options);
|
||||
// 更新action
|
||||
questionsData.value.action = data.action;
|
||||
if ([20004, 20011, 20016].includes(data.action.code)) {
|
||||
return (page.value = pages.value.length + 1);
|
||||
}
|
||||
callback(data.jump_to);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
return (loading.value = false);
|
||||
}
|
||||
// // 质量控制(选择题)
|
||||
// const allPages = pages.value.flatMap((currentPages) => currentPages);
|
||||
// const allQuestions = allPages.map((questionIndex) => {
|
||||
// return questionsData.value.questions.find(
|
||||
// (question) => question.question_index === questionIndex
|
||||
// );
|
||||
// });
|
||||
// const repeat = questionsData.value.survey.repeat_list?.find((repeat) =>
|
||||
// repeat.question_indexes.find(({ first_index: firstIndex, last_index: lastIndex }) => {
|
||||
// const firstIndex = allPages.findIndex((questionIndex) => questionIndex === firstIndex);
|
||||
// const lastIndex = allPages.findIndex((questionIndex) => questionIndex === lastIndex);
|
||||
// const currentQuestions = allQuestions
|
||||
// .slice(firstIndex, lastIndex + 1)
|
||||
// .filter((currentQuestions) => currentQuestions.question_type === repeat.question_type);
|
||||
// const answerIndexes = currentQuestions.map((question) => question.answerIndex);
|
||||
// return hasNConsecutiveNumbers(
|
||||
// answerIndexes,
|
||||
// repeat.allow_repeat_num + 1,
|
||||
// (warnStart, warnEnd) => {
|
||||
// currentQuestions.forEach((question, index) => {
|
||||
// if (index >= warnStart && index < warnEnd) {
|
||||
// if (repeat.repeat_type) {
|
||||
// question.warning
|
||||
// = translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
|
||||
// repeat.allow_repeat_num,
|
||||
// repeat.repeat_type
|
||||
// );
|
||||
// } else {
|
||||
// question.error
|
||||
// = translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
|
||||
// repeat.allow_repeat_num,
|
||||
// repeat.repeat_type
|
||||
// );
|
||||
// }
|
||||
// } else {
|
||||
// question.warning = '';
|
||||
// question.error = '';
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
// () => {
|
||||
// currentQuestions.forEach((question) => {
|
||||
// question.warning = '';
|
||||
// });
|
||||
// }
|
||||
// );
|
||||
// })
|
||||
// );
|
||||
// if (repeat) {
|
||||
// await new Promise((resolve) => {
|
||||
// Modal[repeat.repeat_type ? 'confirm' : 'info']({
|
||||
// class: 'custom-modal custom-modal-title-notice',
|
||||
// title: translatedText.value.PleaseAnswerCarefully,
|
||||
// content: repeat.alert_text,
|
||||
// cancelText: translatedText.value.ContinueAnswer,
|
||||
// okText: translatedText.value.ReviseAnswer,
|
||||
// onCancel: () => {
|
||||
// questions.value.forEach((question) => (question.answerIndex = ''));
|
||||
// resolve();
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// // 判断是作答还是预览
|
||||
// if (!props.isAnswer) {
|
||||
// loading.value = true;
|
||||
// try {
|
||||
// // 模拟接口
|
||||
// const data = answerMock(questionsData.value, page.value);
|
||||
// console.log('模拟作答数据', data);
|
||||
// // 更新答案
|
||||
// updateAnswer(data.answer_info_autofill);
|
||||
// // 更新分页数组
|
||||
// questionsData.value.answer.pages = data.pages;
|
||||
// // 选项隐藏
|
||||
// hideOptions(data.hide_options);
|
||||
// // 更新action
|
||||
// questionsData.value.action = data.action;
|
||||
// if ([20004, 20011, 20016].includes(data.action.code)) {
|
||||
// return (page.value = pages.value.length + 1);
|
||||
// }
|
||||
// callback(data.jump_to);
|
||||
// } catch (error) {
|
||||
// console.log(error);
|
||||
// }
|
||||
// return (loading.value = false);
|
||||
// }
|
||||
// 表单验证通过,开始答题
|
||||
const cycle = [];
|
||||
const questionsAnswer = [];
|
||||
@@ -1110,7 +1152,7 @@ async function answer(callback, callbackBeforePage) {
|
||||
loading.value = false;
|
||||
} else {
|
||||
console.log(errors);
|
||||
const { error, title, question_index } = errors[0];
|
||||
const { error, title, question_index: questionIndex } = errors[0];
|
||||
const lines = (error || '')
|
||||
.split('\n')
|
||||
.filter((i) => !!i)
|
||||
@@ -1118,7 +1160,7 @@ async function answer(callback, callbackBeforePage) {
|
||||
msg.error(lines.join('\n'));
|
||||
|
||||
// 锚点
|
||||
const anchor = document.querySelector(`#questionIndex${question_index}`);
|
||||
const anchor = document.querySelector(`#questionIndex${questionIndex}`);
|
||||
console.log(anchor, scrollbar.value);
|
||||
scrollbar.value.scrollTo(0, anchor.offsetTop - (props.isMobile ? 20 : 40));
|
||||
}
|
||||
@@ -1179,118 +1221,121 @@ function jumpImmediately() {
|
||||
}
|
||||
}
|
||||
|
||||
// 关联引用
|
||||
function onRelation({ options, value, list }, { question_type, question_index, related, answer }) {
|
||||
// 关联
|
||||
related.forEach((relationItem) => {
|
||||
let relationOptions = [];
|
||||
if (question_type === 9 || question_type === 10) {
|
||||
// 矩阵选择
|
||||
list.forEach((item) => {
|
||||
if (item.type === relationItem.cite_type) {
|
||||
relationOptions = [...relationOptions, ...item.options];
|
||||
}
|
||||
if (relationItem.relation_type === 1) {
|
||||
relationOptions = relationOptions.filter((option) =>
|
||||
question_type === 9 ? option.value : option.value?.length
|
||||
);
|
||||
} else if (relationItem.relation_type === 2) {
|
||||
relationOptions = relationOptions.filter((option) =>
|
||||
question_type === 9 ? !option.value : !option.value?.length
|
||||
);
|
||||
}
|
||||
});
|
||||
} else if (question_type === 11) {
|
||||
// 矩阵打分
|
||||
list.forEach((item) => {
|
||||
if (item.type === relationItem.cite_type) {
|
||||
relationOptions = [...relationOptions, ...item.options];
|
||||
}
|
||||
});
|
||||
} else if (question_type === 25 || question_type === 26) {
|
||||
// 热区题
|
||||
relationOptions = options.filter((option) => {
|
||||
if (relationItem.relation_type === 1) {
|
||||
return option.status === 1;
|
||||
} else if (relationItem.relation_type === 2) {
|
||||
return option.status === 2;
|
||||
} else if (relationItem.relation_type === 3) {
|
||||
return !option.status;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
} else if (question_type === 105) {
|
||||
// MXD
|
||||
options.forEach((currentOptions) => {
|
||||
currentOptions.forEach((option) => {
|
||||
const index = relationOptions.findIndex(
|
||||
(relationOption) => relationOption.option_key === option.option_key
|
||||
);
|
||||
if (index === -1) {
|
||||
// 全部项
|
||||
if (relationItem.relation_type === 0) {
|
||||
return relationOptions.push(option);
|
||||
}
|
||||
// 高相关
|
||||
if (relationItem.relation_type === 3) {
|
||||
return option.value === 'b' && relationOptions.push(option);
|
||||
}
|
||||
// 不相关
|
||||
if (relationItem.relation_type === 4) {
|
||||
return option.value === 'w' && relationOptions.push(option);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} else if (relationItem.relation_type === 0) {
|
||||
// 全部选项
|
||||
relationOptions = options;
|
||||
} else {
|
||||
// 过滤选中/未选中选项
|
||||
relationOptions = options.filter((option) => {
|
||||
if (question_type === 1) {
|
||||
// 单选
|
||||
if (relationItem.relation_type === 1) return value === option.option_key;
|
||||
return value !== option.option_key;
|
||||
} else if (question_type === 2) {
|
||||
// 多选
|
||||
if (relationItem.relation_type === 1) return value.includes(option.option_key);
|
||||
return !value.includes(option.option_key);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
// 找到关联题
|
||||
const question = questionsData.value.questions.find(
|
||||
(question) => question.question_index === relationItem.relation_question_index
|
||||
);
|
||||
// 深拷贝关联选项
|
||||
const copyRelationOptions = JSON.parse(JSON.stringify(relationOptions));
|
||||
// 更新关联选项key
|
||||
copyRelationOptions.forEach((option) => {
|
||||
if (option.option_key[0] !== 'Q') {
|
||||
let letter = 'A';
|
||||
// 矩阵题行、列
|
||||
if (question_type >= 9 && question_type <= 11) {
|
||||
letter = relationItem.cite_type === 1 ? 'R' : 'C';
|
||||
}
|
||||
option.option_key = `Q${question_index}${letter}${option.option_key}`;
|
||||
}
|
||||
// 其他项特殊处理
|
||||
if (option.is_other && option.value) {
|
||||
option.is_other = 0;
|
||||
option.option = option.value;
|
||||
}
|
||||
delete option.value;
|
||||
delete option.status;
|
||||
});
|
||||
// 更新关联题列表
|
||||
const relatedList = question.list.find(
|
||||
(relatedListItem) => relatedListItem.relation_question_index === question_index
|
||||
);
|
||||
relatedList.options = answer ? copyRelationOptions : [];
|
||||
});
|
||||
}
|
||||
// // 关联引用
|
||||
// function onRelation(
|
||||
// { options, value, list },
|
||||
// { question_type: questionType, question_index, related, answer }
|
||||
// ) {
|
||||
// // 关联
|
||||
// related.forEach((relationItem) => {
|
||||
// let relationOptions = [];
|
||||
// if (questionType === 9 || questionType === 10) {
|
||||
// // 矩阵选择
|
||||
// list.forEach((item) => {
|
||||
// if (item.type === relationItem.cite_type) {
|
||||
// relationOptions = [...relationOptions, ...item.options];
|
||||
// }
|
||||
// if (relationItem.relation_type === 1) {
|
||||
// relationOptions = relationOptions.filter((option) =>
|
||||
// questionType === 9 ? option.value : option.value?.length
|
||||
// );
|
||||
// } else if (relationItem.relation_type === 2) {
|
||||
// relationOptions = relationOptions.filter((option) =>
|
||||
// questionType === 9 ? !option.value : !option.value?.length
|
||||
// );
|
||||
// }
|
||||
// });
|
||||
// } else if (questionType === 11) {
|
||||
// // 矩阵打分
|
||||
// list.forEach((item) => {
|
||||
// if (item.type === relationItem.cite_type) {
|
||||
// relationOptions = [...relationOptions, ...item.options];
|
||||
// }
|
||||
// });
|
||||
// } else if (questionType === 25 || questionType === 26) {
|
||||
// // 热区题
|
||||
// relationOptions = options.filter((option) => {
|
||||
// if (relationItem.relation_type === 1) {
|
||||
// return option.status === 1;
|
||||
// } else if (relationItem.relation_type === 2) {
|
||||
// return option.status === 2;
|
||||
// } else if (relationItem.relation_type === 3) {
|
||||
// return !option.status;
|
||||
// }
|
||||
// return true;
|
||||
// });
|
||||
// } else if (questionType === 105) {
|
||||
// // MXD
|
||||
// options.forEach((currentOptions) => {
|
||||
// currentOptions.forEach((option) => {
|
||||
// const index = relationOptions.findIndex(
|
||||
// (relationOption) => relationOption.option_key === option.option_key
|
||||
// );
|
||||
// if (index === -1) {
|
||||
// // 全部项
|
||||
// if (relationItem.relation_type === 0) {
|
||||
// return relationOptions.push(option);
|
||||
// }
|
||||
// // 高相关
|
||||
// if (relationItem.relation_type === 3) {
|
||||
// return option.value === 'b' && relationOptions.push(option);
|
||||
// }
|
||||
// // 不相关
|
||||
// if (relationItem.relation_type === 4) {
|
||||
// return option.value === 'w' && relationOptions.push(option);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// } else if (relationItem.relation_type === 0) {
|
||||
// // 全部选项
|
||||
// relationOptions = options;
|
||||
// } else {
|
||||
// // 过滤选中/未选中选项
|
||||
// relationOptions = options.filter((option) => {
|
||||
// if (questionType === 1) {
|
||||
// // 单选
|
||||
// if (relationItem.relation_type === 1) return value === option.option_key;
|
||||
// return value !== option.option_key;
|
||||
// } else if (questionType === 2) {
|
||||
// // 多选
|
||||
// if (relationItem.relation_type === 1) return value.includes(option.option_key);
|
||||
// return !value.includes(option.option_key);
|
||||
// }
|
||||
// return true;
|
||||
// });
|
||||
// }
|
||||
// // 找到关联题
|
||||
// const question = questionsData.value.questions.find(
|
||||
// (question) => question.question_index === relationItem.relation_question_index
|
||||
// );
|
||||
// // 深拷贝关联选项
|
||||
// const copyRelationOptions = JSON.parse(JSON.stringify(relationOptions));
|
||||
// // 更新关联选项key
|
||||
// copyRelationOptions.forEach((option) => {
|
||||
// if (option.option_key[0] !== 'Q') {
|
||||
// let letter = 'A';
|
||||
// // 矩阵题行、列
|
||||
// if (questionType >= 9 && questionType <= 11) {
|
||||
// letter = relationItem.cite_type === 1 ? 'R' : 'C';
|
||||
// }
|
||||
// option.option_key = `Q${question_index}${letter}${option.option_key}`;
|
||||
// }
|
||||
// // 其他项特殊处理
|
||||
// if (option.is_other && option.value) {
|
||||
// option.is_other = 0;
|
||||
// option.option = option.value;
|
||||
// }
|
||||
// delete option.value;
|
||||
// delete option.status;
|
||||
// });
|
||||
// // 更新关联题列表
|
||||
// const relatedList = question.list.find(
|
||||
// (relatedListItem) => relatedListItem.relation_question_index === question_index
|
||||
// );
|
||||
// relatedList.options = answer ? copyRelationOptions : [];
|
||||
// });
|
||||
// }
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.main {
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
<template>
|
||||
<slot></slot>
|
||||
<slot></slot>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BrowsingRecordApi } from '../js/api';
|
||||
|
||||
|
||||
const has3dPages = ['/answer'];
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
},
|
||||
components: {},
|
||||
props: {
|
||||
isStemMiddle: {
|
||||
type: Boolean,
|
||||
@@ -51,56 +49,6 @@ export default defineComponent({
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
canUse3D() {
|
||||
return this.config.is_three_dimensions && has3dPages.includes(this.$route.path);
|
||||
},
|
||||
surveyId() {
|
||||
return this.config.scene;
|
||||
},
|
||||
// scene() {
|
||||
// return this.config.scene_information;
|
||||
// },
|
||||
shelves() {
|
||||
if (!this.scene) return [];
|
||||
return this.scene.shelves || [];
|
||||
},
|
||||
shelf() {
|
||||
if (!this.config.shelf) return this.shelves[0];
|
||||
return this.shelves.find((x) => x.planetid == this.config.shelf);
|
||||
},
|
||||
wares() {
|
||||
if (!this.shelf) return [];
|
||||
return this.shelf.wares;
|
||||
},
|
||||
ware() {
|
||||
return this.wares.find((x) => x.planetid == this.config.ware);
|
||||
},
|
||||
options() {
|
||||
var options = [];
|
||||
try {
|
||||
this.question.list.forEach((item) => {
|
||||
item.options.forEach((option) => {
|
||||
// question_index为0代表当前题型,为了支持复制题时引用的question_index错误的问题
|
||||
var question_index = item.relation_question_index || 0;
|
||||
options.push({
|
||||
...option,
|
||||
question_index
|
||||
});
|
||||
});
|
||||
});
|
||||
if (this.question.hideOptions) {
|
||||
options = options.filter((option) => !this.question.hideOptions.includes(option.option_key));
|
||||
}
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
return options;
|
||||
},
|
||||
defaultWare() {
|
||||
return this.ware;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scene: null,
|
||||
@@ -140,6 +88,58 @@ export default defineComponent({
|
||||
showTimeTimeoutId: 0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
canUse3D() {
|
||||
return this.config.is_three_dimensions && has3dPages.includes(this.$route.path);
|
||||
},
|
||||
surveyId() {
|
||||
return this.config.scene;
|
||||
},
|
||||
// scene() {
|
||||
// return this.config.scene_information;
|
||||
// },
|
||||
shelves() {
|
||||
if (!this.scene) return [];
|
||||
return this.scene.shelves || [];
|
||||
},
|
||||
shelf() {
|
||||
if (!this.config.shelf) return this.shelves[0];
|
||||
return this.shelves.find((x) => x.planetid === this.config.shelf);
|
||||
},
|
||||
wares() {
|
||||
if (!this.shelf) return [];
|
||||
return this.shelf.wares;
|
||||
},
|
||||
ware() {
|
||||
return this.wares.find((x) => x.planetid === this.config.ware);
|
||||
},
|
||||
options() {
|
||||
let options = [];
|
||||
try {
|
||||
this.question.list.forEach((item) => {
|
||||
item.options.forEach((option) => {
|
||||
// question_index为0代表当前题型,为了支持复制题时引用的question_index错误的问题
|
||||
const questionIndex = item.relation_question_index || 0;
|
||||
options.push({
|
||||
...option,
|
||||
question_index: questionIndex
|
||||
});
|
||||
});
|
||||
});
|
||||
if (this.question.hideOptions) {
|
||||
options = options.filter(
|
||||
(option) => !this.question.hideOptions.includes(option.option_key)
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
return options;
|
||||
},
|
||||
defaultWare() {
|
||||
return this.ware;
|
||||
}
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.pager.clear();
|
||||
if (this.showTimeTimeoutId) clearTimeout(this.showTimeTimeoutId);
|
||||
@@ -165,7 +165,7 @@ export default defineComponent({
|
||||
|
||||
// 解决缓存问题,答卷时加载场景信息
|
||||
if (!this.scene) {
|
||||
var res = await BrowsingRecordApi.getSurveysScene({
|
||||
const res = await BrowsingRecordApi.getSurveysScene({
|
||||
sn: this.$route.query.sn,
|
||||
question_index: this.question.question_index
|
||||
});
|
||||
@@ -218,7 +218,7 @@ export default defineComponent({
|
||||
},
|
||||
onLoadingCompletion() {
|
||||
this.shopData.shelves.forEach((shelf) => {
|
||||
var wares = shelf.wares;
|
||||
let wares = shelf.wares;
|
||||
|
||||
// 选项随机
|
||||
if (this.options && this.options.length && this.config.is_binding_goods) {
|
||||
@@ -226,13 +226,15 @@ export default defineComponent({
|
||||
.filter((option) => !option.is_other)
|
||||
.map((option) => {
|
||||
return this.wares.find(
|
||||
(ware) => ware.question_index == option.question_index && ware.option_index == option.option_index
|
||||
(ware) =>
|
||||
ware.question_index === option.question_index
|
||||
&& ware.option_index === option.option_index
|
||||
);
|
||||
});
|
||||
wares = wares.filter((x) => x);
|
||||
}
|
||||
|
||||
if (shelf.layoutType == 'multiCols') {
|
||||
if (shelf.layoutType === 'multiCols') {
|
||||
shelf.cells = shelf.cells.map((cell, index) => {
|
||||
return {
|
||||
...cell,
|
||||
@@ -271,19 +273,19 @@ export default defineComponent({
|
||||
this.sceneAction = {
|
||||
action: 'hold_to_cart'
|
||||
};
|
||||
var hold = this.hold;
|
||||
const hold = this.hold;
|
||||
this.hold = null;
|
||||
|
||||
var ware = this.wares.find((ware) => ware.planetid == hold.data.surveyWare.id);
|
||||
const ware = this.wares.find((ware) => ware.planetid === hold.data.surveyWare.id);
|
||||
if (!ware) return;
|
||||
|
||||
var option = null;
|
||||
let option = null;
|
||||
this.question.list.forEach((qgroup) => {
|
||||
// 获取question_index,考虑到关联选项
|
||||
var question_index = qgroup.relation_question_index || 0;
|
||||
if (question_index != ware.question_index) return;
|
||||
const questionIndex = qgroup.relation_question_index || 0;
|
||||
if (questionIndex !== ware.question_index) return;
|
||||
qgroup.options.forEach((qoption) => {
|
||||
if (qoption.option_index != ware.option_index) return;
|
||||
if (qoption.option_index !== ware.option_index) return;
|
||||
option = qoption;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
:shopData="shopData"
|
||||
:surveyId="surveyId"
|
||||
:hidden="true"
|
||||
@onLoadingCompletion="onLoadingCompletion"
|
||||
:page="page"
|
||||
:page_shelves="page_shelves"
|
||||
@on-loading-completion="onLoadingCompletion"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -52,7 +52,7 @@ export default {
|
||||
|
||||
// 3D资源预获取
|
||||
try {
|
||||
var target = arr.find((question) => question?.config?.is_three_dimensions);
|
||||
const target = arr.find((question) => question?.config?.is_three_dimensions);
|
||||
this.first3DQuestion = target;
|
||||
|
||||
if (!target) return;
|
||||
@@ -61,7 +61,7 @@ export default {
|
||||
|
||||
if (!this.sceneInformation) {
|
||||
// 解决缓存问题,答卷时加载场景信息
|
||||
var res = await BrowsingRecordApi.getSurveysScene({
|
||||
const res = await BrowsingRecordApi.getSurveysScene({
|
||||
sn: this.$route.query.sn,
|
||||
question_index: target.question_index
|
||||
});
|
||||
@@ -84,15 +84,15 @@ export default {
|
||||
async onLoadingCompletion() {
|
||||
// 3D资源预获取
|
||||
try {
|
||||
var target = this.first3DQuestion;
|
||||
const target = this.first3DQuestion;
|
||||
|
||||
if (!target) return;
|
||||
|
||||
var scene = this.sceneInformation;
|
||||
const scene = this.sceneInformation;
|
||||
if (!scene) return;
|
||||
|
||||
scene.shelves.forEach((shelf) => {
|
||||
var wares = shelf.wares;
|
||||
const wares = shelf.wares;
|
||||
shelf.cells = shelf.cells.map((cell, index) => {
|
||||
return {
|
||||
...cell,
|
||||
|
||||
@@ -21,7 +21,7 @@ const props = defineProps({
|
||||
fullText: { type: String, default: '' }
|
||||
});
|
||||
|
||||
const {questionsData : data } = storeToRefs(useQuestionStore())
|
||||
const { questionsData: data } = storeToRefs(useQuestionStore());
|
||||
const text = computed(() => {
|
||||
if (props.fullText) {
|
||||
return props.fullText.split('\n');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="pagination-mob">
|
||||
<div class="pagination-mob">
|
||||
<!-- mob端 -->
|
||||
<a-spin
|
||||
v-show="showPrevious && page > min && page < pages"
|
||||
@@ -8,8 +8,8 @@
|
||||
>
|
||||
<div
|
||||
class="pfe-button btn previous my-btn"
|
||||
@click="previous"
|
||||
:style="`color: ${buttonTextColor};background-color: ${buttonColor}`"
|
||||
@click="previous"
|
||||
>
|
||||
<i class="iconfont"></i>
|
||||
<span>{{ prevButtonText }}</span>
|
||||
@@ -19,16 +19,16 @@
|
||||
<div
|
||||
class="pfe-button btn next my-btn"
|
||||
:class="nextDisabled ? 'disabled' : ''"
|
||||
@click="next"
|
||||
:style="`color: ${buttonTextColor};background-color: ${buttonColor}`"
|
||||
@click="next"
|
||||
>
|
||||
<span>{{
|
||||
showStart && page === 0
|
||||
? startText
|
||||
: showSubmit && page + 1 === pages
|
||||
? submitText
|
||||
: nextText || nextButtonText
|
||||
}}</span>
|
||||
showStart && page === 0
|
||||
? startText
|
||||
: showSubmit && page + 1 === pages
|
||||
? submitText
|
||||
: nextText || nextButtonText
|
||||
}}</span>
|
||||
<i v-show="page + 1 !== pages" class="iconfont"></i>
|
||||
</div>
|
||||
</a-spin>
|
||||
@@ -37,16 +37,10 @@
|
||||
|
||||
<script>
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import {storeToRefs} from 'pinia';
|
||||
import PfeButton from './PfeButton.vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useQuestionStore } from '@/stores/Questions/useQuestionStore';
|
||||
|
||||
// 引入 Spin 组件
|
||||
import { Spin as ASpin } from 'ant-design-vue';
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
components: { PfeButton },
|
||||
props: {
|
||||
// 当前页数
|
||||
page: {
|
||||
@@ -123,10 +117,14 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const {questionsData} = storeToRefs(useQuestionStore())
|
||||
const { questionsData } = storeToRefs(useQuestionStore());
|
||||
|
||||
const prevButtonText = computed(() => questionsData.value?.survey?.style?.up_button_text || '上一页');
|
||||
const nextButtonText = computed(() => questionsData.value?.survey?.style?.next_button_text || '下一页');
|
||||
const prevButtonText = computed(
|
||||
() => questionsData.value?.survey?.style?.up_button_text || '上一页'
|
||||
);
|
||||
const nextButtonText = computed(
|
||||
() => questionsData.value?.survey?.style?.next_button_text || '下一页'
|
||||
);
|
||||
|
||||
// 上一页
|
||||
function previous() {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="remark-section">
|
||||
<div class="icon" v-if="isPreview">
|
||||
<div v-if="isPreview" class="icon">
|
||||
<i class="iconfont icon-pinglun" @click="openDrawer"></i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, computed } from 'vue';import { useRoute, useRouter } from 'vue-router';
|
||||
import {storeToRefs} from 'pinia';
|
||||
import { defineComponent, ref, computed } from 'vue'; import { useRoute, useRouter } from 'vue-router';
|
||||
import { storeToRefs } from 'pinia';
|
||||
// import { useStore } from 'vuex';
|
||||
// import {} from "@/stores/counter.js"
|
||||
|
||||
@@ -34,7 +34,7 @@ export default defineComponent({
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
setup() {
|
||||
const { visible } = storeToRefs(useCommonStore());
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
@@ -50,7 +50,7 @@ export default defineComponent({
|
||||
});
|
||||
return;
|
||||
}
|
||||
const title = props.title.trim();
|
||||
// const title = props.title.trim();
|
||||
|
||||
visible.value = true;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
:class="isMobile ? 'm-title' : ''"
|
||||
:style="`color: ${themeColor.stemColor}`"
|
||||
/>
|
||||
<Remark :title="label + '标题评论'" :type="1" v-if="!isAnswer" />
|
||||
<Remark v-if="!isAnswer" :title="label + '标题评论'" :type="1" />
|
||||
</div>
|
||||
<div v-if="showDesc" class="desc-part" :class="isMobile ? 'm-desc-part' : ''">
|
||||
<rich-text
|
||||
@@ -17,8 +17,8 @@
|
||||
:class="isMobile ? 'm-desc' : 'desc'"
|
||||
:style="`color: ${themeColor.stemColor}`"
|
||||
/>
|
||||
<div style="margin-top: 32px" v-if="desc">
|
||||
<Remark :title="label + '介绍语评论'" :type="2" v-if="!isAnswer" />
|
||||
<div v-if="desc" style="margin-top: 32px">
|
||||
<Remark v-if="!isAnswer" :title="label + '介绍语评论'" :type="2" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <AnswerViewerPrefetch :questions="questions" />-->
|
||||
@@ -30,12 +30,12 @@ import { defineComponent } from 'vue';
|
||||
import RichText from '@/components/RichText.vue';
|
||||
import Remark from '../../components/Remark/index.vue';
|
||||
|
||||
import AnswerViewerPrefetch from '../AnswerViewerPrefetch.vue';
|
||||
// import AnswerViewerPrefetch from '../AnswerViewerPrefetch.vue';
|
||||
import { useQuestionStore } from '@/stores/Questions/useQuestionStore';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
export default defineComponent({
|
||||
components: { RichText, Remark, AnswerViewerPrefetch },
|
||||
components: { RichText, Remark /* AnswerViewerPrefetch */ },
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
<div v-else-if="code === 20016" v-html="survey.quota_end_content" />
|
||||
</div>
|
||||
<div v-if="!isAnswer" class="comment">
|
||||
<!-- <Remark v-if="code === 20004" title="结束语提前结束评论" :type="6" />-->
|
||||
<!-- <Remark v-if="code === 20011" title="结束语成功完成评论" :type="5" />-->
|
||||
<!-- <Remark v-if="code === 20016" title="配额超限页评论" :type="8" />-->
|
||||
<!-- <Remark v-if="code === 20004" title="结束语提前结束评论" :type="6" />-->
|
||||
<!-- <Remark v-if="code === 20011" title="结束语成功完成评论" :type="5" />-->
|
||||
<!-- <Remark v-if="code === 20016" title="配额超限页评论" :type="8" />-->
|
||||
</div>
|
||||
<!-- 立即跳转动画 -->
|
||||
<div v-if="isEndUrl" class="animation-wrapper">
|
||||
@@ -28,7 +28,12 @@
|
||||
<LangTranslate v-else translate-key="QLast_IosRedirectingPrompt" />
|
||||
</div>
|
||||
<div class="m-bottom">
|
||||
<LangTranslate v-if="countTime > 0" translate-key="QLast_Stay" class="m-btn border-right" @click="stopJump" />
|
||||
<LangTranslate
|
||||
v-if="countTime > 0"
|
||||
translate-key="QLast_Stay"
|
||||
class="m-btn border-right"
|
||||
@click="stopJump"
|
||||
/>
|
||||
<LangTranslate translate-key="QLast_Redirect" class="m-btn" @click="jump" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -46,20 +51,26 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed, defineComponent, getCurrentInstance, ref, inject, onMounted } from 'vue';
|
||||
import { computed, defineComponent, getCurrentInstance, ref, onMounted } from 'vue';
|
||||
// import Remark from '@/views/Survey/views/components/Remark/index.vue';
|
||||
// 屏蔽动效库
|
||||
// import lottie from 'lottie-web';
|
||||
import redJson from '@/views/Survey/views/Preview/components/json/red.json';
|
||||
// import lottieJson from './json/lottie.json';
|
||||
import LangTranslate from '../LangTranslate.vue';
|
||||
import {storeToRefs} from 'pinia';
|
||||
import { useQuestionStore} from "@/stores/Questions/useQuestionStore"
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useQuestionStore } from '@/stores/Questions/useQuestionStore';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
// Remark,
|
||||
LangTranslate
|
||||
},
|
||||
props: {
|
||||
action: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
default: () => {
|
||||
/* 占位 */
|
||||
}
|
||||
},
|
||||
code: {
|
||||
type: Number,
|
||||
@@ -67,7 +78,9 @@ export default defineComponent({
|
||||
},
|
||||
survey: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
default: () => {
|
||||
/* 占位 */
|
||||
}
|
||||
},
|
||||
// 是否答题模式
|
||||
isAnswer: {
|
||||
@@ -76,14 +89,10 @@ export default defineComponent({
|
||||
},
|
||||
isTemplate: { type: Boolean, default: false }
|
||||
},
|
||||
components: {
|
||||
// Remark,
|
||||
LangTranslate
|
||||
},
|
||||
setup(props) {
|
||||
const { proxy } = getCurrentInstance();
|
||||
// const questionsData = inject('questionsData'); // 问卷数据
|
||||
const {questionsData} = storeToRefs(useQuestionStore());
|
||||
const { questionsData } = storeToRefs(useQuestionStore());
|
||||
console.log(11, questionsData, props.survey);
|
||||
let countTimer; // 跳转计时器
|
||||
const animation = ref(redJson); // 立即跳转动画
|
||||
@@ -93,7 +102,9 @@ export default defineComponent({
|
||||
const isEndUrl = computed(() => {
|
||||
const code = props.action ? props.action.code : props.code;
|
||||
return (
|
||||
(code === 20004 && props.survey.screening_end_url_select && props.survey.screening_end_url)
|
||||
(code === 20004
|
||||
&& props.survey.screening_end_url_select
|
||||
&& props.survey.screening_end_url)
|
||||
|| (code === 20011 && props.survey.success_end_url_select && props.survey.success_end_url)
|
||||
|| (code === 20016 && props.survey.quota_end_url_select && props.survey.quota_end_url)
|
||||
);
|
||||
@@ -102,26 +113,26 @@ export default defineComponent({
|
||||
// 跳转
|
||||
function toEndUrl() {
|
||||
switch (props.action.code) {
|
||||
case 20004: // 被甄别
|
||||
if (props.survey.screening_end_url_select && props.survey.screening_end_url) {
|
||||
const url = props.survey.screening_end_url;
|
||||
toUrl(url);
|
||||
}
|
||||
break;
|
||||
case 20011: // 成功
|
||||
if (props.survey.success_end_url_select && props.survey.success_end_url) {
|
||||
const url = props.survey.success_end_url;
|
||||
toUrl(url);
|
||||
}
|
||||
break;
|
||||
case 20016: // 配额超限
|
||||
if (props.survey.quota_end_url_select && props.survey.quota_end_url) {
|
||||
const url = props.survey.quota_end_url;
|
||||
toUrl(url);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 20004: // 被甄别
|
||||
if (props.survey.screening_end_url_select && props.survey.screening_end_url) {
|
||||
const url = props.survey.screening_end_url;
|
||||
toUrl(url);
|
||||
}
|
||||
break;
|
||||
case 20011: // 成功
|
||||
if (props.survey.success_end_url_select && props.survey.success_end_url) {
|
||||
const url = props.survey.success_end_url;
|
||||
toUrl(url);
|
||||
}
|
||||
break;
|
||||
case 20016: // 配额超限
|
||||
if (props.survey.quota_end_url_select && props.survey.quota_end_url) {
|
||||
const url = props.survey.quota_end_url;
|
||||
toUrl(url);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,6 +266,7 @@ export default defineComponent({
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
background-color: rgba(1, 21, 53, 0.7);
|
||||
|
||||
//filter: alpha(opacity=50);
|
||||
|
||||
.red-animation {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<template>
|
||||
<a-radio-group v-model:value="value" @change="changeValue" :disabled="disabled" v-if="customRadio">
|
||||
<a-radio-group
|
||||
v-if="customRadio" v-model:value="value" :disabled="disabled"
|
||||
@change="changeValue"
|
||||
>
|
||||
<div class="radio-group">
|
||||
<div class="group" v-for="(group, groupIndex) in optionGroups" :key="groupIndex">
|
||||
<div v-for="(group, groupIndex) in optionGroups" :key="groupIndex" class="group">
|
||||
<div
|
||||
v-if="group.title && !config.option_groups?.is_hide"
|
||||
v-show="showGroupTitle(group.options)"
|
||||
@@ -10,12 +13,14 @@
|
||||
{{ group.title }}
|
||||
</div>
|
||||
<div
|
||||
v-for="option in group.options"
|
||||
v-show="!hideOptions.includes(option.option_key)"
|
||||
:key="option.option_key"
|
||||
class="radio theme-hover-default"
|
||||
:class="group.title && !config.option_groups?.is_hide ? 'margin-left' : ''"
|
||||
v-for="option in group.options"
|
||||
:key="option.option_key"
|
||||
:style="isMobile ? 'width: 100%' : `width: calc(100% / ${config.each_number || 1} - 33px)`"
|
||||
v-show="!hideOptions.includes(option.option_key)"
|
||||
:style="
|
||||
isMobile ? 'width: 100%' : `width: calc(100% / ${config.each_number || 1} - 33px)`
|
||||
"
|
||||
@click="onChangeValue(option.option_key)"
|
||||
>
|
||||
<a-radio :value="option.option_key" @click.stop />
|
||||
@@ -25,30 +30,29 @@
|
||||
<a-input
|
||||
v-if="option.is_other"
|
||||
v-model:value="option.value"
|
||||
@change="changeInput($event, option.option_key)"
|
||||
:disabled="disabled"
|
||||
@change="changeInput($event, option.option_key)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-radio-group>
|
||||
<choice :element="question" v-else />
|
||||
<choice v-else :element="question" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Choice from '@/views/Design/components/Questions/Choice.vue';
|
||||
|
||||
const customRadio = true;
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import RichText from '@/components/RichText.vue';
|
||||
import { computed, defineComponent, ref, watch } from 'vue';
|
||||
import AnswerViewer from '@/views/Survey/views/Preview/AnswerViewer.vue';
|
||||
import { compareArrayByField, randomOptions } from '@/utils/utils.js';
|
||||
|
||||
const customRadio = true;
|
||||
|
||||
export default defineComponent({
|
||||
components: { RichText, AnswerViewer },
|
||||
components: { RichText /* AnswerViewer */ },
|
||||
props: {
|
||||
// 题干
|
||||
stem: {
|
||||
@@ -64,12 +68,14 @@ export default defineComponent({
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
/* 占位 */
|
||||
}
|
||||
},
|
||||
// 答案
|
||||
answer: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
/* 占位 */
|
||||
}
|
||||
},
|
||||
// 答案索引
|
||||
@@ -223,7 +229,7 @@ export default defineComponent({
|
||||
const index = optionGroups.value
|
||||
.flatMap((group) => group.options.map((option) => option))
|
||||
.findIndex((option) => option.option_key === value.value);
|
||||
context.emit('update:answerIndex', index + '');
|
||||
context.emit('update:answerIndex', `${index}`);
|
||||
} else if (props.answerIndex) {
|
||||
context.emit('update:answerIndex', '');
|
||||
}
|
||||
@@ -263,7 +269,10 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
// 清空值和答案
|
||||
if (value.value && options.value.findIndex((option) => option.option_key === value.value) === -1) {
|
||||
if (
|
||||
value.value
|
||||
&& options.value.findIndex((option) => option.option_key === value.value) === -1
|
||||
) {
|
||||
// 清空值
|
||||
value.value = '';
|
||||
// 清空答案
|
||||
@@ -279,7 +288,10 @@ export default defineComponent({
|
||||
watch(
|
||||
() => options.value,
|
||||
(val, oldVal) => {
|
||||
if (compareArrayByField(val, oldVal || [], 'option_key') && compareArrayByField(val, oldVal || [], 'option')) {
|
||||
if (
|
||||
compareArrayByField(val, oldVal || [], 'option_key')
|
||||
&& compareArrayByField(val, oldVal || [], 'option')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setOptionGroups();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="question">
|
||||
<!-- 高级题型不显示 -->
|
||||
<div class="question-inner-wrapper" v-if="questionType <= 100">
|
||||
<div v-if="questionType <= 100" class="question-inner-wrapper">
|
||||
<div class="title" :style="`color: ${themeColor.stemColor}`">
|
||||
<span v-if="showTitle" class="question-inner-span" v-html="title"></span>
|
||||
<!-- question.stem -->
|
||||
@@ -9,13 +9,13 @@
|
||||
<rich-text :nodes="`${newTitle}${tip}`" isPreview :isMobile="isMobile" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <Remark-->
|
||||
<!-- :title="title + '问题评论'"-->
|
||||
<!-- :type="3"-->
|
||||
<!-- :questionIndex="questionIndex"-->
|
||||
<!-- v-if="!isAnswer"-->
|
||||
<!-- style="margin-bottom: 22px"-->
|
||||
<!-- />-->
|
||||
<!-- <Remark-->
|
||||
<!-- :title="title + '问题评论'"-->
|
||||
<!-- :type="3"-->
|
||||
<!-- :questionIndex="questionIndex"-->
|
||||
<!-- v-if="!isAnswer"-->
|
||||
<!-- style="margin-bottom: 22px"-->
|
||||
<!-- />-->
|
||||
</div>
|
||||
<LangTranslate v-if="error && questionType <= 100" :full-text="error" class="error" />
|
||||
<LangTranslate v-if="warning" :full-text="warning" class="error warning" />
|
||||
@@ -33,7 +33,7 @@ import { useQuestionStore } from '@/stores/Questions/useQuestionStore';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
export default defineComponent({
|
||||
components: { RichText, /*Remark,*/ LangTranslate },
|
||||
components: { RichText, /* Remark, */ LangTranslate },
|
||||
props: {
|
||||
// 标题
|
||||
stem: {
|
||||
@@ -101,25 +101,25 @@ export default defineComponent({
|
||||
const answerBorder = answerColor === '#333333' ? '#d9d9d9' : answerColor; // 边框颜色
|
||||
const answerPlaceholder = toRgba(answerColor, 0.3); // placeholder颜色
|
||||
// 鼠标 hover 时的背景色,目前用于:单选、多选、图片单选、图片多选的选项
|
||||
const hoverBackgroundColor = themeColor.value?.buttonColor + '1E';
|
||||
const hoverBackgroundColor = `${themeColor.value?.buttonColor}1E`;
|
||||
|
||||
// 16进制转rgba
|
||||
function toRgba(color, opacity) {
|
||||
return (
|
||||
'rgba('
|
||||
+ parseInt(color.substring(1, 3), 16)
|
||||
+ ','
|
||||
+ parseInt(color.substring(3, 5), 16)
|
||||
+ ','
|
||||
+ parseInt(color.substring(5, 7), 16)
|
||||
+ ','
|
||||
+ opacity
|
||||
+ ')'
|
||||
`rgba(${
|
||||
parseInt(color.substring(1, 3), 16)
|
||||
},${
|
||||
parseInt(color.substring(3, 5), 16)
|
||||
},${
|
||||
parseInt(color.substring(5, 7), 16)
|
||||
},${
|
||||
opacity
|
||||
})`
|
||||
);
|
||||
}
|
||||
|
||||
const replaceStr = (str, firIndex, lastIndex, char) => {
|
||||
if (str.length == 0) {
|
||||
if (str.length === 0) {
|
||||
return '';
|
||||
}
|
||||
if (str.indexOf('<p>') < 0) {
|
||||
@@ -140,16 +140,16 @@ export default defineComponent({
|
||||
let replacement = ''; // 替换文本
|
||||
// 查找引用问题
|
||||
const question = props.questions.find((question) => {
|
||||
// 矩阵题
|
||||
if (question.question_type >= 8 && question.question_type <= 11) {
|
||||
return question.title === value.split('_R')[0].split('_C')[0];
|
||||
}
|
||||
// 排序题
|
||||
if (question.question_type === 16) {
|
||||
return question.title === value.split('_A')[0];
|
||||
}
|
||||
return question.title === value;
|
||||
})
|
||||
// 矩阵题
|
||||
if (question.question_type >= 8 && question.question_type <= 11) {
|
||||
return question.title === value.split('_R')[0].split('_C')[0];
|
||||
}
|
||||
// 排序题
|
||||
if (question.question_type === 16) {
|
||||
return question.title === value.split('_A')[0];
|
||||
}
|
||||
return question.title === value;
|
||||
})
|
||||
|| props.questions.find((question) => {
|
||||
// 矩阵题
|
||||
if (question.question_type >= 8 && question.question_type <= 11) {
|
||||
|
||||
@@ -14,7 +14,6 @@ class AnswerApi {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 获取问卷详情 */
|
||||
static getQuetionDetail(params) {
|
||||
return request({
|
||||
@@ -22,11 +21,10 @@ class AnswerApi {
|
||||
url: `/console/surveys/${params.id}/detail`,
|
||||
params: params.data,
|
||||
headers: {
|
||||
'answer-session-id': AnswerApi.getLocalStorageWithExpiration('answer-session-id') //store.state.answer.answerSessionId,
|
||||
'answer-session-id': AnswerApi.getLocalStorageWithExpiration('answer-session-id') // store.state.answer.answerSessionId,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 答题 */
|
||||
static answer(params) {
|
||||
return request({
|
||||
@@ -38,7 +36,6 @@ class AnswerApi {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 答题 */
|
||||
static surveyPrevious(params) {
|
||||
return request({
|
||||
@@ -50,7 +47,6 @@ class AnswerApi {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 获取验证码 */
|
||||
static getCode(params) {
|
||||
return request({
|
||||
@@ -58,11 +54,10 @@ class AnswerApi {
|
||||
url: `/system/sms_codes`,
|
||||
data: params.data,
|
||||
headers: {
|
||||
'answer-session-id': AnswerApi.getLocalStorageWithExpiration('answer-session-id') //store.state.answer.answerSessionId,
|
||||
'answer-session-id': AnswerApi.getLocalStorageWithExpiration('answer-session-id') // store.state.answer.answerSessionId,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* 问卷密码 */
|
||||
static password(params) {
|
||||
return request({
|
||||
@@ -70,23 +65,20 @@ class AnswerApi {
|
||||
url: `/answer/surveys/${params.id}/password`,
|
||||
data: params.data,
|
||||
headers: {
|
||||
'answer-session-id': AnswerApi.getLocalStorageWithExpiration('answer-session-id') //store.state.answer.answerSessionId,
|
||||
'answer-session-id': AnswerApi.getLocalStorageWithExpiration('answer-session-id') // store.state.answer.answerSessionId,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* word导出 */
|
||||
|
||||
static download(sn, params = '') {
|
||||
return request({
|
||||
method: 'get',
|
||||
url: `/console/survey_word_export/${sn}?${params}`,
|
||||
headers: {
|
||||
'answer-session-id': AnswerApi.getLocalStorageWithExpiration('answer-session-id') //store.state.answer.answerSessionId,
|
||||
'answer-session-id': AnswerApi.getLocalStorageWithExpiration('answer-session-id') // store.state.answer.answerSessionId,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取localStorage数据,并检查过期时间
|
||||
static getLocalStorageWithExpiration(key) {
|
||||
const item = JSON.parse(localStorage.getItem(key));
|
||||
@@ -113,7 +105,6 @@ class BrowsingRecordApi {
|
||||
data: params.data
|
||||
});
|
||||
}
|
||||
|
||||
/* 获取3D资源 */
|
||||
static getSurveysScene(params) {
|
||||
return request({
|
||||
@@ -123,4 +114,4 @@ class BrowsingRecordApi {
|
||||
}
|
||||
}
|
||||
|
||||
export { AnswerApi, BrowsingRecordApi };
|
||||
export { AnswerApi, BrowsingRecordApi };
|
||||
|
||||
@@ -9,7 +9,8 @@ export const language = {
|
||||
zh: (count) => `每行最少选${count}个。`
|
||||
},
|
||||
PleaseSelectAtLeastOneOptionsPerColumn: {
|
||||
en: (count) => `Please select at least ${count} answer option${count > 1 ? 's' : ''} per column.`,
|
||||
en: (count) =>
|
||||
`Please select at least ${count} answer option${count > 1 ? 's' : ''} per column.`,
|
||||
zh: (count) => `每列最少选${count}个。`
|
||||
},
|
||||
PleaseCategorizeAllOptions: {
|
||||
@@ -29,11 +30,13 @@ export const language = {
|
||||
zh: (count) => `最少选择${count}个。`
|
||||
},
|
||||
PleaseSelectAtLeastOneOptionsInTitleGroup: {
|
||||
en: (count, title) => `Please select at least ${count} answer option${count > 1 ? 's' : ''} in ${title} group.`,
|
||||
en: (count, title) =>
|
||||
`Please select at least ${count} answer option${count > 1 ? 's' : ''} in ${title} group.`,
|
||||
zh: (count, title) => `${title}最少选择${count}个。`
|
||||
},
|
||||
PleaseSelectAtMostOneOptionsInTitleGroup: {
|
||||
en: (count, title) => `Please select at most ${count} answer option${count > 1 ? 's' : ''} in ${title} group.`,
|
||||
en: (count, title) =>
|
||||
`Please select at most ${count} answer option${count > 1 ? 's' : ''} in ${title} group.`,
|
||||
zh: (count, title) => `${title}最多选择${count}个。`
|
||||
},
|
||||
PleaseSelectAtLeastOnePictures: {
|
||||
@@ -87,7 +90,7 @@ export const language = {
|
||||
zh: '去修改'
|
||||
},
|
||||
TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise: {
|
||||
en: (count, type) => `The answer is continuously repeated more than ${count} times, please revise.`,
|
||||
en: (count) => `The answer is continuously repeated more than ${count} times, please revise.`,
|
||||
zh: (count, type) => `答案连续重复超过${count}个,${type ? '建议' : '请'}修改。`
|
||||
},
|
||||
|
||||
@@ -154,10 +157,8 @@ export const language = {
|
||||
},
|
||||
|
||||
PleaseAnswerCarefullyOtherwiseRestart: {
|
||||
en:
|
||||
'Please be sure to read the questions carefully. Consecutive answers may invalidate the entire questionnaire. Your answer to each question is of great significance to us.',
|
||||
zh:
|
||||
'您在每一题的态度与观点均对我们有非常重要的意义,请您务必仔细阅读题目后回答,连续一致的答案可能会导致整个问卷的作废,请您重新作答。'
|
||||
en: 'Please be sure to read the questions carefully. Consecutive answers may invalidate the entire questionnaire. Your answer to each question is of great significance to us.',
|
||||
zh: '您在每一题的态度与观点均对我们有非常重要的意义,请您务必仔细阅读题目后回答,连续一致的答案可能会导致整个问卷的作废,请您重新作答。'
|
||||
},
|
||||
|
||||
IGotIt: {
|
||||
@@ -403,8 +404,7 @@ export const language = {
|
||||
zh: '密码需要包含字母/数字/符号/字母和数字/字母和符号/符号和数字/字母、数字和符号'
|
||||
},
|
||||
ThePasswordNeedsToIncludeUpperLowerLettersNumbersSymbolsOrCombination: {
|
||||
en:
|
||||
'The password needs to include uppercase letters, lowercase letters, numbers, symbols, or a combination of uppercase and lowercase letters, numbers and symbols.',
|
||||
en: 'The password needs to include uppercase letters, lowercase letters, numbers, symbols, or a combination of uppercase and lowercase letters, numbers and symbols.',
|
||||
zh: '密码需要包含大/小写字母/数字/符号/大/小写字母和数字/大/小写字母和符号/符号和数字/大/小写字母、数字和符号'
|
||||
},
|
||||
ThePasswordMustBeACombinationOfLettersAndNumbers: {
|
||||
@@ -502,19 +502,19 @@ export const language = {
|
||||
zh: (title) => `${title} 上传失败`
|
||||
},
|
||||
EquipmentNotice: {
|
||||
en: (title) =>
|
||||
en: () =>
|
||||
`Sorry, the number of submissions you have made under the current IP address has reached the limit. Thank you for participating.`,
|
||||
zh: (title) => `很抱歉,您使用当前设备填写问卷已达到限制次数,感谢参与`
|
||||
zh: () => `很抱歉,您使用当前设备填写问卷已达到限制次数,感谢参与`
|
||||
},
|
||||
SubmitIpNotice: {
|
||||
en: (title) =>
|
||||
en: () =>
|
||||
`Sorry, the number of submissions you have made under the current IP address has reached the limit. Thank you for participating.`,
|
||||
zh: (title) => `很抱歉,您在当前IP地址下填写问卷已达到限制次数,感谢参与`
|
||||
zh: () => `很抱歉,您在当前IP地址下填写问卷已达到限制次数,感谢参与`
|
||||
},
|
||||
PrivatizationWxWorkIdentityNotice: {
|
||||
en: (title) =>
|
||||
en: () =>
|
||||
`Sorry, the current environment does not allow you to answer this questionnaire.\nPlease click on the link or scan the code to answer through the privatized enterprise WeChat.`,
|
||||
zh: (title) => `很抱歉,当前环境无法作答该问卷\n请通过私有化企业微信点击链接或扫码作答`
|
||||
zh: () => `很抱歉,当前环境无法作答该问卷\n请通过私有化企业微信点击链接或扫码作答`
|
||||
},
|
||||
|
||||
// QLast 提示
|
||||
@@ -561,8 +561,8 @@ export function getLanguage(langArr = languageTypes) {
|
||||
Object.keys(language).forEach((key) => {
|
||||
result[key] = '';
|
||||
|
||||
let tempStr = [];
|
||||
let tempFunc = [];
|
||||
const tempStr = [];
|
||||
const tempFunc = [];
|
||||
|
||||
l.forEach((lang) => {
|
||||
const res = language[key][lang];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createVNode } from 'vue';
|
||||
import {ElMessage as message} from "element-plus"
|
||||
import { ElMessage as message } from 'element-plus';
|
||||
function getNode(text) {
|
||||
const lines = (text || '').split('\n').filter((i) => !!i);
|
||||
|
||||
|
||||
@@ -2,18 +2,16 @@ import getlogicStatus from './logical';
|
||||
|
||||
// 更新code
|
||||
function updateCode(action, logic, pages, page) {
|
||||
const { question_index, skip_question_index } = logic;
|
||||
const startIndex = pages.findIndex(
|
||||
(page) => page.findIndex((questionIndex) => questionIndex === question_index) !== -1
|
||||
);
|
||||
const { skip_question_index: skipQuestionIndex } = logic;
|
||||
const startIndex = pages.findIndex((page) => page.findIndex(() => true) !== -1);
|
||||
if (startIndex < page) {
|
||||
if (skip_question_index === -1) {
|
||||
if (skipQuestionIndex === -1) {
|
||||
action.code = 20011;
|
||||
action.msg = '成功结束页';
|
||||
} else if (skip_question_index === -2) {
|
||||
} else if (skipQuestionIndex === -2) {
|
||||
action.code = 20004;
|
||||
action.msg = '甄别结束页';
|
||||
} else if (skip_question_index === -3) {
|
||||
} else if (skipQuestionIndex === -3) {
|
||||
action.code = 20016;
|
||||
action.msg = '配额超限页';
|
||||
}
|
||||
@@ -21,19 +19,19 @@ function updateCode(action, logic, pages, page) {
|
||||
}
|
||||
// 更新分页pages(题后跳转逻辑)
|
||||
function updatePagesAfter(pages, logic, jumpTo, page) {
|
||||
const { question_index, skip_question_index } = logic;
|
||||
const startIndex = pages.findIndex(
|
||||
(page) => page.findIndex((questionIndex) => questionIndex === question_index) !== -1
|
||||
);
|
||||
const { question_index: questionIndex, skip_question_index: skipQuestionIndex } = logic;
|
||||
const startIndex = pages.findIndex((page) => page.findIndex(() => true) !== -1);
|
||||
const endIndex = pages.findIndex(
|
||||
(page) => page.findIndex((questionIndex) => questionIndex === skip_question_index) !== -1
|
||||
(page) => page.findIndex((questionIndex) => questionIndex === skipQuestionIndex) !== -1
|
||||
);
|
||||
if (endIndex !== -1) {
|
||||
const endQuestionIndex = pages[endIndex].findIndex((questionIndex) => questionIndex === skip_question_index);
|
||||
const endQuestionIndex = pages[endIndex].findIndex(
|
||||
(questionIndex) => questionIndex === skipQuestionIndex
|
||||
);
|
||||
pages[endIndex].splice(0, endQuestionIndex);
|
||||
// 跳转到某页
|
||||
if (startIndex > endIndex && startIndex < page) {
|
||||
jumpTo.question_index = question_index;
|
||||
jumpTo.question_index = questionIndex;
|
||||
return (jumpTo.question_page = endIndex + 1);
|
||||
}
|
||||
pages.splice(startIndex + 1, endIndex - startIndex - 1);
|
||||
@@ -49,7 +47,9 @@ function updatePagesBefore(pages, hideQuestionIndex) {
|
||||
if (pages[pagesIndex].length === 1) {
|
||||
pages.splice(pagesIndex, 1);
|
||||
} else {
|
||||
const pageIndex = pages[pagesIndex].findIndex((questionIndex) => questionIndex === hideQuestionIndex);
|
||||
const pageIndex = pages[pagesIndex].findIndex(
|
||||
(questionIndex) => questionIndex === hideQuestionIndex
|
||||
);
|
||||
pages[pagesIndex].splice(pageIndex, 1);
|
||||
}
|
||||
}
|
||||
@@ -64,11 +64,11 @@ function autoFill(answerAutoFill, logic) {
|
||||
}
|
||||
|
||||
// 选项隐藏逻辑
|
||||
function updateOptionHidden(hide_options, logic) {
|
||||
const { question_index, hide_option_index } = logic;
|
||||
hide_options.question_index = question_index;
|
||||
function updateOptionHidden(hideOptions, logic) {
|
||||
const { question_index: questionIndex, hide_option_index: hideOptionIndex } = logic;
|
||||
hideOptions.question_index = questionIndex;
|
||||
if (logic.logicStatus) {
|
||||
hide_options.option_key.push(...hide_option_index.map((opt) => opt.option_key));
|
||||
hideOptions.option_key.push(...hideOptionIndex.map((opt) => opt.option_key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,8 @@ export default function answerMock(questionsData, page) {
|
||||
} else if (logic.skip_type === 4) {
|
||||
// 只计算跳转后所在页面的隐藏逻辑,否则会出现只返回最后一道隐藏选项题目的情况,导致失效
|
||||
const toPage = page + 1;
|
||||
const hasHiddenLogicQuizPage = data.pages.findIndex((page) => page.includes(logic.question_index)) + 1;
|
||||
const hasHiddenLogicQuizPage
|
||||
= data.pages.findIndex((page) => page.includes(logic.question_index)) + 1;
|
||||
if (hasHiddenLogicQuizPage === toPage) {
|
||||
// 选项隐藏逻辑
|
||||
updateOptionHidden(data.hide_options, logic);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AnswerApi } from '../js/api';
|
||||
import { computed, getCurrentInstance, defineComponent, provide, ref, watch } from 'vue';
|
||||
import { computed, getCurrentInstance, defineComponent, provide, ref, watch } from 'vue';
|
||||
import answerMock from './mock';
|
||||
import { useRoute } from 'vue-router';
|
||||
import msg from './message';
|
||||
@@ -24,11 +24,11 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const questionStore = useQuestionStore()
|
||||
const questionStore = useQuestionStore();
|
||||
/**
|
||||
* styleInfo 主题样式
|
||||
*/
|
||||
const {questionsData, styleInfo, page, pages,l} = storeToRefs(questionStore)
|
||||
const { questionsData, styleInfo, page, pages } = storeToRefs(questionStore);
|
||||
const route = useRoute();
|
||||
// const questionsData = inject('questionsData'); // 问卷数据
|
||||
|
||||
@@ -38,7 +38,6 @@ export default defineComponent({
|
||||
const scrollbar = ref(null);
|
||||
let localPageInterval;
|
||||
|
||||
|
||||
watch(
|
||||
styleInfo,
|
||||
(style) => {
|
||||
@@ -67,10 +66,9 @@ export default defineComponent({
|
||||
});
|
||||
// 是否显示分页器
|
||||
const showPage = computed(() => {
|
||||
return [102, 104, 105, 201].includes(questions.value[0]?.question_type) ? false : true;
|
||||
return ![102, 104, 105, 201].includes(questions.value[0]?.question_type);
|
||||
});
|
||||
|
||||
|
||||
// 分页计时器
|
||||
watch(
|
||||
page,
|
||||
@@ -80,7 +78,8 @@ export default defineComponent({
|
||||
const lastQuestionIndex = questions.value.slice(-1)[0]?.question_index;
|
||||
console.log(questionsData.value);
|
||||
const localPage = questionsData.value?.survey?.local_pages.find(
|
||||
(localPage) => localPage.question_index === lastQuestionIndex && localPage.timer_config.is_short_time
|
||||
(localPage) =>
|
||||
localPage.question_index === lastQuestionIndex && localPage.timer_config.is_short_time
|
||||
);
|
||||
if (localPage) {
|
||||
localPageTimer.value = localPage.timer_config;
|
||||
@@ -107,7 +106,7 @@ export default defineComponent({
|
||||
let prevNum = arr[0];
|
||||
for (let i = 1; i < arr.length; i++) {
|
||||
if (prevNum && arr[i] === prevNum) {
|
||||
count++;
|
||||
count += 1;
|
||||
} else {
|
||||
count = 1;
|
||||
warnStart = i;
|
||||
@@ -134,9 +133,13 @@ export default defineComponent({
|
||||
if (questionType === 10) {
|
||||
// 矩阵多选题
|
||||
if (question.config.is_change_row_cell) {
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerColumn(config.min_select || 1);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerColumn(
|
||||
config.min_select || 1
|
||||
);
|
||||
} else {
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerLine(config.min_select || 1);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerLine(
|
||||
config.min_select || 1
|
||||
);
|
||||
}
|
||||
} else if (questionType === 12) {
|
||||
// 图片显示题,如果开启了仅显示并且开启了单图显示时长,需要确保用户每一个图片都点开看过了才能下一页
|
||||
@@ -150,7 +153,11 @@ export default defineComponent({
|
||||
} else if (!question.error) {
|
||||
question.error = translatedText.value.ThisIsARequiredQuestion;
|
||||
}
|
||||
} else if (answer && questionType === 1 && Object.keys(answer).findIndex((value) => !answer[value]) !== -1) {
|
||||
} else if (
|
||||
answer
|
||||
&& questionType === 1
|
||||
&& Object.keys(answer).findIndex((value) => !answer[value]) !== -1
|
||||
) {
|
||||
// 单选题
|
||||
isError = true;
|
||||
question.error = translatedText.value.PleaseInputAValue;
|
||||
@@ -167,7 +174,9 @@ export default defineComponent({
|
||||
);
|
||||
if (index === -1) {
|
||||
isError = true;
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptions(config.min_select);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptions(
|
||||
config.min_select
|
||||
);
|
||||
} else {
|
||||
question.error = '';
|
||||
}
|
||||
@@ -181,23 +190,28 @@ export default defineComponent({
|
||||
// 选项分组最少选项数量
|
||||
config.option_groups?.option_group.some((optionGroup) => {
|
||||
const { min, title } = optionGroup;
|
||||
const select = optionGroup.groups.filter((groups) => Object.keys(answer).includes(groups.option_key));
|
||||
const select = optionGroup.groups.filter((groups) =>
|
||||
Object.keys(answer).includes(groups.option_key)
|
||||
);
|
||||
if (title && select.length < min) {
|
||||
// 判断隐藏选项
|
||||
question.hideOptionsSet = new Set(question.hideOptions);
|
||||
const options = question.list.flatMap((list) =>
|
||||
list.options
|
||||
.filter(({ option_key }) =>
|
||||
.filter(({ option_key: optionKey }) =>
|
||||
optionGroup.groups.some(
|
||||
({ option_key: groupKey }) =>
|
||||
groupKey === option_key && !question.hideOptionsSet.has(groupKey)
|
||||
groupKey === optionKey && !question.hideOptionsSet.has(groupKey)
|
||||
)
|
||||
)
|
||||
.map(({ option_key }) => option_key)
|
||||
.map(({ option_key: optionKey }) => optionKey)
|
||||
);
|
||||
if (options.length >= min) {
|
||||
isError = true;
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsInTitleGroup(min, title);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsInTitleGroup(
|
||||
min,
|
||||
title
|
||||
);
|
||||
}
|
||||
}
|
||||
return isError;
|
||||
@@ -205,12 +219,21 @@ export default defineComponent({
|
||||
}
|
||||
} else if (answer && questionType === 10) {
|
||||
// 矩阵多选题,列分组时,校验选项数量
|
||||
const cellGroups = (config?.cell_option_groups?.option_group || []).filter((i) => i.groups?.length);
|
||||
const cellGroups = (config?.cell_option_groups?.option_group || []).filter(
|
||||
(i) => i.groups?.length
|
||||
);
|
||||
if (cellGroups.length) {
|
||||
const rows = question.list.reduce((p, c) => [...p, ...(c.type === 1 ? c.options || [] : [])], []);
|
||||
const cols = question.list.reduce((p, c) => [...p, ...(c.type === 2 ? c.options || [] : [])], []);
|
||||
const rows = question.list.reduce(
|
||||
(p, c) => [...p, ...(c.type === 1 ? c.options || [] : [])],
|
||||
[]
|
||||
);
|
||||
const cols = question.list.reduce(
|
||||
(p, c) => [...p, ...(c.type === 2 ? c.options || [] : [])],
|
||||
[]
|
||||
);
|
||||
const freeCols = cols.filter(
|
||||
(col) => !cellGroups.some((g) => g.groups.find((c) => c.option_key === col.option_key))
|
||||
(col) =>
|
||||
!cellGroups.some((g) => g.groups.find((c) => c.option_key === col.option_key))
|
||||
);
|
||||
|
||||
const arr = rows.map((row) => {
|
||||
@@ -220,7 +243,9 @@ export default defineComponent({
|
||||
});
|
||||
});
|
||||
});
|
||||
arr.forEach((a, idx) => a.push(freeCols.map((col) => `${rows[idx].option_key}_${col.option_key}`)));
|
||||
arr.forEach((a, idx) =>
|
||||
a.push(freeCols.map((col) => `${rows[idx].option_key}_${col.option_key}`))
|
||||
);
|
||||
const answered = Object.keys(answer);
|
||||
|
||||
cellGroups.forEach((group, idx) => {
|
||||
@@ -259,20 +284,28 @@ export default defineComponent({
|
||||
}
|
||||
return p;
|
||||
},
|
||||
question.list.filter((i) => i.type === 1).flatMap((i) => i.options.map((i) => 0))
|
||||
question.list.filter((i) => i.type === 1).flatMap((i) => i.options.map(() => 0))
|
||||
);
|
||||
if (minSelect && minSelect > Math.max(...perLineSelectedCount)) {
|
||||
if (question.config.is_change_row_cell) {
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerColumn(config.min_select || 1);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerColumn(
|
||||
config.min_select || 1
|
||||
);
|
||||
} else {
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerLine(config.min_select || 1);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptionsPerLine(
|
||||
config.min_select || 1
|
||||
);
|
||||
}
|
||||
isError = true;
|
||||
}
|
||||
console.log('===', minSelect, Object.keys(answer), answer, perLineSelectedCount);
|
||||
} else if (answer && questionType === 12) {
|
||||
question.error = '';
|
||||
} else if (answer && questionType === 14 && Object.keys(answer).length < config.min_select) {
|
||||
} else if (
|
||||
answer
|
||||
&& questionType === 14
|
||||
&& Object.keys(answer).length < config.min_select
|
||||
) {
|
||||
// 图片多选题
|
||||
isError = true;
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOnePictures(config.min_select);
|
||||
@@ -281,7 +314,9 @@ export default defineComponent({
|
||||
if (Object.keys(answer).length < (+config.min_select || 0)) {
|
||||
// 选项数量
|
||||
isError = true;
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptions(config.min_select);
|
||||
question.error = translatedText.value.PleaseSelectAtLeastOneOptions(
|
||||
config.min_select
|
||||
);
|
||||
}
|
||||
} else if (answer && questionType === 17) {
|
||||
// 恒定总和题
|
||||
@@ -303,44 +338,48 @@ export default defineComponent({
|
||||
question.error = '';
|
||||
// 填空题
|
||||
const { value } = answer;
|
||||
let newValue = value.replace(/\n|\r|\r\n/g, '');
|
||||
const newValue = value.replace(/\n|\r|\r\n/g, '');
|
||||
switch (config.text_type) {
|
||||
case 3: // 字母
|
||||
isError = config.include_mark == 1
|
||||
? !/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]]+$/.test(
|
||||
newValue
|
||||
) || !newValue.length
|
||||
case 3: // 字母
|
||||
isError
|
||||
= config.include_mark === 1
|
||||
? !/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
|
||||
newValue
|
||||
) || !newValue.length
|
||||
: !/^[a-zA-Z]+$/.test(newValue) || !newValue.length;
|
||||
question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : '';
|
||||
break;
|
||||
case 4: // 中文
|
||||
isError = 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]|[·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]])+$/.test(
|
||||
newValue
|
||||
) || !newValue.length
|
||||
question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : '';
|
||||
break;
|
||||
case 4: // 中文
|
||||
isError
|
||||
= 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]|[·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test(
|
||||
newValue
|
||||
) || !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(
|
||||
newValue
|
||||
) || !newValue.length;
|
||||
question.error = isError ? translatedText.value.PleaseEnterChineseWords : '';
|
||||
break;
|
||||
case 5: // 邮箱
|
||||
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(
|
||||
newValue
|
||||
) || !newValue.length;
|
||||
question.error = isError ? translatedText.value.PleaseEnterChineseWords : '';
|
||||
break;
|
||||
case 5: // 邮箱
|
||||
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(
|
||||
value
|
||||
);
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
|
||||
break;
|
||||
case 6: // 手机号
|
||||
isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value);
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : '';
|
||||
break;
|
||||
case 7: // 身份证号
|
||||
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(
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
|
||||
break;
|
||||
case 6: // 手机号
|
||||
isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value);
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : '';
|
||||
break;
|
||||
case 7: // 身份证号
|
||||
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(
|
||||
value
|
||||
);
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!isError && value.length < config.min && ![1, 2].includes(config.text_type)) {
|
||||
isError = true;
|
||||
@@ -352,44 +391,55 @@ export default defineComponent({
|
||||
Object.keys(answer).forEach((key) => {
|
||||
const value = answer[key];
|
||||
switch (config.text_type) {
|
||||
case 3: // 字母
|
||||
if (
|
||||
!/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]]+$/.test(
|
||||
value
|
||||
)
|
||||
case 3: // 字母
|
||||
if (
|
||||
!/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
value
|
||||
)
|
||||
question.error = translatedText.value.PleaseEnterACorrectEmail;
|
||||
break;
|
||||
case 6: // 手机号
|
||||
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(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(value)
|
||||
) {
|
||||
question.error = translatedText.value.PleaseEnterACorrectEmail;
|
||||
}
|
||||
break;
|
||||
case 6: // 手机号
|
||||
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(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(
|
||||
value
|
||||
)
|
||||
question.error = translatedText.value.PleaseEnterACorrectID;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
) {
|
||||
question.error = translatedText.value.PleaseEnterACorrectID;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
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);
|
||||
}
|
||||
});
|
||||
@@ -442,65 +492,6 @@ export default defineComponent({
|
||||
});
|
||||
});
|
||||
}
|
||||
// 质量控制(选择题)
|
||||
const allPages = pages.value.flatMap((currentPages) => currentPages);
|
||||
const allQuestions = allPages.map((questionIndex) => {
|
||||
return questionsData.value.questions.find((question) => question.question_index === questionIndex);
|
||||
});
|
||||
const repeat = questionsData.value.survey.repeat_list?.find((repeat) =>
|
||||
repeat.question_indexes.find(({ first_index, last_index }) => {
|
||||
const firstIndex = allPages.findIndex((questionIndex) => questionIndex === first_index);
|
||||
const lastIndex = allPages.findIndex((questionIndex) => questionIndex === last_index);
|
||||
const currentQuestions = allQuestions
|
||||
.slice(firstIndex, lastIndex + 1)
|
||||
.filter((currentQuestions) => currentQuestions.question_type === repeat.question_type);
|
||||
const answerIndexes = currentQuestions.map((question) => question.answerIndex);
|
||||
return hasNConsecutiveNumbers(
|
||||
answerIndexes,
|
||||
repeat.allow_repeat_num + 1,
|
||||
(warnStart, warnEnd) => {
|
||||
currentQuestions.forEach((question, index) => {
|
||||
if (index >= warnStart && index < warnEnd) {
|
||||
if (repeat.repeat_type) {
|
||||
question.warning = translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
|
||||
repeat.allow_repeat_num,
|
||||
repeat.repeat_type
|
||||
);
|
||||
} else {
|
||||
question.error = translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
|
||||
repeat.allow_repeat_num,
|
||||
repeat.repeat_type
|
||||
);
|
||||
}
|
||||
} else {
|
||||
question.warning = '';
|
||||
question.error = '';
|
||||
}
|
||||
});
|
||||
},
|
||||
() => {
|
||||
currentQuestions.forEach((question) => {
|
||||
question.warning = '';
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
);
|
||||
if (repeat) {
|
||||
await new Promise((resolve) => {
|
||||
Modal[repeat.repeat_type ? 'confirm' : 'info']({
|
||||
class: 'custom-modal custom-modal-title-notice',
|
||||
title: translatedText.value.PleaseAnswerCarefully,
|
||||
content: repeat.alert_text,
|
||||
cancelText: translatedText.value.ContinueAnswer,
|
||||
okText: translatedText.value.ReviseAnswer,
|
||||
onCancel: () => {
|
||||
questions.value.forEach((question) => (question.answerIndex = ''));
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
// 判断是作答还是预览
|
||||
if (!props.isAnswer) {
|
||||
loading.value = true;
|
||||
@@ -615,7 +606,7 @@ export default defineComponent({
|
||||
loading.value = false;
|
||||
} else {
|
||||
console.log(errors);
|
||||
const { error, title, question_index } = errors[0];
|
||||
const { error, title, question_index: questionIndex } = errors[0];
|
||||
const lines = (error || '')
|
||||
.split('\n')
|
||||
.filter((i) => !!i)
|
||||
@@ -623,7 +614,7 @@ export default defineComponent({
|
||||
msg.error(lines.join('\n'));
|
||||
|
||||
// 锚点
|
||||
const anchor = document.querySelector(`#questionIndex${question_index}`);
|
||||
const anchor = document.querySelector(`#questionIndex${questionIndex}`);
|
||||
console.log(anchor, scrollbar.value);
|
||||
scrollbar.value.scrollTo(0, anchor.offsetTop - (props.isMobile ? 20 : 40));
|
||||
}
|
||||
@@ -632,72 +623,77 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
function jumpImmediately() {
|
||||
const code = questionsData.value.action?.code;
|
||||
if (page.value !== pages.value.length + 1 && ![20004, 20011, 20016].includes(code)) {
|
||||
return;
|
||||
}
|
||||
const survey = questionsData.value.survey;
|
||||
let countTime = 0;
|
||||
let url = '';
|
||||
|
||||
if (code === 20004 && survey.screening_end_url_select && survey.screening_end_url) {
|
||||
countTime = survey.screening_standing_time;
|
||||
url = survey.screening_end_url;
|
||||
}
|
||||
if (code === 20011 && survey.success_end_url_select && survey.success_end_url) {
|
||||
countTime = survey.success_standing_time;
|
||||
url = survey.success_end_url;
|
||||
}
|
||||
if (code === 20016 && survey.quota_end_url_select && survey.quota_end_url) {
|
||||
countTime = survey.quota_standing_time;
|
||||
url = survey.quota_end_url;
|
||||
}
|
||||
|
||||
// 跳转链接
|
||||
if (countTime <= 0 && url) {
|
||||
questionsData.value.action.code = -1 * code; // 防止 AnswerMob AnswerPc 组件里显示最后一页
|
||||
|
||||
url = url.replaceAll('#sn#', questionsData.value.answer.sn);
|
||||
url = url.replaceAll('#user#', questionsData.value.answer.respondent);
|
||||
url = url.replaceAll('#survey_sn#', questionsData.value.answer.survey_sn);
|
||||
if (proxy.$route.query.source === 'YILI_APP_WANGYI') {
|
||||
Object.keys(proxy.$route.query).forEach((key) => {
|
||||
if (!['sn', 'source', 'is_template', 'channelUCode'].includes(key)) {
|
||||
url += `${url.indexOf('?') === -1 ? '?' : '&'}${key}=${proxy.$route.query[key]}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
// 判断是否小程序路径
|
||||
if (url[0] === '/') {
|
||||
// 判断是否在小程序环境
|
||||
wx.miniProgram.getEnv(() => {
|
||||
wx.miniProgram.redirectTo({ url });
|
||||
});
|
||||
} else {
|
||||
if (url.indexOf('http://') === -1 && url.indexOf('https://') === -1) {
|
||||
url = `http://${url}`;
|
||||
}
|
||||
open(url, '_self');
|
||||
}
|
||||
}
|
||||
}
|
||||
// function jumpImmediately() {
|
||||
// const code = questionsData.value.action?.code;
|
||||
// if (page.value !== pages.value.length + 1 && ![20004, 20011, 20016].includes(code)) {
|
||||
// return;
|
||||
// }
|
||||
// const survey = questionsData.value.survey;
|
||||
// let countTime = 0;
|
||||
// let url = '';
|
||||
//
|
||||
// if (code === 20004 && survey.screening_end_url_select && survey.screening_end_url) {
|
||||
// countTime = survey.screening_standing_time;
|
||||
// url = survey.screening_end_url;
|
||||
// }
|
||||
// if (code === 20011 && survey.success_end_url_select && survey.success_end_url) {
|
||||
// countTime = survey.success_standing_time;
|
||||
// url = survey.success_end_url;
|
||||
// }
|
||||
// if (code === 20016 && survey.quota_end_url_select && survey.quota_end_url) {
|
||||
// countTime = survey.quota_standing_time;
|
||||
// url = survey.quota_end_url;
|
||||
// }
|
||||
//
|
||||
// // 跳转链接
|
||||
// if (countTime <= 0 && url) {
|
||||
// questionsData.value.action.code = -1 * code; // 防止 AnswerMob AnswerPc 组件里显示最后一页
|
||||
//
|
||||
// url = url.replaceAll('#sn#', questionsData.value.answer.sn);
|
||||
// url = url.replaceAll('#user#', questionsData.value.answer.respondent);
|
||||
// url = url.replaceAll('#survey_sn#', questionsData.value.answer.survey_sn);
|
||||
// if (proxy.$route.query.source === 'YILI_APP_WANGYI') {
|
||||
// Object.keys(proxy.$route.query).forEach((key) => {
|
||||
// if (!['sn', 'source', 'is_template', 'channelUCode'].includes(key)) {
|
||||
// url += `${url.indexOf('?') === -1 ? '?' : '&'}${key}=${proxy.$route.query[key]}`;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// // 判断是否小程序路径
|
||||
// if (url[0] === '/') {
|
||||
// // 判断是否在小程序环境
|
||||
// wx.miniProgram.getEnv(() => {
|
||||
// wx.miniProgram.redirectTo({ url });
|
||||
// });
|
||||
// } else {
|
||||
// if (url.indexOf('http://') === -1 && url.indexOf('https://') === -1) {
|
||||
// url = `http://${url}`;
|
||||
// }
|
||||
// open(url, '_self');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// 选项隐藏
|
||||
function hideOptions(hide) {
|
||||
const questionIndex = hide?.question_index;
|
||||
if (questionIndex) {
|
||||
const qustion = questionsData.value.questions.find((qustion) => qustion.question_index === questionIndex);
|
||||
const qustion = questionsData.value.questions.find(
|
||||
(qustion) => qustion.question_index === questionIndex
|
||||
);
|
||||
qustion.hideOptions = hide.option_key || [];
|
||||
}
|
||||
}
|
||||
|
||||
// 关联引用
|
||||
function onRelation({ options, value, list }, { question_type, question_index, related, answer }) {
|
||||
function onRelation(
|
||||
{ options, value, list },
|
||||
{ question_type: questionType, question_index: questionIndex, related, answer }
|
||||
) {
|
||||
// 关联
|
||||
related.forEach((relationItem) => {
|
||||
let relationOptions = [];
|
||||
if (question_type === 9 || question_type === 10) {
|
||||
if (questionType === 9 || questionType === 10) {
|
||||
// 矩阵选择
|
||||
list.forEach((item) => {
|
||||
if (item.type === relationItem.cite_type) {
|
||||
@@ -705,22 +701,22 @@ export default defineComponent({
|
||||
}
|
||||
if (relationItem.relation_type === 1) {
|
||||
relationOptions = relationOptions.filter((option) =>
|
||||
question_type === 9 ? option.value : option.value?.length
|
||||
questionType === 9 ? option.value : option.value?.length
|
||||
);
|
||||
} else if (relationItem.relation_type === 2) {
|
||||
relationOptions = relationOptions.filter((option) =>
|
||||
question_type === 9 ? !option.value : !option.value?.length
|
||||
questionType === 9 ? !option.value : !option.value?.length
|
||||
);
|
||||
}
|
||||
});
|
||||
} else if (question_type === 11) {
|
||||
} else if (questionType === 11) {
|
||||
// 矩阵打分
|
||||
list.forEach((item) => {
|
||||
if (item.type === relationItem.cite_type) {
|
||||
relationOptions = [...relationOptions, ...item.options];
|
||||
}
|
||||
});
|
||||
} else if (question_type === 25 || question_type === 26) {
|
||||
} else if (questionType === 25 || questionType === 26) {
|
||||
// 热区题
|
||||
relationOptions = options.filter((option) => {
|
||||
if (relationItem.relation_type === 1) {
|
||||
@@ -732,7 +728,7 @@ export default defineComponent({
|
||||
}
|
||||
return true;
|
||||
});
|
||||
} else if (question_type === 105) {
|
||||
} else if (questionType === 105) {
|
||||
// MXD
|
||||
options.forEach((currentOptions) => {
|
||||
currentOptions.forEach((option) => {
|
||||
@@ -761,11 +757,11 @@ export default defineComponent({
|
||||
} else {
|
||||
// 过滤选中/未选中选项
|
||||
relationOptions = options.filter((option) => {
|
||||
if (question_type === 1) {
|
||||
if (questionType === 1) {
|
||||
// 单选
|
||||
if (relationItem.relation_type === 1) return value === option.option_key;
|
||||
return value !== option.option_key;
|
||||
} else if (question_type === 2) {
|
||||
} else if (questionType === 2) {
|
||||
// 多选
|
||||
if (relationItem.relation_type === 1) return value.includes(option.option_key);
|
||||
return !value.includes(option.option_key);
|
||||
@@ -784,10 +780,10 @@ export default defineComponent({
|
||||
if (option.option_key[0] !== 'Q') {
|
||||
let letter = 'A';
|
||||
// 矩阵题行、列
|
||||
if (question_type >= 9 && question_type <= 11) {
|
||||
if (questionType >= 9 && questionType <= 11) {
|
||||
letter = relationItem.cite_type === 1 ? 'R' : 'C';
|
||||
}
|
||||
option.option_key = `Q${question_index}${letter}${option.option_key}`;
|
||||
option.option_key = `Q${questionIndex}${letter}${option.option_key}`;
|
||||
}
|
||||
// 其他项特殊处理
|
||||
if (option.is_other && option.value) {
|
||||
@@ -799,7 +795,7 @@ export default defineComponent({
|
||||
});
|
||||
// 更新关联题列表
|
||||
const relatedList = question.list.find(
|
||||
(relatedListItem) => relatedListItem.relation_question_index === question_index
|
||||
(relatedListItem) => relatedListItem.relation_question_index === questionIndex
|
||||
);
|
||||
relatedList.options = answer ? copyRelationOptions : [];
|
||||
});
|
||||
@@ -818,9 +814,10 @@ export default defineComponent({
|
||||
const evt1 = {};
|
||||
|
||||
if ([1].includes(question.question_type)) {
|
||||
evt1.value = Object.keys(question.answer)
|
||||
.map((key) => (question.answer[key] ? key : undefined))
|
||||
.filter((i) => !!i)?.[0] || undefined;
|
||||
evt1.value
|
||||
= Object.keys(question.answer)
|
||||
.map((key) => (question.answer[key] ? key : undefined))
|
||||
.filter((i) => !!i)?.[0] || undefined;
|
||||
evt1.options = question.list.flatMap((i) => i.options);
|
||||
onRelation(evt1, question);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user