feat: 新增包装测试

This commit is contained in:
钱冠学
2024-11-01 14:11:23 +08:00
parent 58fb5ccd42
commit 91f6c96257
20 changed files with 1166 additions and 522 deletions

View File

@@ -106,6 +106,7 @@ export default {
<style lang="scss"> <style lang="scss">
@import './style/customize/index.scss'; @import './style/customize/index.scss';
@import './style/utils.scss'; @import './style/utils.scss';
@import './style/scroller.scss';
@font-face { @font-face {
font-display: optional; font-display: optional;
@@ -136,16 +137,7 @@ div {
.scrollbar, .scrollbar,
.ant-table-body, .ant-table-body,
.vxe-table--body-wrapper { .vxe-table--body-wrapper {
&::-webkit-scrollbar { @extend .scroller;
width: 6px;
height: 6px;
background-color: #ffffff;
}
&::-webkit-scrollbar-thumb {
background-color: #d8d8d8;
border-radius: 10px;
}
} }
.ant-table-header, .ant-table-header,
.ant-table-hide-scrollbar { .ant-table-hide-scrollbar {

View File

@@ -29,9 +29,13 @@ const replacing = ref([]);
const urlList = ref([]); const urlList = ref([]);
watch( watch(
() => props.urls, [() => props.urls, () => props.url],
() => { () => {
if (props.urls?.length) {
urlList.value = props.urls || []; urlList.value = props.urls || [];
} else if (props.url) {
urlList.value = [props.url];
}
}, },
{ {
immediate: true immediate: true
@@ -79,21 +83,30 @@ function onBeforeUpload(file, fileList) {
return true; return true;
} }
function setReplacingStatus(index, status) {
if (index === undefined || index === null) {
return;
}
replacing.value[index] = status;
replacing.value = [...replacing.value];
}
// 自定义上传文件 // 自定义上传文件
async function onUpload(e, index) { async function onUpload(e, index) {
loading.value = true; loading.value = true;
replacing.value[index] = true; setReplacingStatus(index, true);
replacing.value = [...replacing.value];
const { file, onSuccess, onError } = e; const { file, onSuccess, onError } = e;
const fileName = file.name.replaceAll(/\s/g, ''); const fileName = file.name.replaceAll(/\s/g, '');
// 图片验重,此方法并不可靠 // 图片验重,此方法并不可靠
if (!props.allowRepeat) { if (!props.allowRepeat) {
const index = urlList.value.findIndex((item) => item.split('_').slice(2).join('_') === fileName); const index = urlList.value.findIndex(
(item) => item.split('_').slice(2).join('_') === fileName
);
if (index !== -1) { if (index !== -1) {
loading.value = false; loading.value = false;
replacing.value.splice(index, 1, false); setReplacingStatus(index, false);
return message.error('图片不能重复'); return message.error('图片不能重复');
} }
} }
@@ -137,19 +150,20 @@ function onChange(info, index) {
urlList.value.push(decodeURIComponent(url)); urlList.value.push(decodeURIComponent(url));
} }
emits('update:urls', urlList.value); emits('update:urls', urlList.value);
emits('update:url', urlList.value[0] || '');
} }
loading.value = false; loading.value = false;
replacing.value.splice(index, 1, false); setReplacingStatus(index, false);
} }
if (status === 'done') { if (status === 'done') {
message.success(`${info.file.name} 上传成功.`); message.success(`${info.file.name} 上传成功.`);
loading.value = false; loading.value = false;
replacing.value.splice(index, 1, false); setReplacingStatus(index, false);
} else if (status === 'error') { } else if (status === 'error') {
message.error(`${info.file.name} 上传失败.`); message.error(`${info.file.name} 上传失败.`);
loading.value = false; loading.value = false;
replacing.value.splice(index, 1, false); setReplacingStatus(index, false);
} }
} }
</script> </script>
@@ -157,7 +171,7 @@ function onChange(info, index) {
<template> <template>
<div class="image-uploader" :class="{ single: props.max === 1 }"> <div class="image-uploader" :class="{ single: props.max === 1 }">
<div v-for="(item, index) in urlList" :key="index" class="image-uploader-item"> <div v-for="(item, index) in urlList" :key="index" class="image-uploader-item">
<a-spin :spinning="replacing[index]"> <a-spin :spinning="replacing[index] || false">
<!-- 图片 --> <!-- 图片 -->
<img :src="item" alt="" class="preview-image" /> <img :src="item" alt="" class="preview-image" />
<!-- 删除 --> <!-- 删除 -->

View File

@@ -4,6 +4,10 @@
align-items: center; align-items: center;
} }
.flex-column {
flex-direction: column;
}
.flex-start, .flex-start,
.flex.flex-start { .flex.flex-start {
display: flex; display: flex;
@@ -29,9 +33,11 @@
.full-width { .full-width {
width: 100%; width: 100%;
} }
.full-height { .full-height {
height: 100%; height: 100%;
} }
.full-size { .full-size {
width: 100%; width: 100%;
height: 100%; height: 100%;

32
src/style/scroller.scss Normal file
View File

@@ -0,0 +1,32 @@
.scroller {
&::-webkit-scrollbar {
width: 6px;
height: 6px;
background-color: #FFFFFF;
}
&::-webkit-scrollbar-thumb {
background-color: #D8D8D8;
border-radius: 10px;
}
}
.scroller-x {
overflow-x: auto;
@extend .scroller;
}
.scroller-y {
overflow-y: auto;
@extend .scroller;
}
.scroller-xy {
overflow-x: auto;
overflow-y: auto;
@extend .scroller;
}

View File

@@ -1,5 +1,14 @@
<script setup> <script setup>
import { computed, defineEmits, defineExpose, reactive, ref, defineProps, watch, watchEffect } from 'vue'; import {
computed,
defineEmits,
defineExpose,
reactive,
ref,
defineProps,
watch,
watchEffect
} from 'vue';
import { CaretRightOutlined } from '@ant-design/icons-vue'; import { CaretRightOutlined } from '@ant-design/icons-vue';
import SectionTitle from '@/components/layout/title/SectionTitle.vue'; import SectionTitle from '@/components/layout/title/SectionTitle.vue';
@@ -17,7 +26,7 @@ import {
packageTypeEnumLabelMap packageTypeEnumLabelMap
} from '../consts'; } from '../consts';
import conceptJson from '../json/concept'; import conceptJson from '../json/concept.json';
import tasteJson from '../json/taste.json'; import tasteJson from '../json/taste.json';
import packageJson from '../json/package.json'; import packageJson from '../json/package.json';
@@ -142,18 +151,25 @@ function getPopupContainer(el) {
return el.parentNode.parentNode || document.body; return el.parentNode.parentNode || document.body;
} }
const indicatorTooltipText = computed(() => indicatorTooltipTexts[props.schemeType][projectFormModel.testType]); const indicatorTooltipText = computed(
() => indicatorTooltipTexts[props.schemeType][projectFormModel.testType]
);
const expandIndicator = ref(true); const expandIndicator = ref(true);
const expandIndicator2 = ref(false); const expandIndicator2 = ref(false);
function getIndicatorList(type, suffix = '') { function getIndicatorList(type, suffix = '') {
let result = [];
if (![schemeEnum.concept, schemeEnum.taste, schemeEnum.package].includes(props.schemeType)) { if (![schemeEnum.concept, schemeEnum.taste, schemeEnum.package].includes(props.schemeType)) {
return []; return result;
} }
if (schemeEnum.package === props.schemeType) { if (schemeEnum.package === props.schemeType) {
return packageJson[`${type}_${suffix}`]; result = packageJson[`${type}_${suffix}`];
} else {
result = [{}, conceptJson, tasteJson, packageJson][props.schemeType][type];
} }
return [{}, conceptJson, tasteJson, packageJson][props.schemeType][type];
return result;
} }
const standardIndicatorList = computed(() => getIndicatorList(`check_list_standard`, 'outer')); const standardIndicatorList = computed(() => getIndicatorList(`check_list_standard`, 'outer'));
@@ -165,18 +181,34 @@ const quickTestIndicator2List = computed(() => getIndicatorList(`check_list_quic
const pairIndicatorList = computed(() => getIndicatorList(`check_list_pair`, 'outer')); const pairIndicatorList = computed(() => getIndicatorList(`check_list_pair`, 'outer'));
const pairIndicator2List = computed(() => getIndicatorList(`check_list_pair`, 'inner')); const pairIndicator2List = computed(() => getIndicatorList(`check_list_pair`, 'inner'));
const isCheckedAll = computed(() => standardChecked.value.length === standardIndicatorList.value.length); const isCheckedAll = computed(
const isIndeterminate = computed(() => standardChecked.value.length !== standardIndicatorList.value.length); () => standardChecked.value.length === standardIndicatorList.value.length
);
const isIndeterminate = computed(
() => standardChecked.value.length !== standardIndicatorList.value.length
);
const standardChecked = ref(standardIndicatorList.value.filter((i) => i.selected).map((i) => i.value)); const standardChecked = ref(
const quickTestChecked = ref(quickTestIndicatorList.value.filter((i) => i.selected).map((i) => i.value)); standardIndicatorList.value.filter((i) => i.selected).map((i) => i.value)
);
const quickTestChecked = ref(
quickTestIndicatorList.value.filter((i) => i.selected).map((i) => i.value)
);
const pairChecked = ref(pairIndicatorList.value.filter((i) => i.selected).map((i) => i.value)); const pairChecked = ref(pairIndicatorList.value.filter((i) => i.selected).map((i) => i.value));
const isCheckedAll2 = computed(() => standardChecked2.value.length === standardIndicator2List.value.length); const isCheckedAll2 = computed(
const isIndeterminate2 = computed(() => standardChecked2.value.length !== standardIndicator2List.value.length); () => standardChecked2.value.length === standardIndicator2List.value.length
);
const isIndeterminate2 = computed(
() => standardChecked2.value.length !== standardIndicator2List.value.length
);
const standardChecked2 = ref(standardIndicator2List.value.filter((i) => i.selected).map((i) => i.value)); const standardChecked2 = ref(
const quickTestChecked2 = ref(quickTestIndicator2List.value.filter((i) => i.selected).map((i) => i.value)); standardIndicator2List.value.filter((i) => i.selected).map((i) => i.value)
);
const quickTestChecked2 = ref(
quickTestIndicator2List.value.filter((i) => i.selected).map((i) => i.value)
);
const pairChecked2 = ref(pairIndicator2List.value.filter((i) => i.selected).map((i) => i.value)); const pairChecked2 = ref(pairIndicator2List.value.filter((i) => i.selected).map((i) => i.value));
watchEffect(() => { watchEffect(() => {
@@ -194,7 +226,9 @@ watchEffect(() => {
function toggleCheckAll() { function toggleCheckAll() {
if (isCheckedAll.value) { if (isCheckedAll.value) {
standardChecked.value = standardIndicatorList.value.filter((item) => item.disabled).map((item) => item.value); standardChecked.value = standardIndicatorList.value
.filter((item) => item.disabled)
.map((item) => item.value);
} else { } else {
standardChecked.value = standardIndicatorList.value.map((item) => item.value); standardChecked.value = standardIndicatorList.value.map((item) => item.value);
} }
@@ -202,7 +236,9 @@ function toggleCheckAll() {
function toggleCheckAll2() { function toggleCheckAll2() {
if (isCheckedAll2.value) { if (isCheckedAll2.value) {
standardChecked2.value = standardIndicator2List.value.filter((item) => item.disabled).map((item) => item.value); standardChecked2.value = standardIndicator2List.value
.filter((item) => item.disabled)
.map((item) => item.value);
} else { } else {
standardChecked2.value = standardIndicator2List.value.map((item) => item.value); standardChecked2.value = standardIndicator2List.value.map((item) => item.value);
} }
@@ -276,7 +312,13 @@ function validateForm() {
}[projectFormModel.testType]; }[projectFormModel.testType];
resolve({ resolve({
status: 'fulfilled', status: 'fulfilled',
data: Object.assign({}, resolveData[0], resolveData[1], { concept_indexes }, { concept_indexes2 }) data: Object.assign(
{},
resolveData[0],
resolveData[1],
{ concept_indexes },
{ concept_indexes2 }
)
}); });
}); });
} }
@@ -290,7 +332,12 @@ defineExpose({
<div> <div>
<SectionTitle class="mb-18">项目配置</SectionTitle> <SectionTitle class="mb-18">项目配置</SectionTitle>
<a-form ref="projectFormRef" :model="projectFormModel" :rules="projectFormRules" :label-col="{ span: 4 }"> <a-form
ref="projectFormRef"
:model="projectFormModel"
:rules="projectFormRules"
:label-col="{ span: 4 }"
>
<a-row :gutter="6"> <a-row :gutter="6">
<a-col :span="16"> <a-col :span="16">
<a-form-item label="品类品牌" name="surveyCategoryStr" required :label-col="{ span: 6 }"> <a-form-item label="品类品牌" name="surveyCategoryStr" required :label-col="{ span: 6 }">
@@ -335,7 +382,12 @@ defineExpose({
<a-form-item label="测试版本" name="testType"> <a-form-item label="测试版本" name="testType">
<a-radio-group v-model:value="projectFormModel.testType"> <a-radio-group v-model:value="projectFormModel.testType">
<a-radio :value="item.id" v-for="item in testTypeList" :key="item.id" @click="onChangeTestType(item)"> <a-radio
:value="item.id"
v-for="item in testTypeList"
:key="item.id"
@click="onChangeTestType(item)"
>
{{ item.name }} {{ item.name }}
</a-radio> </a-radio>
</a-radio-group> </a-radio-group>
@@ -438,7 +490,8 @@ defineExpose({
> >
<div v-if="projectFormModel.testType === testTypeEnum.standard"> <div v-if="projectFormModel.testType === testTypeEnum.standard">
<div class="check-box"> <div class="check-box">
<div v-for="item in standardIndicatorList" :key="item.value" class="check-item"> <template v-for="item in standardIndicatorList" :key="item.value">
<div v-if="!item.hidden" class="check-item">
<a-checkbox <a-checkbox
:checked="standardChecked.includes(item.value)" :checked="standardChecked.includes(item.value)"
:value="item.value" :value="item.value"
@@ -451,6 +504,7 @@ defineExpose({
</span> </span>
</a-checkbox> </a-checkbox>
</div> </div>
</template>
<div v-for="item in 10" :key="item" class="check-item"></div> <div v-for="item in 10" :key="item" class="check-item"></div>
</div> </div>
</div> </div>
@@ -459,7 +513,11 @@ defineExpose({
<a-checkbox-group v-model:value="quickTestChecked"> <a-checkbox-group v-model:value="quickTestChecked">
<div class="check-box"> <div class="check-box">
<div v-for="item in quickTestIndicatorList" :key="item.value" class="check-item"> <div v-for="item in quickTestIndicatorList" :key="item.value" class="check-item">
<a-checkbox class="custom-checkbox my-checkbox" :value="item.value" :disabled="item.disabled"> <a-checkbox
class="custom-checkbox my-checkbox"
:value="item.value"
:disabled="item.disabled"
>
<span :class="{ 'check-label': item.disabled }"> <span :class="{ 'check-label': item.disabled }">
{{ item.label }} {{ item.label }}
</span> </span>
@@ -473,8 +531,16 @@ defineExpose({
<div v-if="projectFormModel.testType === testTypeEnum.pair"> <div v-if="projectFormModel.testType === testTypeEnum.pair">
<a-checkbox-group v-model:value="pairChecked"> <a-checkbox-group v-model:value="pairChecked">
<div class="check-box"> <div class="check-box">
<div v-for="item in pairIndicatorList" :key="item.value" class="check-item check-item-three"> <div
<a-checkbox class="custom-checkbox my-checkbox" :value="item.value" :disabled="item.disabled"> v-for="item in pairIndicatorList"
:key="item.value"
class="check-item check-item-three"
>
<a-checkbox
class="custom-checkbox my-checkbox"
:value="item.value"
:disabled="item.disabled"
>
<span :class="{ 'check-label': item.disabled }"> <span :class="{ 'check-label': item.disabled }">
{{ item.label }} {{ item.label }}
</span> </span>
@@ -488,7 +554,8 @@ defineExpose({
<template <template
v-if=" v-if="
[schemeEnum.package].includes(props.schemeType) && projectFormModel.packageType.includes(packageTypeEnum.inner) [schemeEnum.package].includes(props.schemeType) &&
projectFormModel.packageType.includes(packageTypeEnum.inner)
" "
> >
<div v-if="projectFormModel.packageType.length === 2" class="flex mb-12 mt-12"> <div v-if="projectFormModel.packageType.length === 2" class="flex mb-12 mt-12">
@@ -516,7 +583,8 @@ defineExpose({
> >
<div v-if="projectFormModel.testType === testTypeEnum.standard"> <div v-if="projectFormModel.testType === testTypeEnum.standard">
<div class="check-box"> <div class="check-box">
<div v-for="item in standardIndicator2List" :key="item.value" class="check-item"> <template v-for="item in standardIndicator2List" :key="item.value">
<div v-if="!item.hidden" class="check-item">
<a-checkbox <a-checkbox
:checked="standardChecked2.includes(item.value)" :checked="standardChecked2.includes(item.value)"
:value="item.value" :value="item.value"
@@ -529,6 +597,7 @@ defineExpose({
</span> </span>
</a-checkbox> </a-checkbox>
</div> </div>
</template>
<div v-for="item in 10" :key="item" class="check-item"></div> <div v-for="item in 10" :key="item" class="check-item"></div>
</div> </div>
</div> </div>
@@ -537,7 +606,11 @@ defineExpose({
<a-checkbox-group v-model:value="quickTestChecked2"> <a-checkbox-group v-model:value="quickTestChecked2">
<div class="check-box"> <div class="check-box">
<div v-for="item in quickTestIndicator2List" :key="item.value" class="check-item"> <div v-for="item in quickTestIndicator2List" :key="item.value" class="check-item">
<a-checkbox class="custom-checkbox my-checkbox" :value="item.value" :disabled="item.disabled"> <a-checkbox
class="custom-checkbox my-checkbox"
:value="item.value"
:disabled="item.disabled"
>
<span :class="{ 'check-label': item.disabled }"> <span :class="{ 'check-label': item.disabled }">
{{ item.label }} {{ item.label }}
</span> </span>
@@ -551,8 +624,16 @@ defineExpose({
<div v-if="projectFormModel.testType === testTypeEnum.pair"> <div v-if="projectFormModel.testType === testTypeEnum.pair">
<a-checkbox-group v-model:value="pairChecked2"> <a-checkbox-group v-model:value="pairChecked2">
<div class="check-box"> <div class="check-box">
<div v-for="item in pairIndicator2List" :key="item.value" class="check-item check-item-three"> <div
<a-checkbox class="custom-checkbox my-checkbox" :value="item.value" :disabled="item.disabled"> v-for="item in pairIndicator2List"
:key="item.value"
class="check-item check-item-three"
>
<a-checkbox
class="custom-checkbox my-checkbox"
:value="item.value"
:disabled="item.disabled"
>
<span :class="{ 'check-label': item.disabled }"> <span :class="{ 'check-label': item.disabled }">
{{ item.label }} {{ item.label }}
</span> </span>

View File

@@ -27,7 +27,12 @@
class="custom-select show-select" class="custom-select show-select"
:dropdownStyle="{ zIndex: 10000 }" :dropdownStyle="{ zIndex: 10000 }"
> >
<a-select-option :value="`${item.code}`" :label="item.title" v-for="item in scenesList" :key="`${item.code}`"> <a-select-option
:value="`${item.code}`"
:label="item.title"
v-for="item in scenesList"
:key="`${item.code}`"
>
{{ item.parentTitle }}-{{ item.title }} {{ item.parentTitle }}-{{ item.title }}
</a-select-option> </a-select-option>
</a-select> </a-select>
@@ -43,7 +48,12 @@
class="custom-select show-select" class="custom-select show-select"
:dropdownStyle="{ zIndex: 10000 }" :dropdownStyle="{ zIndex: 10000 }"
> >
<a-select-option :value="item.id" :label="item.title" v-for="item in tagsList" :key="item.id"> <a-select-option
:value="item.id"
:label="item.title"
v-for="item in tagsList"
:key="item.id"
>
<div style="display: flex; justify-content: space-between"> <div style="display: flex; justify-content: space-between">
<span :style="countColor(item.color)" :title="item.title">{{ item.title }}</span> <span :style="countColor(item.color)" :title="item.title">{{ item.title }}</span>
<span class="icon" v-show="isAdmin"> <span class="icon" v-show="isAdmin">
@@ -96,7 +106,12 @@ import { defineComponent, reactive, ref, watch, onBeforeMount, createVNode } fro
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { message, Modal } from 'ant-design-vue'; import { message, Modal } from 'ant-design-vue';
import { PlusOutlined, EditOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue'; import {
PlusOutlined,
EditOutlined,
DeleteOutlined,
ExclamationCircleOutlined
} from '@ant-design/icons-vue';
import { getTagsList, deleteTags, getSceneListForSelect } from '@/views/ProjectManage/api'; import { getTagsList, deleteTags, getSceneListForSelect } from '@/views/ProjectManage/api';
import addTag from '@/views/ProjectManage/components/addTag.vue'; import addTag from '@/views/ProjectManage/components/addTag.vue';
import useEmitter from '@/composables/useEmitter'; import useEmitter from '@/composables/useEmitter';

View File

@@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, defineProps } from 'vue'; import { computed, defineProps, ref, watch } from 'vue';
import conceptJson from '../json/concept.json'; import conceptJson from '../json/concept.json';
import tasteJson from '../json/taste.json'; import tasteJson from '../json/taste.json';
@@ -27,6 +27,36 @@ const questionList = computed(() => {
return [{}, conceptJson, tasteJson, packageJson][props.schemeType][questionIndex]; return [{}, conceptJson, tasteJson, packageJson][props.schemeType][questionIndex];
}); });
// 分页加载,否则数据多时,页面会卡顿
const page = ref(1);
const pageSize = ref(10);
const deferredRenderThreshold = 30;
const questionListForRender = computed(() =>
questionList.value.slice(0, page.value * pageSize.value)
);
watch(questionList, renderDom, { immediate: true });
function renderDom() {
if (questionList.value.length < deferredRenderThreshold) {
page.value = Math.ceil(deferredRenderThreshold / pageSize.value);
return;
}
page.value = 1;
increasePage();
}
function increasePage() {
if (page.value * pageSize.value >= questionList.value.length) {
return;
}
setTimeout(() => {
page.value += 1;
increasePage();
}, 280);
}
</script> </script>
<template> <template>
@@ -39,7 +69,12 @@ const questionList = computed(() => {
<div class="head-title-two">样本量要求60</div> <div class="head-title-two">样本量要求60</div>
</div> </div>
<div class="question-content" v-for="(item, index) in questionList" :key="index" :class="{ nb: item.noBottom }"> <div
class="question-content"
v-for="(item, index) in questionListForRender"
:key="index"
:class="{ nb: item.noBottom }"
>
<div class="question-title" v-if="item?.seq || item?.title"> <div class="question-title" v-if="item?.seq || item?.title">
<span v-if="item?.seq" class="question-seq">{{ item.seq }}</span> <span v-if="item?.seq" class="question-seq">{{ item.seq }}</span>
<span v-if="item?.title" v-html="item.title"></span> <span v-if="item?.title" v-html="item.title"></span>
@@ -53,7 +88,12 @@ const questionList = computed(() => {
<div class="question-tip mb-8" v-if="item?.tip">{{ item.tip }}</div> <div class="question-tip mb-8" v-if="item?.tip">{{ item.tip }}</div>
<div class="question-ans mb-8" v-for="it in item.ans" :key="it" :class="{ 'group-title': it.isGroupTitle }"> <div
class="question-ans mb-8"
v-for="it in item.ans"
:key="it"
:class="{ 'group-title': it.isGroupTitle }"
>
<span v-if="it.isGroupTitle">{{ it.title }}</span> <span v-if="it.isGroupTitle">{{ it.title }}</span>
<span v-else v-html="it"></span> <span v-else v-html="it"></span>
</div> </div>

View File

@@ -77,19 +77,22 @@ function onSave() {
<div class="content-box"> <div class="content-box">
<!-- 配置 --> <!-- 配置 -->
<div class="content scrollbar"> <div class="flex flex-column left">
<div class="flex-auto full-width scroller-y content-wrapper">
<slot></slot> <slot></slot>
</div> </div>
<div class="flex-none full-width footer">
<slot name="footer"></slot>
</div>
</div>
<!-- 模版详情 --> <!-- 模版详情 -->
<div ref="templateScrollerRef" class="content scrollbar"> <div ref="templateScrollerRef" class="right scroller-y">
<div class="template-box">
<SectionTitle>模板详情</SectionTitle> <SectionTitle>模板详情</SectionTitle>
<SurveySchemeTemplate :scheme-type="props.schemeType" :test-type="props.testType" /> <SurveySchemeTemplate :scheme-type="props.schemeType" :test-type="props.testType" />
</div> </div>
</div> </div>
</div> </div>
</div>
</a-modal> </a-modal>
</template> </template>
@@ -136,12 +139,17 @@ function onSave() {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
.content { .left,
width: calc(50% - 12px); .right {
padding: 22px; width: calc(50% - 8px);
height: calc(100vh - 150px); height: calc(100vh - 150px);
}
.content-wrapper,
.right {
overflow: auto; overflow: auto;
overflow: overlay; overflow: overlay;
padding: 22px;
background-color: #ffffff; background-color: #ffffff;
border-radius: 6px; border-radius: 6px;
position: relative; position: relative;

View File

@@ -67,37 +67,49 @@ export const encodeList = [
'Z' 'Z'
]; ];
let indicator2_1 = '您在此处勾选拟调研的指标,每个指标对应一道问题,问卷将针对每个口味分别询问被访者相关问题。'; const indicatorCommon1 = '您在此处勾选拟调研的指标,每个指标对应一道问题,问卷将针对每个';
const indicatorCommon2 = '分别询问被访者相关问题';
let indicator2_1 = indicatorCommon1 + '问卷将针对每个口味分别询问被访者相关问题。';
indicator2_1 += '特别的,若勾选「属性具体评价」则会针对每个口味的属性询问被访者的评价'; indicator2_1 += '特别的,若勾选「属性具体评价」则会针对每个口味的属性询问被访者的评价';
const indicator2_2 = '您在此处勾选拟调研的指标,每个指标对应一道问题,问卷将针对每个口味分别询问被访者相关问题';
const indicator2_3 = '您在此处勾选拟调研的指标,每个指标对应一道问题,问卷将针对每个口味分别询问被访者相关问题';
export const indicatorTooltipTexts = { export const indicatorTooltipTexts = {
[schemeEnum.concept]: { [schemeEnum.concept]: {
[testTypeEnum.standard]: '您在此处勾选拟调研的指标,每个指标对应一道问题,问卷将针对每个概念分别询问被访者相关问题', [testTypeEnum.standard]: indicatorCommon1 + '概念' + indicatorCommon2,
[testTypeEnum.quickTest]: [testTypeEnum.quickTest]: indicatorCommon1 + '概念' + indicatorCommon2,
'您在此处勾选拟调研的指标,每个指标对应一道问题,问卷将针对每个概念分别询问被访者相关问题', [testTypeEnum.pair]: indicatorCommon1 + '概念' + indicatorCommon2
[testTypeEnum.pair]: '您在此处勾选拟调研的指标,每个指标对应一道问题,问卷将针对每个概念分别询问被访者相关问题'
}, },
[schemeEnum.taste]: { [schemeEnum.taste]: {
[testTypeEnum.standard]: indicator2_1, [testTypeEnum.standard]: indicator2_1,
[testTypeEnum.quickTest]: indicator2_2, [testTypeEnum.quickTest]: indicatorCommon1 + '口味' + indicatorCommon2,
[testTypeEnum.pair]: indicator2_3 [testTypeEnum.pair]: indicatorCommon1 + '口味' + indicatorCommon2
}, },
[schemeEnum.package]: { [schemeEnum.package]: {
[testTypeEnum.standard]: '您在此处勾选拟调研的指标,每个指标对应一道问题,问卷将针对每个包装分别询问被访者相关问题', [testTypeEnum.standard]: indicatorCommon1 + '包装' + indicatorCommon2,
[testTypeEnum.quickTest]: [testTypeEnum.quickTest]: indicatorCommon1 + '包装' + indicatorCommon2,
'您在此处勾选拟调研的指标,每个指标对应一道问题,问卷将针对每个包装分别询问被访者相关问题', [testTypeEnum.pair]: indicatorCommon1 + '包装' + indicatorCommon2
[testTypeEnum.pair]: '您在此处勾选拟调研的指标,每个指标对应一道问题,问卷将针对每个包装分别询问被访者相关问题'
} }
}; };
export const packageTypeEnum = { export const packageTypeEnum = {
basic: 0, // 配置 step 组件中,显示 “基础配置” 的,并不真的是包装类型 basic: 0, // 配置 step 组件中,显示 “基础配置” 的,并不真的是包装类型
outer: 1, outer: 1,
inner: 2 inner: 2,
inout: 3 // 后端需要的 package_type 字段: 123前端多选需要给他转一下
}; };
export function getPackageForApi(packageType = []) {
if (packageType.includes(packageTypeEnum.outer) && packageType.includes(packageTypeEnum.inner)) {
return packageTypeEnum.inout;
}
if (packageType.includes(packageTypeEnum.outer)) {
return packageTypeEnum.outer;
}
if (packageType.includes(packageTypeEnum.inner)) {
return packageTypeEnum.inner;
}
}
export const packageTypeEnumLabelMap = { export const packageTypeEnumLabelMap = {
[packageTypeEnum.outer]: '外箱测试', [packageTypeEnum.outer]: '外箱测试',
[packageTypeEnum.inner]: '内包测试' [packageTypeEnum.inner]: '内包测试'

View File

@@ -197,7 +197,9 @@ export default {
}, },
{ {
seq: 'A2', seq: 'A2',
title: `与市场上其他同类产品相比,您认为这款介绍中描述的产品的新颖独特程度是怎样的呢?${qType('【单选题】')}`, title: `与市场上其他同类产品相比,您认为这款介绍中描述的产品的新颖独特程度是怎样的呢?${qType(
'【单选题】'
)}`,
topic: '[系统自动插入新品概念方向一图片]', topic: '[系统自动插入新品概念方向一图片]',
tip: '#新颖独特性 新品概念方向一', tip: '#新颖独特性 新品概念方向一',
ans: ['非常新颖独特', '比较新颖独特', '谈不上有没有,一般', '不太新颖独特', '一点也不新颖独特'] ans: ['非常新颖独特', '比较新颖独特', '谈不上有没有,一般', '不太新颖独特', '一点也不新颖独特']
@@ -275,7 +277,9 @@ export default {
}, },
{ {
seq: 'A11', seq: 'A11',
title: `您刚才看到的这款产品,下列哪句话最能描述它对您购买习惯的影响程度?${qType('【填空题】')}`, title: `您刚才看到的这款产品,下列哪句话最能描述它对您购买习惯的影响程度?${qType(
'【填空题】'
)}`,
topic: '[系统自动插入新品概念方向一图片]', topic: '[系统自动插入新品概念方向一图片]',
tip: '#购买行为影响 新品概念方向一', tip: '#购买行为影响 新品概念方向一',
ans: [ ans: [
@@ -338,7 +342,9 @@ export default {
}, },
{ {
seq: 'A15', seq: 'A15',
title: `看完这款产品介绍后,您觉得这款介绍所描述的内容容易理解吗?您觉得它是……?${qType('【单选题】')}`, title: `看完这款产品介绍后,您觉得这款介绍所描述的内容容易理解吗?您觉得它是……?${qType(
'【单选题】'
)}`,
topic: '[系统自动插入新品概念方向一图片]', topic: '[系统自动插入新品概念方向一图片]',
tip: '#理解度 新品概念方向一', tip: '#理解度 新品概念方向一',
ans: ['非常容易理解', '比较容易理解', '一般', '有些不容易理解', '非常不容易理解'] ans: ['非常容易理解', '比较容易理解', '一般', '有些不容易理解', '非常不容易理解']
@@ -512,7 +518,9 @@ export default {
}, },
{ {
seq: 'B2', seq: 'B2',
title: `与市场上其他同类产品相比,您认为这款介绍中描述的产品的新颖独特程度是怎样的呢?${qType('【单选题】')}`, title: `与市场上其他同类产品相比,您认为这款介绍中描述的产品的新颖独特程度是怎样的呢?${qType(
'【单选题】'
)}`,
topic: '[系统自动插入新品概念方向二图片]', topic: '[系统自动插入新品概念方向二图片]',
tip: '#新颖独特性 新品概念方向二', tip: '#新颖独特性 新品概念方向二',
ans: ['非常新颖独特', '比较新颖独特', '谈不上有没有,一般', '不太新颖独特', '一点也不新颖独特'] ans: ['非常新颖独特', '比较新颖独特', '谈不上有没有,一般', '不太新颖独特', '一点也不新颖独特']
@@ -590,7 +598,9 @@ export default {
}, },
{ {
seq: 'B11', seq: 'B11',
title: `您刚才看到的这款产品,下列哪句话最能描述它对您购买习惯的影响程度?${qType('【单选题】')}`, title: `您刚才看到的这款产品,下列哪句话最能描述它对您购买习惯的影响程度?${qType(
'【单选题】'
)}`,
topic: '[系统自动插入新品概念方向二图片]', topic: '[系统自动插入新品概念方向二图片]',
tip: '#购买行为影响 新品概念方向二', tip: '#购买行为影响 新品概念方向二',
ans: [ ans: [
@@ -652,7 +662,9 @@ export default {
}, },
{ {
seq: 'B15', seq: 'B15',
title: `看完这款产品介绍后,您觉得这款介绍所描述的内容容易理解吗?您觉得它是……?${qType('【单选题】')}`, title: `看完这款产品介绍后,您觉得这款介绍所描述的内容容易理解吗?您觉得它是……?${qType(
'【单选题】'
)}`,
topic: '[系统自动插入新品概念方向二图片]', topic: '[系统自动插入新品概念方向二图片]',
tip: '#理解度 新品概念方向二', tip: '#理解度 新品概念方向二',
ans: ['非常容易理解', '比较容易理解', '一般', '有些不容易理解', '非常不容易理解'] ans: ['非常容易理解', '比较容易理解', '一般', '有些不容易理解', '非常不容易理解']

View File

@@ -196,7 +196,13 @@
"title": "与市场上其他同类产品相比,您认为这款介绍中描述的产品的新颖独特程度是怎样的呢?<span style=\"font-weight:700;\">【单选题】</span>", "title": "与市场上其他同类产品相比,您认为这款介绍中描述的产品的新颖独特程度是怎样的呢?<span style=\"font-weight:700;\">【单选题】</span>",
"topic": "[系统自动插入新品概念方向一图片]", "topic": "[系统自动插入新品概念方向一图片]",
"tip": "#新颖独特性 新品概念方向一", "tip": "#新颖独特性 新品概念方向一",
"ans": ["非常新颖独特", "比较新颖独特", "谈不上有没有,一般", "不太新颖独特", "一点也不新颖独特"] "ans": [
"非常新颖独特",
"比较新颖独特",
"谈不上有没有,一般",
"不太新颖独特",
"一点也不新颖独特"
]
}, },
{ {
"seq": "A3", "seq": "A3",
@@ -495,7 +501,13 @@
"title": "与市场上其他同类产品相比,您认为这款介绍中描述的产品的新颖独特程度是怎样的呢?<span style=\"font-weight:700;\">【单选题】</span>", "title": "与市场上其他同类产品相比,您认为这款介绍中描述的产品的新颖独特程度是怎样的呢?<span style=\"font-weight:700;\">【单选题】</span>",
"topic": "[系统自动插入新品概念方向二图片]", "topic": "[系统自动插入新品概念方向二图片]",
"tip": "#新颖独特性 新品概念方向二", "tip": "#新颖独特性 新品概念方向二",
"ans": ["非常新颖独特", "比较新颖独特", "谈不上有没有,一般", "不太新颖独特", "一点也不新颖独特"] "ans": [
"非常新颖独特",
"比较新颖独特",
"谈不上有没有,一般",
"不太新颖独特",
"一点也不新颖独特"
]
}, },
{ {
"seq": "B3", "seq": "B3",

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,16 @@
{ {
"check_list_standard_outer": [ "check_list_standard_outer": [
{ {
"value": "无提示认知1", "value": "package_out_head",
"label": "外箱的图片题",
"hidden": true,
"disabled": false,
"selected": true,
"alliance": "1",
"fullView": true
},
{
"value": "package_out_head_not_prompt_1",
"label": "无提示认知1", "label": "无提示认知1",
"disabled": false, "disabled": false,
"selected": true, "selected": true,
@@ -9,7 +18,7 @@
"fullView": true "fullView": true
}, },
{ {
"value": "无提示认知2", "value": "package_out_head_not_prompt_2",
"label": "无提示认知2", "label": "无提示认知2",
"disabled": false, "disabled": false,
"selected": true, "selected": true,
@@ -17,7 +26,7 @@
"fullView": true "fullView": true
}, },
{ {
"value": "堆头可见度", "value": "package_out_head_visibility",
"label": "堆头可见度", "label": "堆头可见度",
"disabled": false, "disabled": false,
"selected": true, "selected": true,
@@ -25,7 +34,7 @@
"fullView": true "fullView": true
}, },
{ {
"value": "包装品牌关联", "value": "package_out_brand",
"label": "包装品牌关联", "label": "包装品牌关联",
"disabled": false, "disabled": false,
"selected": true, "selected": true,
@@ -39,19 +48,19 @@
"selected": true "selected": true
}, },
{ {
"value": "包装视觉吸引力1", "value": "package_out_attraction_1",
"label": "包装视觉吸引力1", "label": "包装视觉吸引力1",
"disabled": false, "disabled": false,
"alliance": "2" "alliance": "2"
}, },
{ {
"value": "包装视觉吸引力2", "value": "package_out_attraction_2",
"label": "包装视觉吸引力2", "label": "包装视觉吸引力2",
"disabled": false, "disabled": false,
"alliance": "2" "alliance": "2"
}, },
{ {
"value": "包装视觉吸引力3", "value": "package_out_attraction_3",
"label": "包装视觉吸引力3", "label": "包装视觉吸引力3",
"disabled": false, "disabled": false,
"alliance": "2" "alliance": "2"
@@ -81,7 +90,7 @@
"selected": true "selected": true
}, },
{ {
"value": "包装设计", "value": "package_out_design",
"label": "包装设计", "label": "包装设计",
"disabled": false "disabled": false
}, },
@@ -92,7 +101,7 @@
"selected": true "selected": true
}, },
{ {
"value": "包装品牌影响", "value": "package_out_brand_influence",
"label": "包装品牌影响", "label": "包装品牌影响",
"disabled": false "disabled": false
}, },
@@ -103,54 +112,63 @@
"selected": true "selected": true
}, },
{ {
"value": "新颖独特性", "value": "package_out_novelty_uniqueness",
"label": "新颖独特性", "label": "新颖独特性",
"disabled": false "disabled": false
}, },
{ {
"value": "系列感", "value": "package_out_serial_sense",
"label": "系列感", "label": "系列感",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_drink_time", "value": "package_out_drink_time",
"label": "饮用时间", "label": "饮用时间",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_drink_occasion", "value": "package_out_drink_occasion",
"label": "饮用场合", "label": "饮用场合",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_drink_todo", "value": "package_out_drink_todo",
"label": "饮用时做什么", "label": "饮用时做什么",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_sales_channel", "value": "package_out_sales_channel",
"label": "售卖渠道", "label": "售卖渠道",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_price_test", "value": "package_out_price_test",
"label": "价格测试", "label": "价格测试",
"disabled": false "disabled": false
}, },
{ {
"value": "包装品类关联", "value": "package_out_category_association",
"label": "包装品类关联", "label": "包装品类关联",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_forced_contrast", "value": "package_out_forced_sort",
"label": "强制对比", "label": "强制对比",
"disabled": false "disabled": false
} }
], ],
"check_list_standard_inner": [ "check_list_standard_inner": [
{ {
"value": "无提示认知1", "value": "package_inter_head",
"label": "内包的图片题",
"hidden": true,
"disabled": false,
"selected": true,
"alliance": "1",
"fullView": true
},
{
"value": "package_inter_head_not_prompt_1",
"label": "无提示认知1", "label": "无提示认知1",
"disabled": false, "disabled": false,
"selected": true, "selected": true,
@@ -158,7 +176,7 @@
"fullView": true "fullView": true
}, },
{ {
"value": "无提示认知2", "value": "package_inter_head_not_prompt_2",
"label": "无提示认知2", "label": "无提示认知2",
"disabled": false, "disabled": false,
"selected": true, "selected": true,
@@ -166,7 +184,7 @@
"fullView": true "fullView": true
}, },
{ {
"value": "货架可见度", "value": "package_inter_head_visibility",
"label": "货架可见度", "label": "货架可见度",
"disabled": false, "disabled": false,
"selected": true, "selected": true,
@@ -174,7 +192,7 @@
"fullView": true "fullView": true
}, },
{ {
"value": "包装品牌关联", "value": "package_inter_brand",
"label": "包装品牌关联", "label": "包装品牌关联",
"disabled": false, "disabled": false,
"selected": true, "selected": true,
@@ -188,19 +206,19 @@
"selected": true "selected": true
}, },
{ {
"value": "包装视觉吸引力1", "value": "package_inter_attraction_1",
"label": "包装视觉吸引力1", "label": "包装视觉吸引力1",
"disabled": false, "disabled": false,
"alliance": "2" "alliance": "2"
}, },
{ {
"value": "包装视觉吸引力2", "value": "package_inter_attraction_2",
"label": "包装视觉吸引力2", "label": "包装视觉吸引力2",
"disabled": false, "disabled": false,
"alliance": "2" "alliance": "2"
}, },
{ {
"value": "包装视觉吸引力3", "value": "package_inter_attraction_3",
"label": "包装视觉吸引力3", "label": "包装视觉吸引力3",
"disabled": false, "disabled": false,
"alliance": "2" "alliance": "2"
@@ -230,7 +248,7 @@
"selected": true "selected": true
}, },
{ {
"value": "包装设计", "value": "package_inter_design",
"label": "包装设计", "label": "包装设计",
"disabled": false "disabled": false
}, },
@@ -241,7 +259,7 @@
"selected": true "selected": true
}, },
{ {
"value": "包装品牌影响", "value": "package_inter_brand_influence",
"label": "包装品牌影响", "label": "包装品牌影响",
"disabled": false "disabled": false
}, },
@@ -252,47 +270,47 @@
"selected": true "selected": true
}, },
{ {
"value": "新颖独特性", "value": "package_inter_novelty_uniqueness",
"label": "新颖独特性", "label": "新颖独特性",
"disabled": false "disabled": false
}, },
{ {
"value": "系列感", "value": "package_inter_serial_sense",
"label": "系列感", "label": "系列感",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_drink_time", "value": "package_inter_drink_time",
"label": "饮用时间", "label": "饮用时间",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_drink_occasion", "value": "package_inter_drink_occasion",
"label": "饮用场合", "label": "饮用场合",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_drink_todo", "value": "package_inter_drink_todo",
"label": "饮用时做什么", "label": "饮用时做什么",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_sales_channel", "value": "package_inter_sales_channel",
"label": "售卖渠道", "label": "售卖渠道",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_price_test", "value": "package_inter_price_test",
"label": "价格测试", "label": "价格测试",
"disabled": false "disabled": false
}, },
{ {
"value": "包装品类关联", "value": "package_inter_category_association",
"label": "包装品类关联", "label": "包装品类关联",
"disabled": false "disabled": false
}, },
{ {
"value": "taste_forced_contrast", "value": "package_inter_forced_sort",
"label": "强制对比", "label": "强制对比",
"disabled": false "disabled": false
} }
@@ -305,7 +323,7 @@
"selected": true "selected": true
}, },
{ {
"value": "包装设计", "value": "package_out_design",
"label": "包装设计", "label": "包装设计",
"disabled": false "disabled": false
}, },
@@ -315,7 +333,7 @@
"disabled": false "disabled": false
}, },
{ {
"value": "强制对比", "value": "package_out_forced_sort",
"label": "强制对比", "label": "强制对比",
"disabled": false "disabled": false
} }
@@ -328,7 +346,7 @@
"selected": true "selected": true
}, },
{ {
"value": "包装设计", "value": "package_inter_design",
"label": "包装设计", "label": "包装设计",
"disabled": false "disabled": false
}, },
@@ -338,7 +356,7 @@
"disabled": false "disabled": false
}, },
{ {
"value": "强制对比", "value": "package_inter_forced_sort",
"label": "强制对比", "label": "强制对比",
"disabled": false "disabled": false
} }

View File

@@ -3,11 +3,15 @@ export function red(text) {
} }
export function black(text) { export function black(text) {
return `<span style="font-weight:700;color:black;text-decoration:underline;">${text || ''}</span>`; return `<span style="font-weight:700;color:black;text-decoration:underline;">${
text || ''
}</span>`;
} }
export function green(text) { export function green(text) {
return `<span style="font-weight:700;color:green;text-decoration:underline;">${text || ''}</span>`; return `<span style="font-weight:700;color:green;text-decoration:underline;">${
text || ''
}</span>`;
} }
export function qType(text) { export function qType(text) {

View File

@@ -148,20 +148,26 @@ export default {
}, },
{ {
seq: 'A1', seq: 'A1',
title: `请问您对您刚才品尝过的${red('口味A')}${black('总体喜欢程度')}是怎样的?${qType('【单选题】')}`, title: `请问您对您刚才品尝过的${red('口味A')}${black('总体喜欢程度')}是怎样的?${qType(
'【单选题】'
)}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#总体喜欢程度 口味一名称', tip: '#总体喜欢程度 口味一名称',
ans: ['非常喜欢', '比较喜欢', '一般', '不太喜欢', '完全不喜欢'] ans: ['非常喜欢', '比较喜欢', '一般', '不太喜欢', '完全不喜欢']
}, },
{ {
seq: 'A2', seq: 'A2',
title: `您已经品尝了这款产品,请告诉我您${red('不喜欢')}这款${red('口味A')}的哪些方面?${qType('【填空题】')}`, title: `您已经品尝了这款产品,请告诉我您${red('不喜欢')}这款${red(
'口味A'
)}的哪些方面?${qType('【填空题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#不喜欢方面 口味一名称' tip: '#不喜欢方面 口味一名称'
}, },
{ {
seq: 'A3', seq: 'A3',
title: `您已经品尝了这款产品,请告诉我您${green('喜欢')}这款${red('口味A')}的哪些方面?${qType('【填空题】')}`, title: `您已经品尝了这款产品,请告诉我您${green('喜欢')}这款${red(
'口味A'
)}的哪些方面?${qType('【填空题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#喜欢的方面 口味一名称' tip: '#喜欢的方面 口味一名称'
}, },
@@ -176,9 +182,9 @@ export default {
}, },
{ {
seq: 'A5', seq: 'A5',
title: `与目前市场上销售的其它${black('同类产品')}相比,请问您觉得这款${red('口味A')}${black( title: `与目前市场上销售的其它${black('同类产品')}相比,请问您觉得这款${red(
'新颖独特性' '口味A'
)}如何呢?${qType('【单选题】')}`, )}${black('新颖独特性')}如何呢?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#新颖独特性 口味一名称', tip: '#新颖独特性 口味一名称',
ans: ['非常新颖独特', '比较新颖独特', '谈不上有没有,一般', '不太新颖独特', '一点也不新颖独特'] ans: ['非常新颖独特', '比较新颖独特', '谈不上有没有,一般', '不太新颖独特', '一点也不新颖独特']
@@ -195,50 +201,66 @@ export default {
table: { table: {
headers: ['', '喜欢程度'], headers: ['', '喜欢程度'],
rows: [ rows: [
['奶香味(喝起来奶香浓醇)', '非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'], [
['甜味(自然清甜味,非人工添加糖剂)', '非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'], '奶香味(喝起来奶香浓醇)',
['稀稠度(喝起来的厚薄程度)', '非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'], '非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'
['醇厚度(喝起来没有被稀释过的感觉)', '非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'] ],
[
'甜味(自然清甜味,非人工添加糖剂)',
'非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'
],
[
'稀稠度(喝起来的厚薄程度)',
'非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'
],
[
'醇厚度(喝起来没有被稀释过的感觉)',
'非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'
]
] ]
} }
}, },
{ {
seq: 'A6.1', seq: 'A6.1',
title: `请问您觉得这个${red('口味A')}喝起来的${black('奶香味(喝起来奶香浓醇)')}如何?${qType('【单选题】')}`, title: `请问您觉得这个${red('口味A')}喝起来的${black(
'奶香味(喝起来奶香浓醇)'
)}如何?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#属性具体评价-奶香味(喝起来奶香浓醇) 口味一名称', tip: '#属性具体评价-奶香味(喝起来奶香浓醇) 口味一名称',
ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够'] ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够']
}, },
{ {
seq: 'A6.2', seq: 'A6.2',
title: `请问您觉得这个${red('口味A')}喝起来的${black('甜味(自然清甜味,非人工添加糖剂)')}如何?${qType( title: `请问您觉得这个${red('口味A')}喝起来的${black(
'【单选题】' '甜味(自然清甜味,非人工添加糖剂)'
)}`, )}如何?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#属性具体评价-甜味(自然清甜味,非人工添加糖剂) 口味一名称', tip: '#属性具体评价-甜味(自然清甜味,非人工添加糖剂) 口味一名称',
ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够'] ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够']
}, },
{ {
seq: 'A6.3', seq: 'A6.3',
title: `请问您觉得这个${red('口味A')}喝起来的${black('稀稠度(喝起来的厚薄程度)')}如何?${qType('【单选题】')}`, title: `请问您觉得这个${red('口味A')}喝起来的${black(
'稀稠度(喝起来的厚薄程度)'
)}如何?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#属性具体评价-稀稠度(喝起来的厚薄程度) 口味一名称', tip: '#属性具体评价-稀稠度(喝起来的厚薄程度) 口味一名称',
ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够'] ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够']
}, },
{ {
seq: 'A6.4', seq: 'A6.4',
title: `请问您觉得这个${red('口味A')}喝起来的${black('醇厚度(喝起来没有被稀释过的感觉)')}如何?${qType( title: `请问您觉得这个${red('口味A')}喝起来的${black(
'【单选题】' '醇厚度(喝起来没有被稀释过的感觉)'
)}`, )}如何?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#属性具体评价-醇厚度(喝起来没有被稀释过的感觉) 口味一名称', tip: '#属性具体评价-醇厚度(喝起来没有被稀释过的感觉) 口味一名称',
ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够'] ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够']
}, },
{ {
seq: 'A7', seq: 'A7',
title: `根据您品尝到的这款${red('口味A')}的口味和口感,您认为这款产品适合${black('在什么时候饮用')}呢?${qType( title: `根据您品尝到的这款${red('口味A')}的口味和口感,您认为这款产品适合${black(
'【单选题】' '在什么时候饮用'
)}`, )}呢?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#饮用时间 口味一名称', tip: '#饮用时间 口味一名称',
ans: [ ans: [
@@ -275,14 +297,18 @@ export default {
}, },
{ {
seq: 'A8', seq: 'A8',
title: `您认为这款${red('口味A')}最适合${black('在哪里饮用')}这产品呢?${qType('【单选题】')}`, title: `您认为这款${red('口味A')}最适合${black('在哪里饮用')}这产品呢?${qType(
'【单选题】'
)}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#饮用场合 口味一名称', tip: '#饮用场合 口味一名称',
ans: ['在家中(如自己家或朋友亲戚家)', '在工作/学习场所', '在户外/餐饮场所'] ans: ['在家中(如自己家或朋友亲戚家)', '在工作/学习场所', '在户外/餐饮场所']
}, },
{ {
seq: 'A9', seq: 'A9',
title: `请设想一下,您饮用该${red('口味A')}${black('最可能')}${black('做什么')}呢?${qType('【单选题】')}`, title: `请设想一下,您饮用该${red('口味A')}${black('最可能')}${black(
'做什么'
)}呢?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#饮用时做什么 口味一名称', tip: '#饮用时做什么 口味一名称',
ans: [ ans: [
@@ -366,7 +392,9 @@ export default {
}, },
{ {
seq: 'A10', seq: 'A10',
title: `您认为您刚才品尝的这款${red('口味A')}适合${black('在什么地方售卖')}呢?${qType('【多选题】')}`, title: `您认为您刚才品尝的这款${red('口味A')}适合${black('在什么地方售卖')}呢?${qType(
'【多选题】'
)}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#售卖渠道 口味一名称', tip: '#售卖渠道 口味一名称',
ans: [ ans: [
@@ -423,9 +451,9 @@ export default {
}, },
{ {
seq: 'A11', seq: 'A11',
title: `您刚才品尝的这款${red('口味A')},下列哪句话最能描述它对您的${black('购买习惯的影响程度')}${qType( title: `您刚才品尝的这款${red('口味A')},下列哪句话最能描述它对您的${black(
'【单选题】' '购买习惯的影响程度'
)}`, )}${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#购买行为影响 口味一名称', tip: '#购买行为影响 口味一名称',
ans: [ ans: [
@@ -437,9 +465,11 @@ export default {
}, },
{ {
seq: 'A12', seq: 'A12',
title: `您刚才提到这款${red('口味A')}会替代您目前正在饮用的产品,那么您能告诉我您会用它${black( title: `您刚才提到这款${red(
'替代' '口味A'
)}哪个或哪些您${black('目前正在饮')}用的饮品呢?${qType('【多选题】')}`, )}会替代您目前正在饮用的产品,那么您能告诉我您会用它${black('替代')}哪个或哪些您${black(
'目前正在饮'
)}用的饮品呢?${qType('【多选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#品类替代 口味一名称', tip: '#品类替代 口味一名称',
ans: [ ans: [
@@ -472,7 +502,9 @@ export default {
}, },
{ {
seq: 'A13', seq: 'A13',
title: `基于这款${red('口味A')}介绍中的描述和价格信息,综合您品尝到的口味,您倾向于饮用这款产品的频率为${black( title: `基于这款${red(
'口味A'
)}介绍中的描述和价格信息,综合您品尝到的口味,您倾向于饮用这款产品的频率为${black(
'每周几次' '每周几次'
)}${qType('【多选题】')}`, )}${qType('【多选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
@@ -529,20 +561,26 @@ export default {
}, },
{ {
seq: 'B1', seq: 'B1',
title: `请问您对您刚才品尝过的${red('口味B')}${black('总体喜欢程度')}是怎样的?${qType('【单选题】')}`, title: `请问您对您刚才品尝过的${red('口味B')}${black('总体喜欢程度')}是怎样的?${qType(
'【单选题】'
)}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#总体喜欢程度 口味二名称', tip: '#总体喜欢程度 口味二名称',
ans: ['非常喜欢', '比较喜欢', '一般', '不太喜欢', '完全不喜欢'] ans: ['非常喜欢', '比较喜欢', '一般', '不太喜欢', '完全不喜欢']
}, },
{ {
seq: 'B2', seq: 'B2',
title: `您已经品尝了这款产品,请告诉我您${red('不喜欢')}这款${red('口味B')}的哪些方面?${qType('【单选题】')}`, title: `您已经品尝了这款产品,请告诉我您${red('不喜欢')}这款${red(
'口味B'
)}的哪些方面?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#不喜欢的方面 口味二名称' tip: '#不喜欢的方面 口味二名称'
}, },
{ {
seq: 'B3', seq: 'B3',
title: `您已经品尝了这款产品,请告诉我您${green('喜欢')}这款${red('口味B')}的哪些方面?${qType('【单选题】')}`, title: `您已经品尝了这款产品,请告诉我您${green('喜欢')}这款${red(
'口味B'
)}的哪些方面?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#喜欢的方面 口味二名称' tip: '#喜欢的方面 口味二名称'
}, },
@@ -557,12 +595,18 @@ export default {
}, },
{ {
seq: 'B5', seq: 'B5',
title: `与目前市场上销售的其它${black('同类产品')}相比,请问您觉得这款${red('口味B')}的新颖独特性如何呢?${qType( title: `与目前市场上销售的其它${black('同类产品')}相比,请问您觉得这款${red(
'【单选题】' '口味B'
)}`, )}的新颖独特性如何呢?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#新颖独特性 口味二名称', tip: '#新颖独特性 口味二名称',
ans: ['非常新颖独特', '比较新颖独特', '谈不上有没有,一般', '不太新颖独特', '一点也不新颖独特'] ans: [
'非常新颖独特',
'比较新颖独特',
'谈不上有没有,一般',
'不太新颖独特',
'一点也不新颖独特'
]
}, },
{ {
seq: 'B6', seq: 'B6',
@@ -576,50 +620,66 @@ export default {
table: { table: {
headers: ['', '喜欢程度'], headers: ['', '喜欢程度'],
rows: [ rows: [
['奶香味(喝起来奶香浓醇)', '非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'], [
['甜味(自然清甜味,非人工添加糖剂)', '非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'], '奶香味(喝起来奶香浓醇)',
['稀稠度(喝起来的厚薄程度)', '非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'], '非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'
['醇厚度(喝起来没有被稀释过的感觉)', '非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'] ],
[
'甜味(自然清甜味,非人工添加糖剂)',
'非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'
],
[
'稀稠度(喝起来的厚薄程度)',
'非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'
],
[
'醇厚度(喝起来没有被稀释过的感觉)',
'非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢'
]
] ]
} }
}, },
{ {
seq: 'B6.1', seq: 'B6.1',
title: `请问您觉得这个${red('口味B')}喝起来的${black('奶香味(喝起来奶香浓醇)')}如何?${qType('【单选题】')}`, title: `请问您觉得这个${red('口味B')}喝起来的${black(
'奶香味(喝起来奶香浓醇)'
)}如何?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#属性具体评价-奶香味(喝起来奶香浓醇) 口味二名称', tip: '#属性具体评价-奶香味(喝起来奶香浓醇) 口味二名称',
ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够'] ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够']
}, },
{ {
seq: 'B6.2', seq: 'B6.2',
title: `请问您觉得这个${red('口味B')}喝起来的${black('甜味(自然清甜味,非人工添加糖剂)')}如何?${qType( title: `请问您觉得这个${red('口味B')}喝起来的${black(
'【单选题】' '甜味(自然清甜味,非人工添加糖剂)'
)}`, )}如何?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#属性具体评价-甜味(自然清甜味,非人工添加糖剂) 口味二名称', tip: '#属性具体评价-甜味(自然清甜味,非人工添加糖剂) 口味二名称',
ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够'] ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够']
}, },
{ {
seq: 'B6.3', seq: 'B6.3',
title: `请问您觉得这个${red('口味B')}喝起来的${black('稀稠度(喝起来的厚薄程度)')}如何?${qType('【单选题】')}`, title: `请问您觉得这个${red('口味B')}喝起来的${black(
'稀稠度(喝起来的厚薄程度)'
)}如何?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#属性具体评价-稀稠度(喝起来的厚薄程度) 口味二名称', tip: '#属性具体评价-稀稠度(喝起来的厚薄程度) 口味二名称',
ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够'] ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够']
}, },
{ {
seq: 'B6.4', seq: 'B6.4',
title: `请问您觉得这个${red('口味B')}喝起来的${black('醇厚度(喝起来没有被稀释过的感觉)')}如何?${qType( title: `请问您觉得这个${red('口味B')}喝起来的${black(
'【单选题】' '醇厚度(喝起来没有被稀释过的感觉)'
)}`, )}如何?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#属性具体评价-醇厚度(喝起来没有被稀释过的感觉) 口味二名称', tip: '#属性具体评价-醇厚度(喝起来没有被稀释过的感觉) 口味二名称',
ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够'] ans: ['太过', '有一点过', '刚好', '有一点不够', '完全不够']
}, },
{ {
seq: 'B7', seq: 'B7',
title: `根据您品尝到的这款${red('口味B')}的口味和口感,您认为这款产品适合${black('在什么时候饮用')}呢?${qType( title: `根据您品尝到的这款${red('口味B')}的口味和口感,您认为这款产品适合${black(
'【单选题】' '在什么时候饮用'
)}`, )}呢?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#饮用时间 口味二名称', tip: '#饮用时间 口味二名称',
ans: [ ans: [
@@ -656,14 +716,18 @@ export default {
}, },
{ {
seq: 'B8', seq: 'B8',
title: `您认为这款${red('口味B')}最适合${black('在哪里饮用')}这产品呢?${qType('【单选题】')}`, title: `您认为这款${red('口味B')}最适合${black('在哪里饮用')}这产品呢?${qType(
'【单选题】'
)}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#饮用场合 口味二名称', tip: '#饮用场合 口味二名称',
ans: ['在家中(如自己家或朋友亲戚家)', '在工作/学习场所', '在户外/餐饮场所'] ans: ['在家中(如自己家或朋友亲戚家)', '在工作/学习场所', '在户外/餐饮场所']
}, },
{ {
seq: 'B9', seq: 'B9',
title: `请设想一下,您饮用该${red('口味B')}${black('最可能')}${black('做什么')}呢?${qType('【单选题】')}`, title: `请设想一下,您饮用该${red('口味B')}${black('最可能')}${black(
'做什么'
)}呢?${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#饮用时做什么 口味二名称', tip: '#饮用时做什么 口味二名称',
ans: [ ans: [
@@ -747,7 +811,9 @@ export default {
}, },
{ {
seq: 'B10', seq: 'B10',
title: `您认为您刚才品尝的这款${red('口味B')}适合${black('在什么地方售卖')}呢?${qType('【多选题】')}`, title: `您认为您刚才品尝的这款${red('口味B')}适合${black('在什么地方售卖')}呢?${qType(
'【多选题】'
)}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#售卖渠道 口味二名称', tip: '#售卖渠道 口味二名称',
ans: [ ans: [
@@ -804,9 +870,9 @@ export default {
}, },
{ {
seq: 'B11', seq: 'B11',
title: `您刚才品尝的这款${red('口味B')},下列哪句话最能描述它对您的${black('购买习惯的影响程度')}${qType( title: `您刚才品尝的这款${red('口味B')},下列哪句话最能描述它对您的${black(
'【单选题】' '购买习惯的影响程度'
)}`, )}${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#购买行为影响 口味二名称', tip: '#购买行为影响 口味二名称',
ans: [ ans: [
@@ -818,9 +884,11 @@ export default {
}, },
{ {
seq: 'B12', seq: 'B12',
title: `您刚才提到这款${red('口味B')}会替代您目前正在饮用的产品,那么您能告诉我您会用它${black( title: `您刚才提到这款${red(
'替代' '口味B'
)}哪个或哪些您${black('目前正在饮')}用的饮品呢?${qType('【多选题】')}`, )}会替代您目前正在饮用的产品,那么您能告诉我您会用它${black('替代')}哪个或哪些您${black(
'目前正在饮'
)}用的饮品呢?${qType('【多选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#品类替代 口味二名称', tip: '#品类替代 口味二名称',
ans: [ ans: [
@@ -853,7 +921,9 @@ export default {
}, },
{ {
seq: 'B13', seq: 'B13',
title: `基于这款${red('口味B')}介绍中的描述和价格信息,综合您品尝到的口味,您倾向于饮用这款产品的频率为${black( title: `基于这款${red(
'口味B'
)}介绍中的描述和价格信息,综合您品尝到的口味,您倾向于饮用这款产品的频率为${black(
'每周几次' '每周几次'
)}${qType('【单选题】')}`, )}${qType('【单选题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
@@ -898,7 +968,9 @@ export default {
}, },
{ {
seq: 'E1', seq: 'E1',
title: `综合比较这几款产品的口味和口感,您${black('更加喜欢')}哪一款产品呢?${qType('【单选题】')}`, title: `综合比较这几款产品的口味和口感,您${black('更加喜欢')}哪一款产品呢?${qType(
'【单选题】'
)}`,
tip: '#强制对比', tip: '#强制对比',
noBottom: true noBottom: true
}, },
@@ -927,7 +999,9 @@ export default {
}, },
{ {
seq: 'A1', seq: 'A1',
title: `请问您对您刚才品尝过的${red('口味A')}${black('总体喜欢程度')}是怎样的?${qType('【单选题】')}`, title: `请问您对您刚才品尝过的${red('口味A')}${black('总体喜欢程度')}是怎样的?${qType(
'【单选题】'
)}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#总体喜欢程度 口味一名称', tip: '#总体喜欢程度 口味一名称',
ans: ['非常喜欢', '比较喜欢', '一般', '不太喜欢', '完全不喜欢'] ans: ['非常喜欢', '比较喜欢', '一般', '不太喜欢', '完全不喜欢']
@@ -949,7 +1023,9 @@ export default {
}, },
{ {
seq: 'B1', seq: 'B1',
title: `请问您对您刚才品尝过的${red('口味B')}${black('总体喜欢程度')}是怎样的?${qType('【单选题】')}`, title: `请问您对您刚才品尝过的${red('口味B')}${black('总体喜欢程度')}是怎样的?${qType(
'【单选题】'
)}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#总体喜欢程度 口味二名称', tip: '#总体喜欢程度 口味二名称',
ans: ['非常喜欢', '比较喜欢', '一般', '不太喜欢', '完全不喜欢'] ans: ['非常喜欢', '比较喜欢', '一般', '不太喜欢', '完全不喜欢']
@@ -959,7 +1035,9 @@ export default {
}, },
{ {
seq: 'E1', seq: 'E1',
title: `综合比较这几款产品的口味和口感,您${black('更加喜欢')}哪一款产品呢?${qType('【单选题】')}`, title: `综合比较这几款产品的口味和口感,您${black('更加喜欢')}哪一款产品呢?${qType(
'【单选题】'
)}`,
tip: '#强制对比', tip: '#强制对比',
noBottom: true noBottom: true
}, },
@@ -1019,13 +1097,17 @@ export default {
}, },
{ {
seq: 'A1', seq: 'A1',
title: `您已经品尝了这款产品,请告诉我您${red('不喜欢')}这款${red('口味A')}的哪些方面?${qType('【填空题】')}`, title: `您已经品尝了这款产品,请告诉我您${red('不喜欢')}这款${red(
'口味A'
)}的哪些方面?${qType('【填空题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#不喜欢方面 口味一名称' tip: '#不喜欢方面 口味一名称'
}, },
{ {
seq: 'A2', seq: 'A2',
title: `您已经品尝了这款产品,请告诉我您${green('喜欢')}这款${red('口味A')}的哪些方面?${qType('【填空题】')}`, title: `您已经品尝了这款产品,请告诉我您${green('喜欢')}这款${red(
'口味A'
)}的哪些方面?${qType('【填空题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#喜欢方面 口味一名称' tip: '#喜欢方面 口味一名称'
}, },
@@ -1034,13 +1116,17 @@ export default {
}, },
{ {
seq: 'B1', seq: 'B1',
title: `您已经品尝了这款产品,请告诉我您${red('不喜欢')}这款${red('口味B')}的哪些方面?${qType('【填空题】')}`, title: `您已经品尝了这款产品,请告诉我您${red('不喜欢')}这款${red(
'口味B'
)}的哪些方面?${qType('【填空题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#不喜欢方面 口味二名称' tip: '#不喜欢方面 口味二名称'
}, },
{ {
seq: 'B2', seq: 'B2',
title: `您已经品尝了这款产品,请告诉我您${green('喜欢')}这款${red('口味B')}的哪些方面?${qType('【填空题】')}`, title: `您已经品尝了这款产品,请告诉我您${green('喜欢')}这款${red(
'口味B'
)}的哪些方面?${qType('【填空题】')}`,
topic: '[题干系统自动插入口味编号]', topic: '[题干系统自动插入口味编号]',
tip: '#喜欢方面 口味二名称' tip: '#喜欢方面 口味二名称'
} }

View File

@@ -171,7 +171,13 @@
"title": "与目前市场上销售的其它<span style=\"font-weight:700;color:black;text-decoration:underline;\">同类产品</span>相比,请问您觉得这款<span style=\"font-weight:700;color:red;text-decoration:underline;\">口味A</span>的<span style=\"font-weight:700;color:black;text-decoration:underline;\">新颖独特性</span>如何呢?<span style=\"font-weight:700;\">【单选题】</span>", "title": "与目前市场上销售的其它<span style=\"font-weight:700;color:black;text-decoration:underline;\">同类产品</span>相比,请问您觉得这款<span style=\"font-weight:700;color:red;text-decoration:underline;\">口味A</span>的<span style=\"font-weight:700;color:black;text-decoration:underline;\">新颖独特性</span>如何呢?<span style=\"font-weight:700;\">【单选题】</span>",
"topic": "[题干系统自动插入口味编号]", "topic": "[题干系统自动插入口味编号]",
"tip": "#新颖独特性 口味一名称", "tip": "#新颖独特性 口味一名称",
"ans": ["非常新颖独特", "比较新颖独特", "谈不上有没有,一般", "不太新颖独特", "一点也不新颖独特"] "ans": [
"非常新颖独特",
"比较新颖独特",
"谈不上有没有,一般",
"不太新颖独特",
"一点也不新颖独特"
]
}, },
{ {
"seq": "A6", "seq": "A6",
@@ -181,10 +187,22 @@
"table": { "table": {
"headers": ["", "喜欢程度"], "headers": ["", "喜欢程度"],
"rows": [ "rows": [
["奶香味(喝起来奶香浓醇)", "非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"], [
["甜味(自然清甜味,非人工添加糖剂)", "非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"], "奶香味(喝起来奶香浓醇)",
["稀稠度(喝起来的厚薄程度)", "非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"], "非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"
["醇厚度(喝起来没有被稀释过的感觉)", "非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"] ],
[
"甜味(自然清甜味,非人工添加糖剂)",
"非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"
],
[
"稀稠度(喝起来的厚薄程度)",
"非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"
],
[
"醇厚度(喝起来没有被稀释过的感觉)",
"非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"
]
] ]
} }
}, },
@@ -524,7 +542,13 @@
"title": "与目前市场上销售的其它<span style=\"font-weight:700;color:black;text-decoration:underline;\">同类产品</span>相比,请问您觉得这款<span style=\"font-weight:700;color:red;text-decoration:underline;\">口味B</span>的新颖独特性如何呢?<span style=\"font-weight:700;\">【单选题】</span>", "title": "与目前市场上销售的其它<span style=\"font-weight:700;color:black;text-decoration:underline;\">同类产品</span>相比,请问您觉得这款<span style=\"font-weight:700;color:red;text-decoration:underline;\">口味B</span>的新颖独特性如何呢?<span style=\"font-weight:700;\">【单选题】</span>",
"topic": "[题干系统自动插入口味编号]", "topic": "[题干系统自动插入口味编号]",
"tip": "#新颖独特性 口味二名称", "tip": "#新颖独特性 口味二名称",
"ans": ["非常新颖独特", "比较新颖独特", "谈不上有没有,一般", "不太新颖独特", "一点也不新颖独特"] "ans": [
"非常新颖独特",
"比较新颖独特",
"谈不上有没有,一般",
"不太新颖独特",
"一点也不新颖独特"
]
}, },
{ {
"seq": "B6", "seq": "B6",
@@ -534,10 +558,22 @@
"table": { "table": {
"headers": ["", "喜欢程度"], "headers": ["", "喜欢程度"],
"rows": [ "rows": [
["奶香味(喝起来奶香浓醇)", "非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"], [
["甜味(自然清甜味,非人工添加糖剂)", "非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"], "奶香味(喝起来奶香浓醇)",
["稀稠度(喝起来的厚薄程度)", "非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"], "非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"
["醇厚度(喝起来没有被稀释过的感觉)", "非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"] ],
[
"甜味(自然清甜味,非人工添加糖剂)",
"非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"
],
[
"稀稠度(喝起来的厚薄程度)",
"非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"
],
[
"醇厚度(喝起来没有被稀释过的感觉)",
"非常喜欢、比较喜欢、一般,谈不上喜欢不喜欢、不太喜欢、一点也不喜欢"
]
] ]
} }
}, },

View File

@@ -13,7 +13,15 @@ import BasicConfig from '../components/BasicConfig.vue';
import PackageTestItem from './PackageTestItem.vue'; import PackageTestItem from './PackageTestItem.vue';
import Steps from '../components/Steps.vue'; import Steps from '../components/Steps.vue';
import { schemeEnum, testTypeEnum, standardNewestEnum, packageTypeEnum, encodeList } from '../consts'; import {
schemeEnum,
testTypeEnum,
standardNewestEnum,
packageTypeEnum,
encodeList,
getPackageForApi
} from '../consts';
import { isFullView } from './util';
import { postTemplates } from '../api'; import { postTemplates } from '../api';
@@ -46,19 +54,31 @@ const expandInnerNewest = ref(true);
const expandInnerStandard = ref(true); const expandInnerStandard = ref(true);
// 标准版 - 外箱 // 标准版 - 外箱
const outerNewList1 = ref([getNewItem(standardNewestEnum.newest), getNewItem(standardNewestEnum.newest)]); const outerNewList1 = ref([
getNewItem(standardNewestEnum.newest),
getNewItem(standardNewestEnum.newest)
]);
const outerStandardList1 = ref([getNewItem(standardNewestEnum.standard)]); const outerStandardList1 = ref([getNewItem(standardNewestEnum.standard)]);
// 标准版 - 内包 // 标准版 - 内包
const innerNewList1 = ref([getNewItem(standardNewestEnum.newest), getNewItem(standardNewestEnum.newest)]); const innerNewList1 = ref([
getNewItem(standardNewestEnum.newest),
getNewItem(standardNewestEnum.newest)
]);
const innerStandardList1 = ref([getNewItem(standardNewestEnum.standard)]); const innerStandardList1 = ref([getNewItem(standardNewestEnum.standard)]);
// 快测版 - 外箱 // 快测版 - 外箱
const outerNewList2 = ref([getNewItem(standardNewestEnum.newest), getNewItem(standardNewestEnum.newest)]); const outerNewList2 = ref([
getNewItem(standardNewestEnum.newest),
getNewItem(standardNewestEnum.newest)
]);
const outerStandardList2 = ref([getNewItem(standardNewestEnum.standard)]); const outerStandardList2 = ref([getNewItem(standardNewestEnum.standard)]);
// 快测版 - 内包 // 快测版 - 内包
const innerNewList2 = ref([getNewItem(standardNewestEnum.newest), getNewItem(standardNewestEnum.newest)]); const innerNewList2 = ref([
getNewItem(standardNewestEnum.newest),
getNewItem(standardNewestEnum.newest)
]);
const innerStandardList2 = ref([getNewItem(standardNewestEnum.standard)]); const innerStandardList2 = ref([getNewItem(standardNewestEnum.standard)]);
// 配对版 - 外箱 // 配对版 - 外箱
@@ -194,10 +214,30 @@ function onAddItem(pType, standardAndNewest) {
} }
function updateEncode() { function updateEncode() {
[outerNewList1.value, outerStandardList1.value] = updateEncodeForGroup(outerNewList1.value, outerStandardList1.value); [outerNewList1.value, outerStandardList1.value] = updateEncodeForGroup(
[innerNewList1.value, innerStandardList1.value] = updateEncodeForGroup(innerNewList1.value, innerStandardList1.value); outerNewList1.value,
[outerNewList2.value, outerStandardList2.value] = updateEncodeForGroup(outerNewList2.value, outerStandardList2.value); outerStandardList1.value
[innerNewList2.value, innerStandardList2.value] = updateEncodeForGroup(innerNewList2.value, innerStandardList2.value); );
[innerNewList1.value, innerStandardList1.value] = updateEncodeForGroup(
innerNewList1.value,
innerStandardList1.value
);
[outerNewList2.value, outerStandardList2.value] = updateEncodeForGroup(
outerNewList2.value,
outerStandardList2.value
);
[innerNewList2.value, innerStandardList2.value] = updateEncodeForGroup(
innerNewList2.value,
innerStandardList2.value
);
[outerNewList3.value, outerStandardList3.value] = updateEncodeForGroup(
outerNewList3.value,
outerStandardList3.value
);
[innerNewList3.value, innerStandardList3.value] = updateEncodeForGroup(
innerNewList3.value,
innerStandardList3.value
);
} }
function updateEncodeForGroup(list1, list2) { function updateEncodeForGroup(list1, list2) {
@@ -272,7 +312,7 @@ function checkTasteType(list) {
const newestList = []; const newestList = [];
const newList = JSON.parse(JSON.stringify(list)); const newList = JSON.parse(JSON.stringify(list));
newList.forEach((i) => { newList.forEach((i) => {
switch (i.data.taste_type) { switch (i.data.package_type) {
case standardNewestEnum.standard: case standardNewestEnum.standard:
standardList.push(i); standardList.push(i);
break; break;
@@ -294,15 +334,9 @@ function checkTasteType(list) {
return true; return true;
} }
function checkTaste() { function checkAdvanced(list, packageType) {
const list = {
[testTypeEnum.standard]: list1.value,
[testTypeEnum.quickTest]: list2.value,
[testTypeEnum.pair]: list3.value
}[testType.value];
// 检查是否有空名称 // 检查是否有空名称
const names = list.map((item) => item.data.taste_name); const names = list.map((item) => item.data.package_name);
const emptyNameExists = names.some((name) => !name.trim()); const emptyNameExists = names.some((name) => !name.trim());
if (emptyNameExists) { if (emptyNameExists) {
message.error('包装名称不可为空,请检查后重试!'); message.error('包装名称不可为空,请检查后重试!');
@@ -311,7 +345,7 @@ function checkTaste() {
// 检查是否有重复名称 // 检查是否有重复名称
const nameCounts = list const nameCounts = list
.map((item) => item.data.taste_name) .map((item) => item.data.package_name)
.reduce((acc, name) => { .reduce((acc, name) => {
acc[name] = (acc[name] || 0) + 1; acc[name] = (acc[name] || 0) + 1;
return acc; return acc;
@@ -322,68 +356,133 @@ function checkTaste() {
return false; return false;
} }
if ([testTypeEnum.standard].includes(testType.value)) { const metricFieldMap = {
// 检查是否有空关键属性指标 [testTypeEnum.standard]: 'standardChecked',
const indicators = list.flatMap((item) => item.data.taste_attr_indicator); [testTypeEnum.quickTest]: 'quickTestChecked',
const emptyIndicatorsExists = indicators.some((name) => !name.trim()); [testTypeEnum.pair]: 'pairChecked'
if (emptyIndicatorsExists) { };
message.error('关键属性指标不可为空,请检查后重试!'); let metricField = metricFieldMap[testType.value];
metricField += packageType.value === packageTypeEnum.inner ? '2' : '';
const metricList = metric.value[metricField];
if (isFullView(metricList, packageType)) {
if (list.some((item) => !item.data.package_cover_picture?.length)) {
message.error('堆头图片不可为空,请检查后重试!');
return false; return false;
} }
if (list.some((item) => !item.data.not_hint_package_picture)) {
// 检查同一包装下是否有重复的关键属性指标 message.error('无提示包装图片不可为空,请检查后重试!');
if (
list.some((item) => {
item.data.taste_attr_indicator;
const idt = item.data.taste_attr_indicator;
return Array.from(new Set(idt)).length !== idt.length;
})
) {
message.error('同一包装内的关键属性指标不可重复,请检查后重试!');
return false; return false;
} }
} }
return [testTypeEnum.standard, testTypeEnum.quickTest].includes(testType.value) ? checkTasteType(list) : true; if (list.some((item) => !item.data.hint_package_picture)) {
message.error('提示后包装图片不可为空,请检查后重试!');
return false;
}
return [testTypeEnum.standard, testTypeEnum.quickTest].includes(testType.value)
? checkTasteType(list)
: true;
}
function checkOuter() {
if (packageType.value.includes(packageTypeEnum.outer)) {
const map = {
[testTypeEnum.standard]: [...outerNewList1.value, ...outerStandardList1.value],
[testTypeEnum.quickTest]: [...outerNewList2.value, ...outerStandardList2.value],
[testTypeEnum.pair]: [...outerNewList3.value, ...outerStandardList3.value]
};
const list = map[testType.value];
return checkAdvanced(list, packageTypeEnum.outer);
}
return true;
}
function checkInner() {
if (packageType.value.includes(packageTypeEnum.inner)) {
const map = {
[testTypeEnum.standard]: [...innerNewList1.value, ...innerStandardList1.value],
[testTypeEnum.quickTest]: [...innerNewList2.value, ...innerStandardList2.value],
[testTypeEnum.pair]: [...innerNewList3.value, ...innerStandardList3.value]
};
const list = map[testType.value];
return checkAdvanced(list, packageTypeEnum.inner);
}
return true;
} }
const basicConfigRef = ref(null); const basicConfigRef = ref(null);
function onPrev() {
const index = stepList.value.findIndex((item) => item.id === stepId.value);
stepId.value = stepList.value[Math.max(0, index - 1)].id;
}
function onNext() {
const index = stepList.value.findIndex((item) => item.id === stepId.value);
stepId.value = stepList.value[Math.min(stepList.value.length - 1, index + 1)].id;
}
async function onSave() { async function onSave() {
const result = await basicConfigRef.value.validateForm(); const result = await basicConfigRef.value.validateForm();
if (result.status === 'rejected') { if (result.status === 'rejected') {
message.error(result.reason.flatMap((i) => i.errors).join('、')); message.error(result.reason.flatMap((i) => i.errors).join('、'));
stepId.value = packageTypeEnum.basic;
return; return;
} }
if (!checkTaste()) { if (!checkOuter()) {
stepId.value = packageTypeEnum.outer;
return; return;
} }
const list = { if (!checkInner()) {
[testTypeEnum.standard]: list1.value, stepId.value = packageTypeEnum.inner;
[testTypeEnum.quickTest]: list2.value, return;
[testTypeEnum.pair]: list3.value }
}[testType.value].map((i) => Object.assign({}, i.data, { taste_encode: '' }));
const metricList = [];
const metricListTemp = [
...(result.data.concept_indexes || []),
...(result.data.concept_indexes2 || [])
].map((i) => Object.assign({ type: i, is_select: 1 }));
metricListTemp.forEach((item) => {
if (!metricList.find((met) => met.type === item.type)) {
metricList.push(item);
}
});
const outerList = {
[testTypeEnum.standard]: [...outerNewList1.value, ...outerStandardList1.value],
[testTypeEnum.quickTest]: [...outerNewList2.value, ...outerStandardList2.value],
[testTypeEnum.pair]: [outerNewList3.value, ...outerStandardList3.value]
}[testType.value].map((i) => Object.assign({}, i.data));
const innerList = {
[testTypeEnum.standard]: [...innerNewList1.value, ...innerStandardList1.value],
[testTypeEnum.quickTest]: [...innerNewList2.value, ...innerStandardList2.value],
[testTypeEnum.pair]: [innerNewList3.value, ...innerStandardList3.value]
}[testType.value].map((i) => Object.assign({}, i.data));
const packageType = getPackageForApi(result.data.packageType);
const params = { const params = {
brand_id: result.data.brand_id, brand_id: result.data.brand_id,
scene_code_info: result.data.scene_code_info, scene_code_info: result.data.scene_code_info,
package_type: packageType,
sn: templateSn.value, sn: templateSn.value,
project_name: result.data.project_name || '', project_name: result.data.project_name || '',
tags: result.data.tags || [], tags: result.data.tags || [],
remarks: result.data.remarks || '', remarks: result.data.remarks || '',
concept_indexes: (result.data.concept_indexes || []).map((i) => concept_indexes: metricList || [],
Object.assign({ study_package_out: outerList || [],
type: i, study_package_inter: innerList || []
is_select: 1
})
),
study_tastes: list,
study_package_out: [],
study_package_inter: []
}; };
const confirmModal = Modal.confirm({ const confirmModal = Modal.confirm({
@@ -424,6 +523,8 @@ async function onSave() {
:scheme-type="schemeEnum.package" :scheme-type="schemeEnum.package"
:test-type="testType" :test-type="testType"
:show-save="false" :show-save="false"
:no-padding="true"
class="template-modal"
@save="onSave" @save="onSave"
> >
<Steps v-model:value="stepId" :list="stepList" /> <Steps v-model:value="stepId" :list="stepList" />
@@ -486,7 +587,11 @@ async function onSave() {
> >
<div class="actions"> <div class="actions">
<i class="iconfont action-button draggable-outer-newest-1">&#xe71b;</i> <i class="iconfont action-button draggable-outer-newest-1">&#xe71b;</i>
<i class="iconfont action-button" @click="onDeleteOuterNewestStandardItem(element.key)">&#xe6b5;</i> <i
class="iconfont action-button"
@click="onDeleteOuterNewestStandardItem(element.key)"
>&#xe6b5;</i
>
</div> </div>
</PackageTestItem> </PackageTestItem>
</template> </template>
@@ -515,7 +620,11 @@ async function onSave() {
> >
<div class="actions"> <div class="actions">
<i class="iconfont action-button draggable-outer-newest-2">&#xe71b;</i> <i class="iconfont action-button draggable-outer-newest-2">&#xe71b;</i>
<i class="iconfont action-button" @click="onDeleteOuterNewestQuickTestItem(element.key)">&#xe6b5;</i> <i
class="iconfont action-button"
@click="onDeleteOuterNewestQuickTestItem(element.key)"
>&#xe6b5;</i
>
</div> </div>
</PackageTestItem> </PackageTestItem>
</template> </template>
@@ -541,11 +650,7 @@ async function onSave() {
:test-type="testTypeEnum.pair" :test-type="testTypeEnum.pair"
:package-type="packageTypeEnum.outer" :package-type="packageTypeEnum.outer"
:metric="metric.pairChecked" :metric="metric.pairChecked"
> />
<div class="actions">
<i class="iconfont action-button draggable-outer-newest-3">&#xe71b;</i>
</div>
</PackageTestItem>
</template> </template>
</draggable> </draggable>
</template> </template>
@@ -595,7 +700,11 @@ async function onSave() {
> >
<div class="actions"> <div class="actions">
<i class="iconfont action-button draggable-outer-standard-1">&#xe71b;</i> <i class="iconfont action-button draggable-outer-standard-1">&#xe71b;</i>
<i class="iconfont action-button" @click="onDeleteOuterStandardStandardItem(element.key)">&#xe6b5;</i> <i
class="iconfont action-button"
@click="onDeleteOuterStandardStandardItem(element.key)"
>&#xe6b5;</i
>
</div> </div>
</PackageTestItem> </PackageTestItem>
</template> </template>
@@ -624,7 +733,11 @@ async function onSave() {
> >
<div class="actions"> <div class="actions">
<i class="iconfont action-button draggable-outer-standard-2">&#xe71b;</i> <i class="iconfont action-button draggable-outer-standard-2">&#xe71b;</i>
<i class="iconfont action-button" @click="onDeleteOuterStandardQuickTestItem(element.key)">&#xe6b5;</i> <i
class="iconfont action-button"
@click="onDeleteOuterStandardQuickTestItem(element.key)"
>&#xe6b5;</i
>
</div> </div>
</PackageTestItem> </PackageTestItem>
</template> </template>
@@ -650,11 +763,7 @@ async function onSave() {
:test-type="testTypeEnum.pair" :test-type="testTypeEnum.pair"
:package-type="packageTypeEnum.outer" :package-type="packageTypeEnum.outer"
:metric="metric.pairChecked" :metric="metric.pairChecked"
> />
<div class="actions">
<i class="iconfont action-button draggable-outer-standard-3">&#xe71b;</i>
</div>
</PackageTestItem>
</template> </template>
</draggable> </draggable>
</template> </template>
@@ -706,7 +815,11 @@ async function onSave() {
> >
<div class="actions"> <div class="actions">
<i class="iconfont action-button draggable-inner-newest-1">&#xe71b;</i> <i class="iconfont action-button draggable-inner-newest-1">&#xe71b;</i>
<i class="iconfont action-button" @click="onDeleteInnerNewestStandardItem(element.key)">&#xe6b5;</i> <i
class="iconfont action-button"
@click="onDeleteInnerNewestStandardItem(element.key)"
>&#xe6b5;</i
>
</div> </div>
</PackageTestItem> </PackageTestItem>
</template> </template>
@@ -735,7 +848,11 @@ async function onSave() {
> >
<div class="actions"> <div class="actions">
<i class="iconfont action-button draggable-inner-newest-2">&#xe71b;</i> <i class="iconfont action-button draggable-inner-newest-2">&#xe71b;</i>
<i class="iconfont action-button" @click="onDeleteInnerNewestQuickTestItem(element.key)">&#xe6b5;</i> <i
class="iconfont action-button"
@click="onDeleteInnerNewestQuickTestItem(element.key)"
>&#xe6b5;</i
>
</div> </div>
</PackageTestItem> </PackageTestItem>
</template> </template>
@@ -761,11 +878,7 @@ async function onSave() {
:test-type="testTypeEnum.pair" :test-type="testTypeEnum.pair"
:package-type="packageTypeEnum.inner" :package-type="packageTypeEnum.inner"
:metric="metric.pairChecked2" :metric="metric.pairChecked2"
> />
<div class="actions">
<i class="iconfont action-button draggable-inner-newest-3">&#xe71b;</i>
</div>
</PackageTestItem>
</template> </template>
</draggable> </draggable>
</template> </template>
@@ -815,7 +928,11 @@ async function onSave() {
> >
<div class="actions"> <div class="actions">
<i class="iconfont action-button draggable-inner-standard-1">&#xe71b;</i> <i class="iconfont action-button draggable-inner-standard-1">&#xe71b;</i>
<i class="iconfont action-button" @click="onDeleteInnerStandardStandardItem(element.key)">&#xe6b5;</i> <i
class="iconfont action-button"
@click="onDeleteInnerStandardStandardItem(element.key)"
>&#xe6b5;</i
>
</div> </div>
</PackageTestItem> </PackageTestItem>
</template> </template>
@@ -844,7 +961,11 @@ async function onSave() {
> >
<div class="actions"> <div class="actions">
<i class="iconfont action-button draggable-inner-standard-2">&#xe71b;</i> <i class="iconfont action-button draggable-inner-standard-2">&#xe71b;</i>
<i class="iconfont action-button" @click="onDeleteInnerStandardQuickTestItem(element.key)">&#xe6b5;</i> <i
class="iconfont action-button"
@click="onDeleteInnerStandardQuickTestItem(element.key)"
>&#xe6b5;</i
>
</div> </div>
</PackageTestItem> </PackageTestItem>
</template> </template>
@@ -870,23 +991,26 @@ async function onSave() {
:test-type="testTypeEnum.pair" :test-type="testTypeEnum.pair"
:package-type="packageTypeEnum.inner" :package-type="packageTypeEnum.inner"
:metric="metric.pairChecked2" :metric="metric.pairChecked2"
> />
<div class="actions">
<i class="iconfont action-button draggable-inner-standard-3">&#xe71b;</i>
</div>
</PackageTestItem>
</template> </template>
</draggable> </draggable>
</template> </template>
</template> </template>
<div class="footer"> <template #footer>
<div class="footer-inner"> <div class="flex-none full-width flex flex-end footer">
<a-button class="custom-button btn-outline">上一步</a-button> <a-button v-if="stepId !== stepList[0].id" class="custom-button btn-outline" @click="onPrev"
<a-button class="custom-button btn-outline">一步</a-button> >一步</a-button
>
<a-button
v-if="stepId !== stepList[stepList.length - 1].id"
class="custom-button btn-outline"
@click="onNext"
>下一步</a-button
>
<a-button type="primary" class="custom-button" @click="onSave">保存方案</a-button> <a-button type="primary" class="custom-button" @click="onSave">保存方案</a-button>
</div> </div>
</div> </template>
</TemplateModal> </TemplateModal>
</template> </template>
@@ -895,6 +1019,10 @@ async function onSave() {
margin-bottom: 10px; margin-bottom: 10px;
} }
.p-20 {
padding: 20px;
}
.pointer { .pointer {
cursor: pointer; cursor: pointer;
} }
@@ -926,18 +1054,17 @@ async function onSave() {
transform: rotate(90deg); transform: rotate(90deg);
} }
.scroller {
height: calc(100% - 52px);
}
.footer { .footer {
height: 52px; height: 52px;
background-color: #FFFFFF; padding: 0 20px;
background-color: #ffffff;
.footer-inner { .custom-button:not(:last-child) {
display: flex;
justify-content: flex-end;
align-items: center;
.custom-button {
margin-right: 14px; margin-right: 14px;
} }
} }
}
</style> </style>

View File

@@ -99,28 +99,43 @@ function onNameChange() {
<div v-if="fullView" class="flex item-row mb-24"> <div v-if="fullView" class="flex item-row mb-24">
<div class="flex-none label">测试品牌</div> <div class="flex-none label">测试品牌</div>
<a-input v-model:value="item.study_brand" :maxlength="12" placeholder="请输入测试品牌" class="custom-input"> <a-input
v-model:value="item.study_brand"
:maxlength="12"
placeholder="请输入测试品牌"
class="custom-input"
>
<template #suffix> <template #suffix>
<span class="suffix"> <span class="suffix">
{{ `${item.package_name?.length || 0} / 12` }} {{ `${item.study_brand?.length || 0} / 12` }}
</span> </span>
</template> </template>
</a-input> </a-input>
</div> </div>
<div v-if="fullView" class="item-row"> <div v-if="fullView" class="item-row mb-10">
<div class="flex-none label mb-8">堆头图片</div> <div class="flex-none label mb-8">堆头图片</div>
<ImageUploader v-model:urls="item.package_cover_picture" :max="9" image-name="货架" /> <ImageUploader v-model:urls="item.package_cover_picture" :max="9" image-name="货架" />
</div> </div>
<div v-if="fullView" class="item-row"> <div v-if="fullView" class="item-row mb-24">
<div class="flex-none label mb-8">无提示包装图片无品牌信息</div> <div class="flex-none label mb-8">无提示包装图片无品牌信息</div>
<ImageUploader v-model:url="item.not_hint_package_picture" :max="1" :multiple="false" image-name="包装" /> <ImageUploader
v-model:url="item.not_hint_package_picture"
:max="1"
:multiple="false"
image-name="包装"
/>
</div> </div>
<div class="item-row"> <div class="item-row">
<div v-if="fullView" class="flex-none label mb-8">提示后包装图片含品牌信息</div> <div v-if="fullView" class="flex-none label mb-8">提示后包装图片含品牌信息</div>
<ImageUploader v-model:url="item.hint_package_picture" :max="1" :multiple="false" image-name="包装" /> <ImageUploader
v-model:url="item.hint_package_picture"
:max="1"
:multiple="false"
image-name="包装"
/>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -211,7 +211,9 @@ function checkTaste() {
} }
} }
return [testTypeEnum.standard, testTypeEnum.quickTest].includes(testType.value) ? checkTasteType(list) : true; return [testTypeEnum.standard, testTypeEnum.quickTest].includes(testType.value)
? checkTasteType(list)
: true;
} }
const basicConfigRef = ref(null); const basicConfigRef = ref(null);
@@ -284,7 +286,12 @@ async function onSave() {
</script> </script>
<template> <template>
<TemplateModal v-model:visible="shown" :scheme-type="schemeEnum.taste" :test-type="testType" @save="onSave"> <TemplateModal
v-model:visible="shown"
:scheme-type="schemeEnum.taste"
:test-type="testType"
@save="onSave"
>
<BasicConfig <BasicConfig
ref="basicConfigRef" ref="basicConfigRef"
:scheme-type="schemeEnum.taste" :scheme-type="schemeEnum.taste"

View File

@@ -197,8 +197,13 @@ function onMultipleLineInputChange(evt) {
</template> </template>
</a-input> </a-input>
<i class="iconfont" :class="[`drag-handler-indicator-${props.itemKey}`]">&#xe71b;</i> <i class="iconfont" :class="[`drag-handler-indicator-${props.itemKey}`]"
<i v-if="item?.taste_attr_indicator?.length > 1" class="iconfont" @click="onDeleteIndicator(index)" >&#xe71b;</i
>
<i
v-if="item?.taste_attr_indicator?.length > 1"
class="iconfont"
@click="onDeleteIndicator(index)"
>&#xe6b5;</i >&#xe6b5;</i
> >
</div> </div>