feat:全部问卷接口联调

This commit is contained in:
du.meimei
2025-03-17 15:58:29 +08:00
parent 00a52ba8b4
commit 80fe686c8e
56 changed files with 1027 additions and 837 deletions

4
auto-imports.d.ts vendored
View File

@@ -5,6 +5,4 @@
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
}
declare global {}

5
components.d.ts vendored
View File

@@ -29,8 +29,6 @@ declare module 'vue' {
VanCol: typeof import('vant/es')['Col']
VanDivider: typeof import('vant/es')['Divider']
VanField: typeof import('vant/es')['Field']
VanGrid: typeof import('vant/es')['Grid']
VanGridItem: typeof import('vant/es')['GridItem']
VanIcon: typeof import('vant/es')['Icon']
VanNavBar: typeof import('vant/es')['NavBar']
VanPicker: typeof import('vant/es')['Picker']
@@ -38,12 +36,9 @@ declare module 'vue' {
VanRadio: typeof import('vant/es')['Radio']
VanRadioGroup: typeof import('vant/es')['RadioGroup']
VanRow: typeof import('vant/es')['Row']
VanSearch: typeof import('vant/es')['Search']
VanStepper: typeof import('vant/es')['Stepper']
VanSwitch: typeof import('vant/es')['Switch']
VanTab: typeof import('vant/es')['Tab']
VanTabbar: typeof import('vant/es')['Tabbar']
VanTabbarItem: typeof import('vant/es')['TabbarItem']
VanTabs: typeof import('vant/es')['Tabs']
YLCascader: typeof import('./src/components/YLCascader.vue')['default']
YLInput: typeof import('./src/components/YLInput.vue')['default']

84
package-lock.json generated
View File

@@ -10,11 +10,13 @@
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.8.2",
"cos-js-sdk-v5": "^1.8.7",
"dotenv": "^16.4.7",
"element-plus": "^2.7.8",
"js-base64": "^3.7.7",
"lodash": "^4.17.21",
"pinia": "^2.1.7",
"shrinkpng": "^1.2.0-beta.1",
"sortablejs": "^1.15.6",
"uuid": "^11.1.0",
"vant": "^4.9.17",
@@ -508,6 +510,18 @@
"node": ">=6.9.0"
}
},
"node_modules/@babel/runtime-corejs3": {
"version": "7.26.10",
"resolved": "https://registry.npmmirror.com/@babel/runtime-corejs3/-/runtime-corejs3-7.26.10.tgz",
"integrity": "sha512-uITFQYO68pMEYR46AHgQoyBg7KPPJDAbGn4jUTIRgCFJIp88MIBUianVOplhZDEec07bp9zIyr4Kp0FCyQzmWg==",
"dependencies": {
"core-js-pure": "^3.30.2",
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": {
"version": "7.26.9",
"dev": true,
@@ -5416,6 +5430,24 @@
"url": "https://opencollective.com/core-js"
}
},
"node_modules/core-js-pure": {
"version": "3.41.0",
"resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.41.0.tgz",
"integrity": "sha512-71Gzp96T9YPk63aUvE5Q5qP+DryB4ZloUZPSOebGM88VNw8VNfvdA7z6kGA8iGOTEzAomsRidp4jXSmUIJsL+Q==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/cos-js-sdk-v5": {
"version": "1.8.7",
"resolved": "https://registry.npmmirror.com/cos-js-sdk-v5/-/cos-js-sdk-v5-1.8.7.tgz",
"integrity": "sha512-KK3PYbUiLxcjvVhyvEeBQRWzDgAmuldDZQL1lTRM0aeQaI+hlm84xQQQyv+oIRxPnnAIleZF2vUgB4sJFUzcxQ==",
"dependencies": {
"fast-xml-parser": "4.5.0"
}
},
"node_modules/cosmiconfig": {
"version": "9.0.0",
"resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
@@ -6848,6 +6880,27 @@
}
]
},
"node_modules/fast-xml-parser": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz",
"integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
},
{
"type": "paypal",
"url": "https://paypal.me/naturalintelligence"
}
],
"dependencies": {
"strnum": "^1.0.5"
},
"bin": {
"fxparser": "src/cli/cli.js"
}
},
"node_modules/fastest-levenshtein": {
"version": "1.0.16",
"resolved": "https://registry.npmmirror.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
@@ -8635,6 +8688,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/pako": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/pako/-/pako-2.1.0.tgz",
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
@@ -9545,6 +9603,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/shrinkpng": {
"version": "1.2.0-beta.1",
"resolved": "https://registry.npmmirror.com/shrinkpng/-/shrinkpng-1.2.0-beta.1.tgz",
"integrity": "sha512-14B3Na+thQHyXkz1cMXKcMQ/mYBCJFWck1Z5z3NzmQqF5x712vuM9WWt2g/2V6/+ZYUA40FQLyNl6Q9TcffdEw==",
"dependencies": {
"@babel/runtime-corejs3": "^7.18.3",
"pako": "^2.0.4",
"uzip": "^0.20201231.0"
}
},
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz",
@@ -9825,6 +9893,17 @@
"integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
"dev": true
},
"node_modules/strnum": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/strnum/-/strnum-1.1.2.tgz",
"integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
}
]
},
"node_modules/style-search": {
"version": "0.1.0",
"resolved": "https://registry.npmmirror.com/style-search/-/style-search-0.1.0.tgz",
@@ -10768,6 +10847,11 @@
"uuid": "dist/esm/bin/uuid"
}
},
"node_modules/uzip": {
"version": "0.20201231.0",
"resolved": "https://registry.npmmirror.com/uzip/-/uzip-0.20201231.0.tgz",
"integrity": "sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng=="
},
"node_modules/vant": {
"version": "4.9.17",
"resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.17.tgz",

View File

@@ -4,7 +4,7 @@ import { onMounted } from 'vue';
import appBridge from '@/assets/js/appBridge';
import utils from '@/assets/js/common';
onMounted(async() => {
onMounted(async () => {
if (utils.getParameter('digitalYiliToken')) {
// 隐藏/显示 header
appBridge.setHeaderShown(false);

View File

@@ -85,9 +85,9 @@ export default class CommonApi {
};
/* eslint-disable no-useless-escape */
const reg = /\\|\/|\?|\|\*|"|“|”|'|||<|>|{|}|\[|\]|\【|\】||:|、|\^|\$|!|~|`|\s|\+/g;
name
= name
|| getRandomFileName(file?.name?.replace(reg, '') ?? '' ?? `${new Date().getTime()}.png`);
name =
name ||
getRandomFileName(file?.name?.replace(reg, '') ?? '' ?? `${new Date().getTime()}.png`);
const res = await CommonApi.getOssInfo();
/* eslint-enable no-useless-escape */

View File

@@ -1,5 +1,5 @@
.van-nav-bar {
z-index:999;
z-index: 999;
padding-top: calc(var(--status-bar-height) + 15px) !important;
}

View File

@@ -170,8 +170,8 @@ const getMaxDateLimit = computed(() => {
props.format
);
const tempStr = '0000-12-31 23:59:59';
const result
= props.maxDate.length !== 0 && thisMax.length > props.maxDate.length
const result =
props.maxDate.length !== 0 && thisMax.length > props.maxDate.length
? thisMax.slice(0, props.maxDate.length) + tempStr.slice(props.maxDate.length)
: thisMax;
return result.slice(0, props.format.length);
@@ -194,8 +194,8 @@ function onChange({ selectedValues, columnIndex }) {
renderMinuteColumns,
renderSecondColumns
];
updateColumns[columnIndex]
&& updateColumns[columnIndex](changeValue, getMinDateLimit.value, getMaxDateLimit.value, false);
updateColumns[columnIndex] &&
updateColumns[columnIndex](changeValue, getMinDateLimit.value, getMaxDateLimit.value, false);
}
// 渲染全部列

View File

@@ -62,7 +62,7 @@ const functions = {
document.execCommand('italic', false, null);
},
uploadImage: async() => {
uploadImage: async () => {
// 保存当前光标位置
savedRange.value = saveSelection();
@@ -71,7 +71,7 @@ const functions = {
fileInput.click();
fileInput.onchange = async(e) => {
fileInput.onchange = async (e) => {
const [file] = e.target.files;
if (!file) return;
if (file.size > 2 * 1024 * 1024) {

View File

@@ -4,7 +4,7 @@
<header class="header">
<van-nav-bar :title="$route.meta.title" left-arrow safe-area-inset-top @click-left="goBack">
<template #left>
<van-icon name="left-long" class-prefix="mobilefont" size="18" style="color: #000" />
<van-icon name="left-long" class-prefix="mobilefont" size="18" style="color: #fff" />
</template>
</van-nav-bar>
</header>

View File

@@ -376,39 +376,39 @@ export function isCross(range1, range2) {
const isSibling = isLeft || isRight;
// 逻辑包含循环
const contain
= (isPlainSequence
&& (((isNullish(start2) || isSequence(judge, start2, start1))
&& (isNullish(end2) || isSequence(judge, end2, start1)))
|| ((isNullish(start2) || isSequence(start1, start2, end1))
&& (isNullish(end2) || isSequence(start1, end2, end1)))))
|| (!isPlainSequence
&& (judge < start1
? ((isNullish(start2) || isSequence(judge, start2, start1))
&& (isNullish(end2) || isSequence(judge, end2, start1)))
|| ((isNullish(start2) || isSequence(start1, start2, end1))
&& (isNullish(end2) || isSequence(start1, end2, end1)))
: ((isNullish(start2) || isSequence(start1, start2, judge))
&& (isNullish(end2) || isSequence(start1, end2, judge)))
|| ((isNullish(start2) || isSequence(judge, start2, end1))
&& (isNullish(end2) || isSequence(judge, end2, end1)))));
const contain =
(isPlainSequence &&
(((isNullish(start2) || isSequence(judge, start2, start1)) &&
(isNullish(end2) || isSequence(judge, end2, start1))) ||
((isNullish(start2) || isSequence(start1, start2, end1)) &&
(isNullish(end2) || isSequence(start1, end2, end1))))) ||
(!isPlainSequence &&
(judge < start1
? ((isNullish(start2) || isSequence(judge, start2, start1)) &&
(isNullish(end2) || isSequence(judge, end2, start1))) ||
((isNullish(start2) || isSequence(start1, start2, end1)) &&
(isNullish(end2) || isSequence(start1, end2, end1)))
: ((isNullish(start2) || isSequence(start1, start2, judge)) &&
(isNullish(end2) || isSequence(start1, end2, judge))) ||
((isNullish(start2) || isSequence(judge, start2, end1)) &&
(isNullish(end2) || isSequence(judge, end2, end1)))));
// 循环存在封闭区间,并且循环包含逻辑
const contained
= !isNullish(start2)
&& !isNullish(end2)
const contained =
!isNullish(start2) &&
!isNullish(end2) &&
// [judge, start1, end1];
&& ((isPlainSequence && start2 <= judge && end1 <= end2)
((isPlainSequence && start2 <= judge && end1 <= end2) ||
// [judge, start1, end1];
// [start1, judge, end1];
|| (!isPlainSequence && start2 <= start1 && start2 <= judge && end1 <= end2));
(!isPlainSequence && start2 <= start1 && start2 <= judge && end1 <= end2));
// 循环不存在封闭区间
const unCircled
= (!isNullish(start2)
&& isNullish(end2)
&& ((isPlainSequence && start2 === judge) || (!isPlainSequence && judge < start1)
const unCircled =
(!isNullish(start2) &&
isNullish(end2) &&
((isPlainSequence && start2 === judge) || (!isPlainSequence && judge < start1)
? start2 === judge
: start2 === start1))
|| (isNullish(start2) && !isNullish(end2) && end2 === end1);
: start2 === start1)) ||
(isNullish(start2) && !isNullish(end2) && end2 === end1);
return !(isSibling || contain || contained || unCircled);
}
@@ -428,8 +428,8 @@ function isSequence(s1, s2, s3, equal) {
* @param store
*/
export function updateNewQuestionsByLoopingEffect(quesSaveParam, store) {
const { questionInfoBeforeModified = {}, questionInfo = {} }
= JSON.parse(JSON.stringify(store.state.common)) || {};
const { questionInfoBeforeModified = {}, questionInfo = {} } =
JSON.parse(JSON.stringify(store.state.common)) || {};
const oldPages = questionInfoBeforeModified.survey.pages;
const newQuestions = questionInfo.questions;

View File

@@ -43,13 +43,13 @@ function showModal(options) {
* @param {*} data
* @returns
*/
const canPlanetPublishPSM = function(data) {
const canPlanetPublishPSM = function (data) {
let isFb = true;
let message = '';
let title = '题目设置未完成';
const incompleteQuestionList = [];
data.questions
&& data.questions.forEach((s) => {
data.questions &&
data.questions.forEach((s) => {
if (s.question_type === 101 && s.config.price_gradient.length <= 0) {
isFb = false;
message = 'psm题目未完成设置请设置价格区间后投放';
@@ -73,15 +73,15 @@ const canPlanetPublishPSM = function(data) {
* @param {*} data
* @returns
*/
const canPlanetPublishMxdAndHotArea = function(data) {
const canPlanetPublishMxdAndHotArea = function (data) {
let isFb = true;
let message = '';
const qSteams = [];
const incompleteQuestionList = [];
let type = 0;
let title = '题目设置未完成';
data.questions
&& data.questions.forEach((s) => {
data.questions &&
data.questions.forEach((s) => {
if (s.question_type === 105 && s.config.design_version <= 0) {
isFb = false;
message = 'maxdiff题目未完成设置请生成设计后投放';
@@ -120,14 +120,14 @@ const canPlanetPublishMxdAndHotArea = function(data) {
* @param {*} data
* @returns
*/
const canPlanetPublish3D = function(data) {
const canPlanetPublish3D = function (data) {
{
let canFB = true;
let message = '';
const qSteams = [];
let title = '';
data.questions
&& data.questions.forEach((s) => {
data.questions &&
data.questions.forEach((s) => {
if (QUESTION_TYPE.contains(s.question_type)) {
try {
if (s.config.is_three_dimensions && !s.config.scene) {
@@ -157,15 +157,15 @@ const canPlanetPublish3D = function(data) {
let message = '';
const qSteams = [];
let title = '';
data.questions
&& data.questions.forEach((s) => {
data.questions &&
data.questions.forEach((s) => {
if (QUESTION_TYPE.contains(s.question_type)) {
try {
if (s.config.is_three_dimensions && s.config.is_binding_goods) {
const wares = [];
const _sceneInformation = s.config.scene_information;
const sceneInformation
= typeof _sceneInformation === 'string'
const sceneInformation =
typeof _sceneInformation === 'string'
? JSON.parse(_sceneInformation)
: _sceneInformation;
sceneInformation.shelves.forEach((shelf) => {
@@ -215,14 +215,14 @@ const canPlanetPublish3D = function(data) {
* @param {*} data
* @returns
*/
const canPlanetPublishImage = function(data) {
const canPlanetPublishImage = function (data) {
{
let canFB = true;
let message = '';
const qSteams = [];
let title = '';
data.questions
&& data.questions.forEach((s) => {
data.questions &&
data.questions.forEach((s) => {
if (s.question_type === 13) {
try {
if (s.options.length <= 0 || s.options.some((y) => y.length <= 0)) {
@@ -317,8 +317,8 @@ function canPublishRandom(data, publishType) {
if (!isValidated) {
errors.push({
message:
field.message
|| `请填写"${random.title}"中第${index + 1}组"随机题组"的"${field.name}"`
field.message ||
`请填写"${random.title}"中第${index + 1}组"随机题组"的"${field.name}"`
});
}
});
@@ -397,11 +397,11 @@ function isLoopingLogicValid(data, publishType) {
if (
(data?.cycle_pages || []).every((i) => {
return (
i.question_index
&& i.relation_type !== undefined
&& i.relation_type !== null
&& i.first_page
&& i.last_page
i.question_index &&
i.relation_type !== undefined &&
i.relation_type !== null &&
i.first_page &&
i.last_page
);
})
) {
@@ -425,7 +425,7 @@ function isLoopingLogicValid(data, publishType) {
* @param sn
* @param publishType undefined投放null投放0投放1预览2投放3测试
*/
export const canPlanetPublish = async function(sn, publishType) {
export const canPlanetPublish = async function (sn, publishType) {
const parsedPublishType = !publishType ? 2 : publishType;
const num = window.location.href.indexOf('code=');
let code;

View File

@@ -1,2 +1,2 @@
export const surveyQuestion
= 'https://yls-api-uat.dctest.digitalyili.com/api/console/surveys/RWNK9BYp/questions';
export const surveyQuestion =
'https://yls-api-uat.dctest.digitalyili.com/api/console/surveys/RWNK9BYp/questions';

View File

@@ -39,10 +39,10 @@ service.interceptors.request.use(
service.interceptors.response.use(
(response) => {
if (
response.status === 200
|| response.status === 201
|| response.status === 202
|| response.status === 204
response.status === 200 ||
response.status === 201 ||
response.status === 202 ||
response.status === 204
) {
if (response.config.method === 'put') {
// message.success('保存中...');

View File

@@ -45,10 +45,10 @@ service.interceptors.request.use(
service.interceptors.response.use(
(response) => {
if (
response.status === 200
|| response.status === 201
|| response.status === 202
|| response.status === 204
response.status === 200 ||
response.status === 201 ||
response.status === 202 ||
response.status === 204
) {
if (response.config.method === 'put') {
// message.success('保存中...');

View File

@@ -1,7 +1,11 @@
<template>
<div class="option-action">
<draggable
v-model:data="data" item-key="option_index" :handle="handle" chosenClass="chosen" animation="300"
v-model:data="data"
item-key="option_index"
:handle="handle"
chosenClass="chosen"
animation="300"
:scroll="true"
>
<!-- eslint-disable-next-line -->
@@ -13,7 +17,11 @@
name="setting "
@click="openMoveModel(element, index)
"/>-->
<van-icon class-prefix="mobilefont" name="gengduo " @click="openOptionActionModel(element, index)" />
<van-icon
class-prefix="mobilefont"
name="gengduo "
@click="openOptionActionModel(element, index)"
/>
<van-icon class-prefix="mobilefont" name="del1 " @click="deleteOption(index)" />
</span>
</div>
@@ -29,7 +37,10 @@
<van-cell title="固定置底" :border="false">
<template #right-icon>
<van-switch
v-model="activeOption.is_fixed" class="option-action-sheet-switch" size="0.5rem" :active-value="1"
v-model="activeOption.is_fixed"
class="option-action-sheet-switch"
size="0.5rem"
:active-value="1"
:inactive-value="0"
></van-switch>
</template>
@@ -37,17 +48,26 @@
<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"
v-model="activeOption.is_other"
class="option-action-sheet-switch"
size="0.5rem"
:active-value="1"
:inactive-value="0"
></van-switch>
</template>
</van-cell>
<!--复选时出现-->
<checkbox-action v-if="question?.question_type === 2" v-model="activeOption.is_remove_other"></checkbox-action>
<checkbox-action
v-if="question?.question_type === 2"
v-model="activeOption.is_remove_other"
></checkbox-action>
</van-cell-group>
</van-action-sheet>
<van-action-sheet
v-model:show="moveShow" cancel-text="取消" :actions="actions" @select="optionMove"
v-model:show="moveShow"
cancel-text="取消"
:actions="actions"
@select="optionMove"
@cancel="moveShow = false"
>
<!-- <template #description>-->
@@ -166,15 +186,15 @@ const deleteOption = (index) => {
font-size: 16px;
}
& .mobilefont+.mobilefont {
& .mobilefont + .mobilefont {
margin-left: 5px;
}
& .van-icon+.van-icon {
& .van-icon + .van-icon {
margin-left: 5px;
}
& .van-icon+.mobilefont {
& .van-icon + .mobilefont {
margin-left: 5px;
}
}

View File

@@ -260,8 +260,8 @@ const getSkipTypeText = (skipType) => {
const ls = [];
logics.map((item) => {
if (
item.skip_type === skipType
&& item.question_index === activeQuestion.value.question_index
item.skip_type === skipType &&
item.question_index === activeQuestion.value.question_index
) {
ls.push(item);
}

View File

@@ -4,7 +4,11 @@
<yl-select v-model="logic.row_index" :options="getOptions('row')" class="group"></yl-select>
<!-- 选项 or 分组 -->
<yl-select v-model="logic.is_option_group" :options="groupOptions" class="ml10 group"></yl-select>
<yl-select
v-model="logic.is_option_group"
:options="groupOptions"
class="ml10 group"
></yl-select>
<!-- <yl-select v-model="logic.operator" :options="symbolOptions" class="ml10 symbol"></yl-select>-->
<yl-select v-model="logic.cell_index" :options="getOptions('col')" class="ml10"></yl-select>
<yl-select v-model="logic.is_select" class="ml10" :options="chooseOptions"></yl-select>

View File

@@ -4,7 +4,11 @@
<yl-select v-model="logic.row_index" :options="getOptions('row')" class="group"></yl-select>
<!-- 选项 or 分组 -->
<yl-select v-model="logic.is_option_group" :options="groupOptions" class="ml10 group"></yl-select>
<yl-select
v-model="logic.is_option_group"
:options="groupOptions"
class="ml10 group"
></yl-select>
<yl-select v-model="logic.operator" :options="symbolOptions" class="ml10 symbol"></yl-select>
<yl-select v-model="logic.cell_index" :options="getOptions('col')" class="ml10"></yl-select>

View File

@@ -108,9 +108,9 @@ function isSurplus() {
return false;
} else {
return (
parseFloat(((localConfig.value.max - localConfig.value.min) * 1000).toFixed(4, 10))
% parseFloat((localConfig.value.score_interval * 1000).toFixed(4, 10))
=== 0
parseFloat(((localConfig.value.max - localConfig.value.min) * 1000).toFixed(4, 10)) %
parseFloat((localConfig.value.score_interval * 1000).toFixed(4, 10)) ===
0
);
}
}

View File

@@ -1,31 +1,48 @@
<template>
<van-field
v-model="element.stem" :label="element.stem" :required="element.config.is_required === 1" label-align="top"
v-model="element.stem"
:label="element.stem"
:required="element.config.is_required === 1"
label-align="top"
class="contenteditable-question-title base-select"
>
<template #left-icon>
{{ index + 1 }}
</template>
<template #label>
<contenteditable v-model="element.stem" className="contenteditable-label" :active="active" @blur="emitValue">
<contenteditable
v-model="element.stem"
className="contenteditable-label"
:active="active"
@blur="emitValue"
>
</contenteditable>
</template>
<template #input>
<template v-for="(item, optionIndex) in element.options" :key="item.id">
<van-radio-group v-if="element.question_type === 1" v-model="choiceValue">
<option-action
:data="isPreview ? item.options : item" :active="active" :question="element"
:data="isPreview ? item.options : item"
:active="active"
:question="element"
handle=".moverQues"
>
<template #item="{ element: it, index: itIndex }">
<van-radio
:key="itIndex" :name="it.option_index" :label="it.label" :disabled="it.disabled"
:key="itIndex"
:name="it.option_index"
:label="it.label"
:disabled="it.disabled"
icon-size="0.45rem"
>
<!-- 自定义文本 -->
<template #default>
<div class="flex align-center van-cell">
<contenteditable v-model="it.option" className="contenteditable-input" :active="active">
<contenteditable
v-model="it.option"
className="contenteditable-input"
:active="active"
>
<template #right-icon>
<div v-if="active" class="moverQues">
<van-icon class-prefix="mobilefont" name="option "></van-icon>
@@ -44,17 +61,26 @@
<van-checkbox-group v-if="element.question_type === 2" v-model="value" shape="square">
<option-action
v-model:data="element.options[optionIndex]" handle=".moverQues" :active="active"
v-model:data="element.options[optionIndex]"
handle=".moverQues"
:active="active"
:question="element"
>
<template #item="{ element: it, index: itIndex }">
<van-checkbox
:key="itIndex" :name="it.option_index" :label="it.label" :disabled="it.disabled"
:key="itIndex"
:name="it.option_index"
:label="it.label"
:disabled="it.disabled"
icon-size="0.45rem"
>
<template #default>
<div class="flex align-center van-cell">
<contenteditable v-model="it.option" className="contenteditable-input" :active="active">
<contenteditable
v-model="it.option"
className="contenteditable-input"
:active="active"
>
<template #right-icon>
<div v-if="active" class="moverQues">
<van-icon class-prefix="mobilefont" name="option "></van-icon>

View File

@@ -1,18 +1,26 @@
<template>
<div class="cont">
<van-field
v-model="element.stem" :label="element.stem" :required="element.config.is_required === 1"
v-model="element.stem"
:label="element.stem"
:required="element.config.is_required === 1"
label-align="top"
>
<template #left-icon>
{{ index + 1 }}
</template>
<template #label>
<contenteditable v-model="element.stem" :active="active" @blur="emitValue"></contenteditable>
<contenteditable
v-model="element.stem"
:active="active"
@blur="emitValue"
></contenteditable>
</template>
<template #input>
<textarea
v-model="completionValue" class="other_input" :placeholder="element.config.placeholder"
v-model="completionValue"
class="other_input"
:placeholder="element.config.placeholder"
:rows="element.config.line_height"
></textarea>
</template>

View File

@@ -6,7 +6,11 @@
<td v-for="col in cols" :key="col.option">
<!-- 编辑状态单次点击出输入框失焦后关闭 -->
<input
v-if="col.editor" v-model="col.option" v-focus type="text" @focusout="col.editor = false"
v-if="col.editor"
v-model="col.option"
v-focus
type="text"
@focusout="col.editor = false"
@click="handleRowNameChange(col.option!)"
/>
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
@@ -18,8 +22,11 @@
<th v-html="row.option"></th>
<td v-for="(col, colIndex) in cols" :key="colIndex">
<input
type="checkbox" :name="`R${rowIndex + 1}`" :value="`${rowIndex + 1}_${colIndex + 1}`"
:checked="isOptionChecked(rowIndex, colIndex)" @change="handleMatrixRadioChange(rowIndex, colIndex)"
type="checkbox"
:name="`R${rowIndex + 1}`"
:value="`${rowIndex + 1}_${colIndex + 1}`"
:checked="isOptionChecked(rowIndex, colIndex)"
@change="handleMatrixRadioChange(rowIndex, colIndex)"
/>
</td>
</tr>
@@ -37,7 +44,7 @@ const rowRecord = defineModel<number[][]>('rowRecord', { required: false, defaul
// 检查 rowRecord 是否存在
// console.log(`rowRecord:`, rowRecord.value);
/* const isPreview = */defineModel<boolean>('isPreview', { required: false, default: false });
/* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false });
defineProps<{
rows: OptionType[];
cols: OptionType[];

View File

@@ -6,7 +6,11 @@
<td v-for="col in cols" :key="col.option">
<!-- 编辑状态单次点击出输入框失焦后关闭 -->
<input
v-if="col.editor" v-model="col.option" v-focus type="text" @focusout="col.editor = false"
v-if="col.editor"
v-model="col.option"
v-focus
type="text"
@focusout="col.editor = false"
@click="handleRowNameChange(col.option!)"
/>
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
@@ -18,8 +22,11 @@
<th v-html="row.option"></th>
<td v-for="(col, colIndex) in cols" :key="colIndex">
<input
type="radio" :name="`R${rowIndex + 1}`" :value="`${rowIndex + 1}_${colIndex + 1}`"
:checked="isOptionChecked(rowIndex, colIndex)" @change="handleMatrixRadioChange(rowIndex, colIndex)"
type="radio"
:name="`R${rowIndex + 1}`"
:value="`${rowIndex + 1}_${colIndex + 1}`"
:checked="isOptionChecked(rowIndex, colIndex)"
@change="handleMatrixRadioChange(rowIndex, colIndex)"
/>
</td>
</tr>
@@ -37,7 +44,7 @@ const rowRecord = defineModel<number[]>('rowRecord', { required: false, default:
// 检查 rowRecord 是否存在
// console.log(`rowRecord:`, rowRecord.value);
/* const isPreview = */defineModel<boolean>('isPreview', { required: false, default: false });
/* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false });
defineProps<{
rows: OptionType[];
cols: OptionType[];

View File

@@ -6,7 +6,11 @@
<td v-for="col in cols" :key="col.option">
<!-- 编辑状态单次点击出输入框失焦后关闭 -->
<input
v-if="col.editor" v-model="col.option" v-focus type="text" @focusout="col.editor = false"
v-if="col.editor"
v-model="col.option"
v-focus
type="text"
@focusout="col.editor = false"
@click="handleRowNameChange(col.option!)"
/>
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
@@ -18,7 +22,9 @@
<th v-html="row.option"></th>
<td v-for="(col, colIndex) in cols" :key="colIndex">
<input
type="text" :name="`R${rowIndex + 1}`" :value="getInputValue(rowIndex, colIndex)"
type="text"
:name="`R${rowIndex + 1}`"
:value="getInputValue(rowIndex, colIndex)"
@change="handleMatrixTextChange(rowIndex, colIndex, $event)"
/>
</td>
@@ -37,7 +43,7 @@ const rowRecord = defineModel<string[][]>('rowRecord', { required: false, defaul
// 检查 rowRecord 是否存在
// console.log(`rowRecord:`, rowRecord.value);
/* const isPreview = */defineModel<boolean>('isPreview', { required: false, default: false });
/* const isPreview = */ defineModel<boolean>('isPreview', { required: false, default: false });
defineProps<{
rows: OptionType[];
cols: OptionType[];

View File

@@ -1,7 +1,9 @@
<template>
<div class="content">
<van-field
v-model="element.stem" :label="element.stem" :required="element.config.is_required === 1"
v-model="element.stem"
:label="element.stem"
:required="element.config.is_required === 1"
label-align="top"
>
<template #left-icon>
@@ -11,12 +13,21 @@
<contenteditable v-model="element.stem" :active="active" @blur="saveStem"></contenteditable>
</template>
<template #input>
<div v-for="(optionItem, optionItemIndex) in isPreview ? element.list : element.options" :key="optionItemIndex">
<div
v-for="(item, optionIndex) in isPreview ? optionItem.options : optionItem" :key="optionIndex"
v-for="(optionItem, optionItemIndex) in isPreview ? element.list : element.options"
:key="optionItemIndex"
>
<div
v-for="(item, optionIndex) in isPreview ? optionItem.options : optionItem"
:key="optionIndex"
@click="chooseOption(item)"
>
<RateCharacter v-model="rate" :index="optionIndex" :config="element.config" @change="handleRateChange">
<RateCharacter
v-model="rate"
:index="optionIndex"
:config="element.config"
@change="handleRateChange"
>
</RateCharacter>
<div class="tips">
<p>{{ element.config.prompt_left }}</p>

View File

@@ -2,7 +2,10 @@
<div>
<ul :key="test">
<li
v-for="(rate, rateIndex) in rateItem" :key="rateIndex" class="rate_item" :class="{ active_item: rate.active }"
v-for="(rate, rateIndex) in rateItem"
:key="rateIndex"
class="rate_item"
:class="{ active_item: rate.active }"
@click="getItem(rate)"
>
{{ rate.label }}
@@ -79,12 +82,16 @@ function getItem(value) {
});
}
watch(model, () => {
watch(
model,
() => {
getItem({ label: model.value, active: false });
emit('change', index.value, model.value);
}, {
},
{
// immediate: true
});
}
);
// 监听 min、max 和 score_interval 的变化
watch(

View File

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

View File

@@ -9,7 +9,7 @@ import { showFailToast } from 'vant';
const contentShow = ref(false);
const show = ref(false);
onMounted(async() => {
onMounted(async () => {
if (utils.getSessionStorage('xToken')) {
const appToken = utils.getSessionStorage('xToken');
getUserInfo(appToken)

View File

@@ -46,7 +46,7 @@ import { getSurveysPage } from '@/api/home/index.js';
const survey = ref({
project_name: ''
});
const fetchSurveys = async() => {
const fetchSurveys = async () => {
const params = {
page: 1,
per_page: 10,

View File

@@ -20,7 +20,7 @@ const marketList = ref([]);
const active = ref(null);
const marketInfo = ref([]);
const getTableList = async() => {
const getTableList = async () => {
const res = await getListScene();
if (res.data.code === 0) {
res.data.data.forEach((item) => {
@@ -31,7 +31,7 @@ const getTableList = async() => {
getMarketInfo(marketList.value[0]);
}
};
const getMarketInfo = async(item) => {
const getMarketInfo = async (item) => {
const data = marketList.value.filter((market, index) => item === index)[0];
if (data) {
const params = {

View File

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

View File

@@ -1,48 +1,48 @@
<template>
<div class="new-survey-container">
<div v-for="item in 10" :key="item" class="new-survey_item">
<div class="new-survey-container container">
<div v-for="item in survey" :key="item" class="new-survey_item">
<!-- 问卷详情 -->
<div class="survey_item_info">
<div style="position: relative">
<div class="survey_item_info_title">
<el-text>
<b>{{ '报名签到问卷标题' }}</b>
<b>{{ item.project_name }}</b>
</el-text>
<el-text>{{ 100 }}</el-text>
<el-text>{{ item.answer_num }}</el-text>
</div>
<div class="survey_item_info_status">
<el-space spacer="|">
<!--报名签到-->
<div>
<span><img src="" alt="" /></span>
<el-text size="small">{{ '报名签到' }}</el-text>
<el-text size="small">{{ item.scene_name }}</el-text>
</div>
<!-- 问卷来源 -->
<div>
<span><img src="" alt="" /></span>
<el-text size="small">{{ '移动端' }}</el-text>
<el-text size="small">{{ item.source === 1 ? '移动端' : 'PC端' }}</el-text>
</div>
<!-- 问卷时间 -->
<div>
<span><img src="" alt="" /></span>
<el-text size="small">{{ '2025.03.04' }}</el-text>
<el-text size="small">{{ item.created_at }}</el-text>
</div>
</el-space>
</div>
<div class="survey_item_status">
<span class="survey_item_info_status_text">-已结束-</span>
<span class="survey_item_info_status_text">-{{ item.status_txt }}-</span>
</div>
</div>
<!--问卷描述-->
<div class="survey_item_info_desc">
<div v-if="item.remarks" class="survey_item_info_desc">
<el-text>
{{ '问卷描述:为优化活动服务品质,烦请完成问卷,感谢配合!您的反馈至关重要' }}
{{ item.remarks }}
</el-text>
</div>
</div>
<!-- action 功能位置 -->
<div class="survey_item_action">
<el-space direction="horizontal">
<!-- <el-space direction="horizontal">-->
<div>
<el-button> 删除</el-button>
<el-button> 复制</el-button>
@@ -62,26 +62,51 @@
</el-dropdown-menu>
</template>
</el-dropdown>
</el-space>
<!-- </el-space>-->
</div>
</div>
</div>
</template>
<script setup lang="ts">
// import { ref } from 'vue';
<script setup>
import { ref, onMounted } from 'vue';
import { getSurveysPage } from '@/api/home/index.js';
import { Io5EllipsisHorizontalSharp } from 'vue-icons-plus/io5';
const survey = ref([]);
const form = ref({
page: 1,
pageSize: 10
});
// const surveyStatus = ref('end');
// const getSurveyStatusUrl = computed(() => {
// const urlMap: { [key: string]: string } = {
// end: 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbb370d01215f9cedc28d567c637c011047f83a99fbb5e7ac348ebd0ef0015f32',
// edit: 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPngaa20b2a05d267d040d17ba3aca15ae8c8f43fc3d2541283276b51d601d069bcc',
// publish:
// 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbdfd7252fb5f0fa698039bafcab00305a5b80f0e19c67522e6d4d29820f0d58e'
// };
// return `url(${urlMap[surveyStatus.value]})`;
// });
const fetchSurveys = async () => {
const params = {
page: form.value.page,
per_page: form.value.pageSize,
group_id: 0
};
const res = await getSurveysPage(params);
if (res.data.code === 0) {
survey.value = res.data.data;
survey.value.forEach((item) => {
const sceneName = JSON.parse(JSON.stringify(item.scene_name));
const nameList = sceneName.split('-');
if (nameList.length > 0) {
item.scene_name = nameList[1] ? nameList[1] : nameList[0];
}
const timeList = item.created_at.split(' ');
if (nameList.length) {
item.created_at = timeList[0];
}
});
} else {
// Toast()
}
};
onMounted(() => {
fetchSurveys();
});
</script>
<style scoped lang="scss">
@@ -91,7 +116,8 @@ import { Io5EllipsisHorizontalSharp } from 'vue-icons-plus/io5';
.new-survey-container {
min-height: calc(100vh - 100px);
padding: 1px;
background: linear-gradient(to bottom, $theme-color 200px, #f2f2f2 300px);
//background: linear-gradient(to bottom, $theme-color 200px, #f2f2f2 300px);
.new-survey_item {
margin: 10px;
@@ -100,12 +126,17 @@ import { Io5EllipsisHorizontalSharp } from 'vue-icons-plus/io5';
background-color: white;
.survey_item_info {
.survey_item_info_status {
margin-bottom: 15px;
}
.survey_item_status {
position: absolute;
top: 0;
right: 10px;
padding: 28px 13px 19px 7px;
background: url('https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbb370d01215f9cedc28d567c637c011047f83a99fbb5e7ac348ebd0ef0015f32') 100% no-repeat;
background: url('https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbb370d01215f9cedc28d567c637c011047f83a99fbb5e7ac348ebd0ef0015f32')
100% no-repeat;
background-size: 100% 100%;
opacity: 1;
@@ -129,10 +160,10 @@ import { Io5EllipsisHorizontalSharp } from 'vue-icons-plus/io5';
font-size: 15px;
}
&> :nth-child(2) {
& > :nth-child(2) {
position: relative;
left: 10px;
padding: 1px;
padding: 1px 3px;
border: 2px solid #f5f5f5;
border-radius: 6px;
font-size: 12px;
@@ -140,7 +171,7 @@ import { Io5EllipsisHorizontalSharp } from 'vue-icons-plus/io5';
}
.survey_item_info_desc {
margin: 15px 7px 0 0;
margin: 0 7px 0 0;
padding: 7px 9px 6px;
border-radius: 8px;
background-color: rgba(246, 247, 248, 0.5);
@@ -161,7 +192,9 @@ import { Io5EllipsisHorizontalSharp } from 'vue-icons-plus/io5';
}
.survey_item_action {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px;
border-top: 1px dashed #f5f5f5;

View File

@@ -549,7 +549,7 @@ const previewQuestion = () => {
router.push({ name: 'preview', query: { ...route.query } });
};
onMounted(async() => {
onMounted(async () => {
await getQuestionDetail();
});
</script>

View File

@@ -1,10 +1,6 @@
<template>
<div ref="scrollbar" class="container">
<van-nav-bar title="预览" left-arrow>
<template #left>
<van-icon name="left-long" class-prefix="mobilefont" size="18" style="color: #fff" />
</template>
</van-nav-bar>
<van-nav-bar title="预览" left-arrow />
<!-- <van-nav-bar :title="getDomString(questionsData?.survey?.title)" left-arrow />-->
<!-- 进度条 -->
@@ -23,10 +19,7 @@
</van-field>
</van-cell-group>
</van-cell-group>
<div
v-if="styleInfo.logo_status && styleInfo.logo_url"
class="example-logo"
:style="[
<div v-if="styleInfo.logo_status && styleInfo.logo_url" class="example-logo" :style="[
{
'justify-content':
styleInfo.logo_site === 1
@@ -41,60 +34,28 @@
!styleInfo.head_img_status && styleInfo.background_status
? `background-color: ${styleInfo.background_color};background-image: url(${styleInfo.background_url})`
: ''
]"
>
]">
<img class="logo" :src="styleInfo.logo_url" alt="logo" />
</div>
<!-- 问题 -->
<!-- eslint-disable-next-line -->
<div
class="questions"
:style="`min-height: ${styleInfo.head_img_status ? 'calc(100% - 240px)' : '100%'};${
styleInfo.background_status
<div class="questions" :style="`min-height: ${styleInfo.head_img_status ? 'calc(100% - 240px)' : '100%'};${styleInfo.background_status
? `background-color: ${styleInfo.background_color};background-image: url(${styleInfo.background_url})`
: ''
}`"
>
}`">
<!-- 提前终止和正常完成 -->
<q-last
v-if="page === pages.length + 1"
:code="questionsData.action?.code"
:action="questionsData.action"
:survey="questionsData.survey"
:isAnswer="isAnswer"
:isTemplate="isTemplate"
/>
<q-last v-if="page === pages.length + 1" :code="questionsData.action?.code" :action="questionsData.action"
:survey="questionsData.survey" :isAnswer="isAnswer" :isTemplate="isTemplate" />
<!-- 问卷名和描述 -->
<q-first
v-else-if="page === 0"
isMobile
:title="questionsData?.survey?.title"
:desc="questionsData?.survey?.introduction"
:questions="questionsData?.questions"
:isAnswer="isAnswer"
:showTitle="styleInfo.is_title"
:showDesc="styleInfo.is_introduce"
:label="questionsData?.survey?.title"
/>
<q-first v-else-if="page === 0" isMobile :title="questionsData?.survey?.title"
:desc="questionsData?.survey?.introduction" :questions="questionsData?.questions" :isAnswer="isAnswer"
:showTitle="styleInfo.is_title" :showDesc="styleInfo.is_introduce" :label="questionsData?.survey?.title" />
<!-- -mobile -->
<question
v-for="question in questions"
v-else
:id="'questionIndex' + question.question_index"
:key="question.question_index"
class="question"
:tip="question.tip"
:stem="question.stem"
:title="question.title"
:error="question.error"
:warning="question.warning"
:questions="questionsData.questions"
:questionType="question.question_type"
:questionIndex="question.question_index"
:showTitle="styleInfo.is_question_number && true"
isMobile
:isAnswer="isAnswer"
>
<question v-for="question in questions" v-else :id="'questionIndex' + question.question_index"
:key="question.question_index" class="question" :tip="question.tip" :stem="question.stem"
:title="question.title" :error="question.error" :warning="question.warning" :questions="questionsData.questions"
:questionType="question.question_type" :questionIndex="question.question_index"
:showTitle="styleInfo.is_question_number && true" isMobile :isAnswer="isAnswer">
<!-- <q-radio-->
<!-- v-if="question.question_type === 1"-->
<!-- :list="question.list"-->
@@ -110,21 +71,11 @@
<!-- :question="question"-->
<!-- />-->
<!-- 单选题 -->
<preview-choice
v-if="question.question_type === 1"
v-model:answer="question.answer"
v-model:answerIndex="question.answerIndex"
:list="question.list"
:config="question.config"
:hideOptions="question.hideOptions"
:stem="question.stem"
:answerSn="questionsData.answer.sn"
:answerSurveySn="questionsData.answer.survey_sn"
:question="question"
@previous="previous"
@next="next"
@change-answer="onRelation($event, question)"
/>
<preview-choice v-if="question.question_type === 1" v-model:answer="question.answer"
v-model:answerIndex="question.answerIndex" :list="question.list" :config="question.config"
:hideOptions="question.hideOptions" :stem="question.stem" :answerSn="questionsData.answer.sn"
:answerSurveySn="questionsData.answer.survey_sn" :question="question" @previous="previous" @next="next"
@change-answer="onRelation($event, question)" />
<!-- &lt;!&ndash; 多选题 &ndash;&gt;-->
<!-- <q-checkbox-->
<!-- v-else-if="question.question_type === 2"-->
@@ -152,18 +103,9 @@
<!-- isMobile-->
<!-- />-->
<!-- 填空题 -->
<preview-completion
v-else-if="question.question_type === 4"
:config="question.config"
:answer="question.answer"
:stem="question.stem"
:answerSn="questionsData.answer.sn"
:answerSurveySn="questionsData.answer.survey_sn"
:question="question"
@previous="previous"
@next="next"
@change-answer="onRelation($event, question)"
/>
<preview-completion v-else-if="question.question_type === 4" :config="question.config" :answer="question.answer"
:stem="question.stem" :answerSn="questionsData.answer.sn" :answerSurveySn="questionsData.answer.survey_sn"
:question="question" @previous="previous" @next="next" @change-answer="onRelation($event, question)" />
<!-- &lt;!&ndash; 打分题 &ndash;&gt;-->
<!-- <q-rate-->
<!-- v-else-if="question.question_type === 5"-->
@@ -196,41 +138,18 @@
<!-- isMobile-->
<!-- />-->
<!-- 矩阵填空题 -->
<preview-matrix-text
v-else-if="question.question_type === 8"
v-model:answer="question.answer"
:list="question.list"
:config="question.config"
:stem="question.stem"
:question="question"
@previous="previous"
@next="next"
@change-answer="onRelation($event, question)"
/>
<preview-matrix-text v-else-if="question.question_type === 8" v-model:answer="question.answer"
:list="question.list" :config="question.config" :stem="question.stem" :question="question"
@previous="previous" @next="next" @change-answer="onRelation($event, question)" />
<!-- 矩阵单选题 -->
<preview-matrix-radio
v-else-if="question.question_type === 9"
v-model:answer="question.answer"
:list="question.list"
:config="question.config"
:stem="question.stem"
:answerSn="questionsData.answer.sn"
:answerSurveySn="questionsData.answer.survey_sn"
:question="question"
@change-answer="onRelation($event, question)"
@previous="previous"
@next="next"
/>
<preview-matrix-radio v-else-if="question.question_type === 9" v-model:answer="question.answer"
:list="question.list" :config="question.config" :stem="question.stem" :answerSn="questionsData.answer.sn"
:answerSurveySn="questionsData.answer.survey_sn" :question="question"
@change-answer="onRelation($event, question)" @previous="previous" @next="next" />
<!-- 矩阵多选题 -->
<preview-matrix-checkbox
v-else-if="question.question_type === 10"
v-model:answer="question.answer"
:list="question.list"
:config="question.config"
:question="question"
isMobile
@change-answer="onRelation($event, question)"
/>
<preview-matrix-checkbox v-else-if="question.question_type === 10" v-model:answer="question.answer"
:list="question.list" :config="question.config" :question="question" isMobile
@change-answer="onRelation($event, question)" />
<!-- &lt;!&ndash; 矩阵打分题 &ndash;&gt;-->
<!-- <matrix-rate-->
<!-- v-else-if="question.question_type === 11"-->
@@ -298,15 +217,9 @@
<!-- isMobile-->
<!-- />-->
<!-- 文件上传题 -->
<preview-file-upload
v-else-if="question.question_type === 18"
v-model:answer="question.answer"
:config="question.config"
:question="question"
isMobile
:questionIndex="question.question_index"
@change-answer="onRelation($event, question)"
/>
<preview-file-upload v-else-if="question.question_type === 18" v-model:answer="question.answer"
:config="question.config" :question="question" isMobile :questionIndex="question.question_index"
@change-answer="onRelation($event, question)" />
<!-- &lt;!&ndash; 地理位置题 &ndash;&gt;-->
<!-- <q-map-->
<!-- v-else-if="question.question_type === 19"-->
@@ -465,63 +378,28 @@
<!-- :question="question"-->
<!-- />-->
<!-- &lt;!&ndash; 高级题型-NPS &ndash;&gt;-->
<preview-n-p-s
v-else-if="question.question_type === 106"
v-model:answer="question.answer"
:isPreview="true"
:title="question.title"
:stem="question.stem"
:list="question.list"
:config="question.config"
:isAnswer="isAnswer"
:questionIndex="question.question_index"
:label="question.title"
:loading="loading"
:isTemplate="isTemplate"
:showTitle="styleInfo.is_question_number"
:question="question"
@previous="previous"
@next="next"
@change-answer="onRelation($event, question)"
/>
<preview-n-p-s v-else-if="question.question_type === 106" v-model:answer="question.answer" :isPreview="true"
:title="question.title" :stem="question.stem" :list="question.list" :config="question.config"
:isAnswer="isAnswer" :questionIndex="question.question_index" :label="question.title" :loading="loading"
:isTemplate="isTemplate" :showTitle="styleInfo.is_question_number" :question="question" @previous="previous"
@next="next" @change-answer="onRelation($event, question)" />
</question>
<!-- 分页 -->
<!-- eslint-disable max-len -->
<div v-show="showPage" class="footer-page">
<pfe-pagination
class="pagination"
:page="page"
:pages="pages.length + 1"
:min="styleInfo.is_home ? 0 : 1"
:loading="loading"
:showPrevious="styleInfo.is_up_button"
:showStart="styleInfo.is_start_button"
:startText="styleInfo.start_button_text"
:showSubmit="styleInfo.is_submit_button"
:submitText="
localPageTimer.is_show && localPageTimer.short_time
<pfe-pagination class="pagination" :page="page" :pages="pages.length + 1" :min="styleInfo.is_home ? 0 : 1"
:loading="loading" :showPrevious="styleInfo.is_up_button" :showStart="styleInfo.is_start_button"
:startText="styleInfo.start_button_text" :showSubmit="styleInfo.is_submit_button" :submitText="localPageTimer.is_show && localPageTimer.short_time
? `${localPageTimer.short_time}S`
: styleInfo.submit_button_text
"
:buttonTextColor="styleInfo.button_text_color"
:buttonColor="styleInfo.button_color"
:nextText="
localPageTimer.is_show && localPageTimer.short_time
" :buttonTextColor="styleInfo.button_text_color" :buttonColor="styleInfo.button_color" :nextText="localPageTimer.is_show && localPageTimer.short_time
? `${localPageTimer.short_time}S`
: ''
"
:nextDisabled="localPageTimer.short_time"
isMobile
@previous="previous"
@next="next"
/>
" :nextDisabled="localPageTimer.short_time" isMobile @previous="previous" @next="next" />
</div>
<!-- eslint-enable max-len -->
<LangTranslate
v-if="isAnswer && styleInfo.is_yip"
translate-key="PoweredByDigitalTechnologyCenterYIP"
class="footer"
/>
<LangTranslate v-if="isAnswer && styleInfo.is_yip" translate-key="PoweredByDigitalTechnologyCenterYIP"
class="footer" />
</div>
</div>
</template>
@@ -587,7 +465,7 @@ const props = defineProps({
getQuestions();
// 更新数据
async function getQuestions() {
async function getQuestions () {
let { data } = await AnswerApi.getQuetions({
id: route.query.sn,
data: {
@@ -610,14 +488,14 @@ async function getQuestions() {
}
// 获取 DOM 的内容
function getDomString(htmlString) {
function getDomString (htmlString) {
if (typeof htmlString !== 'string') return;
const match = htmlString.match(/<.*>(.*?)<\/.*>/);
if (match) return match[1];
}
// 上一页
async function previous() {
async function previous () {
if (prevLoading.value || loading.value) {
return;
}
@@ -640,7 +518,7 @@ async function previous() {
}
// 下一页
async function next(callbackBeforePage) {
async function next (callbackBeforePage) {
if (prevLoading.value || loading.value) {
return;
}
@@ -659,7 +537,7 @@ async function next(callbackBeforePage) {
// 开始答题
// 答题
async function answer(callback, callbackBeforePage) {
async function answer (callback, callbackBeforePage) {
// console.log(`start input answer`);
// console.log(
// `(questions.value.length || !questionsData.value.questions.length)`,
@@ -700,9 +578,9 @@ async function answer(callback, callbackBeforePage) {
question.error = translatedText.value.ThisIsARequiredQuestion;
}
} else if (
answer
&& questionType === 1
&& Object.keys(answer).findIndex((value) => !answer[value]) !== -1
answer &&
questionType === 1 &&
Object.keys(answer).findIndex((value) => !answer[value]) !== -1
) {
// 单选题
isError = true;
@@ -983,6 +861,57 @@ async function answer(callback, callbackBeforePage) {
isError = true;
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
}
} else if (answer && questionType === 8) {
// 矩阵填空题
question.error = '';
Object.keys(answer).forEach((key) => {
const value = answer[key];
switch (config.text_type) {
case 3: // 字母
isError =
config.include_mark === 1
? !/^[a-zA-Z·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
newValue
) || !newValue.length
: !/^[a-zA-Z]+$/.test(newValue) || !newValue.length;
question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : '';
break;
case 4: // 中文
isError =
config.include_mark === 1
? !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test(
newValue
) || !newValue.length
: !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0])+$/.test(
newValue
) || !newValue.length;
question.error = isError ? translatedText.value.PleaseEnterChineseWords : '';
break;
case 5: // 邮箱
isError =
!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
value
);
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
break;
case 6: // 手机号
isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value);
question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : '';
break;
case 7: // 身份证号
isError =
!/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(
value
);
question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
break;
default:
break;
}
if (!isError && value.length < config.min && ![1, 2].includes(config.text_type)) {
isError = true;
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
}
});
} else if (questionType === 27 && question.error) {
// 多项填空题
@@ -1054,14 +983,14 @@ async function answer(callback, callbackBeforePage) {
currentQuestions.forEach((question, index) => {
if (index >= warnStart && index < warnEnd) {
if (repeat.repeat_type) {
question.warning
= translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
question.warning =
translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
repeat.allow_repeat_num,
repeat.repeat_type
);
} else {
question.error
= translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
question.error =
translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
repeat.allow_repeat_num,
repeat.repeat_type
);
@@ -1228,7 +1157,7 @@ async function answer(callback, callbackBeforePage) {
}
// 选项隐藏
function hideOptions(hide) {
function hideOptions (hide) {
const questionIndex = hide?.question_index;
if (questionIndex) {
const qustion = questionsData.value.questions.find(
@@ -1239,7 +1168,7 @@ function hideOptions(hide) {
}
// 更新答案
function updateAnswer(auto) {
function updateAnswer (auto) {
if (auto) {
auto.forEach((autoItem) => {
const question = questionsData.value.questions.find(
@@ -1251,8 +1180,8 @@ function updateAnswer(auto) {
const evt1 = {};
if ([1].includes(question.question_type)) {
evt1.value
= Object.keys(question.answer)
evt1.value =
Object.keys(question.answer)
.map((key) => (question.answer[key] ? key : undefined))
.filter((i) => !!i)?.[0] || undefined;
evt1.options = question.list.flatMap((i) => i.options);
@@ -1263,7 +1192,7 @@ function updateAnswer(auto) {
}
// 如果有结束跳转,则判断是否需要立即跳转
function jumpImmediately() {
function jumpImmediately () {
// 2000
const code = questionsData.value.action?.code;
// 检测是否是最后一页
@@ -1318,7 +1247,7 @@ function jumpImmediately() {
}
// // 关联引用
function onRelation(
function onRelation (
{ options, value, list },
{ question_type: questionType, question_index: questionIndex, related, answer }
) {

View File

@@ -227,8 +227,8 @@ export default defineComponent({
.map((option) => {
return this.wares.find(
(ware) =>
ware.question_index === option.question_index
&& ware.option_index === option.option_index
ware.question_index === option.question_index &&
ware.option_index === option.option_index
);
});
wares = wares.filter((x) => x);

View File

@@ -2,7 +2,10 @@
<div class="base">
<div ref="target" class="container-viewer-1-"></div>
<div ref="elCart" style="position: absolute; right: 80px; bottom: 80px"></div>
<div v-if="spinning" style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; background-color: #fff">
<div
v-if="spinning"
style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; background-color: #fff"
>
<a-spin style="position: absolute; top: 50%; left: 50%" />
</div>
<div v-if="freezeRotY" style="position: absolute; top: 0; right: 0; bottom: 0; left: 0"></div>
@@ -141,7 +144,7 @@ export default {
methods: {
debounce(func, wait) {
let timeout;
return function(...args) {
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};

View File

@@ -1,5 +1,10 @@
<template>
<choice v-model:answer="choiceValue" :element="question" :index="answerIndex" :is-preview="true" />
<choice
v-model:answer="choiceValue"
:element="question"
:index="answerIndex"
:is-preview="true"
/>
</template>
<script setup lang="ts">
import { watch, ref } from 'vue';

View File

@@ -1,7 +1,11 @@
<template>
<!-- <van-field v-model="inputValue" v-focus placeholder="请输入内容"> </van-field>-->
<!-- <completion />-->
<completion v-model:completionValue="completionValue" :index="answerIndex" :element="question"></completion>
<completion
v-model:completionValue="completionValue"
:index="answerIndex"
:element="question"
></completion>
</template>
<script setup lang="ts">
import { defineEmits, ref, watch } from 'vue';

View File

@@ -1,6 +1,9 @@
<template>
<MatrixCheckbox
v-model:rowRecord="rowRecord" v-model:matrix-radio-answer="answer!" :rows="rows" :cols="cols"
v-model:rowRecord="rowRecord"
v-model:matrix-radio-answer="answer!"
:rows="rows"
:cols="cols"
:is-preview="true"
/>
</template>
@@ -79,7 +82,9 @@ function parseAnswer(answer: answer) {
const rows = computed(() => question.value?.list[0]?.options ?? []);
const cols = computed(() => question.value?.list[1]?.options ?? []);
watch(rowRecord, () => {
watch(
rowRecord,
() => {
// console.log(`record has changed`, rowRecord.value);
// 重新生成 answer
const newAnswer: answer = {};
@@ -90,8 +95,9 @@ watch(rowRecord, () => {
});
answer.value = newAnswer;
emit('changeAnswer', newAnswer);
}, { deep: true });
},
{ deep: true }
);
</script>
<style scoped lang="scss">

View File

@@ -1,6 +1,9 @@
<template>
<matrix-radio
v-model:rowRecord="rowRecord" v-model:matrix-radio-answer="answer!" :rows="rows" :cols="cols"
v-model:rowRecord="rowRecord"
v-model:matrix-radio-answer="answer!"
:rows="rows"
:cols="cols"
:is-preview="true"
></matrix-radio>
</template>
@@ -64,7 +67,9 @@ function parseAnswer(answer: answerType) {
const rows = computed(() => question.value?.list[0]?.options ?? []);
const cols = computed(() => question.value?.list[1]?.options ?? []);
watch(rowRecord, () => {
watch(
rowRecord,
() => {
// console.log(`record has changed`, rowRecord.value);
// 生成 answer
const newAnswer: answerType = {};
@@ -73,8 +78,9 @@ watch(rowRecord, () => {
});
answer.value = newAnswer;
emit('changeAnswer', newAnswer);
}, { deep: true });
},
{ deep: true }
);
</script>
<style scoped lang="scss">

View File

@@ -1,6 +1,9 @@
<template>
<MatrixText
v-model:rowRecord="rowRecord" v-model:matrix-radio-answer="answer!" :rows="rows" :cols="cols"
v-model:rowRecord="rowRecord"
v-model:matrix-radio-answer="answer!"
:rows="rows"
:cols="cols"
:is-preview="true"
/>
</template>
@@ -80,7 +83,9 @@ function parseAnswer(answer: answerType) {
const rows = computed(() => question.value?.list[0]?.options ?? []);
const cols = computed(() => question.value?.list[1]?.options ?? []);
watch(rowRecord, () => {
watch(
rowRecord,
() => {
// 重新生成 answer
const newAnswer: answerType = {};
rowRecord.value.forEach((rows, rowIndex) => {
@@ -90,8 +95,9 @@ watch(rowRecord, () => {
});
answer.value = newAnswer;
emit('changeAnswer', newAnswer);
}, { deep: true });
},
{ deep: true }
);
</script>
<style scoped lang="scss">

View File

@@ -1,18 +1,28 @@
<template>
<div class="content">
<van-field
v-model="element.stem" :label="element.stem" :required="element.config.is_required === 1"
v-model="element.stem"
:label="element.stem"
:required="element.config.is_required === 1"
label-align="top"
>
<template #left-icon>
{{ index + 1 }}
</template>
<template #label>
<contenteditable v-model="element.stem" :active="active" @blur="emitValue"></contenteditable>
<contenteditable
v-model="element.stem"
:active="active"
@blur="emitValue"
></contenteditable>
</template>
<template #input>
<div v-for="(optionItem, optionItemIndex) in element.options" :key="optionItemIndex">
<div v-for="(item, optionIndex) in optionItem" :key="optionIndex" @click="chooseOption(item)">
<div
v-for="(item, optionIndex) in optionItem"
:key="optionIndex"
@click="chooseOption(item)"
>
<contenteditable v-model="item.option" :active="active"></contenteditable>
<RateCharacter :config="element.config"></RateCharacter>
<div class="tips">

View File

@@ -21,20 +21,27 @@
<div class="modal">
<div class="m-title">
<LangTranslate
v-if="countTime > 0" translate-key="QLast_RedirectingIn5Seconds"
v-if="countTime > 0"
translate-key="QLast_RedirectingIn5Seconds"
:translate-params="[countTime]"
/>
<LangTranslate v-else translate-key="QLast_IosRedirectingPrompt" />
</div>
<div class="m-bottom">
<LangTranslate v-if="countTime > 0" translate-key="QLast_Stay" class="m-btn border-right" @click="stopJump" />
<LangTranslate
v-if="countTime > 0"
translate-key="QLast_Stay"
class="m-btn border-right"
@click="stopJump"
/>
<LangTranslate translate-key="QLast_Redirect" class="m-btn" @click="jump" />
</div>
</div>
</div>
<LangTranslate
v-if="isAnswer && questionsData.survey?.style?.is_yip"
translate-key="PoweredByDigitalTechnologyCenterYIP" class="footer"
translate-key="PoweredByDigitalTechnologyCenterYIP"
class="footer"
>
<template #prefix>
<img src="https://diaoyan-files.automark.cc/yili_logo.png" alt="" class="yip-icon" />
@@ -99,11 +106,11 @@ export default defineComponent({
const isEndUrl = computed(() => {
const code = props.action ? props.action.code : props.code;
return (
(code === 20004
&& props.survey.screening_end_url_select
&& props.survey.screening_end_url)
|| (code === 20011 && props.survey.success_end_url_select && props.survey.success_end_url)
|| (code === 20016 && props.survey.quota_end_url_select && props.survey.quota_end_url)
(code === 20004 &&
props.survey.screening_end_url_select &&
props.survey.screening_end_url) ||
(code === 20011 && props.survey.success_end_url_select && props.survey.success_end_url) ||
(code === 20016 && props.survey.quota_end_url_select && props.survey.quota_end_url)
);
});

View File

@@ -267,16 +267,16 @@ export default defineComponent({
});
if (
!compareArrayByField(options.value, newOptions, 'option_key')
|| !compareArrayByField(options.value, newOptions, 'option')
!compareArrayByField(options.value, newOptions, 'option_key') ||
!compareArrayByField(options.value, newOptions, 'option')
) {
options.value = newOptions;
}
// 清空值和答案
if (
value.value
&& options.value.findIndex((option) => option.option_key === value.value) === -1
value.value &&
options.value.findIndex((option) => option.option_key === value.value) === -1
) {
// 清空值
value.value = '';
@@ -294,8 +294,8 @@ export default defineComponent({
() => options.value,
(val, oldVal) => {
if (
compareArrayByField(val, oldVal || [], 'option_key')
&& compareArrayByField(val, oldVal || [], 'option')
compareArrayByField(val, oldVal || [], 'option_key') &&
compareArrayByField(val, oldVal || [], 'option')
) {
return;
}

View File

@@ -142,8 +142,8 @@ export default defineComponent({
// 替换文本
let replacement = '';
// 查找引用问题
const question
= props.questions.find((question) => {
const question =
props.questions.find((question) => {
// 矩阵题
if (question.question_type >= 8 && question.question_type <= 11) {
return question.title === value.split('_R')[0].split('_C')[0];
@@ -153,8 +153,8 @@ export default defineComponent({
return question.title === value.split('_A')[0];
}
return question.title === value;
})
|| props.questions.find((question) => {
}) ||
props.questions.find((question) => {
// 矩阵题
if (question.question_type >= 8 && question.question_type <= 11) {
return question.title === (value + cycleIndexStr).split('_R')[0].split('_C')[0];
@@ -182,8 +182,8 @@ export default defineComponent({
replacement = answer[option.option_key];
}
} else if (
question.question_type === 2
&& Object.keys(answer).length >= question.config.min_select
question.question_type === 2 &&
Object.keys(answer).length >= question.config.min_select
) {
// 查找引用选项(多选)
options.forEach((option) => {
@@ -285,7 +285,7 @@ export default defineComponent({
min-height: 24px;
margin-bottom: 24px;
>span {
> span {
flex-shrink: 0;
}
@@ -313,7 +313,8 @@ export default defineComponent({
// .question-inner-span {
// width: 100%;
// }</style>
// }
</style>
<style lang="scss" scoped>
:deep(.theme-hover-default) {

View File

@@ -350,7 +350,7 @@ export const language = {
zh: '请点击查看图片'
},
NoteCantViewAfterTimeLimit: {
en: 'Note: Can\'t view after time limit',
en: "Note: Can't view after time limit",
zh: '注意:超过显示时间限制后将无法再次查看'
},
DisplayTimeLimitExceeded: {

View File

@@ -250,10 +250,10 @@ function quesHandle(answer, logChild) {
const matrixRateHandle = () => {
// 如果配置的逻辑中参数为空,则代表没有配置逻辑匹配值,此时不做校验
if (
logChild.cell_index === 0
|| logChild.row_index === 0
|| !logChild.operator
|| !logChild.value
logChild.cell_index === 0 ||
logChild.row_index === 0 ||
!logChild.operator ||
!logChild.value
) {
return true;
}
@@ -265,10 +265,10 @@ function quesHandle(answer, logChild) {
const matrixInputHandle = () => {
// 如果配置的逻辑中参数为空,则代表没有配置逻辑匹配值,此时不做校验
if (
logChild.cell_index === 0
|| logChild.row_index === 0
|| !logChild.operator
|| !logChild.value
logChild.cell_index === 0 ||
logChild.row_index === 0 ||
!logChild.operator ||
!logChild.value
) {
return true;
}
@@ -519,10 +519,10 @@ function getlogicStatus(questionData) {
// } else {
// statusStr = statusStr + conditionStatus;
// }
statusStr
= statusStr
+ (logChild.logic === 'and' ? '&&' : logChild.logic === 'or' ? '||' : '')
+ conditionStatus;
statusStr =
statusStr +
(logChild.logic === 'and' ? '&&' : logChild.logic === 'or' ? '||' : '') +
conditionStatus;
});
// eslint-disable-next-line no-eval
logs.logicStatus = eval(statusStr);

View File

@@ -105,8 +105,8 @@ export default function answerMock(questionsData, page) {
} else if (logic.skip_type === 4) {
// 只计算跳转后所在页面的隐藏逻辑,否则会出现只返回最后一道隐藏选项题目的情况,导致失效
const toPage = page + 1;
const hasHiddenLogicQuizPage
= data.pages.findIndex((page) => page.includes(logic.question_index)) + 1;
const hasHiddenLogicQuizPage =
data.pages.findIndex((page) => page.includes(logic.question_index)) + 1;
if (hasHiddenLogicQuizPage === toPage) {
// 选项隐藏逻辑
updateOptionHidden(data.hide_options, logic);

View File

@@ -155,9 +155,9 @@ export default defineComponent({
question.error = translatedText.value.ThisIsARequiredQuestion;
}
} else if (
answer
&& questionType === 1
&& Object.keys(answer).findIndex((value) => !answer[value]) !== -1
answer &&
questionType === 1 &&
Object.keys(answer).findIndex((value) => !answer[value]) !== -1
) {
// 单选题
isError = true;
@@ -303,9 +303,9 @@ export default defineComponent({
} else if (answer && questionType === 12) {
question.error = '';
} else if (
answer
&& questionType === 14
&& Object.keys(answer).length < config.min_select
answer &&
questionType === 14 &&
Object.keys(answer).length < config.min_select
) {
// 图片多选题
isError = true;
@@ -343,8 +343,8 @@ export default defineComponent({
switch (config.text_type) {
// 字母
case 3:
isError
= config.include_mark === 1
isError =
config.include_mark === 1
? !/^[a-zA-Z·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
newValue
) || !newValue.length
@@ -353,8 +353,8 @@ export default defineComponent({
break;
// 中文
case 4:
isError
= config.include_mark === 1
isError =
config.include_mark === 1
? !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test(
newValue
) || !newValue.length
@@ -365,8 +365,8 @@ export default defineComponent({
break;
// 邮箱
case 5:
isError
= !/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
isError =
!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
value
);
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
@@ -378,8 +378,8 @@ export default defineComponent({
break;
// 身份证号
case 7:
isError
= !/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(
isError =
!/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(
value
);
question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
@@ -447,9 +447,9 @@ export default defineComponent({
break;
}
if (
!question.error
&& value.length < config.min
&& ![1, 2].includes(config.text_type)
!question.error &&
value.length < config.min &&
![1, 2].includes(config.text_type)
) {
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
}
@@ -825,8 +825,8 @@ export default defineComponent({
const evt1 = {};
if ([1].includes(question.question_type)) {
evt1.value
= Object.keys(question.answer)
evt1.value =
Object.keys(question.answer)
.map((key) => (question.answer[key] ? key : undefined))
.filter((i) => !!i)?.[0] || undefined;
evt1.options = question.list.flatMap((i) => i.options);

View File

@@ -6,8 +6,8 @@
</template>
<script setup>
const successImg
= 'https://files.axshare.com/gsc/DR6075/c7/5a/53/c75a534148d349f1bb8e185629f784ac/images/%E9%A2%84%E8%A7%88/u123.png?pageId=18fb9d8a-b9b7-465f-9bd7-625b1b78f72e';
const successImg =
'https://files.axshare.com/gsc/DR6075/c7/5a/53/c75a534148d349f1bb8e185629f784ac/images/%E9%A2%84%E8%A7%88/u123.png?pageId=18fb9d8a-b9b7-465f-9bd7-625b1b78f72e';
</script>
<style lang="scss" scoped>