import { showConfirmDialog } from 'vant'; import { getQuestionList } from '@/api/survey'; import { QUESTION_TYPE } from '@/layouts/config3d.constant.js'; import { loopingAvailable } from '@/layouts/logic.js'; import { getDomText } from '@/utils/utils'; // /** // * 统一的弹窗 // * @param options // */ /** * 统一的弹窗 * @param options */ function showModal(options) { showConfirmDialog({ title: '提示', icon: null, ...options }) .then(() => { // then back }) .catch(() => { // error back }); } /** * PSM的判断 * @param {*} data * @returns */ const canPlanetPublishPSM = function (data) { let isFb = true; let message = ''; let title = '题目设置未完成'; const incompleteQuestionList = []; data.questions && data.questions.forEach((s) => { if (s.question_type === 101 && s.config.price_gradient.length <= 0) { isFb = false; message = 'psm题目未完成设置,请设置价格区间后投放'; title = '题目设置未完成'; incompleteQuestionList.push(s); } }); if (isFb === true && data.questions.length > 0) { return true; } else { const titleStr = incompleteQuestionList.map((item) => item.title).join('、') || ''; showModal({ title, message: `${titleStr} ${message}`, incompleteQuestionList }); } }; /** * Mxd和热区的判断 * @param {*} data * @returns */ const canPlanetPublishMxdAndHotArea = function (data) { let isFb = true; let message = ''; const qSteams = []; const incompleteQuestionList = []; let type = 0; let title = '题目设置未完成'; data.questions && data.questions.forEach((s) => { if (s.question_type === 105 && s.config.design_version <= 0) { isFb = false; message = 'maxdiff题目未完成设置,请生成设计后投放'; title = '题目设置未完成'; type = 1; incompleteQuestionList.push(s); } if (s.question_type === 25 || s.question_type === 26) { if ((s.options?.[0]?.length || 0) <= 0 && (s?.associate?.length || 0) <= 0) { isFb = false; qSteams.push(`(${s.title})`); type = 2; incompleteQuestionList.push(s); } } }); if (isFb === true) { return true; } else { if (type === 2) { const titleStr = qSteams.join(','); title = '添加选区'; message = `${titleStr} 未添加选区,请添加选区后进行投放`; } showModal({ title, message, incompleteQuestionList }); } }; /** * 3D相关的判断 * @param {*} data * @returns */ const canPlanetPublish3D = function (data) { { let canFB = true; let message = ''; const qSteams = []; let title = ''; data.questions && data.questions.forEach((s) => { if (QUESTION_TYPE.contains(s.question_type)) { try { if (s.config.is_three_dimensions && !s.config.scene) { canFB = false; qSteams.push(`(${s.title})`); } } catch (error) { // error } } }); if (!canFB === true) { const titleStr = qSteams.join(','); title = '选择场景'; message = `${titleStr} 未选择场景,请选择场景后进行投放`; showModal({ title, message }); return; } } { let canFB = true; let message = ''; const qSteams = []; let title = ''; 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' ? JSON.parse(_sceneInformation) : _sceneInformation; sceneInformation.shelves.forEach((shelf) => { shelf.wares.forEach((ware) => { if (!ware.option_index) return; wares.push(ware); }); }); const options = s.options.flat(); s.associate.forEach((ass) => { // eslint-disable-next-line no-eval const question = data.questions.find( (q) => q.question_index === ass.question_index ); if (!question) return; options.push(...question.options.flat()); }); // 判定是否有选项未关联商品 if (options.length > wares.length) { canFB = false; qSteams.push(`(${s.title})`); } } } catch (error) { // error } } }); if (!canFB === true) { const titleStr = qSteams.join(','); title = '商品关联选项'; message = `${titleStr} 仍有选项未关联商品,无法进行投放`; showModal({ title, message }); return; } } return true; }; /** * 图片题的判断 * @param {*} data * @returns */ const canPlanetPublishImage = function (data) { { let canFB = true; let message = ''; const qSteams = []; let title = ''; data.questions && data.questions.forEach((s) => { if (s.question_type === 13) { try { if (s.options.length <= 0 || s.options.some((y) => y.length <= 0)) { canFB = false; qSteams.push(`(${s.title})`); } } catch (error) { // console.warn(error); } } }); if (!canFB === true) { const titleStr = qSteams.join(','); title = '题目设置未完成'; message = `图片题 ${titleStr} 未上传图片,请设置后投放`; showModal({ title, message }); return; } } return true; }; /** * 多项填空题 * @param data * @param publishType */ function canPublishMultiCompletion(data, publishType) { const publishStr = ['', '预览', '投放'][publishType] || '投放'; const questions = []; if (!data?.questions?.length) { return true; } data.questions.forEach((quiz) => { if (quiz.question_type !== 27) { return; } if (!getDomText(quiz.config?.text_content)) { questions.push(quiz.title); } }); if (questions.length) { showModal({ title: '题目设置未完成', message: `多项填空题 (${questions.join('、')}) 未设置填空,请设置后${publishStr}` }); return false; } return true; } /** * 校验 "逻辑 -> 随机列表" 是否满足投放条件 * @param data * @return {boolean} */ function canPublishRandom(data, publishType) { const publishStr = ['', '预览', '投放'][publishType] || '投放'; const errors = []; // eslint-disable-next-line no-eval const randomList = data?.survey?.group_pages || []; randomList.forEach((random) => { const list = random.list || []; // 每一个随机,至少要有两个随机题组 if (list.length < 2) { errors.push({ message: `"${random.title}"需至少配置2个"随机题组"` }); return false; } list.forEach((item, index) => { // 这三个是必填的 const fields = [ { label: 'title', name: '题组名称', validator: (value) => !!value }, { label: 'start', name: '题组起点', validator: (value) => !!value }, { label: 'end', name: '题组终点', validator: (value) => !!value } ]; fields.forEach((field) => { const isValidated = field.validator(item[field.label]); if (!isValidated) { errors.push({ message: field.message || `请填写"${random.title}"中第${index + 1}组"随机题组"的"${field.name}"` }); } }); }); }); if (errors.length) { showModal({ title: '修改随机题组', message: `随机题组设置不完全,请前往"逻辑设置-随机列表"修改后${publishStr}` }); return false; } return true; } /** * 将接口返回的题目和分页两个数组合并为一个 * @param {Array} quesList 要合并的题目 * @param {Array} pages 分页完成的题目id数组 * @param {Array} pagesStr 分页的内容数组 * @returns */ function combineQuesAndPage(quesList, pages, pagesStr) { if (pages.length === 0) return quesList; const newPages = `${pages.join(',empty,')},empty`.split(',').filter((x) => x.length !== 0); const copyList = quesList.filter((x) => x.id); let startIndex = 0; newPages.forEach((x, index) => { if (x === 'empty') { copyList.splice(index, 0, pagesStr[startIndex]); startIndex += 1; } }); return copyList; } /** * 根据原始数据pages和问题列表quesList处理成包含分页的quesList * @param {Array} questions 要合并的题目 * @param {Array} page 分页完成的题目ques_index数组 * @param {Array} pageConfig 分页配置,由于是后添加的功能,所以只好分开传,再合到一起了 * @returns */ function getQuesByPages(questions, page, pageConfig) { const oldPages = questions.filter((q) => !!q.page); const quesList = questions.filter((ques) => ques.id); const pageStr = []; page.forEach((x, xIndex) => { const temp = { ...(oldPages[xIndex] || {}), page: xIndex + 1, total: page.length, first_title: '', last_title: '', ...(pageConfig?.[xIndex] || {}) }; x.forEach((y, yIndex) => { if (yIndex === 0) { temp.first_title = quesList.find((ques) => ques.question_index === y)?.title || ''; } if (yIndex === x.length - 1) { temp.last_title = quesList.find((ques) => ques.question_index === y)?.title || ''; } }); pageStr.push(temp); }); return combineQuesAndPage(quesList, page, pageStr); } /** * 循环逻辑的判断 * @param data * @param publishType */ function isLoopingLogicValid(data, publishType) { const publishStr = ['', '预览', '投放'][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 ); }) ) { return loopingAvailable({ cycles: data.cycle_pages || [], questions: getQuesByPages(data.questions || [], data.survey.pages), logics: data.logics || [], isPerPage: data.survey?.is_one_page_one_question }); } showModal({ title: '修改循环', message: `循环题组不完全,请前往循环列表修改后${publishStr}` }); return false; } /** * 判断问卷是否可以投放(原本应该后端实现,前端实现会有并发的问题,但后端表示做不了) * @param sn * @param publishType undefined投放;null投放;0投放;1预览;2投放;3测试 */ export const canPlanetPublish = async function (sn, publishType) { const parsedPublishType = !publishType ? 2 : publishType; const num = window.location.href.indexOf('code='); let code; if (num > -1) { code = window.location.href.slice(num + 5, window.location.href.length); } else { code = ''; } const { data } = await getQuestionList(sn, code); if (!canPlanetPublishPSM(data?.data)) return false; if (!canPlanetPublishMxdAndHotArea(data?.data)) return false; if (!canPlanetPublish3D(data?.data)) return false; if (!canPlanetPublishImage(data?.data)) return false; if (!canPublishMultiCompletion(data, parsedPublishType)) return false; if (!canPublishRandom(data?.data, parsedPublishType)) return false; if (!isLoopingLogicValid(data?.data, parsedPublishType)) return false; /* eslint-disable */ // if (parsedPublishType === 2) { // const qrcodeRes = await getCheckSurvey(sn); // if (qrcodeRes?.data?.data?.show_test_button) { // const res = await new Promise((resolve) => { // showConfirmDialog({ // class: 'custom-modal custom-modal-title-confirm-notice show-icon', // title: '确认要投放这个问卷吗?', // messageStyle: { // position: 'absolute', // top: '0', // right: '0', // display: 'flex', // justifyContent: 'center', // alignItems: 'center', // width: '56px', // height: '56px', // fontSize: '14px', // cursor: 'pointer' // }, // message: // '投放前测试能帮助您确认问卷设计逻辑及作答数据是否正确,避免因问卷设计问题造成重大损失。', // confirmButtonText: '去测试', // onConfirm() { // resolve(false); // if (utils.getSessionStorage('xToken')) { // location.href = `/preview?sn=${sn}&name=${data.data.survey.project_name}&source=0&is_test=1&navTitle=测试`; // } else { // window.open( // `${location.origin}/preview?sn=${sn}&name=${data.data.survey.project_name}+source=0&is_test=1&navTitle=测试` // ); // } // }, // width: '640px', // height: '364px', // cancelButtonText: '继续投放', // onCancel() { // resolve(true); // }, // dialogStyle: { // fontSize: '44px' // }, // zIndex: 9999999 // }); // }); // if (!res) return; // } // } /* eslint-enable */ return true; };