feat(component): 优化 contenteditable组件功能
- 添加 showAction 控制编辑按钮显示 - 实现文本域聚焦和失焦时的编辑按钮显示和隐藏 -优化键盘弹出和收起时的编辑按钮显示逻辑 -修复文档中描述的产品问卷配置- 优化问卷设计页面的题目编辑功能
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -162,16 +162,5 @@ export default {
|
||||
question_value: '',
|
||||
question_tag: '',
|
||||
planet_id: '',
|
||||
permissions: {
|
||||
id: 9032,
|
||||
question_id: 17835006,
|
||||
parent_question_id: 0,
|
||||
disable_update: 1,
|
||||
disable_option_update: 1,
|
||||
disable_copy: 1,
|
||||
disable_delete: 1,
|
||||
delete_group_keep_one: 1,
|
||||
disable_copy_delete: 1,
|
||||
disable_copy_update: 1
|
||||
}
|
||||
permissions: {}
|
||||
};
|
||||
60
src/utils/QuestionJsons/Completion.js
Normal file
60
src/utils/QuestionJsons/Completion.js
Normal file
@@ -0,0 +1,60 @@
|
||||
export default {
|
||||
id: '',
|
||||
title: '',
|
||||
stem: '<p>请输入题目(填空)</p>',
|
||||
other: '',
|
||||
question_index: '',
|
||||
question_type: 4,
|
||||
config: {
|
||||
min: '',
|
||||
max: '',
|
||||
version: '',
|
||||
scene: null,
|
||||
shelf: null,
|
||||
ware: null,
|
||||
placeholder: '',
|
||||
is_required: 1,
|
||||
is_three_dimensions: 0,
|
||||
material_sn: '',
|
||||
scene_information: null,
|
||||
simple_scene_information: null,
|
||||
is_behavior: 0,
|
||||
is_price_tag: 0,
|
||||
is_brand: 0,
|
||||
is_initialize: 0,
|
||||
is_default_perspective: 0,
|
||||
left_prompt: '',
|
||||
right_prompt: '',
|
||||
text_type: 0,
|
||||
include_mark: 0,
|
||||
line_type: 1,
|
||||
line_height: 3,
|
||||
decimal_few: 1,
|
||||
type_name: '',
|
||||
float_window: 0,
|
||||
float_window_content: '',
|
||||
popup_window: 0,
|
||||
popup_window_content: '',
|
||||
is_show: [],
|
||||
quick_type: 0
|
||||
},
|
||||
created_at: '',
|
||||
created_user_id: 1180,
|
||||
updated_user_id: null,
|
||||
survey_id: 8721,
|
||||
logic_config: {
|
||||
expect: '',
|
||||
order: 0,
|
||||
type: 0,
|
||||
stay_time: ''
|
||||
},
|
||||
options: [],
|
||||
associate: [],
|
||||
logics_has: false,
|
||||
last_option_index: 0,
|
||||
question_code: '',
|
||||
question_value: '',
|
||||
question_tag: '',
|
||||
planet_id: '',
|
||||
permissions: {}
|
||||
};
|
||||
54
src/utils/QuestionJsons/MartrixQuestion.js
Normal file
54
src/utils/QuestionJsons/MartrixQuestion.js
Normal file
@@ -0,0 +1,54 @@
|
||||
export default {
|
||||
// JSON 需要修改
|
||||
id: '',
|
||||
question_type: 5,
|
||||
question_index: '',
|
||||
stem: '请完成打分',
|
||||
title: '',
|
||||
options: [
|
||||
[
|
||||
{
|
||||
id: 'e46f51b1-bfd8-4d9c-becc-4fb7d175a6f4',
|
||||
is_fixed: 0,
|
||||
is_other: 0,
|
||||
is_remove_other: 0,
|
||||
option: '<p>选项1</p>',
|
||||
option_config: {
|
||||
image_url: [],
|
||||
title: '',
|
||||
instructions: [],
|
||||
option_type: 0,
|
||||
limit_right_content: ''
|
||||
},
|
||||
option_index: 1,
|
||||
parent_id: 0,
|
||||
type: 0,
|
||||
cascade: [],
|
||||
config: []
|
||||
}
|
||||
]
|
||||
],
|
||||
last_option_index: 1,
|
||||
config: {
|
||||
is_required: 1,
|
||||
quick_type: 0,
|
||||
is_show: [],
|
||||
max: 5,
|
||||
min: 1,
|
||||
prompt_center: '',
|
||||
prompt_left: '',
|
||||
prompt_right: '',
|
||||
score_interval: 1,
|
||||
score_type: 0,
|
||||
score_way: 0,
|
||||
prompt_score: 2
|
||||
},
|
||||
associate: [],
|
||||
question_code: '',
|
||||
logic_config: {
|
||||
order: 0,
|
||||
type: 0,
|
||||
expect: '',
|
||||
stay_time: ''
|
||||
}
|
||||
};
|
||||
@@ -162,16 +162,5 @@ export default {
|
||||
question_value: '',
|
||||
question_tag: '',
|
||||
planet_id: '',
|
||||
permissions: {
|
||||
id: 9032,
|
||||
question_id: 17835006,
|
||||
parent_question_id: 0,
|
||||
disable_update: 1,
|
||||
disable_option_update: 1,
|
||||
disable_copy: 1,
|
||||
disable_delete: 1,
|
||||
delete_group_keep_one: 1,
|
||||
disable_copy_delete: 1,
|
||||
disable_copy_update: 1
|
||||
}
|
||||
permissions: {}
|
||||
};
|
||||
53
src/utils/QuestionJsons/Rate.js
Normal file
53
src/utils/QuestionJsons/Rate.js
Normal file
@@ -0,0 +1,53 @@
|
||||
export default {
|
||||
id: '',
|
||||
question_type: 5,
|
||||
question_index: '',
|
||||
stem: '请完成打分',
|
||||
title: '',
|
||||
options: [
|
||||
[
|
||||
{
|
||||
id: 'e46f51b1-bfd8-4d9c-becc-4fb7d175a6f4',
|
||||
is_fixed: 0,
|
||||
is_other: 0,
|
||||
is_remove_other: 0,
|
||||
option: '<p>选项1</p>',
|
||||
option_config: {
|
||||
image_url: [],
|
||||
title: '',
|
||||
instructions: [],
|
||||
option_type: 0,
|
||||
limit_right_content: ''
|
||||
},
|
||||
option_index: 1,
|
||||
parent_id: 0,
|
||||
type: 0,
|
||||
cascade: [],
|
||||
config: []
|
||||
}
|
||||
]
|
||||
],
|
||||
last_option_index: 1,
|
||||
config: {
|
||||
is_required: 1,
|
||||
quick_type: 0,
|
||||
is_show: [],
|
||||
max: 5,
|
||||
min: 1,
|
||||
prompt_center: '',
|
||||
prompt_left: '',
|
||||
prompt_right: '',
|
||||
score_interval: 1,
|
||||
score_type: 0,
|
||||
score_way: 0,
|
||||
prompt_score: 2
|
||||
},
|
||||
associate: [],
|
||||
question_code: '',
|
||||
logic_config: {
|
||||
order: 0,
|
||||
type: 0,
|
||||
expect: '',
|
||||
stay_time: ''
|
||||
}
|
||||
};
|
||||
@@ -1,3 +1,6 @@
|
||||
// 引入QuestionJsons 下的radio 并导出
|
||||
export { default as radio } from './QuestionJsons/radio.js';
|
||||
export { default as checkbox } from './QuestionJsons/checkbox.js';
|
||||
export { default as radio } from './QuestionJsons/Radio.js';
|
||||
export { default as checkbox } from './QuestionJsons/Checkbox.js';
|
||||
export { default as completion } from './QuestionJsons/Completion.js';
|
||||
export { default as rate } from './QuestionJsons/Rate.js';
|
||||
export { default as martrixQuestion } from './QuestionJsons/MartrixQuestion.js';
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
<Choice
|
||||
v-if="element.question_type === 1 || element.question_type === 2"
|
||||
:element="element"
|
||||
:index="index"
|
||||
:active="chooseQuestionId === element.id"
|
||||
></Choice>
|
||||
<!-- 填空题 -->
|
||||
<Completion
|
||||
v-if="element.question_type === 4"
|
||||
:index="index"
|
||||
:element="element"
|
||||
:active="chooseQuestionId === element.id"
|
||||
sn="lXEBBpE2"
|
||||
@@ -38,13 +40,15 @@
|
||||
element.question_type === 10
|
||||
"
|
||||
:element="element"
|
||||
:index="index"
|
||||
:active="chooseQuestionId === element.id"
|
||||
/>
|
||||
|
||||
<!-- 签名题 -->
|
||||
<sign-question
|
||||
v-if="[9, 10, 22].includes(element.question_type)"
|
||||
v-if="[22].includes(element.question_type)"
|
||||
:element="element"
|
||||
:index="index"
|
||||
:active="chooseQuestionId === element.id"
|
||||
/>
|
||||
|
||||
@@ -52,6 +56,7 @@
|
||||
<file-upload
|
||||
v-if="element.question_type === 18"
|
||||
:element="element"
|
||||
:index="index"
|
||||
:active="chooseQuestionId === element.id"
|
||||
></file-upload>
|
||||
|
||||
@@ -59,6 +64,7 @@
|
||||
<Rate
|
||||
v-if="element.question_type === 5"
|
||||
:element="element"
|
||||
:index="index"
|
||||
:active="chooseQuestionId === element.id"
|
||||
sn="lXEBBpE2"
|
||||
/>
|
||||
@@ -67,12 +73,14 @@
|
||||
<TextWithImages
|
||||
v-if="element.question_type === 6"
|
||||
:element="element"
|
||||
:index="index"
|
||||
:active="chooseQuestionId === element.id"
|
||||
/>
|
||||
<!--图文-->
|
||||
<NPS
|
||||
v-if="element.question_type === 106"
|
||||
:element="element"
|
||||
:index="index"
|
||||
:active="chooseQuestionId === element.id"
|
||||
/>
|
||||
<!--组件底部左侧操作-->
|
||||
|
||||
@@ -7,12 +7,7 @@
|
||||
class="base-select"
|
||||
>
|
||||
<template #left-icon>
|
||||
<div
|
||||
class="van-filed"
|
||||
:contenteditable="active"
|
||||
@blur="saveStem($event, element, 'title')"
|
||||
v-html="element.title"
|
||||
/>
|
||||
{{ index + 1 }}
|
||||
</template>
|
||||
<template #label>
|
||||
<contenteditable v-model="element.stem" :active="active"></contenteditable>
|
||||
@@ -93,6 +88,10 @@ const props = defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
});
|
||||
|
||||
@@ -100,9 +99,6 @@ const element = ref(props.element);
|
||||
const saveOption = (e, ele) => {
|
||||
ele.option = e.target.innerHTML;
|
||||
};
|
||||
const saveStem = (e, ele, key) => {
|
||||
ele[key] = e.target.innerHTML;
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.choice-html {
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
:required="element.config.is_required === 1"
|
||||
label-align="top"
|
||||
>
|
||||
<template #left-icon>
|
||||
{{ index + 1 }}
|
||||
</template>
|
||||
<template #label>
|
||||
<div
|
||||
:contenteditable="active"
|
||||
@@ -30,6 +33,10 @@ const props = defineProps({
|
||||
// 补充
|
||||
}
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
:required="element.config.is_required === 1"
|
||||
label-align="top"
|
||||
>
|
||||
<template #left-icon>
|
||||
{{ index + 1 }}
|
||||
</template>
|
||||
<template #label>
|
||||
<div
|
||||
:contenteditable="active"
|
||||
@@ -43,6 +46,10 @@ const props = defineProps({
|
||||
element: {
|
||||
type: Object
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
:required="element.config.is_required === 1"
|
||||
label-align="top"
|
||||
>
|
||||
<template #left-icon>
|
||||
{{ index + 1 }}
|
||||
</template>
|
||||
<template #label>
|
||||
<div
|
||||
:contenteditable="active"
|
||||
@@ -47,6 +50,10 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
sn: { type: String, default: '' },
|
||||
questionType: { type: [String, Number], default: 4 }
|
||||
});
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
label-align="top"
|
||||
class="base-select"
|
||||
>
|
||||
<template #left-icon>
|
||||
{{ index + 1 }}
|
||||
</template>
|
||||
<template #label>
|
||||
<contenteditable v-model="element.stem" :active="active"></contenteditable>
|
||||
<!-- <div v-html="element.stem" v-else></div>-->
|
||||
@@ -29,11 +32,13 @@ const props = defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
});
|
||||
|
||||
const element = ref(props.element);
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -66,8 +66,9 @@ import Design from '@/views/Design/Index.vue';
|
||||
import { useCounterStore } from '@/stores/counter';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { radio, checkbox } from '@/utils/importJsons';
|
||||
import { radio, checkbox, completion, rate, martrixQuestion } from '@/utils/importJsons';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
// 获取 Store 实例
|
||||
const counterStore = useCounterStore();
|
||||
const store = storeToRefs(counterStore);
|
||||
@@ -108,67 +109,102 @@ const quesList = ref([
|
||||
{
|
||||
icon: 'star-o',
|
||||
name: '填空题',
|
||||
question_type: '3'
|
||||
},
|
||||
{
|
||||
icon: 'phone-o',
|
||||
name: '图形打分',
|
||||
question_type: '4'
|
||||
question_type: '3',
|
||||
json: completion
|
||||
},
|
||||
// {
|
||||
// icon: 'phone-o',
|
||||
// name: '图形打分',
|
||||
// question_type: '4',
|
||||
// json: rate
|
||||
// },
|
||||
{
|
||||
icon: 'cart-o',
|
||||
name: '数值打分',
|
||||
question_type: '5'
|
||||
question_type: '4',
|
||||
json: rate
|
||||
},
|
||||
{
|
||||
icon: 'comment-o',
|
||||
name: '矩阵单选',
|
||||
question_type: '6'
|
||||
question_type: '8',
|
||||
json: martrixQuestion
|
||||
},
|
||||
{
|
||||
icon: 'bag-o',
|
||||
name: '矩阵多选',
|
||||
question_type: '7'
|
||||
question_type: '9',
|
||||
json: martrixQuestion
|
||||
},
|
||||
{
|
||||
icon: 'gift-o',
|
||||
name: '矩阵填空',
|
||||
question_type: '8'
|
||||
question_type: '10',
|
||||
json: martrixQuestion
|
||||
},
|
||||
{
|
||||
icon: 'bag-o',
|
||||
name: '文件上传',
|
||||
question_type: '9'
|
||||
},
|
||||
{
|
||||
icon: 'bag-o',
|
||||
name: 'NPS',
|
||||
question_type: '106'
|
||||
}
|
||||
]);
|
||||
|
||||
const questionEvent = (item) => {
|
||||
let questionJson = {};
|
||||
switch (item.question_type) {
|
||||
// 单选
|
||||
case '1':
|
||||
case '2':
|
||||
questionJson = JSON.parse(
|
||||
JSON.stringify({
|
||||
...item.json,
|
||||
id: uuidv4(),
|
||||
question_index: questionInfo.value.survey.last_question_index + 1,
|
||||
options: item.json.options.map((item) => {
|
||||
return item.map((it) => {
|
||||
return {
|
||||
...it,
|
||||
// 主键生成
|
||||
id: uuidv4()
|
||||
};
|
||||
});
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
questionInfo.value.questions.splice(activeQuestionIndex.value + 1, 0);
|
||||
break;
|
||||
}
|
||||
// switch (item.question_type) {
|
||||
// // 单选 多选
|
||||
// case '1':
|
||||
// case '2':
|
||||
//
|
||||
//
|
||||
// break;
|
||||
// // 填空
|
||||
// case '3':
|
||||
// questionJson = JSON.parse(
|
||||
// JSON.stringify({
|
||||
// ...item.json,
|
||||
// id: uuidv4(),
|
||||
// question_index: questionInfo.value.survey.last_question_index + 1
|
||||
// })
|
||||
// );
|
||||
// break;
|
||||
// // 图形打分
|
||||
// case '4':
|
||||
// questionJson = JSON.parse(
|
||||
// JSON.stringify({
|
||||
// ...item.json,
|
||||
// id: uuidv4(),
|
||||
// question_index: questionInfo.value.survey.last_question_index + 1
|
||||
// })
|
||||
// );
|
||||
// break
|
||||
// }
|
||||
|
||||
questionJson = JSON.parse(
|
||||
JSON.stringify({
|
||||
...item.json,
|
||||
id: uuidv4(),
|
||||
question_type: Number(item.question_type),
|
||||
question_index: questionInfo.value.survey.last_question_index + 1,
|
||||
options:
|
||||
item.json.options.length > 0
|
||||
? item.json.options.map((item) => {
|
||||
return item.map((it) => {
|
||||
return {
|
||||
...it,
|
||||
// 主键生成
|
||||
id: uuidv4()
|
||||
};
|
||||
});
|
||||
})
|
||||
: []
|
||||
})
|
||||
);
|
||||
// 给store 装数据 判断是 push 还是 splice
|
||||
if (activeQuestionIndex.value === -1) {
|
||||
questionInfo.value.questions.push(questionJson);
|
||||
|
||||
Reference in New Issue
Block a user