featDesign(): 优化矩阵题配置和功能

- 移除 CompletionQuestionAction 组件中的多余分割线
- 在 MartrixQuestionAction 组件中添加选项随机功能和右极文字限制
-调整 QuestionAction 组件中矩阵题的显示逻辑
-优化 MartrixQuestion 和 MatrixQuestion 组件的表格渲染
- 更新 API 基础 URL
This commit is contained in:
陈昱达
2025-03-13 19:44:53 +08:00
parent 33ac908ef9
commit ef59888490
7 changed files with 185 additions and 87 deletions

View File

@@ -1,5 +1,5 @@
# .env.development # .env.development
VITE_APP_BASEURL=https://yls-api-uat.dctest.digitalyili.com/api/ VITE_APP_BASEURL=https://yls-api-uat.dctest.digitalyili.com/
VITE_APP_ENV=uat VITE_APP_ENV=uat
VITE_APP_CURRENTMODE=uat VITE_APP_CURRENTMODE=uat
VITE_APP_BASEOSS=https://diaoyan-files.automark.cc VITE_APP_BASEOSS=https://diaoyan-files.automark.cc

View File

@@ -13,6 +13,9 @@
"lint": "npx eslint -c ./node_modules/@yl/yili-fe-lint-config/eslintrc.vue3.js \"src/**/*.{js,ts,tsx,vue,html}\" --fix", "lint": "npx eslint -c ./node_modules/@yl/yili-fe-lint-config/eslintrc.vue3.js \"src/**/*.{js,ts,tsx,vue,html}\" --fix",
"stylelint": "npx stylelint -c ./node_modules/@yl/yili-fe-lint-config/stylelintrc.js \"**/*.{css,scss,sass,less,vue,html}\" --fix" "stylelint": "npx stylelint -c ./node_modules/@yl/yili-fe-lint-config/stylelintrc.js \"**/*.{css,scss,sass,less,vue,html}\" --fix"
}, },
"optionalDependencies": {
"@rollup/rollup-linux-x64-musl": "*"
},
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "^2.3.1", "@element-plus/icons-vue": "^2.3.1",
"axios": "^1.8.2", "axios": "^1.8.2",

View File

@@ -29,7 +29,7 @@
</template> </template>
</van-cell> </van-cell>
<van-cell <van-cell
v-if="[1, 2, 9].includes(activeQuestion.question_type)" v-if="[1, 2].includes(activeQuestion.question_type)"
title="选项随机" title="选项随机"
:border="false" :border="false"
> >
@@ -45,12 +45,6 @@
</template> </template>
</van-cell> </van-cell>
<!-- 矩阵题目-->
<martrix-question-action
v-if="[8, 9, 10].includes(activeQuestion.question_type)"
v-model="activeQuestion"
@save-option="saveSettings"
></martrix-question-action>
<van-divider></van-divider> <van-divider></van-divider>
<van-cell title="题前隐藏" :border="false" @click="questionSetting('before')"> <van-cell title="题前隐藏" :border="false" @click="questionSetting('before')">
<template #right-icon> <template #right-icon>
@@ -78,7 +72,7 @@
></rate-question-action> ></rate-question-action>
<!-- 填空--> <!-- 填空-->
<completion-question-action <completion-question-action
v-if="activeQuestion.question_type === 4" v-if="[4, 8].includes(activeQuestion.question_type)"
v-model="activeQuestion" v-model="activeQuestion"
@save-option="saveSettings" @save-option="saveSettings"
></completion-question-action> ></completion-question-action>
@@ -88,6 +82,13 @@
v-model="activeQuestion" v-model="activeQuestion"
@save-option="saveSettings" @save-option="saveSettings"
></field-upload-question-action> ></field-upload-question-action>
<!-- 矩阵题目-->
<martrix-question-action
v-if="[8, 9, 10].includes(activeQuestion.question_type)"
v-model="activeQuestion"
@save-option="saveSettings"
></martrix-question-action>
</van-cell-group> </van-cell-group>
</van-action-sheet> </van-action-sheet>
<!-- 移动 复制--> <!-- 移动 复制-->
@@ -252,8 +253,8 @@ const getSkipTypeText = (skipType) => {
const ls = []; const ls = [];
logics.map((item) => { logics.map((item) => {
if ( if (
item.skip_type === skipType item.skip_type === skipType &&
&& item.question_index === activeQuestion.value.question_index item.question_index === activeQuestion.value.question_index
) { ) {
ls.push(item); ls.push(item);
} }
@@ -269,13 +270,13 @@ const getSkipTypeText = (skipType) => {
const questionSetting = (type) => { const questionSetting = (type) => {
switch (type) { switch (type) {
case 'before': case 'before':
questionBeforeShow.value = true; questionBeforeShow.value = true;
break; break;
case 'after': case 'after':
questionBeforeShow.value = true; questionBeforeShow.value = true;
break; break;
} }
skipType.value = type === 'before' ? 1 : 0; skipType.value = type === 'before' ? 1 : 0;
}; };

View File

@@ -68,7 +68,6 @@
</template> </template>
</van-field> </van-field>
</van-cell-group> </van-cell-group>
<van-divider></van-divider>
<van-cell <van-cell
v-if="![5, 6, 7].includes(actionQuestion.config.text_type)" v-if="![5, 6, 7].includes(actionQuestion.config.text_type)"

View File

@@ -1,6 +1,20 @@
<template> <template>
<van-cell v-if="[9, 10].includes(actionQuestion.question_type)" title="选项随机" :border="false">
<template #right-icon>
<van-switch
v-model="actionQuestion.config.select_random"
class="option-action-sheet-switch"
size="0.5rem"
:active-value="1"
:inactive-value="0"
@change="emit('saveOption')"
></van-switch>
</template>
</van-cell>
<van-field <van-field
v-if="actionQuestion.question_type === 9 && actionQuestion.config.select_random === 1" v-if="
[9, 10].includes(actionQuestion.question_type) && actionQuestion.config.select_random === 1
"
v-model="actionQuestion.config.min_select" v-model="actionQuestion.config.min_select"
label="" label=""
:border="false" :border="false"
@@ -22,6 +36,7 @@
shape="square" shape="square"
name="actionQuestion.config.row_random" name="actionQuestion.config.row_random"
icon-size="0.5rem" icon-size="0.5rem"
@change="emit('saveOption')"
> >
行随机 行随机
</van-checkbox> </van-checkbox>
@@ -31,18 +46,87 @@
shape="square" shape="square"
icon-size="0.5rem" icon-size="0.5rem"
name="actionQuestion.config.cell_random" name="actionQuestion.config.cell_random"
@change="emit('saveOption')"
> >
列随机 列随机
</van-checkbox> </van-checkbox>
</div> </div>
<!-- <van-checkbox-group v-model="">-->
<!-- </van-checkbox-group>-->
</template> </template>
</van-field> </van-field>
<van-cell
title="右极文字"
type="number"
:border="false"
label-align="left"
input-align="right"
label-width="8em"
placeholder="不限"
readonly
@blur="emit('saveOption')"
>
<template #right-icon>
<van-switch
v-model="actionQuestion.config.is_limit_right_content"
:active-value="1"
:inactive-value="0"
size="0.5rem"
@change="emit('saveOption')"
></van-switch>
</template>
</van-cell>
<!-- 每行可选数量-->
<van-cell
v-if="[10].includes(actionQuestion.question_type)"
title="每行可选数量"
:border="false"
label-align="left"
>
</van-cell>
<van-cell-group v-if="[10].includes(actionQuestion.question_type)">
<van-field
v-model="actionQuestion.config.min_select"
label="最少"
type="number"
:border="false"
label-align="left"
input-align="right"
class="action-field"
placeholder="不限"
@blur="emit('saveOption')"
@update:model-value="
(value) => {
actionQuestion.config.min_select = Number(value);
}
"
>
<template #right-icon>
<span>个</span>
</template>
</van-field>
<van-field
v-model="actionQuestion.config.max_select"
label="最多"
type="number"
:border="false"
placeholder="不限"
input-align="right"
class="action-field"
@blur="emit('saveOption')"
@update:model-value="
(value) => {
actionQuestion.config.max_select = Number(value);
}
"
>
<template #right-icon>
<span>个</span>
</template>
</van-field>
</van-cell-group>
</template> </template>
<script setup> <script setup>
import { computed, defineEmits } from 'vue'; import { computed, defineEmits } from 'vue';
import { saveQuestion } from '@/api/design/index.js';
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: Object, type: Object,

View File

@@ -21,14 +21,14 @@ const { element } = toRefs(props);
*/ */
const tableInputTypeMapping = (/** regx?: any */) => { const tableInputTypeMapping = (/** regx?: any */) => {
switch (element.value.question_type) { switch (element.value.question_type) {
case 8: case 8:
return 'text'; return 'text';
case 9: case 9:
return 'radio'; return 'radio';
case 10: case 10:
return 'checkbox'; return 'checkbox';
default: default:
return 'radio'; return 'radio';
} }
}; };
@@ -68,6 +68,8 @@ const emitValue = () => {
@blur="emitValue" @blur="emitValue"
></contenteditable> ></contenteditable>
</td> </td>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -84,6 +86,14 @@ const emitValue = () => {
<!-- 编辑状态单次点击出输入框失焦后关闭 --> <!-- 编辑状态单次点击出输入框失焦后关闭 -->
<input :id="col.option" :type="tableInputTypeMapping()" :name="row.option" /> <input :id="col.option" :type="tableInputTypeMapping()" :name="row.option" />
</td> </td>
<td v-if="element.config.is_limit_right_content === 1">
<contenteditable
v-model="row.option_config.limit_right_content"
:active="active"
@blur="emitValue"
></contenteditable>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -23,14 +23,14 @@ const matrixAnswer = ref({
*/ */
const tableInputTypeMapping = (/** regx?: any */) => { const tableInputTypeMapping = (/** regx?: any */) => {
switch (element.question_type) { switch (element.question_type) {
case 8: case 8:
return 'text'; return 'text';
case 9: case 9:
return 'radio'; return 'radio';
case 10: case 10:
return 'checkbox'; return 'checkbox';
default: default:
return 'radio'; return 'radio';
} }
}; };
@@ -67,55 +67,55 @@ function handleColNameChange(rowOption: string, colOption: string, e: any) {
// 不同的 question_type 的 matrix 问卷处理不同的结果 // 不同的 question_type 的 matrix 问卷处理不同的结果
switch (element.question_type) { switch (element.question_type) {
case 8: { case 8: {
// 获取输入框元素 // 获取输入框元素
const inputElement = e.target as HTMLInputElement; const inputElement = e.target as HTMLInputElement;
// 如果没有获取到输入框元素,则直接返回 // 如果没有获取到输入框元素,则直接返回
if (!inputElement) return; if (!inputElement) return;
// 将输入框的值保存到 rowRecord 对应位置 // 将输入框的值保存到 rowRecord 对应位置
rowRecord[col] = e!.target!.value; rowRecord[col] = e!.target!.value;
// 清空 matrixAnswer 的 answer 属性 // 清空 matrixAnswer 的 answer 属性
matrixAnswer.value.answer = {}; matrixAnswer.value.answer = {};
// 遍历所有行选项 // 遍历所有行选项
element.options[0].forEach((_, rowIndex) => { element.options[0].forEach((_, rowIndex) => {
// 获取当前行记录 // 获取当前行记录
const colOptions = rowRecord[rowIndex]; const colOptions = rowRecord[rowIndex];
// 如果当前行有记录,则更新 matrixAnswer 的 answer 属性 // 如果当前行有记录,则更新 matrixAnswer 的 answer 属性
if (colOptions) { if (colOptions) {
matrixAnswer.value.answer[`R${rowIndex + 1}_C${col + 1}`] = colOptions; matrixAnswer.value.answer[`R${rowIndex + 1}_C${col + 1}`] = colOptions;
} }
}); });
break; break;
} }
case 9: case 9:
// 将选择的行索引加1后保存到 rowRecord 对应位置 // 将选择的行索引加1后保存到 rowRecord 对应位置
rowRecord[col] = row + 1; rowRecord[col] = row + 1;
// 清空 matrixAnswer 的 answer 属性 // 清空 matrixAnswer 的 answer 属性
matrixAnswer.value.answer = {}; matrixAnswer.value.answer = {};
// 遍历 rowRecord更新 matrixAnswer 的 answer 属性 // 遍历 rowRecord更新 matrixAnswer 的 answer 属性
rowRecord.forEach((row, index) => { rowRecord.forEach((row, index) => {
matrixAnswer.value.answer[`${index + 1}_${row}`] = 1; matrixAnswer.value.answer[`${index + 1}_${row}`] = 1;
}); });
break; break;
case 10: case 10:
// 将选择的行索引加1后添加到 rowRecord 对应位置的数组中 // 将选择的行索引加1后添加到 rowRecord 对应位置的数组中
rowRecord[col] = (rowRecord[col] || []).concat(row + 1); rowRecord[col] = (rowRecord[col] || []).concat(row + 1);
// 清空 matrixAnswer 的 answer 属性 // 清空 matrixAnswer 的 answer 属性
matrixAnswer.value.answer = {}; matrixAnswer.value.answer = {};
// 遍历所有行选项 // 遍历所有行选项
element.options[0].forEach((rowOption, rowIndex) => { element.options[0].forEach((rowOption, rowIndex) => {
// 获取当前行记录 // 获取当前行记录
const colOptions = rowRecord[rowIndex]; const colOptions = rowRecord[rowIndex];
// 如果当前行有记录,则更新 matrixAnswer 的 answer 属性 // 如果当前行有记录,则更新 matrixAnswer 的 answer 属性
if (colOptions) { if (colOptions) {
colOptions.forEach((col: any) => { colOptions.forEach((col: any) => {
matrixAnswer.value.answer[`R${rowIndex + 1}_C${col}`] = true; matrixAnswer.value.answer[`R${rowIndex + 1}_C${col}`] = true;
}); });
} }
}); });
break; break;
default: default:
break; break;
} }
} }
</script> </script>
@@ -151,6 +151,7 @@ function handleColNameChange(rowOption: string, colOption: string, e: any) {
/> />
<span v-else @click="col.editor = true" v-html="col.option"></span> <span v-else @click="col.editor = true" v-html="col.option"></span>
</td> </td>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>