|
@@ -1,1284 +0,0 @@
|
|
-<template>
|
|
|
|
- <div
|
|
|
|
- :style="{
|
|
|
|
- 'padding-top':
|
|
|
|
- [QUESTION_TYPE_CHECKBOX, QUESTION_TYPE_RATING].includes(item.type) &&
|
|
|
|
- (props.child || !item.isAnswered)
|
|
|
|
- ? '25px'
|
|
|
|
- : '',
|
|
|
|
- 'min-width': [
|
|
|
|
- QUESTION_TYPE_RADIO,
|
|
|
|
- QUESTION_TYPE_CHECKBOX,
|
|
|
|
- QUESTION_TYPE_RATING
|
|
|
|
- ].includes(item.type)
|
|
|
|
- ? '200px'
|
|
|
|
- : ''
|
|
|
|
- }"
|
|
|
|
- >
|
|
|
|
- <p v-if="item.type !== QUESTION_TYPE_TEXT" class="survey-title">
|
|
|
|
- <span class="text-red-500" v-if="item.config.required">*</span>
|
|
|
|
- {{ item.attr && item.attr.includes("target") ? "" : item.number }}
|
|
|
|
- {{ item.title }}
|
|
|
|
- </p>
|
|
|
|
- <div v-else-if="item.isHtml" class="survey-title" v-html="item.title" />
|
|
|
|
- <p v-else class="survey-title">{{ item.title }}</p>
|
|
|
|
- <!-- 临时选项 -->
|
|
|
|
- <template v-if="item.type === QUESTION_TYPE_TEMP_CHECK">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <template v-if="props.child">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div class="text-right pt-2">
|
|
|
|
- <van-button
|
|
|
|
- color="#4B72F6"
|
|
|
|
- class="confirm-input-btn"
|
|
|
|
- @click="check(item, true)"
|
|
|
|
- >是</van-button
|
|
|
|
- >
|
|
|
|
-
|
|
|
|
- <van-button class="confirm-input-btn" @click="check(item, false)"
|
|
|
|
- >否</van-button
|
|
|
|
- >
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 单选 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_RADIO">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div>
|
|
|
|
- <div
|
|
|
|
- v-if="
|
|
|
|
- item.title.includes('性别') &&
|
|
|
|
- /男|女/.test(item.choices.map(v => v.label).join(''))
|
|
|
|
- "
|
|
|
|
- class="gender-select"
|
|
|
|
- >
|
|
|
|
- <div v-for="(sub, idx) in item.choices" :key="idx">
|
|
|
|
- <div
|
|
|
|
- v-if="!props.hideList.includes(sub.attr)"
|
|
|
|
- :data-topic="item.attr"
|
|
|
|
- class="gender-item"
|
|
|
|
- :class="{
|
|
|
|
- active: item.value === idx
|
|
|
|
- }"
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- :value="idx"
|
|
|
|
- @click="reply(item, sub, idx)"
|
|
|
|
- >
|
|
|
|
- <Image
|
|
|
|
- v-if="sub.label.includes('男')"
|
|
|
|
- :src="iconMan"
|
|
|
|
- alt=""
|
|
|
|
- mode="cover"
|
|
|
|
- />
|
|
|
|
- <Image
|
|
|
|
- v-if="sub.label.includes('女')"
|
|
|
|
- :src="iconWoman"
|
|
|
|
- alt=""
|
|
|
|
- mode="cover"
|
|
|
|
- />
|
|
|
|
- <span>{{ sub.label }}</span>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <template v-else>
|
|
|
|
- <div v-for="(sub, idx) in item.choices" :key="idx">
|
|
|
|
- <div
|
|
|
|
- v-if="!props.hideList.includes(sub.attr)"
|
|
|
|
- :data-topic="item.attr"
|
|
|
|
- class="sub-title mt-4"
|
|
|
|
- >
|
|
|
|
- <div
|
|
|
|
- class="text-left answer-btn"
|
|
|
|
- :class="{
|
|
|
|
- active: item.value === idx
|
|
|
|
- }"
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- :value="idx"
|
|
|
|
- @click="reply(item, sub, idx, true)"
|
|
|
|
- >
|
|
|
|
- {{ sub.label }}
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <el-input
|
|
|
|
- v-if="sub.isInput && item.value === idx"
|
|
|
|
- v-model="sub.extra"
|
|
|
|
- type="textarea"
|
|
|
|
- autosize
|
|
|
|
- :autocomplete="false"
|
|
|
|
- class="border border-solid border-gray-200 rounded px-2 py-1 outline-none border-radius-5 mt-2"
|
|
|
|
- :placeholder="sub.inputPlaceholder || '请输入'"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <div>
|
|
|
|
- <!-- <div
|
|
|
|
- v-for="(sub, idx) in item.choices"
|
|
|
|
- :key="idx"
|
|
|
|
- class="sub-title margin-top-5 hide"
|
|
|
|
- @click.stop="reply(item, sub, idx, true)"
|
|
|
|
- >
|
|
|
|
- <el-radio-group v-model="item.rawValue">
|
|
|
|
- <el-radio :label="sub.label">
|
|
|
|
- <span class="cursor-copy">{{ sub.label }}</span>
|
|
|
|
- </el-radio>
|
|
|
|
- </el-radio-group>
|
|
|
|
-
|
|
|
|
- <el-input
|
|
|
|
- v-if="sub.isInput && item.rawValue === idx"
|
|
|
|
- v-model="sub.extra"
|
|
|
|
- type="textarea"
|
|
|
|
- autosize
|
|
|
|
- :autocomplete="false"
|
|
|
|
- :placeholder="sub.inputPlaceholder || '请输入'"
|
|
|
|
- />
|
|
|
|
- </div> -->
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 多选 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_CHECKBOX">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div>
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <span class="survey-tag">可多选</span>
|
|
|
|
- <div v-for="(sub, idx) in item.choices" :key="idx">
|
|
|
|
- <div
|
|
|
|
- v-if="!props.hideList.includes(sub.attr)"
|
|
|
|
- :key="idx"
|
|
|
|
- :data-topic="item.attr"
|
|
|
|
- class="mt-4 sub-title"
|
|
|
|
- >
|
|
|
|
- <div
|
|
|
|
- class="text-left answer-btn"
|
|
|
|
- :class="{
|
|
|
|
- active: item.value && item.value?.includes(idx)
|
|
|
|
- }"
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- :value="idx"
|
|
|
|
- @click="reply(item, sub, idx, true)"
|
|
|
|
- >
|
|
|
|
- {{ sub.label }}
|
|
|
|
- </div>
|
|
|
|
- <input
|
|
|
|
- v-if="sub.isInput && item.value?.includes(idx)"
|
|
|
|
- v-model="sub.extra"
|
|
|
|
- type="textarea"
|
|
|
|
- autosize
|
|
|
|
- :autocomplete="false"
|
|
|
|
- class="border border-solid border-gray-200 rounded px-2 py-1 outline-none border-radius-5 mt-2"
|
|
|
|
- :placeholder="sub.inputPlaceholder || '请输入'"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 单行文本题 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_INPUT">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div>
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <!-- v-if="item.value !== null && item.value !== undefined" -->
|
|
|
|
- <div class="mb-5 mt-2 flex items-center">
|
|
|
|
- <el-input
|
|
|
|
- v-model="item.value"
|
|
|
|
- placeholder="请输入"
|
|
|
|
- autosize
|
|
|
|
- autocomplete="off"
|
|
|
|
- @keyup.enter="reply(item)"
|
|
|
|
- />
|
|
|
|
- <!-- <input
|
|
|
|
- :type="inputType(item.config)"
|
|
|
|
- v-model="item.value"
|
|
|
|
- placeholder="请输入"
|
|
|
|
- class="mr-2 w-40 confirm-input"
|
|
|
|
- :style="{
|
|
|
|
- width: !props.child ? '150px' : '100%'
|
|
|
|
- }"
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- :type="inputType(item.config?.rule)"
|
|
|
|
- @keyup.enter="reply(item)"
|
|
|
|
- @blur="inputBlur()"
|
|
|
|
- /> -->
|
|
|
|
- <!-- <el-button
|
|
|
|
- v-if="!props.child"
|
|
|
|
- :disabled="item.isAnswered"
|
|
|
|
- color="#4B72F6"
|
|
|
|
- class="confirm-input-btn ml-2"
|
|
|
|
- @click="reply(item)"
|
|
|
|
- size="mini"
|
|
|
|
- >确定</el-button
|
|
|
|
- > -->
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 多行文本题 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_TEXTAREA">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div>
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <!-- v-if="item.value !== null && item.value !== undefined" -->
|
|
|
|
- <div class="mb-5 mt-2 flex items-center">
|
|
|
|
- <!-- <textarea
|
|
|
|
- v-model="item.value"
|
|
|
|
- placeholder="请输入"
|
|
|
|
- autosize
|
|
|
|
- autocomplete="off"
|
|
|
|
- :style="{
|
|
|
|
- width: !props.child ? '150px' : '100%'
|
|
|
|
- }"
|
|
|
|
- class="mr-2 w-40 border border-solid border-gray-200 rounded px-2 py-1 outline-none"
|
|
|
|
- /> -->
|
|
|
|
- <el-input
|
|
|
|
- type="textarea"
|
|
|
|
- v-model="item.value"
|
|
|
|
- placeholder="请输入"
|
|
|
|
- />
|
|
|
|
- <!-- <input
|
|
|
|
- :type="inputType(item.config)"
|
|
|
|
- v-model="item.value"
|
|
|
|
- placeholder="请输入"
|
|
|
|
- class="mr-2 w-40 confirm-input"
|
|
|
|
- :style="{
|
|
|
|
- width: !props.child ? '150px' : '100%'
|
|
|
|
- }"
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- :type="inputType(item.config?.rule)"
|
|
|
|
- @keyup.enter="reply(item)"
|
|
|
|
- @blur="inputBlur()"
|
|
|
|
- /> -->
|
|
|
|
- <!-- <el-button
|
|
|
|
- v-if="!props.child"
|
|
|
|
- :disabled="item.isAnswered"
|
|
|
|
- color="#4B72F6"
|
|
|
|
- class="confirm-input-btn ml-2"
|
|
|
|
- @click="reply(item)"
|
|
|
|
- size="mini"
|
|
|
|
- >确定</el-button
|
|
|
|
- > -->
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 量表题 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_SCALE">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div class="text-left padding-top-10 padding-bottom-10">
|
|
|
|
- <div class="row pt-4">
|
|
|
|
- <div class="flex">
|
|
|
|
- <div class="flex items-center flex-col">
|
|
|
|
- <span class="whitespace-nowrap mx-4">{{
|
|
|
|
- item.choices[0].label
|
|
|
|
- }}</span>
|
|
|
|
- <div>{{ item.min }}</div>
|
|
|
|
- </div>
|
|
|
|
- <el-slider
|
|
|
|
- v-model="item.value"
|
|
|
|
- :show-tooltip="true"
|
|
|
|
- :min="item.min"
|
|
|
|
- :max="item.max"
|
|
|
|
- :step="1"
|
|
|
|
- />
|
|
|
|
- <div class="flex items-center flex-col">
|
|
|
|
- <span class="whitespace-nowrap mx-4">{{
|
|
|
|
- item.choices[1].label
|
|
|
|
- }}</span>
|
|
|
|
- <div>{{ item.max }}</div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <!-- <div>
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <div class="flex w-[60vw] items-center">
|
|
|
|
- <div class="flex flex-col">
|
|
|
|
- <span class="text-sm text-gray-600 whitespace-nowrap">{{
|
|
|
|
- item.choices[0].label
|
|
|
|
- }}</span>
|
|
|
|
- <span class="text-xs text-gray-500">{{ item.min }}</span>
|
|
|
|
- </div>
|
|
|
|
- <div class="flex-1 px-4 mt-2">
|
|
|
|
- <van-slider
|
|
|
|
- v-model="item.value"
|
|
|
|
- :min="item.min"
|
|
|
|
- :max="item.max"
|
|
|
|
- >
|
|
|
|
- <template #button>
|
|
|
|
- <div
|
|
|
|
- class="w-7 h-7 rounded-full shadow border-2 border-solid border-[#4B72F6] bg-white text-[#4B72F6] text-sm p-2 flex justify-center items-center"
|
|
|
|
- >
|
|
|
|
- {{ item.value }}
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- </van-slider>
|
|
|
|
- </div>
|
|
|
|
- <div class="flex flex-col text-right">
|
|
|
|
- <span class="text-sm text-gray-600 whitespace-nowrap">{{
|
|
|
|
- item.choices[1].label
|
|
|
|
- }}</span>
|
|
|
|
- <span class="text-xs text-gray-500">{{ item.max }}</span>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <div class="pt-4 flex justify-end">
|
|
|
|
- <van-button
|
|
|
|
- v-if="!props.child"
|
|
|
|
- :disabled="item.isAnswered"
|
|
|
|
- color="#4B72F6"
|
|
|
|
- class="confirm-input-btn"
|
|
|
|
- @click="reply(item)"
|
|
|
|
- >确定</van-button
|
|
|
|
- >
|
|
|
|
- </div>
|
|
|
|
- </div> -->
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 量表题 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_RATING_SCALE">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div>
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <div class="row">
|
|
|
|
- <div class="flex justify-between items-center mb-2">
|
|
|
|
- <span class="mr-5">{{ item.choices[0].label }}</span>
|
|
|
|
- <span class="ml-2">{{ item.choices[1].label }}</span>
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <el-button
|
|
|
|
- v-for="(sub, idx) in item.rating"
|
|
|
|
- :key="idx"
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- :style="{
|
|
|
|
- marginLeft: idx ? '-1px' : ''
|
|
|
|
- }"
|
|
|
|
- :type="item.value === sub ? 'primary' : 'default'"
|
|
|
|
- :value="idx"
|
|
|
|
- @click="reply(item, sub, idx)"
|
|
|
|
- >{{ sub }}</el-button
|
|
|
|
- >
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 评分题 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_RATING">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div>
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <span class="survey-tag">可多选</span>
|
|
|
|
- <div v-for="(sub, idx) in item.choices" :key="idx">
|
|
|
|
- <div
|
|
|
|
- v-if="!props.hideList.includes(sub.attr)"
|
|
|
|
- :key="idx"
|
|
|
|
- :data-topic="item.attr"
|
|
|
|
- class="mt-4 sub-title"
|
|
|
|
- >
|
|
|
|
- <template v-if="item.isMultiple">
|
|
|
|
- <div
|
|
|
|
- class="text-left answer-btn"
|
|
|
|
- :class="{
|
|
|
|
- active: item.value && item.value.includes(idx)
|
|
|
|
- }"
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- :value="idx"
|
|
|
|
- @click="reply(item, sub, idx, true)"
|
|
|
|
- >
|
|
|
|
- {{ sub.label }}
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <template v-else>
|
|
|
|
- <div
|
|
|
|
- class="text-left answer-btn"
|
|
|
|
- :class="{
|
|
|
|
- active: item.value && item.value.includes(idx)
|
|
|
|
- }"
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- :value="idx"
|
|
|
|
- @click="reply(item, sub, idx)"
|
|
|
|
- >
|
|
|
|
- {{ sub.label }}
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 时间题 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_DATE">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div>
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <!-- :label="item.title" -->
|
|
|
|
- <!-- <EditDatetimeCell
|
|
|
|
- v-model:value="item.value"
|
|
|
|
- :type="item.config.type"
|
|
|
|
- :placeholder="item?.config?.desc"
|
|
|
|
- /> -->
|
|
|
|
- <div class="flex items-center">
|
|
|
|
- <el-date-picker
|
|
|
|
- v-model="item.value"
|
|
|
|
- type="date"
|
|
|
|
- :placeholder="item.remark || '选择时间'"
|
|
|
|
- />
|
|
|
|
- <div class="text-right">
|
|
|
|
- <!-- <el-button
|
|
|
|
- v-if="!props.child"
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- color="#4B72F6"
|
|
|
|
- class="confirm-input-btn ml-2"
|
|
|
|
- @click="reply(item)"
|
|
|
|
- size="mini"
|
|
|
|
- >确定</el-button
|
|
|
|
- > -->
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 矩阵矢量题 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_MATRIX">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div>
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <div class="survey-matrix-container">
|
|
|
|
- <table class="survey-matrix">
|
|
|
|
- <tr>
|
|
|
|
- <th />
|
|
|
|
- <th
|
|
|
|
- v-for="(subTh, subThIdx) in item.columns"
|
|
|
|
- :key="subThIdx"
|
|
|
|
- >
|
|
|
|
- {{ subTh.label }}
|
|
|
|
- </th>
|
|
|
|
- </tr>
|
|
|
|
- <tr v-for="(row, rowIdx) in item.rows" :key="rowIdx">
|
|
|
|
- <td>{{ row.label }}</td>
|
|
|
|
- <td
|
|
|
|
- v-for="(col, colIdx) in item.columns"
|
|
|
|
- :key="colIdx"
|
|
|
|
- @click="checkMatrix(rowIdx, colIdx)"
|
|
|
|
- >
|
|
|
|
- <div class="flex items-center justify-center">
|
|
|
|
- <!-- <Icon
|
|
|
|
- :name="
|
|
|
|
- item.matrix[rowIdx][colIdx] ? 'checked' : 'circle'
|
|
|
|
- "
|
|
|
|
- color="#4B72F6"
|
|
|
|
- size="20"
|
|
|
|
- /> -->
|
|
|
|
- <el-icon
|
|
|
|
- v-if="item.matrix[rowIdx][colIdx]"
|
|
|
|
- style="color: #67c23a; font-size: 20px"
|
|
|
|
- class="mr-2"
|
|
|
|
- ><SuccessFilled
|
|
|
|
- /></el-icon>
|
|
|
|
- <el-icon v-else style="font-size: 20px" class="mr-2"
|
|
|
|
- ><CircleCheck
|
|
|
|
- /></el-icon>
|
|
|
|
- <!-- <el-checkbox
|
|
|
|
- :checked="
|
|
|
|
- (item.value || []).includes(
|
|
|
|
- `${item.rows[$index]?.label}${item.columns[colIdx]?.label}`
|
|
|
|
- )
|
|
|
|
- "
|
|
|
|
- /> -->
|
|
|
|
- </div>
|
|
|
|
- </td>
|
|
|
|
- </tr>
|
|
|
|
- </table>
|
|
|
|
- </div>
|
|
|
|
- <!-- <div class="pt-4 text-right">
|
|
|
|
- <van-button
|
|
|
|
- v-if="!props.child"
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- color="#4B72F6"
|
|
|
|
- class="confirm-input-btn"
|
|
|
|
- @click="reply(item)"
|
|
|
|
- >确定</van-button>
|
|
|
|
- </div> -->
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_GROUP">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div>
|
|
|
|
- <!-- <p class="survey-desc">{{ item.remark || item.config.desc }}</p> -->
|
|
|
|
- <div v-for="(sub, subIdx) in item.children" :key="subIdx">
|
|
|
|
- <QuestionItem
|
|
|
|
- v-model:info="item.children[subIdx]"
|
|
|
|
- :child="true"
|
|
|
|
- class="w-100"
|
|
|
|
- @skip="skip"
|
|
|
|
- @back="back"
|
|
|
|
- @check-matrix="checkMatrix"
|
|
|
|
- @reply="reply"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <div class="pt-4 text-right">
|
|
|
|
- <!-- <van-button
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- color="#4B72F6"
|
|
|
|
- class="confirm-input-btn"
|
|
|
|
- @click="reply(item)"
|
|
|
|
- >确定</van-button
|
|
|
|
- > -->
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 组合题 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_COMBINATION">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <transition name="fade">
|
|
|
|
- <div>
|
|
|
|
- <p class="survey-desc">{{ item.remark || item.config.desc }}</p>
|
|
|
|
- <div
|
|
|
|
- v-for="(sub, subIdx) in item.children"
|
|
|
|
- :key="subIdx"
|
|
|
|
- class="pt-4"
|
|
|
|
- >
|
|
|
|
- <QuestionItem
|
|
|
|
- :info="sub"
|
|
|
|
- :child="true"
|
|
|
|
- class="w-100"
|
|
|
|
- @skip="skip"
|
|
|
|
- @back="back"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- <div class="pt-4 text-right">
|
|
|
|
- <!-- <van-button
|
|
|
|
- :disabled="!props.child && item.isAnswered"
|
|
|
|
- color="#4B72F6"
|
|
|
|
- class="confirm-input-btn"
|
|
|
|
- @click="reply(item)"
|
|
|
|
- >确定</van-button
|
|
|
|
- > -->
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </transition>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- <!-- 下拉题 -->
|
|
|
|
- <template v-else-if="item.type === QUESTION_TYPE_SELECT">
|
|
|
|
- <!-- 常规显示 -->
|
|
|
|
- <div class="text-left">
|
|
|
|
- <template v-if="props.child || !item.isAnswered">
|
|
|
|
- <div class="min-w-[40vw]">
|
|
|
|
- <van-cell is-link @click="openSelect">
|
|
|
|
- <template #title>
|
|
|
|
- <span class="text-gray-600">{{
|
|
|
|
- item.value && item.value?.length
|
|
|
|
- ? item.value?.map(v => v.value).join()
|
|
|
|
- : "请选择"
|
|
|
|
- }}</span>
|
|
|
|
- </template>
|
|
|
|
- </van-cell>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- </div>
|
|
|
|
- <van-popup v-model:show="selectVisible" position="bottom" teleport="body">
|
|
|
|
- <div class="text-center p-4">{{ item.title }}</div>
|
|
|
|
- <div v-if="selectChecked.length" class="p-4">
|
|
|
|
- <p>已选择:</p>
|
|
|
|
- <div
|
|
|
|
- v-for="(checkItem, checkIdx) in selectChecked"
|
|
|
|
- :key="checkIdx"
|
|
|
|
- class="inline-flex items-center bg-gray-100 rounded-full text-gray-600 text-sm p-1 px-3 m-1"
|
|
|
|
- >
|
|
|
|
- <span>{{ checkItem.properties.name }}</span>
|
|
|
|
-
|
|
|
|
- <van-icon
|
|
|
|
- name="clear"
|
|
|
|
- class="ml-2"
|
|
|
|
- @click="selectChecked.splice(checkIdx, 1)"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- <div class="flex p-4">
|
|
|
|
- <input
|
|
|
|
- type="text"
|
|
|
|
- v-model="selectKeyword"
|
|
|
|
- class="border border-gray-200 border-r-0 rounded-l px-4"
|
|
|
|
- placeholder="请输入后搜索"
|
|
|
|
- @keyup.enter.native="searchSelectOptions"
|
|
|
|
- />
|
|
|
|
- <van-button
|
|
|
|
- type="primary"
|
|
|
|
- class="rounded-l-none"
|
|
|
|
- @click="searchSelectOptions"
|
|
|
|
- >搜索</van-button
|
|
|
|
- >
|
|
|
|
- </div>
|
|
|
|
- <div v-if="item.config.isAppendNull" class="px-4 text-sm text-gray-500">
|
|
|
|
- 未搜索到?可填入后直接保存
|
|
|
|
- </div>
|
|
|
|
- <div class="h-[50vh] overflow-y-auto">
|
|
|
|
- <div
|
|
|
|
- v-for="(selectItem, selectIndex) in selectOptions"
|
|
|
|
- :key="selectIndex"
|
|
|
|
- class="border-0 border-b border-gray-100 py-2 px-4 flex justify-between"
|
|
|
|
- :class="{
|
|
|
|
- 'text-blue-700': selectChecked.find(v => v.id == selectItem.id)
|
|
|
|
- }"
|
|
|
|
- @click="selectItemChange(selectItem)"
|
|
|
|
- >
|
|
|
|
- <span>{{ selectItem.properties?.name }}</span>
|
|
|
|
- <van-icon
|
|
|
|
- v-if="selectChecked.find(v => v.id == selectItem.id)"
|
|
|
|
- name="success"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- <van-empty v-if="!selectOptions.length"
|
|
|
|
- ><span class="text-gray-600 text-sm">暂无数据</span></van-empty
|
|
|
|
- >
|
|
|
|
- </div>
|
|
|
|
- <div class="flex w-full">
|
|
|
|
- <van-button
|
|
|
|
- class="flex-1 rounded-none border-0"
|
|
|
|
- @click="selectVisible = false"
|
|
|
|
- >取消</van-button
|
|
|
|
- >
|
|
|
|
- <van-button
|
|
|
|
- type="primary"
|
|
|
|
- class="flex-1 rounded-none border-0"
|
|
|
|
- @click="saveSelect"
|
|
|
|
- >保存</van-button
|
|
|
|
- >
|
|
|
|
- </div>
|
|
|
|
- </van-popup>
|
|
|
|
- </template>
|
|
|
|
- <!-- <template v-if="!props.child">
|
|
|
|
- <p
|
|
|
|
- v-if="!item.isAnswered && !item.config?.required"
|
|
|
|
- class="link text-center"
|
|
|
|
- @click="skip(item)"
|
|
|
|
- >
|
|
|
|
- 跳过该题
|
|
|
|
- </p>
|
|
|
|
- <div
|
|
|
|
- v-if="
|
|
|
|
- !item.isAnswered &&
|
|
|
|
- (item.isMultiple ||
|
|
|
|
- item.type === QUESTION_TYPE_MATRIX ||
|
|
|
|
- (item.choices?.length && item.choices.find(v => v.isInput)))
|
|
|
|
- "
|
|
|
|
- class="flex items-center justify-center"
|
|
|
|
- >
|
|
|
|
- <van-button
|
|
|
|
- type="primary"
|
|
|
|
- round
|
|
|
|
- class="text-center confirm-btn"
|
|
|
|
- size="small"
|
|
|
|
- @click="reply(item, null, undefined)"
|
|
|
|
- >确定<span v-if="item.value?.length"
|
|
|
|
- >({{ item.value.length }}个)</span
|
|
|
|
- >
|
|
|
|
- </van-button>
|
|
|
|
- </div>
|
|
|
|
- <p
|
|
|
|
- v-if="!item.isAnswered && repeatAnswer"
|
|
|
|
- class="link text-center"
|
|
|
|
- @click="back(item)"
|
|
|
|
- >
|
|
|
|
- 重答该题
|
|
|
|
- </p>
|
|
|
|
- </template> -->
|
|
|
|
- </div>
|
|
|
|
-</template>
|
|
|
|
-
|
|
|
|
-<script setup>
|
|
|
|
-import { defineProps, defineEmits, computed, ref, reactive } from "vue";
|
|
|
|
-// import { Button, Icon, showNotify, Field, Image, Popup } from "vant";
|
|
|
|
-import { CircleCheck, SuccessFilled } from "@element-plus/icons-vue";
|
|
|
|
-import { formatAge, request } from "@/utils";
|
|
|
|
-// import EditDatetimeCell from "@/components/EditDatetimeCell.vue";
|
|
|
|
-import QuestionItem from "./questionItem.vue";
|
|
|
|
-import iconMan from "@/assets/icon-man.png";
|
|
|
|
-import iconWoman from "@/assets/icon-woman.png";
|
|
|
|
-import { ElMessage } from "element-plus";
|
|
|
|
-const QUESTION_TYPE_TEMP_CHECK = "temp_check"; // 单选 => Q1A1
|
|
|
|
-const QUESTION_TYPE_INPUT = "input"; // 输入 => Q1
|
|
|
|
-const QUESTION_TYPE_TEXTAREA = "textarea"; // 输入 => Q1
|
|
|
|
-const QUESTION_TYPE_TEXT = "text"; // 输入 => Q1
|
|
|
|
-const QUESTION_TYPE_CHECKBOX = "checkbox"; // 多选 => Q1A1
|
|
|
|
-const QUESTION_TYPE_RADIO = "radio"; // 单选 => Q1A1
|
|
|
|
-const QUESTION_TYPE_SCALE = "scale"; // 量表(一排的radio选择指定) => Q1
|
|
|
|
-const QUESTION_TYPE_RATING_SCALE = "rating_scale"; // 量表(一排的radio选择指定) => Q1
|
|
|
|
-const QUESTION_TYPE_RATING = "rating"; // 评分题(选项后面有分值) => Q1A1
|
|
|
|
-const QUESTION_TYPE_DATE = "date"; // 时间题
|
|
|
|
-const QUESTION_TYPE_MATRIX = "matrix_checkbox"; // 矢量题
|
|
|
|
-const QUESTION_TYPE_COMBINATION = "combination"; // 组合题
|
|
|
|
-const QUESTION_TYPE_GROUP = "group"; // 组合题
|
|
|
|
-const QUESTION_TYPE_SELECT = "select"; // 组合题
|
|
|
|
-const emits = defineEmits(["update:info", "skip", "back", "check", "reply"]);
|
|
|
|
-const props = defineProps({
|
|
|
|
- info: {
|
|
|
|
- type: Object,
|
|
|
|
- default: () => {}
|
|
|
|
- },
|
|
|
|
- hideList: {
|
|
|
|
- type: Array,
|
|
|
|
- default: () => []
|
|
|
|
- },
|
|
|
|
- repeatAnswer: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: false
|
|
|
|
- },
|
|
|
|
- child: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: false
|
|
|
|
- }
|
|
|
|
-});
|
|
|
|
-// console.log(props.info);
|
|
|
|
-
|
|
|
|
-const item = computed({
|
|
|
|
- get() {
|
|
|
|
- return props.info;
|
|
|
|
- },
|
|
|
|
- set(value) {
|
|
|
|
- emits("update:info", value);
|
|
|
|
- }
|
|
|
|
-});
|
|
|
|
-
|
|
|
|
-const init = () => {
|
|
|
|
- if (item.value.type === QUESTION_TYPE_MATRIX) {
|
|
|
|
- console.log("测试", item.value);
|
|
|
|
-
|
|
|
|
- item.value.matrix = Array(item.value.rows.length)
|
|
|
|
- .fill(0)
|
|
|
|
- .map(() => Array(item.value.columns.length).fill(false))
|
|
|
|
- .map((rows, rowIdx) => {
|
|
|
|
- rows = rows.map((col, colIdx) => {
|
|
|
|
- if (item.value.value && Array.isArray(item.value.value)) {
|
|
|
|
- return item.value.value.includes(
|
|
|
|
- item.value.rows[rowIdx].label + item.value.columns[colIdx].label
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- return col;
|
|
|
|
- });
|
|
|
|
- return rows;
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-const replyLock = ref(false);
|
|
|
|
-
|
|
|
|
-const inputType = config => {
|
|
|
|
- if (config?.regexRule) {
|
|
|
|
- const { dataType } = config.regexRule;
|
|
|
|
- switch (dataType) {
|
|
|
|
- case "numeric":
|
|
|
|
- return "number";
|
|
|
|
- default:
|
|
|
|
- return "text";
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- switch (config.rule) {
|
|
|
|
- case "number":
|
|
|
|
- return config.rule;
|
|
|
|
- case "phone":
|
|
|
|
- return "tel";
|
|
|
|
- default:
|
|
|
|
- return "text";
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-// 矩阵题选择
|
|
|
|
-const checkMatrix = (rowIdx, colIdx) => {
|
|
|
|
- const curState = item.value.matrix[rowIdx][colIdx];
|
|
|
|
- const isMultiple = item.value.isMultiple;
|
|
|
|
- const mutuallyExclusive = item.value.columns[colIdx].mutuallyExclusive;
|
|
|
|
- // 单选
|
|
|
|
- if (!isMultiple) {
|
|
|
|
- item.value.matrix[rowIdx].forEach((v, k) => {
|
|
|
|
- item.value.matrix[rowIdx][k] = k === colIdx ? !curState : false;
|
|
|
|
- });
|
|
|
|
- } else {
|
|
|
|
- // 多选
|
|
|
|
- // 该列有互斥
|
|
|
|
- if (mutuallyExclusive) {
|
|
|
|
- if (curState) {
|
|
|
|
- item.value.matrix[rowIdx][colIdx] = !curState;
|
|
|
|
- } else {
|
|
|
|
- item.value.matrix[rowIdx].forEach((v, k) => {
|
|
|
|
- item.value.matrix[rowIdx][k] = k === colIdx;
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- item.value.matrix[rowIdx].forEach((v, k) => {
|
|
|
|
- if (item.value.columns[k].mutuallyExclusive) {
|
|
|
|
- item.value.matrix[rowIdx][k] = false;
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- item.value.matrix[rowIdx][colIdx] = !item.value.matrix[rowIdx][colIdx];
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-const skip = item => {
|
|
|
|
- item.value = null;
|
|
|
|
- emits("skip", item);
|
|
|
|
-};
|
|
|
|
-const back = item => {
|
|
|
|
- emits("back", item);
|
|
|
|
-};
|
|
|
|
-const check = (item, flag) => {
|
|
|
|
- emits("check", item, flag);
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-const regexRuleCheck = item => {
|
|
|
|
- if (item.config?.regexRule) {
|
|
|
|
- const { regexRule } = item.config;
|
|
|
|
- const { name, data, dataType, dataTotal } = regexRule;
|
|
|
|
- const { valueList, total } = data;
|
|
|
|
- const value = item.value;
|
|
|
|
-
|
|
|
|
- if (dataTotal === "required") {
|
|
|
|
- if (!value && value !== 0) return "请输入内容";
|
|
|
|
- return "";
|
|
|
|
- }
|
|
|
|
- console.log("value", dataType, value);
|
|
|
|
-
|
|
|
|
- switch (dataType) {
|
|
|
|
- case "specific":
|
|
|
|
- if (valueList.includes(value)) {
|
|
|
|
- return "";
|
|
|
|
- }
|
|
|
|
- return `仅能输入${valueList.join("、")}`;
|
|
|
|
- case "numeric":
|
|
|
|
- if (isNaN(value)) {
|
|
|
|
- return "请输入数字";
|
|
|
|
- }
|
|
|
|
- if (total.min && value <= total.min) {
|
|
|
|
- return `正确的数字区间为${total.min}~${total.max}`;
|
|
|
|
- }
|
|
|
|
- if (total.max && value >= total.max) {
|
|
|
|
- return `正确的数字区间为${total.min}~${total.max}`;
|
|
|
|
- }
|
|
|
|
- return "";
|
|
|
|
- case "string":
|
|
|
|
- if (total.min && value.length <= total.min) {
|
|
|
|
- return `请输入至少${total.min}位`;
|
|
|
|
- }
|
|
|
|
- if (total.max && value.length >= total.max) {
|
|
|
|
- return `请输入最多${total.max}位`;
|
|
|
|
- }
|
|
|
|
- return "";
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- return "";
|
|
|
|
- }
|
|
|
|
- return "";
|
|
|
|
-};
|
|
|
|
-const checkReply = item => {
|
|
|
|
- if (regexRuleCheck(item)) {
|
|
|
|
- ElMessage.error(regexRuleCheck(item));
|
|
|
|
- // showNotify({ type: "danger", message: regexRuleCheck(item) });
|
|
|
|
- replyLock.value = false;
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- if (item.type === QUESTION_TYPE_MATRIX) {
|
|
|
|
- return true;
|
|
|
|
- } else if (item["choices"]?.length) {
|
|
|
|
- if (
|
|
|
|
- (!item.value && item.value !== 0) ||
|
|
|
|
- (Array.isArray(item.value) && !item.value.length)
|
|
|
|
- ) {
|
|
|
|
- // showNotify({ type: "danger", message: "请选择" });
|
|
|
|
- ElMessage.error("请选择");
|
|
|
|
- replyLock.value = false;
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- if (!item.value && item.value !== 0) {
|
|
|
|
- // showNotify(item.value)
|
|
|
|
- ElMessage.error(
|
|
|
|
- `请${item.type === QUESTION_TYPE_DATE ? "选择" : "填写正确内容"}后提交`
|
|
|
|
- );
|
|
|
|
- // showNotify({
|
|
|
|
- // type: "danger",
|
|
|
|
- // message: `请${
|
|
|
|
- // item.type === QUESTION_TYPE_DATE ? "选择" : "填写正确内容"
|
|
|
|
- // }后提交`
|
|
|
|
- // });
|
|
|
|
- replyLock.value = false;
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return true;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-const reply = (item, sub, idx, skip) => {
|
|
|
|
- console.log("触发reply", replyLock.value, item);
|
|
|
|
- if (replyLock.value) return;
|
|
|
|
- console.log("执行reply", item, sub);
|
|
|
|
-
|
|
|
|
- replyLock.value = true;
|
|
|
|
- let text = "";
|
|
|
|
- if (
|
|
|
|
- item.type === QUESTION_TYPE_INPUT ||
|
|
|
|
- item.type === QUESTION_TYPE_TEXTAREA
|
|
|
|
- ) {
|
|
|
|
- // if (!item.value && item.value !== 0) {
|
|
|
|
- // showNotify({ type: 'danger', message: '请输入内容后提交' })
|
|
|
|
- // replyLock.value = false
|
|
|
|
- // return
|
|
|
|
- // }
|
|
|
|
- if (!checkReply(item)) return;
|
|
|
|
- if (item.config?.rule) {
|
|
|
|
- let reg = null;
|
|
|
|
- let errMsg = "";
|
|
|
|
- switch (item.config?.rule) {
|
|
|
|
- case "number":
|
|
|
|
- reg = /^\d+(\d+|\.\d+)?$/;
|
|
|
|
- errMsg = "请输入数字";
|
|
|
|
- break;
|
|
|
|
- case "phone":
|
|
|
|
- reg = /^(?:(?:\+|00)86)?1\d{10}$/;
|
|
|
|
- errMsg = "请输入手机号码";
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- if (reg && !new RegExp(reg).test(item.value)) {
|
|
|
|
- // showNotify({ type: "danger", message: errMsg });
|
|
|
|
- ElMessage.error(errMsg);
|
|
|
|
- replyLock.value = false;
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- text = item.value;
|
|
|
|
- } else if (item.type === QUESTION_TYPE_SCALE) {
|
|
|
|
- text = item.value;
|
|
|
|
- } else if (
|
|
|
|
- item.type === QUESTION_TYPE_CHECKBOX ||
|
|
|
|
- (item.type !== QUESTION_TYPE_MATRIX && item.isMultiple)
|
|
|
|
- ) {
|
|
|
|
- if (skip) {
|
|
|
|
- // let temp = [] as Array<number>
|
|
|
|
- if (typeof item.value === "string" || (!item.value && item.value !== 0)) {
|
|
|
|
- item.value = [idx];
|
|
|
|
- } else {
|
|
|
|
- if (sub?.mutuallyExclusive) {
|
|
|
|
- item.value = [idx];
|
|
|
|
- } else {
|
|
|
|
- item.value = item.value.filter(
|
|
|
|
- v => !item.choices[v]?.mutuallyExclusive
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
- if (item.value.includes(idx)) {
|
|
|
|
- item.value.splice(item.value.indexOf(idx), 1);
|
|
|
|
- } else {
|
|
|
|
- item.value = [...new Set([...item.value, idx])];
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- replyLock.value = false;
|
|
|
|
- return;
|
|
|
|
- } else {
|
|
|
|
- if (item.isMultiple) {
|
|
|
|
- // if (!item.value || (Array.isArray(item.value) && !item.value.length)) {
|
|
|
|
- // showNotify({ type: 'danger', message: '请选择' })
|
|
|
|
- // replyLock.value = false
|
|
|
|
- // return
|
|
|
|
- // }
|
|
|
|
- if (!checkReply(item)) return;
|
|
|
|
- if (Array.isArray(item.value)) {
|
|
|
|
- text = [];
|
|
|
|
- item.value.map(v => {
|
|
|
|
- text.push(item.choices[v].label);
|
|
|
|
- });
|
|
|
|
- text = text.join();
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- text = idx;
|
|
|
|
- }
|
|
|
|
- console.log(item.title);
|
|
|
|
- console.log(item.value);
|
|
|
|
- }
|
|
|
|
- } else if (item.choices?.length && item.choices.find(v => v.isInput)) {
|
|
|
|
- if (skip) {
|
|
|
|
- const _sub = item.choices[idx];
|
|
|
|
- item.value = idx;
|
|
|
|
- text = _sub.isInput ? _sub.extra : _sub.label;
|
|
|
|
- console.log(idx, _sub);
|
|
|
|
- replyLock.value = false;
|
|
|
|
- // return;
|
|
|
|
- } else {
|
|
|
|
- const _sub = item.choices[item.value];
|
|
|
|
- text = _sub.isInput ? _sub.extra || _sub.label : _sub.label;
|
|
|
|
- }
|
|
|
|
- } else if (
|
|
|
|
- item.type === QUESTION_TYPE_COMBINATION ||
|
|
|
|
- item.type === QUESTION_TYPE_GROUP
|
|
|
|
- ) {
|
|
|
|
- console.log("QUESTION_TYPE_COMBINATION");
|
|
|
|
- console.log("组合题value: ");
|
|
|
|
- const val = [];
|
|
|
|
- const t = [];
|
|
|
|
- for (const child of item.children) {
|
|
|
|
- if (!checkReply(child)) return;
|
|
|
|
- if (child.type === QUESTION_TYPE_MATRIX) {
|
|
|
|
- const res = [];
|
|
|
|
- child.matrix.forEach((cols, k1) => {
|
|
|
|
- cols.forEach((c, k2) => {
|
|
|
|
- c && res.push(child.rows[k1].label + "" + child.columns[k2].label);
|
|
|
|
- });
|
|
|
|
- });
|
|
|
|
- if (res?.length) {
|
|
|
|
- t.push(res.join(","));
|
|
|
|
- val.push(res);
|
|
|
|
- } else {
|
|
|
|
- t.push("无");
|
|
|
|
- val.push(["无"]);
|
|
|
|
- }
|
|
|
|
- } else if (child["choices"]?.length) {
|
|
|
|
- t.push(
|
|
|
|
- Array.isArray(child.value)
|
|
|
|
- ? child.value.map(c => child["choices"][c]?.label).join(",")
|
|
|
|
- : child["choices"][child.value]?.label
|
|
|
|
- );
|
|
|
|
- val.push(child.value);
|
|
|
|
- } else {
|
|
|
|
- t.push(child.value);
|
|
|
|
- val.push(child.value);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // item.value = item.children.map((child) => {
|
|
|
|
- // if (child.type === QUESTION_TYPE_MATRIX) {
|
|
|
|
- // let res = []
|
|
|
|
- // child.matrix.forEach((cols: boolean[], k1: number) => {
|
|
|
|
- // cols.forEach((c: boolean, k2: number) => {
|
|
|
|
- // c && res.push(child.rows[k1].label + '' + child.columns[k2].label)
|
|
|
|
- // })
|
|
|
|
- // })
|
|
|
|
- // if (res?.length) {
|
|
|
|
- // t.push(res.join(','))
|
|
|
|
- // return res
|
|
|
|
- // } else {
|
|
|
|
- // t.push('无')
|
|
|
|
- // return ['无']
|
|
|
|
- // }
|
|
|
|
- // } else if (child['choices']?.length) {
|
|
|
|
- // t.push(Array.isArray(child.value) ? child.value.map((c) => child['choices'][c]?.label).join(',') : child['choices'][child.value]?.label)
|
|
|
|
- // } else {
|
|
|
|
- // t.push(child.value)
|
|
|
|
- // return child.value
|
|
|
|
- // }
|
|
|
|
- // return child.value
|
|
|
|
- // })
|
|
|
|
- text = t.join(",");
|
|
|
|
- console.log(item.value, text);
|
|
|
|
-
|
|
|
|
- console.log("==========");
|
|
|
|
- } else if (item.type === QUESTION_TYPE_RATING_SCALE) {
|
|
|
|
- item.value = sub;
|
|
|
|
- text = sub;
|
|
|
|
- } else if (item.type === QUESTION_TYPE_DATE) {
|
|
|
|
- // if (!item.value && item.value !== 0) {
|
|
|
|
- // showNotify({ type: 'danger', message: '请选择后提交' })
|
|
|
|
- // replyLock.value = false
|
|
|
|
- // return
|
|
|
|
- // }
|
|
|
|
- if (!checkReply(item)) return;
|
|
|
|
- // if (item.config?.rule && item.config?.rule === 'age') {
|
|
|
|
- // item.value = formatAge(item.value)
|
|
|
|
- // } else {
|
|
|
|
- // }
|
|
|
|
- item.value = item.value || "";
|
|
|
|
- text = item.config?.rule === "age" ? formatAge(item.value) : item.value;
|
|
|
|
- } else if (item.type === QUESTION_TYPE_MATRIX) {
|
|
|
|
- const res = [];
|
|
|
|
- console.log(`回答矩阵题-----1`);
|
|
|
|
- console.log(item.matrix, item.rows, item.columns);
|
|
|
|
-
|
|
|
|
- item.matrix.forEach((cols, k1) => {
|
|
|
|
- cols.forEach((c, k2) => {
|
|
|
|
- c && res.push(item.rows[k1].label + "" + item.columns[k2].label);
|
|
|
|
- });
|
|
|
|
- });
|
|
|
|
- item.value = res && res.length ? res : ["无"];
|
|
|
|
- text = res && res.length ? res.join(",") : "无";
|
|
|
|
- console.log(`回答矩阵题`);
|
|
|
|
- console.log(res);
|
|
|
|
- } else if (item.type === QUESTION_TYPE_SELECT) {
|
|
|
|
- item.value = selectChecked.value.map(v => {
|
|
|
|
- return {
|
|
|
|
- key: v.id || "",
|
|
|
|
- value: v.properties.name
|
|
|
|
- };
|
|
|
|
- });
|
|
|
|
- text = selectChecked.value.map(v => v.properties.name).join() || "无";
|
|
|
|
- } else {
|
|
|
|
- console.log(`执行到else来了 ${item.type}`);
|
|
|
|
- item.value = idx;
|
|
|
|
- text = item.choices[idx].label;
|
|
|
|
- }
|
|
|
|
- // item.isAnswered = true;
|
|
|
|
- replyLock.value = false;
|
|
|
|
- emits("reply", item, text);
|
|
|
|
-};
|
|
|
|
-// init();
|
|
|
|
-
|
|
|
|
-const selectVisible = ref(false);
|
|
|
|
-const selectKeyword = ref();
|
|
|
|
-const selectOptions = ref([]);
|
|
|
|
-const selectChecked = ref([]);
|
|
|
|
-const selectItemChange = selectItem => {
|
|
|
|
- if (selectChecked.value.find(v => v.id == selectItem.id)) {
|
|
|
|
- selectChecked.value.splice(
|
|
|
|
- selectChecked.value.findIndex(v => v == selectItem.id),
|
|
|
|
- 1
|
|
|
|
- );
|
|
|
|
- } else {
|
|
|
|
- if (item.value.config.isMultiple) {
|
|
|
|
- selectChecked.value.push(selectItem);
|
|
|
|
- } else {
|
|
|
|
- selectChecked.value = [selectItem];
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-const searchSelectOptions = async () => {
|
|
|
|
- const { data } = await request.get(`/graphService/open/node/paginate`, {
|
|
|
|
- params: {
|
|
|
|
- page: 1,
|
|
|
|
- pageSize: 999,
|
|
|
|
- tag: item.value.config.sourceTag,
|
|
|
|
- name: selectKeyword.value
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- selectOptions.value = data.list;
|
|
|
|
-};
|
|
|
|
-const saveSelect = () => {
|
|
|
|
- if (
|
|
|
|
- !selectChecked.value.length &&
|
|
|
|
- selectKeyword.value &&
|
|
|
|
- item.value.config.isAppendNull
|
|
|
|
- ) {
|
|
|
|
- selectChecked.value.push({
|
|
|
|
- id: "",
|
|
|
|
- properties: {
|
|
|
|
- name: selectKeyword.value
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- reply(item.value);
|
|
|
|
- selectVisible.value = false;
|
|
|
|
- selectOptions.value = [];
|
|
|
|
- selectKeyword.value = "";
|
|
|
|
-};
|
|
|
|
-const openSelect = () => {
|
|
|
|
- if (item.value.value) {
|
|
|
|
- selectChecked.value = item.value.value.map(v => {
|
|
|
|
- return {
|
|
|
|
- id: v.key,
|
|
|
|
- properties: {
|
|
|
|
- name: v.value
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- selectVisible.value = true;
|
|
|
|
-};
|
|
|
|
-</script>
|
|
|
|
-
|
|
|
|
-<style lang="scss">
|
|
|
|
-.survey-matrix-container {
|
|
|
|
- overflow-x: auto;
|
|
|
|
- padding: 10px 0;
|
|
|
|
- .survey-matrix {
|
|
|
|
- font-size: 12px;
|
|
|
|
- border-collapse: collapse;
|
|
|
|
- margin: 0 auto;
|
|
|
|
- min-width: 100%;
|
|
|
|
- th,
|
|
|
|
- td {
|
|
|
|
- border: 1px solid #ccc;
|
|
|
|
- padding: 10px;
|
|
|
|
- text-align: center;
|
|
|
|
- }
|
|
|
|
- th {
|
|
|
|
- white-space: nowrap;
|
|
|
|
- }
|
|
|
|
- tr {
|
|
|
|
- td:first-of-type {
|
|
|
|
- font-weight: blod;
|
|
|
|
- white-space: nowrap;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-.confirm-input-btn {
|
|
|
|
- cursor: pointer;
|
|
|
|
- height: 34px;
|
|
|
|
- &:not(:last-of-type) {
|
|
|
|
- margin-right: 10px;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-.link {
|
|
|
|
- color: #4b72f6;
|
|
|
|
-}
|
|
|
|
-</style>
|
|
|