Merge remote-tracking branch 'origin/feature/feature-20250331-h5' into feature/feature-20250331-h5

This commit is contained in:
陈昱达
2025-03-06 17:39:57 +08:00
13 changed files with 993 additions and 451 deletions

View File

@@ -3,7 +3,7 @@
<!-- title 标题和搜索栏 --> <!-- title 标题和搜索栏 -->
<header class="header"> <header class="header">
<div class="title">{{ $route.meta.title }}</div> <div class="title">{{ $route.meta.title }}</div>
<van-search placeholder="请输入搜索关键词" background="#B9F8CF" /> <van-search placeholder="请输入搜索关键词" background="#A5D380" />
</header> </header>
<!-- content --> <!-- content -->
<RouterView /> <RouterView />
@@ -53,7 +53,7 @@ const table = [
<style scoped lang="scss"> <style scoped lang="scss">
.common-layout { .common-layout {
min-height: calc(100vh); min-height: calc(100vh);
background-color: #e9eef3; background-color: white;
color: #333; color: #333;
} }
@@ -61,7 +61,7 @@ const table = [
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 1000; z-index: 1000;
background-color: #b9f8cf; background-color: #A5D380;
.title { .title {
display: flex; display: flex;

View File

@@ -5734,26 +5734,33 @@ export const useCommonStore = defineStore('common', {
logics_has: false logics_has: false
}, },
{ {
id: '123', id: '17852527',
title: 'Q4', title: 'Q1',
stem: '请每行选择1个选项', stem: '<p>这是一个请每行选择1个选项</p>',
question_index: 4, other: '',
question_index: 1,
question_type: 9, question_type: 9,
config: { config: {
disabled: [],
version: '',
scene: null,
shelf: null,
ware: null,
row_option_groups: null,
cell_option_groups: null,
is_repeat: 0,
allow_repeat_num: 2,
repeat_type: 0,
alert_text: '您在每一题的态度与观点均对我们有非常重要的意义,请您务必仔细阅读题目后回答,连续一致的答案可能会导致整个问卷的作废,谢谢您的配合。',
is_required: 1, is_required: 1,
is_change_row_cell: 0, is_change_row_cell: 0,
select_random: 0, select_random: 0,
row_random: 0, row_random: 0,
cell_random: 0, cell_random: 0,
disabled: [],
is_three_dimensions: 0, is_three_dimensions: 0,
material_sn: '', material_sn: '',
version: '',
scene_information: null, scene_information: null,
simple_scene_information: null, simple_scene_information: null,
scene: null,
shelf: null,
ware: null,
is_behavior: 0, is_behavior: 0,
is_price_tag: 0, is_price_tag: 0,
is_brand: 0, is_brand: 0,
@@ -5770,282 +5777,601 @@ export const useCommonStore = defineStore('common', {
quick_type: 0, quick_type: 0,
is_limit_right_content: 0, is_limit_right_content: 0,
option_group_random_inside: null, option_group_random_inside: null,
option_group_random_outside: null, option_group_random_outside: null
row_option_groups: {
max: 2,
min: 0,
option_group: [],
is_hide: 0
},
cell_option_groups: null,
is_repeat: 0,
allow_repeat_num: 2,
repeat_type: 0,
alert_text:
'您在每一题的态度与观点均对我们有非常重要的意义,请您务必仔细阅读题目后回答,连续一致的答案可能会导致整个问卷的作废,谢谢您的配合。'
}, },
tip: '', created_at: '2025-03-05T14:52:06',
question_code: '', created_user_id: 1281,
question_value: '', updated_user_id: null,
other: '', survey_id: 9486,
logic_config: { logic_config: {
expect: '', expect: '',
order: 0, order: 0,
type: 0, type: 0,
stay_time: '' stay_time: ''
}, },
list: [ options: [
{ [
type: 2, {
cite_type: 0, option: '<p style="text-align:center">行标签1</p>',
relation_type: 2, id: '1049186',
relation_out_scope: [], type: 1,
relation_last_scope: 0, is_other: 0,
relation_first_scope: 0, is_fixed: 0,
relation_question_index: 2, is_remove_other: 0,
options: [ created_at: null,
{ created_user_id: null,
option: '<p>选项1</p>', parent_id: null,
is_other: 0, option_index: 1,
is_fixed: 0, list_id: 74484,
is_remove_other: 0, option_code: '',
level: 0, option_config: {
option_key: 'Q2A1', title: '',
option_index: '1', instructions: [],
option_code: '', price: 0,
option_config: { gradient: '',
type: 0, image_url: [],
price: 0, option_type: 0,
title: '', type: 0,
gradient: '', limit_right_content: '<p style="text-align:center">右极文字1</p>',
image_url: [], child_area: null,
child_area: null, binding_goods_id: ''
option_type: 0,
instructions: [],
binding_goods_id: '',
limit_right_content: ''
},
parent_option_index: 0,
children: null
}, },
{ disable_option_update: null,
option: '<p>选项2</p>', cascade: []
is_other: 0, },
is_fixed: 0, {
is_remove_other: 0, option: '<p style="text-align:center">行标签2</p>',
level: 0, id: '1049187',
option_key: 'Q2A2', type: 1,
option_index: '2', is_other: 0,
option_code: '', is_fixed: 0,
option_config: { is_remove_other: 0,
type: 0, created_at: null,
price: 0, created_user_id: null,
title: '', parent_id: null,
gradient: '', option_index: 2,
image_url: [], list_id: 74484,
child_area: null, option_code: '',
option_type: 0, option_config: {
instructions: [], title: '',
binding_goods_id: '', instructions: [],
limit_right_content: '' price: 0,
}, gradient: '',
parent_option_index: 0, image_url: [],
children: null option_type: 0,
type: 0,
limit_right_content: '<p style="text-align:center">右极文字2</p>',
child_area: null,
binding_goods_id: ''
}, },
{ disable_option_update: null,
option: '<p>选项3</p>', cascade: []
is_other: 0, }
is_fixed: 0, ],
is_remove_other: 0, [
level: 0, {
option_key: 'Q2A3', option: '<p style="text-align:center">列标签1</p>',
option_index: '3', id: '1049188',
option_code: '', type: 2,
option_config: { is_other: 0,
type: 0, is_fixed: 0,
price: 0, is_remove_other: 0,
title: '', created_at: null,
gradient: '', created_user_id: null,
image_url: [], parent_id: null,
child_area: null, option_index: 3,
option_type: 0, list_id: 74485,
instructions: [], option_code: '',
binding_goods_id: '', option_config: {
limit_right_content: '' title: '',
}, instructions: [],
parent_option_index: 0, price: 0,
children: null gradient: '',
} image_url: [],
] option_type: 0,
}, type: 0,
{ limit_right_content: '',
type: 1, child_area: null,
cite_type: 0, binding_goods_id: ''
relation_type: 0,
relation_out_scope: [],
relation_last_scope: 0,
relation_first_scope: 0,
relation_question_index: 0,
options: [
{
option: '<p style="text-align:center;">行标签11</p>',
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
level: 0,
option_key: '1',
option_index: '9',
option_code: '',
option_config: {
type: 0,
price: 0,
title: '',
gradient: '',
image_url: [],
child_area: null,
option_type: 0,
instructions: [],
binding_goods_id: '',
limit_right_content: '右极文字1'
},
parent_option_index: 0,
children: null
}, },
{ disable_option_update: null,
option: '<p style="text-align:center;">行标签21</p>', cascade: []
is_other: 0, },
is_fixed: 0, {
is_remove_other: 0, option: '<p style="text-align:center">列标签2</p>',
level: 0, id: '1049189',
option_key: '2', type: 2,
option_index: '10', is_other: 0,
option_code: '', is_fixed: 0,
option_config: { is_remove_other: 0,
type: 0, created_at: null,
price: 0, created_user_id: null,
title: '', parent_id: null,
gradient: '', option_index: 4,
image_url: [], list_id: 74485,
child_area: null, option_code: '',
option_type: 0, option_config: {
instructions: [], title: '',
binding_goods_id: '', instructions: [],
limit_right_content: '右极文字2' price: 0,
}, gradient: '',
parent_option_index: 0, image_url: [],
children: null option_type: 0,
type: 0,
limit_right_content: '',
child_area: null,
binding_goods_id: ''
}, },
{ disable_option_update: null,
option: '<p style="text-align:center;">行标签31</p>', cascade: []
is_other: 0, },
is_fixed: 0, {
is_remove_other: 0, option: '<p style="text-align:center">列标签3</p>',
level: 0, id: '1049190',
option_key: '3', type: 2,
option_index: '11', is_other: 0,
option_code: '', is_fixed: 0,
option_config: { is_remove_other: 0,
type: 0, created_at: null,
price: 0, created_user_id: null,
title: '', parent_id: null,
gradient: '', option_index: 5,
image_url: [], list_id: 74485,
child_area: null, option_code: '',
option_type: 0, option_config: {
instructions: [], title: '',
binding_goods_id: '', instructions: [],
limit_right_content: '右极文字3' price: 0,
}, gradient: '',
parent_option_index: 0, image_url: [],
children: null option_type: 0,
} type: 0,
] limit_right_content: '',
}, child_area: null,
{ binding_goods_id: ''
type: 2,
cite_type: 0,
relation_type: 0,
relation_out_scope: [],
relation_last_scope: 0,
relation_first_scope: 0,
relation_question_index: 0,
options: [
{
option: '<p style="text-align:center;">列标签1</p>',
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
level: 0,
option_key: '1',
option_index: '12',
option_code: '',
option_config: {
type: 0,
price: 0,
title: '',
gradient: '',
image_url: [],
child_area: null,
option_type: 0,
instructions: [],
binding_goods_id: '',
limit_right_content: '右极文字1'
},
parent_option_index: 0,
children: null
}, },
{ disable_option_update: null,
option: '<p style="text-align:center;">列标签2</p>', cascade: []
is_other: 0, }
is_fixed: 0, ]
is_remove_other: 0,
level: 0,
option_key: '2',
option_index: '13',
option_code: '',
option_config: {
type: 0,
price: 0,
title: '',
gradient: '',
image_url: [],
child_area: null,
option_type: 0,
instructions: [],
binding_goods_id: '',
limit_right_content: '右极文字2'
},
parent_option_index: 0,
children: null
},
{
option: '<p style="text-align:center;">列标签3</p>',
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
level: 0,
option_key: '3',
option_index: '14',
option_code: '',
option_config: {
type: 0,
price: 0,
title: '',
gradient: '',
image_url: [],
child_area: null,
option_type: 0,
instructions: [],
binding_goods_id: '',
limit_right_content: '右极文字3'
},
parent_option_index: 0,
children: null
}
]
}
], ],
related: [] associate: [],
logics_has: null,
last_option_index: 5,
question_code: '',
question_value: '',
question_tag: '',
planet_id: '',
permissions: null
}, {
id: '17852528',
title: 'Q2',
stem: '<p>这是多选矩阵内容</p>',
other: '',
question_index: 2,
question_type: 10,
config: {
disabled: [],
version: '',
scene: null,
shelf: null,
ware: null,
row_option_groups: null,
cell_option_groups: null,
is_repeat: 0,
allow_repeat_num: 2,
repeat_type: 0,
alert_text: '您在每一题的态度与观点均对我们有非常重要的意义,请您务必仔细阅读题目后回答,连续一致的答案可能会导致整个问卷的作废,谢谢您的配合。',
is_required: 1,
is_change_row_cell: 0,
row_random: 0,
cell_random: 0,
select_random: 0,
min_select: '',
max_select: '',
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,
is_disable_lines_same: 0,
disable_lines_same: 1,
float_window: 0,
is_disable: 0,
float_window_content: '',
popup_window: 0,
popup_window_content: '',
is_show: [],
quick_type: 0,
is_limit_right_content: 0,
each_number: 1,
option_group_random_inside: null,
option_group_random_outside: null
},
created_at: '2025-03-05T14:53:03',
created_user_id: 1281,
updated_user_id: null,
survey_id: 9486,
logic_config: {
expect: '',
order: 0,
type: 0,
stay_time: ''
},
options: [
[
{
option: '<p style="text-align:center">行标签1</p>',
id: '1049191',
type: 1,
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
created_at: null,
created_user_id: null,
parent_id: null,
option_index: 1,
list_id: 74486,
option_code: '',
option_config: {
title: '',
instructions: [],
price: 0,
gradient: '',
image_url: [],
option_type: 0,
type: 0,
limit_right_content: '<p style="text-align:center">右极文字1</p>',
child_area: null,
binding_goods_id: ''
},
disable_option_update: null,
cascade: []
},
{
option: '<p style="text-align:center">行标签2</p>',
id: '1049192',
type: 1,
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
created_at: null,
created_user_id: null,
parent_id: null,
option_index: 2,
list_id: 74486,
option_code: '',
option_config: {
title: '',
instructions: [],
price: 0,
gradient: '',
image_url: [],
option_type: 0,
type: 0,
limit_right_content: '<p style="text-align:center">右极文字2</p>',
child_area: null,
binding_goods_id: ''
},
disable_option_update: null,
cascade: []
}
],
[
{
option: '<p style="text-align:center">列标签1</p>',
id: '1049193',
type: 2,
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
created_at: null,
created_user_id: null,
parent_id: null,
option_index: 3,
list_id: 74487,
option_code: '',
option_config: {
title: '',
instructions: [],
price: 0,
gradient: '',
image_url: [],
option_type: 0,
type: 0,
limit_right_content: '',
child_area: null,
binding_goods_id: ''
},
disable_option_update: null,
cascade: []
},
{
option: '<p style="text-align:center">列标签2</p>',
id: '1049194',
type: 2,
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
created_at: null,
created_user_id: null,
parent_id: null,
option_index: 4,
list_id: 74487,
option_code: '',
option_config: {
title: '',
instructions: [],
price: 0,
gradient: '',
image_url: [],
option_type: 0,
type: 0,
limit_right_content: '',
child_area: null,
binding_goods_id: ''
},
disable_option_update: null,
cascade: []
},
{
option: '<p style="text-align:center">列标签3</p>',
id: '1049214',
type: 2,
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
created_at: null,
created_user_id: null,
parent_id: null,
option_index: 5,
list_id: 74487,
option_code: '',
option_config: {
title: '',
instructions: [],
price: 0,
gradient: '',
image_url: [],
option_type: 0,
type: 0,
limit_right_content: '',
child_area: null,
binding_goods_id: ''
},
disable_option_update: null,
cascade: []
}
]
],
associate: [],
logics_has: null,
last_option_index: 5,
question_code: '',
question_value: '',
question_tag: '',
planet_id: '',
permissions: null
}, {
id: '17852530',
title: 'Q3',
stem: '<p>这个是多选填空内容</p>',
other: '',
question_index: 3,
question_type: 8,
config: {
min: '',
max: '',
placeholder: '请输入',
disabled: [],
version: '',
scene: null,
shelf: null,
ware: null,
row_option_groups: null,
cell_option_groups: null,
is_repeat: 0,
allow_repeat_num: 2,
repeat_type: 0,
alert_text: '您在每一题的态度与观点均对我们有非常重要的意义,请您务必仔细阅读题目后回答,连续一致的答案可能会导致整个问卷的作废,谢谢您的配合。',
is_required: 1,
is_change_row_cell: 0,
row_random: 0,
cell_random: 0,
select_random: 0,
left_prompt: '',
right_prompt: '',
text_type: 0,
include_mark: 0,
decimal_few: 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,
float_window: 0,
is_disable: 0,
float_window_content: '',
popup_window: 0,
popup_window_content: '',
is_show: [],
quick_type: 0,
is_limit_right_content: 0,
line_type: 0,
line_height: 1
},
created_at: '2025-03-05T14:53:33',
created_user_id: 1281,
updated_user_id: null,
survey_id: 9486,
logic_config: {
expect: '',
order: 0,
type: 0,
stay_time: ''
},
options: [
[
{
option: '<p style="text-align:center">行标签1</p>',
id: '1049199',
type: 1,
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
created_at: null,
created_user_id: null,
parent_id: null,
option_index: 1,
list_id: 74490,
option_code: '',
option_config: {
title: '',
instructions: [],
price: 0,
gradient: '',
image_url: [],
option_type: 0,
type: 0,
limit_right_content: '<p style="text-align:center">右极文字1</p>',
child_area: null,
binding_goods_id: ''
},
disable_option_update: null,
cascade: []
},
{
option: '<p style="text-align:center">行标签2</p>',
id: '1049200',
type: 1,
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
created_at: null,
created_user_id: null,
parent_id: null,
option_index: 2,
list_id: 74490,
option_code: '',
option_config: {
title: '',
instructions: [],
price: 0,
gradient: '',
image_url: [],
option_type: 0,
type: 0,
limit_right_content: '<p style="text-align:center">右极文字2</p>',
child_area: null,
binding_goods_id: ''
},
disable_option_update: null,
cascade: []
}
],
[
{
option: '<p style="text-align:center">列标签1</p>',
id: '1049201',
type: 2,
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
created_at: null,
created_user_id: null,
parent_id: null,
option_index: 3,
list_id: 74491,
option_code: '',
option_config: {
title: '',
instructions: [],
price: 0,
gradient: '',
image_url: [],
option_type: 0,
type: 0,
limit_right_content: '',
child_area: null,
binding_goods_id: ''
},
disable_option_update: null,
cascade: []
},
{
option: '<p style="text-align:center">列标签2</p>',
id: '1049202',
type: 2,
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
created_at: null,
created_user_id: null,
parent_id: null,
option_index: 4,
list_id: 74491,
option_code: '',
option_config: {
title: '',
instructions: [],
price: 0,
gradient: '',
image_url: [],
option_type: 0,
type: 0,
limit_right_content: '',
child_area: null,
binding_goods_id: ''
},
disable_option_update: null,
cascade: []
},
{
option: '<p style="text-align:center">列标签3</p>',
id: '1049213',
type: 2,
is_other: 0,
is_fixed: 0,
is_remove_other: 0,
created_at: null,
created_user_id: null,
parent_id: null,
option_index: 5,
list_id: 74491,
option_code: '',
option_config: {
title: '',
instructions: [],
price: 0,
gradient: '',
image_url: [],
option_type: 0,
type: 0,
limit_right_content: '',
child_area: null,
binding_goods_id: ''
},
disable_option_update: null,
cascade: []
}
]
],
associate: [],
logics_has: null,
last_option_index: 5,
question_code: '',
question_value: '',
question_tag: '',
planet_id: '',
permissions: null
} }
], ],
cycle_pages: null cycle_pages: null

View File

@@ -1,46 +1,33 @@
<template> <template>
<div class="design-create"> <div class="design-create">
<draggable <draggable
v-model:data="questionInfo.questions" v-model:data="questionInfo.questions" item-key="id" handle=".moverQues" chosenClass="chosen"
item-key="id" animation="300" :scroll="true"
handle=".moverQues"
chosenClass="chosen"
animation="300"
:scroll="true"
> >
<template #item="{ element, index }"> <template #item="{ element, index }">
<choose-question <choose-question
:element="element" :element="element" :questions="questionInfo.questions" :index="index"
:questions="questionInfo.questions" :chooseQuestionId="chooseQuestionId" @get-choose-question-id="getChooseQuestionId"
:index="index"
:chooseQuestionId="chooseQuestionId"
@get-choose-question-id="getChooseQuestionId"
> >
<!-- 选择题 --> <!-- 选择题 -->
<Choice <Choice
v-if="element.question_type === 1 || element.question_type === 2" v-if="element.question_type === 1 || element.question_type === 2" :element="element"
:element="element"
:active="chooseQuestionId === element.id" :active="chooseQuestionId === element.id"
></Choice> ></Choice>
<!-- 填空题 --> <!-- 填空题 -->
<Completion <Completion
v-if="element.question_type === 4" v-if="element.question_type === 4" :element="element" :active="chooseQuestionId === element.id"
:element="element"
:active="chooseQuestionId === element.id"
sn="lXEBBpE2" sn="lXEBBpE2"
></Completion> ></Completion>
<martrix-question <martrix-question
v-if="element.question_type === 9" v-if="element.question_type === 8 || element.question_type === 9 || element.question_type === 10"
:element="element" :element="element" :active="chooseQuestionId === element.id"
:active="chooseQuestionId === element.id"
/> />
<!-- 打分题 --> <!-- 打分题 -->
<Rate <Rate
v-if="element.question_type === 5" v-if="element.question_type === 5" :element="element" :active="chooseQuestionId === element.id"
:element="element"
:active="chooseQuestionId === element.id"
sn="lXEBBpE2" sn="lXEBBpE2"
/> />
@@ -55,11 +42,7 @@
<template #action="{ element: el }"> <template #action="{ element: el }">
<div class="flex slot-actions"> <div class="flex slot-actions">
<template v-for="(item, optionIndex) in actionOptions"> <template v-for="(item, optionIndex) in actionOptions">
<div <div v-if="item.question_type.includes(el.question_type)" :key="optionIndex" class="flex">
v-if="item.question_type.includes(el.question_type)"
:key="optionIndex"
class="flex"
>
<template v-for="(act, actIndex) in item.actions" :key="actIndex"> <template v-for="(act, actIndex) in item.actions" :key="actIndex">
<div class="flex align-center action-item" @click="actionEvent(act, el)"> <div class="flex align-center action-item" @click="actionEvent(act, el)">
<van-icon :name="act.icon"></van-icon> <van-icon :name="act.icon"></van-icon>
@@ -75,11 +58,8 @@
<!-- {{ element.question_type }}--> <!-- {{ element.question_type }}-->
<!-- {{questionInfo.survey.pages.length}}--> <!-- {{questionInfo.survey.pages.length}}-->
<paging <paging
v-if="!element.question_type && questionInfo.survey.pages.length > 1" v-if="!element.question_type && questionInfo.survey.pages.length > 1" :info="element" :index="index"
:info="element" :active="pageIsActive(activeIndex, questionInfo.questions, element.page)" @click.stop=""
:index="index"
:active="pageIsActive(activeIndex, questionInfo.questions, element.page)"
@click.stop=""
/> />
</template> </template>
</draggable> </draggable>
@@ -168,6 +148,21 @@ const actionOptions = [
fun: 'radioAddOption' fun: 'radioAddOption'
} }
] ]
}, {
question_type: [8, 9, 10],
// 矩阵问卷逻辑处理
actions: [
{
label: '添加行标签',
icon: 'add',
fun: 'addMatrixRowOption'
},
{
label: '添加列标签',
icon: 'add',
fun: 'addMatrixColumnOption'
}
]
} }
]; ];
// 事件分发 // 事件分发
@@ -197,6 +192,23 @@ const actionFun = {
}); });
}); });
element.last_option_index += 1; element.last_option_index += 1;
},
/**
* martrix 矩阵行数增加
* @param element {import('./components/Questions/types/martrix.js').MatrixSurveyQuestion}
*/
addMatrixRowOption: (element) => {
element.options[0].push({
option: '新增行'
});
},
/**
* martrix 矩阵列数增加
* @param element {import('./components/Questions/types/martrix.js').MatrixSurveyQuestion}
*/
addMatrixColumnOption: (element) => {
element.options[1].push({ option: '新增列' });
} }
}; };
@@ -215,7 +227,7 @@ onMounted(() => {
color: #333; color: #333;
.slot-actions { .slot-actions {
& .action-item + .action-item { & .action-item+.action-item {
margin-left: 10px; margin-left: 10px;
} }
} }

View File

@@ -117,23 +117,23 @@ const openMoveModel = (item, index) => {
// 上下移动 // 上下移动
const optionMove = (action) => { const optionMove = (action) => {
switch (action.action) { switch (action.action) {
case 'up': case 'up':
if (activeIndex.value === 0) { if (activeIndex.value === 0) {
moveShow.value = false; moveShow.value = false;
return false; return false;
} }
// 向上移动 // 向上移动
element.value.splice(activeIndex.value - 1, 0, element.value.splice(activeIndex.value, 1)[0]); element.value.splice(activeIndex.value - 1, 0, element.value.splice(activeIndex.value, 1)[0]);
activeIndex.value -= 1; activeIndex.value -= 1;
break; break;
case 'down': case 'down':
if (activeIndex.value === element.value.length - 1) { if (activeIndex.value === element.value.length - 1) {
moveShow.value = false; moveShow.value = false;
return false; return false;
} }
element.value.splice(activeIndex.value + 1, 0, element.value.splice(activeIndex.value, 1)[0]); element.value.splice(activeIndex.value + 1, 0, element.value.splice(activeIndex.value, 1)[0]);
activeIndex.value += 1; activeIndex.value += 1;
break; break;
} }
}; };

View File

@@ -1,98 +1,84 @@
<script setup lang="ts"> <script setup lang="ts">
// import { showConfirmDialog } from 'vant'; import { useTemplateRef, type Directive } from 'vue';
const { element } = defineProps({ const columnLabels = useTemplateRef<HTMLElement[]>('columnLabels');
element: {
type: Object, // 注意, element.options 里面的东西是数组,第一项内容是行标签内容,第二项内容是列标签内容
required: true, // 类型 AI 生成 切勿盲目相信,以实际为准
default: () => ({}) const { element } = defineProps<{ element: MatrixSurveyQuestion }>();
}
});
/** /**
* input 类型映射,里面自行处理逻辑返回对应类型 * input 类型映射,里面自行处理逻辑返回对应类型
* @param regx * // remark: 填空内容 question_type 8
* // remark: 单选打分矩阵 question_type 9
* // remark: 多选矩阵内容 question_type 10
* @default 'radio' * @default 'radio'
*/ */
const tableInputTypeMapping = (/** regx?: any */) => { const tableInputTypeMapping = (/** regx?: any */) => {
return 'radio'; switch (element.question_type) {
case 8:
return 'text';
case 9:
return 'radio';
case 10:
return 'checkbox';
default:
return 'radio';
}
}; };
/** /**
* 增加行或者列 * 自定义指令,用于在元素挂载后自动获取焦点
* @param addType 增加行或列的类型
*/ */
const handleAdd = (addType: 'row' | 'col') => { const vFocus: Directive = {
const row = element.list[1].options; mounted(el: HTMLInputElement) {
const col = element.list[2].options; el.focus();
addType === 'row' ? row.push([]) : col.push([]);
};
const handleMartrixAction = (action: 'delete' | 'setting' | 'more') => {
switch (action) {
// case 'delete':
// showConfirmDialog({
// title: '提示',
// message: '是否确认删除题目?'
// }).then(() => {
// element.list = [];
// });
// break;
// case 'setting':
// break;
// case 'more':
// break;
default:
break;
} }
}; };
</script> </script>
<template> <template>
<van-cell-group :border="false"> <van-cell>
<van-cell> <!-- 使用 title 插槽来自定义标题 -->
<!-- 使用 title 插槽来自定义标题 --> <template #title>
<template #title> <span>
<span v-if="element.config.is_required">*</span> <span v-if="element?.config?.is_required">*</span>
<span>{{ element.title }} {{ element.stem }}</span> <span v-html="element.title"></span>
</template> <span v-html="element.stem"></span>
</span>
</template>
<!-- 使用 label 插槽来自定义标题 --> <!-- 使用 label 插槽来自定义标题 -->
<template #label> <template #label>
<table class="martrix-table"> <table class="martrix-table">
<thead>
<tr> <tr>
<!-- 第一行内容为空 -->
<th></th> <th></th>
<th v-for="col in element.list[2].options" :key="col.option" v-html="col.option"></th> <!-- 第二行内容开始填充 -->
</tr> <td v-for="(col) in element.options[1]" :key="col.option" ref="columnLabels">
<tr v-for="row in element.list[1].options" :key="row.option"> <!-- 编辑状态单次点击出输入框失焦后关闭 -->
<td v-html="row.option"></td> <input v-if="col.editor" v-model="col.option" v-focus type="text" @focusout="col.editor = false" />
<!-- table 表格里面的内容和 th 保持一致 --> <span v-else @click="col.editor = true" v-html="col.option"></span>
<td v-for="col in element.list[2].options" :key="col.option">
<input :type="tableInputTypeMapping()" :name="col.option" />
</td> </td>
</tr> </tr>
</table> </thead>
<!-- 底部功能按钮 --> <tbody>
<van-row class="martrix-table-action"> <tr v-for="row in element.options[0]" :key="row.option">
<van-col :span="12"> <!-- 编辑状态单次点击出输入框失焦后关闭 -->
<span @click="handleAdd('row')"> <van-icon name="add-o" />添加行标签</span> <td>
<span @click="handleAdd('col')"> <van-icon name="add-o" />添加列标签</span> <input v-if="row.editor" v-model="row.option" v-focus type="text" @focusout="row.editor = false" />
</van-col> <span v-else @click="row.editor = true" v-html="row.option"></span>
<van-col :span="6" :offset="6" class="martrix-table-action-tool"> </td>
<span @click="handleMartrixAction('delete')"> <td v-for="col in element.options[1]" :key="col.option">
<van-icon name="delete" style="color: red" <!-- 编辑状态单次点击出输入框失焦后关闭 -->
/></span> <input :id="col.option" :type="tableInputTypeMapping()" :name="row.option" />
<span @click="handleMartrixAction('setting')"> </td>
<van-icon name="setting" style="color: lightgrey" </tr>
/></span> </tbody>
<span @click="handleMartrixAction('more')"> </table>
<van-icon name="ellipsis" style="color: lightgrey" </template>
/></span> </van-cell>
</van-col>
</van-row>
</template>
</van-cell>
</van-cell-group>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.martrix-table { .martrix-table {
@@ -107,6 +93,11 @@ const handleMartrixAction = (action: 'delete' | 'setting' | 'more') => {
border-width: 0 0 1px; border-width: 0 0 1px;
text-align: left; text-align: left;
} }
}
input[type="text"] {
width: 85%;
} }
.martrix-table-action { .martrix-table-action {
@@ -121,7 +112,7 @@ const handleMartrixAction = (action: 'delete' | 'setting' | 'more') => {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
& > span { &>span {
margin-right: 6px; margin-right: 6px;
font-size: 16px; font-size: 16px;
} }

View File

@@ -11,8 +11,7 @@
class="iconfont active-icon" class="iconfont active-icon"
:style="{ marginRight: isLastPage ? '0' : '16px' }" :style="{ marginRight: isLastPage ? '0' : '16px' }"
@click="activePage" @click="activePage"
>&#xe86c;</i >&#xe86c;</i>
>
<template v-if="!isLastPage"> <template v-if="!isLastPage">
<i class="iconfont moverQues" style="margin-right: 16px">&#xe71b;</i> <i class="iconfont moverQues" style="margin-right: 16px">&#xe71b;</i>
<i class="iconfont" @click="deleteHandle">&#xe6c5;</i> <i class="iconfont" @click="deleteHandle">&#xe6c5;</i>

View File

@@ -0,0 +1,213 @@
/**
* 选项配置类型
* @property {string} title - 标题(通常为空)
* @property {string[]} instructions - 指导语(通常为空数组)
* @property {number} price - 价格(通常为 0
* @property {string} gradient - 渐变(通常为空字符串)
* @property {string[]} image_url - 图片 URL 列表(通常为空数组)
* @property {number} option_type - 选项类型(通常为 0
* @property {number} type - 类型(通常为 0
* @property {string} limit_right_content - 右侧极限文字内容
* @property {null | any} child_area - 子区域(通常为 null
* @property {string} binding_goods_id - 绑定商品 ID通常为空字符串
*/
type OptionConfig = {
title?: string;
instructions?: string[];
price?: number;
gradient?: string;
image_url?: string[];
option_type?: number;
type?: number;
limit_right_content?: string;
child_area?: null | any;
binding_goods_id?: string;
};
/**
* 单个选项类型
* @property {boolean} editor - 是否处于编辑状态
* @property {string} option - 选项内容HTML 格式)
* @property {string} id - 选项 ID
* @property {number} type - 选项类型1 表示行选项2 表示列选项等)
* @property {number} is_other - 是否为其他选项0 表示否1 表示是)
* @property {number} is_fixed - 是否固定0 表示否1 表示是)
* @property {number} is_remove_other - 是否移除其他选项0 表示否1 表示是)
* @property {string | null} created_at - 创建时间(可能为 null
* @property {string | null} created_user_id - 创建用户 ID可能为 null
* @property {string | null} parent_id - 父级 ID通常为 null
* @property {number} option_index - 选项索引
* @property {number} list_id - 列表 ID
* @property {string} option_code - 选项代码(通常为空字符串)
* @property {OptionConfig} option_config - 选项配置
* @property {string | null} disable_option_update - 禁用选项更新(通常为 null
* @property {any[]} cascade - 级联关系(通常为空数组)
*/
type Option = {
editor: boolean;
option?: string;
id?: string;
type?: number;
is_other?: number;
is_fixed?: number;
is_remove_other?: number;
created_at?: string | null;
created_user_id?: string | null;
parent_id?: string | null;
option_index?: number;
list_id?: number;
option_code?: string;
option_config?: OptionConfig;
disable_option_update?: string | null;
cascade?: any[];
};
/**
* 配置类型
* @property {string[]} disabled - 禁用的选项列表(通常为空数组)
* @property {string} version - 版本号(通常为空字符串)
* @property {string | null} scene - 场景(通常为 null
* @property {string | null} shelf - 货架(通常为 null
* @property {string | null} ware - 商品(通常为 null
* @property {string | null} row_option_groups - 行选项组(通常为 null
* @property {string | null} cell_option_groups - 列选项组(通常为 null
* @property {number} is_repeat - 是否重复0 表示否1 表示是)
* @property {number} allow_repeat_num - 允许重复的数量
* @property {number} repeat_type - 重复类型(通常为 0
* @property {string} alert_text - 提示文本
* @property {number} is_required - 是否必填0 表示否1 表示是)
* @property {number} is_change_row_cell - 是否允许更改行列选项0 表示否1 表示是)
* @property {number} select_random - 是否随机选择行0 表示否1 表示是)
* @property {number} row_random - 是否随机选择行选项0 表示否1 表示是)
* @property {number} cell_random - 是否随机选择列选项0 表示否1 表示是)
* @property {number} is_three_dimensions - 是否为三维矩阵0 表示否1 表示是)
* @property {string} material_sn - 材料编号(通常为空字符串)
* @property {string | null} scene_information - 场景信息(通常为 null
* @property {string | null} simple_scene_information - 简单场景信息(通常为 null
* @property {number} is_behavior - 是否为行为相关0 表示否1 表示是)
* @property {number} is_price_tag - 是否为价格标签0 表示否1 表示是)
* @property {number} is_brand - 是否为品牌相关0 表示否1 表示是)
* @property {number} is_initialize - 是否初始化0 表示否1 表示是)
* @property {number} is_default_perspective - 是否为默认视角0 表示否1 表示是)
* @property {number} is_disable_lines_same - 是否禁用行列相同0 表示否1 表示是)
* @property {number} disable_lines_same - 禁用行列相同的值(通常为 1
* @property {number} float_window - 是否显示悬浮窗0 表示否1 表示是)
* @property {number} is_disable - 是否禁用0 表示否1 表示是)
* @property {string} float_window_content - 悬浮窗内容(通常为空字符串)
* @property {number} popup_window - 是否显示弹窗0 表示否1 表示是)
* @property {string} popup_window_content - 弹窗内容(通常为空字符串)
* @property {string[]} is_show - 是否显示的选项列表(通常为空数组)
* @property {number} quick_type - 快速类型(通常为 0
* @property {number} is_limit_right_content - 是否限制右侧内容0 表示否1 表示是)
* @property {string | null} option_group_random_inside - 行列选项组内随机(通常为 null
* @property {string | null} option_group_random_outside - 行列选项组外随机(通常为 null
*/
type Config = {
disabled?: string[];
version?: string;
scene?: string | null;
shelf?: string | null;
ware?: string | null;
row_option_groups?: string | null;
cell_option_groups?: string | null;
is_repeat?: number;
allow_repeat_num?: number;
repeat_type?: number;
alert_text?: string;
is_required?: number;
is_change_row_cell?: number;
select_random?: number;
row_random?: number;
cell_random?: number;
is_three_dimensions?: number;
material_sn?: string;
scene_information?: string | null;
simple_scene_information?: string | null;
is_behavior?: number;
is_price_tag?: number;
is_brand?: number;
is_initialize?: number;
is_default_perspective?: number;
is_disable_lines_same?: number;
disable_lines_same?: number;
float_window?: number;
is_disable?: number;
float_window_content?: string;
popup_window?: number;
popup_window_content?: string;
is_show?: string[];
quick_type?: number;
is_limit_right_content?: number;
option_group_random_inside?: string | null;
option_group_random_outside?: string | null;
};
/**
* 逻辑配置类型
* @property {string} expect - 期望值(通常为空字符串)
* @property {number} order - 排序(通常为 0
* @property {number} type - 类型(通常为 0
* @property {string} stay_time - 停留时间(通常为空字符串)
*/
type LogicConfig = {
expect?: string;
order?: number;
type?: number;
stay_time?: string;
};
/**
* 矩阵调查问题类型
* @property {string} id - 问题 ID
* @property {string} title - 问题标题(如 Q1
* @property {string} stem - 问题描述
* @property {string} other - 其他信息(通常为空字符串)
* @property {number} question_index - 问题索引
* @property {number} question_type - 问题类型(如矩阵类型)
* @property {Config} config - 配置信息
* @property {string} created_at - 创建时间
* @property {number} created_user_id - 创建用户 ID
* @property {number | null} updated_user_id - 更新用户 ID可能为 null
* @property {number} survey_id - 所属问卷 ID
* @property {LogicConfig} logic_config - 逻辑配置
* @property {[Option[], Option[]]} options - 选项列表,第一个子数组是行标签,第二个子数组是列标签
* @property {any[]} associate - 关联信息(通常为空数组)
* @property {string | null} logics_has - 是否有逻辑关联(通常为 null
* @property {number} last_option_index - 最后一个选项索引
* @property {string} question_code - 问题代码(通常为空字符串)
* @property {string} question_value - 问题值(通常为空字符串)
* @property {string} question_tag - 问题标签(通常为空字符串)
* @property {string} planet_id - 行星 ID通常为空字符串
* @property {any | null} permissions - 权限信息(通常为 null
*/
type MatrixSurveyQuestion = {
id: string;
title: string;
stem: string;
other?: string;
question_index?: number;
question_type?: number;
config?: Config;
created_at?: string;
created_user_id?: number;
updated_user_id?: number | null;
survey_id?: number;
logic_config?: LogicConfig;
options: [Option[], Option[]];
associate?: any[];
logics_has?: string | null;
last_option_index?: number;
question_code?: string;
question_value?: string;
question_tag?: string;
planet_id?: string;
permissions?: any | null;
};
/**
* 矩阵调查类型
* @property {MatrixSurveyQuestion} question - 矩阵调查问题
*/
type MatrixSurvey = {
question?: MatrixSurveyQuestion;
};

View File

@@ -21,7 +21,7 @@ import CreateSurvey from './components/CreateSurvey/Index.vue';
<style scoped lang="scss"> <style scoped lang="scss">
.container { .container {
padding: 0 10px 60px; padding: 0 10px 60px;
background: linear-gradient(0deg, #f5f5f5 0%, #f5f5f5 84%, rgba(185, 248, 207, 1) 100%); background: linear-gradient(0deg, #f5f5f5 0%, #f5f5f5 84%, #A5D380 100%);
&> :first-child { &> :first-child {
display: flex; display: flex;

View File

@@ -17,7 +17,8 @@ import { lastSurveys } from './hooks/useLastSurveyHooks';
<div class="last-survey_items_status"> <div class="last-survey_items_status">
<img <img
src="https://files.axshare.com/gsc/DR6075/63/4d/77/634d77293a4d41d1b3d145974a8fb6a7/images/首页_1/u249.svg?pageId=5cc10b9f-56eb-48dc-943a-bfe7afb18a64" src="https://files.axshare.com/gsc/DR6075/63/4d/77/634d77293a4d41d1b3d145974a8fb6a7/images/首页_1/u249.svg?pageId=5cc10b9f-56eb-48dc-943a-bfe7afb18a64"
alt=" " width="10px" height="10px" /> alt=" " width="10px" height="10px"
/>
<small> {{ survey.status }} - 100</small> <small> {{ survey.status }} - 100</small>
</div> </div>
<div class="last-survey_items_info"> <div class="last-survey_items_info">

View File

@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, h } from 'vue'; import { ref, h } from 'vue';
import { tables } from './hooks/useMarketHooks'; import { tables } from './hooks/useMarketHooks';
import TestComponent from './components/TestComponent.vue' import TestComponent from './components/TestComponent.vue';
const activeComponet = ref(h(TestComponent, { cn: '报名签到' })) const activeComponet = ref(h(TestComponent, { cn: '报名签到' }));
</script> </script>
@@ -16,7 +16,7 @@ const activeComponet = ref(h(TestComponent, { cn: '报名签到' }))
</div> </div>
<div class="market_table"> <div class="market_table">
<div v-for="item in tables" @click="activeComponet = item.component" :key="item.title">{{ item.title }}</div> <div v-for="item in tables" :key="item.title" @click="activeComponet = item.component">{{ item.title }}</div>
</div> </div>
<van-cell class="market_items"> <van-cell class="market_items">
<component :is="activeComponet" /> <component :is="activeComponet" />
@@ -24,7 +24,6 @@ const activeComponet = ref(h(TestComponent, { cn: '报名签到' }))
</div> </div>
</template> </template>
<style scoped> <style scoped>
.market { .market {
&> :first-child { &> :first-child {

View File

@@ -1,28 +1,31 @@
<script setup lang="ts"> <script setup lang="ts">
const { cn } = defineProps({ const { cn } = defineProps({
cn: { cn: {
type: String, type: String,
required: false, required: false,
deault: 'default' deault: 'default'
} }
}) });
</script> </script>
<template> <template>
<van-row :gutter="4"> <van-row :gutter="4">
<van-col :span="10" v-for="item in 2" :key="item" <van-col
style="display: flex; flex-direction: column; align-items: start; box-shadow: 0 3px 3px rgba(0, 0, 0, 0.1);"> v-for="item in 2" :key="item" :span="10"
<div style="display: flex; align-items: center; justify-content: space-evenly;width: 100%;"> style="display: flex; flex-direction: column; align-items: start; box-shadow: 0 3px 3px rgba(0, 0, 0, 0.1);"
<span>{{ cn }} 模板</span> >
<img <div style="display: flex; align-items: center; justify-content: space-evenly;width: 100%;">
src="https://files.axshare.com/gsc/DR6075/63/4d/77/634d77293a4d41d1b3d145974a8fb6a7/images/首页_1/u42.svg?pageId=5cc10b9f-56eb-48dc-943a-bfe7afb18a64" /> <span>{{ cn }} 模板</span>
</div> <img
src="https://files.axshare.com/gsc/DR6075/63/4d/77/634d77293a4d41d1b3d145974a8fb6a7/images/首页_1/u42.svg?pageId=5cc10b9f-56eb-48dc-943a-bfe7afb18a64"
/>
</div>
<div> <div>
<span>引用10次</span> | <span>创建人: 张三</span> <span>引用10次</span> | <span>创建人: 张三</span>
</div> </div>
</van-col> </van-col>
</van-row> </van-row>
</template> </template>
<style lang="sass" scoped> <style lang="sass" scoped>

View File

@@ -1,24 +1,24 @@
import TestComponent from '../components/TestComponent.vue' import TestComponent from '../components/TestComponent.vue';
import { h } from 'vue' import { h } from 'vue';
export const tables = [ export const tables = [
{ {
title: '报名签到', title: '报名签到',
component: h(TestComponent, { cn: '报名签到' }) component: h(TestComponent, { cn: '报名签到' })
}, { }, {
title: '满意度调研', title: '满意度调研',
component: h(TestComponent, { cn: '满意度调研' }) component: h(TestComponent, { cn: '满意度调研' })
}, { }, {
title: '快速投票', title: '快速投票',
component: h(TestComponent, { cn: '快速投票' }) component: h(TestComponent, { cn: '快速投票' })
}, { }, {
title: '打分评估', title: '打分评估',
component: h(TestComponent, { cn: '打分评估' }) component: h(TestComponent, { cn: '打分评估' })
}, { }, {
title: 'NPS', title: 'NPS',
component: h(TestComponent, { cn: 'NPS' }) component: h(TestComponent, { cn: 'NPS' })
}, { }, {
title: '考评测试', title: '考评测试',
component: h(TestComponent, { cn: '考评测试' }) component: h(TestComponent, { cn: '考评测试' })
} }
] ];

View File

@@ -3,9 +3,7 @@
<div v-for="item in 10" :key="item" class="template"> <div v-for="item in 10" :key="item" class="template">
<img src="https://picsum.photos/131/128" width="110" height="100" alt="" /> <img src="https://picsum.photos/131/128" width="110" height="100" alt="" />
<span>报名/签到模板</span> <span>报名/签到模板</span>
<span style="color: rgb(127, 127, 127)" <span style="color: rgb(127, 127, 127)">报名签到 | 引用 {{ item }} | 创建人: {{ '张三' }}</span>
>报名签到 | 引用 {{ item }} | 创建人: {{ '张三' }}</span
>
</div> </div>
</div> </div>
</template> </template>