Merge branch 'feature/feature-20250331-h5' of https://e.coding.yili.com/yldc/ylst/ylst-survey-h5 into feature

This commit is contained in:
Huangzhe
2025-03-04 18:18:31 +08:00
16 changed files with 481 additions and 88 deletions

1
.gitignore vendored
View File

@@ -19,6 +19,7 @@ coverage
# Editor directories and files # Editor directories and files
.idea .idea
.vscode
*.suo *.suo
*.ntvs* *.ntvs*
*.njsproj *.njsproj

18
.vscode/settings.json vendored
View File

@@ -2,7 +2,7 @@
"explorer.confirmDelete": false, "explorer.confirmDelete": false,
"editor.fontSize": 18, "editor.fontSize": 18,
"workbench.editorAssociations": { "workbench.editorAssociations": {
"*.ipynb": "jupyter.notebook.ipynb" "*.ipynb": "jupyter.notebook.ipynb"
}, },
"window.zoomLevel": 1, "window.zoomLevel": 1,
"workbench.iconTheme": "vscode-icons", "workbench.iconTheme": "vscode-icons",
@@ -32,13 +32,14 @@
"editor.formatOnSave": true "editor.formatOnSave": true
}, },
"[vue]": { "[vue]": {
"editor.defaultFormatter": "octref.vetur", "editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true "editor.formatOnSave": true
}, },
"css.validate": false, //用来校验CSS文件中的语法错误和潜在的问题 "css.validate": false, //用来校验CSS文件中的语法错误和潜在的问题
"less.validate": false, //用来校验LESS文件中的语法错误和潜在的问题 "less.validate": false, //用来校验LESS文件中的语法错误和潜在的问题
"scss.validate": false, //用来校验SCSS文件中的语法错误和潜在的问题 "scss.validate": false, //用来校验SCSS文件中的语法错误和潜在的问题
"editor.codeActionsOnSave": { // 用于在保存文件时自动执行代码操作 "editor.codeActionsOnSave": {
// 用于在保存文件时自动执行代码操作
"source.fixAll.eslint": "explicit", // 自动执行ESlint "source.fixAll.eslint": "explicit", // 自动执行ESlint
"source.fixAll.stylelint": "explicit" // 自动执行stylelint "source.fixAll.stylelint": "explicit" // 自动执行stylelint
}, },
@@ -54,15 +55,16 @@
"xml", "xml",
"gql", "gql",
"graphql", "graphql",
"astro", "astro"
], ],
"eslint.nodePath": "./node_modules/@yl/yili-fe-lint-config/node_modules", // 指定ESLint可执行文件路径 "eslint.nodePath": "./node_modules/@yl/yili-fe-lint-config/node_modules", // 指定ESLint可执行文件路径
"eslint.options": { // 用于配置 "eslint.options": {
// 用于配置
"overrideConfigFile": "./node_modules/@yl/yili-fe-lint-config/eslintrc.vue3.js" //该选项指定了 ESLint 应使用的配置文件路径。此项设置会覆盖所有其他位置查找的 ESLint 配置文件。 "overrideConfigFile": "./node_modules/@yl/yili-fe-lint-config/eslintrc.vue3.js" //该选项指定了 ESLint 应使用的配置文件路径。此项设置会覆盖所有其他位置查找的 ESLint 配置文件。
}, },
"stylelint.configBasedir": "./node_modules/@yl/yili-fe-lint-config/", //该选项用于定义 Stylelint 配置文件所基于的基础目录。当您的配置文件中使用 extends、plugins 或其他引用时,这个基础目录将作为解析路径的起点 "stylelint.configBasedir": "./node_modules/@yl/yili-fe-lint-config/", //该选项用于定义 Stylelint 配置文件所基于的基础目录。当您的配置文件中使用 extends、plugins 或其他引用时,这个基础目录将作为解析路径的起点
"stylelint.configFile": "./node_modules/@yl/yili-fe-lint-config/stylelintrc.js", // 该选项指定了 stylelint 应使用的配置文件路径。此项设置会覆盖所有其他位置查找的 stylelint 配置文件 "stylelint.configFile": "./node_modules/@yl/yili-fe-lint-config/stylelintrc.js", // 该选项指定了 stylelint 应使用的配置文件路径。此项设置会覆盖所有其他位置查找的 stylelint 配置文件
"stylelint.customSyntax": "postcss-scss", // 配置stylelint使用的预处理器 "stylelint.customSyntax": "postcss-scss", // 配置stylelint使用的预处理器
"stylelint.stylelintPath": "./node_modules/@yl/yili-fe-lint-config/node_modules/stylelint", // 指定stylelint安装路径 "stylelint.stylelintPath": "./node_modules/@yl/yili-fe-lint-config/node_modules/stylelint", // 指定stylelint安装路径
"stylelint.validate": ["html", "css", "scss", "less", "vue"] "stylelint.validate": ["html", "css", "scss", "less", "vue"]
} }

11
components.d.ts vendored
View File

@@ -7,16 +7,9 @@ export {}
/* prettier-ignore */ /* prettier-ignore */
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
ElButton: typeof import('element-plus/es')['ElButton']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElMain: typeof import('element-plus/es')['ElMain']
Index: typeof import('./src/components/VanCellModel/Index.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
Van: typeof import('vant/es')['default']
VanActionSheet: typeof import('vant/es')['ActionSheet'] VanActionSheet: typeof import('vant/es')['ActionSheet']
VanButton: typeof import('vant/es')['Button']
VanCell: typeof import('vant/es')['Cell'] VanCell: typeof import('vant/es')['Cell']
VanCellGroup: typeof import('vant/es')['CellGroup'] VanCellGroup: typeof import('vant/es')['CellGroup']
VanCheckbox: typeof import('vant/es')['Checkbox'] VanCheckbox: typeof import('vant/es')['Checkbox']
@@ -24,5 +17,9 @@ declare module 'vue' {
VanDivider: typeof import('vant/es')['Divider'] VanDivider: typeof import('vant/es')['Divider']
VanField: typeof import('vant/es')['Field'] VanField: typeof import('vant/es')['Field']
VanIcon: typeof import('vant/es')['Icon'] VanIcon: typeof import('vant/es')['Icon']
VanSearch: typeof import('vant/es')['Search']
VanSwitch: typeof import('vant/es')['Switch']
VanTabbar: typeof import('vant/es')['Tabbar']
VanTabbarItem: typeof import('vant/es')['TabbarItem']
} }
} }

View File

@@ -1,3 +1,11 @@
.van-cell { .van-cell {
padding: 8px !important; padding: 8px !important;
} }
.van-divider {
margin: 5px 0 !important;
}
.van-popup--bottom.van-popup--round {
border-radius: 10px 10px 0 0 !important;
}

View File

@@ -4,11 +4,11 @@
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: src:
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix')
format('embedded-opentype'), format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont')
format('svg'); format('svg');
} }
.logo { .logo {

View File

@@ -26,39 +26,41 @@ import { RouterView } from 'vue-router';
import { ref } from 'vue'; import { ref } from 'vue';
const active = ref(); const active = ref();
const table = [{ const table = [
title: '首页', {
path: '/', title: '首页',
icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u18.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6' path: '/',
icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u18.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6'
}, { },
title: '问卷', {
path: '/survey', title: '问卷',
icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u21.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6' path: '/survey',
}, { icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u21.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6'
title: '新建问卷', },
path: '/survey/create', {
icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/首页_1/u15.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6' title: '新建问卷',
path: '/survey/create',
}, { icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/首页_1/u15.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6'
title: '模板', },
path: '/market', {
icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u24.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6' title: '模板',
}]; path: '/market',
icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u24.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6'
}
];
</script> </script>
<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: #e9eef3;
color: #333; color: #333;
text-align: center;
} }
.header { .header {
position: sticky; position: sticky;
top: 0; top: 0;
background-color: #B9F8CF; background-color: #b9f8cf;
.title { .title {
display: flex; display: flex;

View File

@@ -4,6 +4,8 @@ import { createApp } from 'vue';
import { createPinia } from 'pinia'; import { createPinia } from 'pinia';
import App from './App.vue'; import App from './App.vue';
import router from './router'; import router from './router';
// 2. 引入组件样式
import 'vant/lib/index.css';
const app = createApp(App); const app = createApp(App);
app.use(createPinia()); app.use(createPinia());
app.use(router); app.use(router);

View File

@@ -93,7 +93,96 @@ export const useCommonStore = defineStore('common', {
} }
] ]
}, },
logics: [], logics: [
{
id: 472148,
question_index: 24,
sample_number: 0,
skip_question_index: 27,
skip_type: 0,
question_id: '17852294',
logic: [
{
value: '',
location: 0,
date: '',
time: '',
type: 0,
row_type: 0,
cell_type: 0,
logic: 'if',
operator: '=',
is_answer: 1,
is_select: 0,
row_index: 0,
cell_index: 0,
question_type: 1,
question_index: 24,
relation_question_index: 0,
relation_question_row_index: 0,
relation_question_cell_index: 0,
is_option_group: 0,
option_index: 1,
skip_type: null,
question_id: null
}
],
autofill: {
value: '',
date: '',
time: '',
question_type: 1,
option_indexs: [],
row_indexs: [],
cell_indexs: []
},
hide_option_index: []
},
{
id: 472149,
question_index: 24,
sample_number: 0,
skip_question_index: 0,
skip_type: 0,
question_id: '17852294',
logic: [
{
value: '',
location: 0,
date: '',
time: '',
type: 0,
row_type: 0,
cell_type: 0,
logic: 'if',
operator: '=',
is_answer: 1,
is_select: 0,
row_index: 0,
cell_index: 0,
question_type: 1,
question_index: 24,
relation_question_index: 0,
relation_question_row_index: 0,
relation_question_cell_index: 0,
is_option_group: 0,
option_index: 0,
skip_type: null,
question_id: null
}
],
autofill: {
value: '',
date: '',
time: '',
question_type: 1,
option_indexs: [],
row_indexs: [],
cell_indexs: []
},
hide_option_index: []
}
],
questions: [ questions: [
{ {
id: '17852294', id: '17852294',
@@ -274,7 +363,7 @@ export const useCommonStore = defineStore('common', {
id: '1048968', id: '1048968',
type: 0, type: 0,
is_other: 0, is_other: 0,
is_fixed: 0, is_fixed: 1,
is_remove_other: 0, is_remove_other: 0,
created_at: null, created_at: null,
created_user_id: null, created_user_id: null,
@@ -1406,7 +1495,7 @@ export const useCommonStore = defineStore('common', {
{ {
id: '17835010', id: '17835010',
title: 'A6', title: 'A6',
stem: '<p>请问您为什么<span style="text-decoration: underline; color: #2dc26b;" data-mce-style="text-decoration: underline; color: #2dc26b;"><strong>喜欢</strong></span>这些地方?</p><p><img style="height: 50px; max-height: 440px;" src="https://test-cxp-public-web-1302259445.cos.ap-beijing.myqcloud.com/uat-yls/packing/imgs/1725421981418_809_mao-23.jpg"></p>', stem: '<p>请问您为什么<span style="text-decoration: underline; color: #2dc26b;" data-mce-style="text-decoration: underline; color: #2dc26b;"><strong>喜欢</strong></span>这些地方?</p>',
other: '概念诊断问卷配置概念诊断1', other: '概念诊断问卷配置概念诊断1',
question_index: 6, question_index: 6,
question_type: 4, question_type: 4,
@@ -2743,7 +2832,7 @@ export const useCommonStore = defineStore('common', {
{ {
id: '17835015', id: '17835015',
title: 'B4', title: 'B4',
stem: '<p>请问您为什么<span style="text-decoration: underline; color: #e03e2d;" data-mce-style="text-decoration: underline; color: #e03e2d;"><strong>不喜欢</strong></span>这些地方?</p><p><img style="height: 50px; max-height: 440px;" src="https://test-cxp-public-web-1302259445.cos.ap-beijing.myqcloud.com/uat-yls/packing/imgs/1725421988964_889_mao-012-small.jpg"></p>', stem: '<p>请问您为什么<span style="text-decoration: underline; color: #e03e2d;" data-mce-style="text-decoration: underline; color: #e03e2d;"><strong>不喜欢</strong></span>这些地方?</p>',
other: '概念诊断问卷配置概念诊断2', other: '概念诊断问卷配置概念诊断2',
question_index: 11, question_index: 11,
question_type: 4, question_type: 4,

View File

@@ -11,6 +11,7 @@
<template #item="{ element, index }"> <template #item="{ element, index }">
<choose-question <choose-question
:element="element" :element="element"
:questions="questionInfo.questions"
:index="index" :index="index"
:chooseQuestionId="chooseQuestionId" :chooseQuestionId="chooseQuestionId"
@get-choose-question-id="getChooseQuestionId" @get-choose-question-id="getChooseQuestionId"
@@ -20,7 +21,14 @@
:element="element" :element="element"
:active="chooseQuestionId === element.id" :active="chooseQuestionId === element.id"
></base-select> ></base-select>
<Completion
v-if="element.question_type === 4"
:element="element"
:active="chooseQuestionId === element.id"
sn="lXEBBpE2"
></Completion>
</choose-question> </choose-question>
<!-- {{ element.question_type }}--> <!-- {{ element.question_type }}-->
<!-- {{questionInfo.survey.pages.length}}--> <!-- {{questionInfo.survey.pages.length}}-->
<paging <paging
@@ -42,6 +50,7 @@ import Draggable from './components/Draggable.vue';
import BaseSelect from './components/Questions/BaseSelect.vue'; import BaseSelect from './components/Questions/BaseSelect.vue';
import ChooseQuestion from './components/ChooseQuestion.vue'; import ChooseQuestion from './components/ChooseQuestion.vue';
import Paging from './components/Questions/paging/Paging.vue'; import Paging from './components/Questions/paging/Paging.vue';
import Completion from './components/Questions/Completion.vue';
const activeIndex = ref(-1); const activeIndex = ref(-1);
/** /**

View File

@@ -1,30 +1,53 @@
<template> <template>
<div class="option-action"> <div class="option-action">
<template v-for="(item, index) in data" :key="item.id"> <template v-for="(item, index) in data" :key="index">
<div class="flex align-center option-action-container"> <div class="flex align-center option-action-container">
<slot name="item" :element="item" :index="index"></slot> <slot name="item" :element="item" :index="index"></slot>
<span v-if="active" class="flex"> <span v-if="active" class="flex">
<van-icon name="close"></van-icon> <van-icon name="close" @click="deleteOption(index)"></van-icon>
<van-icon name="more-o" @click="openOptionActionModel"></van-icon> <van-icon name="more-o" @click="openOptionActionModel(item, index)"></van-icon>
</span> </span>
</div> </div>
</template> </template>
</div> </div>
<!-- 操作项弹窗-->
<van-action-sheet v-model:show="show"> <van-action-sheet v-model:show="show">
<template #description> <template #description>
<div class="flex flex-start">操作选项</div> <div class="flex flex-start">操作选项</div>
</template> </template>
<div class=""> <van-cell-group :border="false" class="ml10">
<van-cell title="固定置底"></van-cell> <van-cell title="固定置底" :border="false">
<van-cell title="固定置底"></van-cell> <template #right-icon>
<van-cell title="固定置底"></van-cell> <van-switch
<van-cell title="固定置底"></van-cell> v-model="activeOption.is_fixed"
</div> class="option-action-sheet-switch"
size="0.5rem"
:active-value="1"
:inactive-value="0"
></van-switch>
</template>
</van-cell>
<van-cell title="设为其他项" :border="false">
<template #right-icon>
<van-switch
v-model="activeOption.is_other"
class="option-action-sheet-switch"
size="0.5rem"
:active-value="1"
:inactive-value="0"
></van-switch>
</template>
</van-cell>
<van-divider></van-divider>
<van-cell title="下移选项" :border="false" @click="optionMove('down')"></van-cell>
<van-cell title="上移选项" :border="false" @click="optionMove('up')"></van-cell>
</van-cell-group>
</van-action-sheet> </van-action-sheet>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue'; import { ref } from 'vue';
defineProps({ import { showConfirmDialog } from 'vant';
const props = defineProps({
data: { data: {
type: Object, type: Object,
default: () => { default: () => {
@@ -40,17 +63,66 @@ defineProps({
}); });
// const emit = defineEmits(['update:data']); // const emit = defineEmits(['update:data']);
const show = ref(false); const show = ref(false);
const activeOption = ref({});
const activeIndex = ref(-1);
const element = ref(props.data);
// emit('update:data');
/** /**
* @name 打开model弹窗 * @name 打开model弹窗
* @created_date 2025/3/4 * @created_date 2025/3/4
* @description * @description
**/ **/
const openOptionActionModel = () => { const openOptionActionModel = (item, index) => {
show.value = true; show.value = true;
activeOption.value = item;
activeIndex.value = index;
};
// 上下移动
const optionMove = (action) => {
switch (action) {
case 'up':
if (activeIndex.value === 0) {
show.value = false;
return;
}
// 向上移动
element.value.splice(activeIndex.value - 1, 0, element.value.splice(activeIndex.value, 1)[0]);
activeIndex.value -= 1;
break;
case 'down':
if (activeIndex.value === element.value.length) {
show.value = false;
return;
}
element.value.splice(activeIndex.value + 1, 0, element.value.splice(activeIndex.value, 1)[0]);
activeIndex.value += 1;
break;
}
};
// 删除当前选项
const deleteOption = (index) => {
showConfirmDialog({
title: '提示',
message: '是否删除选项?'
})
.then(() => {
// on confirm
element.value.splice(index, 1);
})
.catch(() => {
// on cancel
});
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.ml10 {
margin-left: 10px;
}
.option-action { .option-action {
font-size: 20px; font-size: 20px;

View File

@@ -1,11 +1,139 @@
<template> <template>
<div class="container question-action-container flex"> <div class="container question-action-container flex">
<van-icon name="delete"></van-icon> <van-icon name="delete" @click="deleteQuestion"></van-icon>
<van-icon name="more"></van-icon> <van-icon name="more" @click="openQuestionActionModel"></van-icon>
</div> </div>
<!-- 操作项弹窗-->
<van-action-sheet v-model:show="show">
<template #description>
<div class="flex flex-start">操作选项</div>
</template>
<van-cell-group :border="false" class="ml10">
<van-cell title="此题必答" :border="false" label-align="left">
<template #right-icon>
<van-switch
v-model="activeQuestion.config.is_required"
class="option-action-sheet-switch"
size="0.5rem"
:active-value="1"
:inactive-value="0"
></van-switch>
</template>
</van-cell>
<van-cell title="选项随机" :border="false">
<template #right-icon>
<van-switch
v-model="activeQuestion.config.select_random"
class="option-action-sheet-switch"
size="0.5rem"
:active-value="1"
:inactive-value="0"
></van-switch>
</template>
</van-cell>
<van-divider></van-divider>
<van-cell title="题前隐藏" :border="false">
<template #right-icon>
<span> {{ getSkipTypeText() }} <van-icon name="arrow"></van-icon></span>
</template>
</van-cell>
<van-cell title="题后跳转" :border="false">
<template #right-icon>
<span> 设置 <van-icon name="arrow"></van-icon></span>
</template>
</van-cell>
<van-divider></van-divider>
<van-cell title="下移选项" :border="false" @click="questionMove('down')"></van-cell>
<van-cell title="上移选项" :border="false" @click="questionMove('up')"></van-cell>
</van-cell-group>
</van-action-sheet>
</template> </template>
<script setup></script> <script setup>
import { showConfirmDialog } from 'vant';
import { ref } from 'vue';
import { useCounterStore } from '@/stores/counter';
import { storeToRefs } from 'pinia';
const store = useCounterStore();
const { questionsInfo } = storeToRefs(store);
const logics = questionsInfo.value.logics;
const props = defineProps({
index: {
type: Number,
default: 0
},
data: {
type: Object,
default: () => {
// 传递
}
},
questions: {
type: Array,
default: () => []
},
questionIndex: {
type: Number,
default: 0
}
});
const questions = ref(props.questions);
// 当前题目
const activeQuestion = ref(props.data);
const show = ref(false);
const deleteQuestion = () => {
showConfirmDialog({
title: '提示',
message: '是否删除问题?'
})
.then(() => {
// on confirm
questions.value.splice(props.questionIndex, 1);
})
.catch(() => {
// on cancel
});
};
// 打开题目弹窗
const openQuestionActionModel = () => {
show.value = true;
};
// 题目上下移动
const questionMove = (action) => {
if (action === 'down') {
if (props.questionIndex === questions.value.length - 1) {
return;
}
const temp = questions.value[props.questionIndex];
questions.value.splice(props.questionIndex, 1);
questions.value.splice(props.questionIndex + 1, 0, temp);
} else {
if (props.questionIndex === 0) {
return;
}
const temp = questions.value[props.questionIndex];
questions.value.splice(props.questionIndex, 1);
questions.value.splice(props.questionIndex - 1, 0, temp);
}
};
// 获取题前隐藏 和题后 跳转 文字
const getSkipTypeText = () => {
setTimeout(() => {
logics[0].id = 123;
}, 2000);
return logics[0].id;
};
</script>
<style scoped lang="scss"> <style scoped lang="scss">
.ml10 {
margin-left: 10px;
}
.question-action-container { .question-action-container {
font-size: 20px; font-size: 20px;

View File

@@ -16,7 +16,11 @@
</template> </template>
<template #title>{{}}</template> <template #title>{{}}</template>
<template #right-icon> <template #right-icon>
<question-action></question-action> <question-action
v-model:data="element"
:questions="questions"
:questionIndex="index"
></question-action>
</template> </template>
<!-- <div--> <!-- <div-->
<!-- v-for="item in questionAction"--> <!-- v-for="item in questionAction"-->
@@ -51,6 +55,10 @@ const props = defineProps({
type: Number, type: Number,
default: 0 default: 0
}, },
questions: {
type: Array,
default: () => []
},
chooseQuestionId: { chooseQuestionId: {
type: String, type: String,
default: '0' default: '0'

View File

@@ -16,7 +16,7 @@
</template> </template>
<template #input> <template #input>
<van-checkbox-group> <van-checkbox-group>
<template v-for="(item, index) in element.options" :key="item.id"> <template v-for="(item, index) in element.options" :key="index">
<option-action v-model:data="element.options[index]" :active="active"> <option-action v-model:data="element.options[index]" :active="active">
<template #item="{ element: it, index: itIndex }"> <template #item="{ element: it, index: itIndex }">
<van-checkbox <van-checkbox
@@ -27,13 +27,16 @@
icon-size="0.45rem" icon-size="0.45rem"
> >
<template #default> <template #default>
<div class="flex align-center space-between"> <div class="flex align-center van-cell">
<div <div
class="van-cell van-cell--borderless" class="van-cell--borderless"
:contenteditable="active" :contenteditable="active"
@blur="saveOption($event, it)" @blur="saveOption($event, it)"
v-html="it.option" v-html="it.option"
></div> ></div>
<div v-if="it.is_other">
<input class="other-input" type="text" />
</div>
</div> </div>
</template> </template>
</van-checkbox> </van-checkbox>
@@ -83,5 +86,15 @@ const saveStem = (e, ele) => {
} }
} }
} }
& .other-input {
width: 100px;
height: 20px;
margin-left: 20px;
padding: 3px 5px;
border: 1px solid #ccc;
border-radius: 5px;
outline: none;
}
} }
</style> </style>

View File

@@ -0,0 +1,67 @@
<template>
<div class="cont">
<van-field
v-model="element.stem"
:label="element.stem"
:required="element.config.is_required === 1"
label-align="top"
>
<template #label>
<div
:contenteditable="active"
class="van-field"
@blur="saveStem($event, element)"
v-html="element.stem"
></div>
</template>
<template #input>
<div contenteditable="true" class="input other_input"></div>
</template>
</van-field>
</div>
</template>
<script setup>
import { ref } from 'vue';
const props = defineProps({
element: {
type: Object,
default: () => {
// 补充
}
},
active: {
type: Boolean,
default: false
},
sn: { type: String, default: '' },
questionType: { type: [String, Number], default: 4 }
});
const element = ref(props.element);
// 创建一个本地副本以保存更改
const localElement = ref({ ...props.element });
const saveStem = (e) => {
localElement.value.stem = e.target.innerHTML;
// 如果需要,可以在这里发出事件以通知父组件
// this.$emit('update:element', localElement.value);
};
</script>
<style scoped lang="scss">
.cont {
.other_input {
width: 100%;
height: 40px;
margin-bottom: 10px;
padding: 3px 5px;
border: 1px solid #ccc;
border-radius: 5px;
outline: none;
}
}
.text_value {
border: 1px solid #ccc !important;
}
</style>

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

@@ -1,23 +1,24 @@
<script setup> <script setup>
import Survey from './components/Suvrey/Index.vue'; import Survey from './components/Suvrey/Index.vue';
import Template from './components/Market/Index.vue';
const func = [{ const func = [
title: '报名签到', {
icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u48.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6' title: '报名签到',
}, icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u48.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6'
{ },
title: '问卷调查', {
icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u51.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6' title: '问卷调查',
}, icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u51.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6'
{ },
title: '活动模板', {
icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u54.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6' title: '活动模板',
}, icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u54.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6'
{ },
title: '活动管理', {
icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u57.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6' title: '活动管理',
}]; icon: 'https://files.axshare.com/gsc/DR6075/de/a0/49/dea049d6ad3e4c2c80af44258c6c76d6/images/%E9%A6%96%E9%A1%B5_1/u57.png?pageId=74b3e5b2-848e-4258-8a34-9e220127c8a6'
}
];
</script> </script>
<template> <template>
@@ -34,26 +35,21 @@ const func = [{
</div> </div>
<Survey /> <Survey />
<Template />
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.container { .container {
padding: 0 10px; padding: 0 10px;
background: linear-gradient(0deg, background: linear-gradient(0deg, #f5f5f5 0%, #f5f5f5 84%, rgba(185, 248, 207, 1) 100%);
#f5f5f5 0%,
#f5f5f5 84%,
rgba(185, 248, 207, 1) 100%);
&>:first-child { & > :first-child {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
border-radius: 6px; border-radius: 6px;
background-color: white; background-color: white;
&>div { & > div {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 50px; width: 50px;