* @package zin * @link http://www.zentao.net */ namespace zin; /** * 思引师基础节点内容。 * thinmory basic node content. */ class thinkStepBase extends wg { /** * @var mixed[] */ protected static $defineProps = array( 'title?: string', // 标题 'desc?: string', // 描述 'isRun?: bool=false', // 是否是分析活动 'step?: object', // 整个步骤的对象 'mode?: string="detail"', // detail|create|edit 'type?: string="node"', // node|transition/question 'quoteQuestions?: array'. // 引用的问题 'quotedQuestions?: attay', // 被引用的问题 'isResult?: bool=false', // 是否是结果页 'wizard?: object', // 模型数据 ); public static function getPageCSS() { return file_get_contents(__DIR__ . DS . 'css' . DS . 'v1.css'); } protected function buildDetail() { global $lang, $app; $app->loadLang('thinkrun'); $app->loadLang('thinkstep'); list($step, $mode, $wizard) = $this->prop(array('step', 'mode', 'wizard')); if($mode != 'detail') return array(); $options = $step->options; if($step->type == 'question') { $questionType = $options->questionType; $tips = $lang->thinkstep->$questionType; $setOption = empty($options->setOption) || $options->setOption == 0; if(!empty($options->required) && $questionType == 'checkbox' && $setOption) { $tips = $lang->thinkrun->requiredTitle[$questionType]; $tips = str_replace(array('%min%', '%max%'), array($options->minCount, $options->maxCount), $tips); } if(!empty($options->required) && $questionType == 'tableInput') { if($wizard->model == 'bcg' && empty($options->requiredRows)) $options->requiredRows = 3; if($options->supportAdd) $tips = sprintf($lang->thinkrun->tableInputTitle->notSupportAdd, count($options->fields), $options->requiredRows); if(!$options->supportAdd) $tips = sprintf($lang->thinkrun->tableInputTitle->supportAdd, $options->requiredRows); } } $requiredSymbal = !empty($options->required) ? span(setClass('text-danger mr-0.5 h-5'), '*') : null; $questionTips = !empty($tips) ? span(setClass('text-gray mx-1'), '(' . $tips . ')') : null; $errorText = isset($options->questionType) && !empty($lang->thinkrun->error->requiredType[$options->questionType]) ? span ( setClass('run-error-msg h-5 inline-block text-canvas text-md px-2 ml-0.5 rounded-md hidden'), setStyle('background', 'var(--color-danger-600)'), $lang->thinkrun->error->requiredType[$options->questionType] ) : null; return array ( div ( setClass('flex items-start justify-between mb-2 step-title'), $step->type == 'question' ? div ( setClass('h-full text-fore text-lg'), $requiredSymbal, isset($step->index) ? $step->index . '. ' : '', $step->title, $questionTips, $errorText ) : div ( setClass('text-2xl'), $step->title ) ), div ( setClass('run-desc mb-3.5'), setStyle(array('margin-top' => '-28px')), section ( setClass('break-words'), set::content(!empty($step->desc) ? htmlspecialchars_decode($step->desc) : ''), set::useHtml(true) ) ) ); } protected function buildDetailTip() { global $lang, $app, $config; $app->loadLang('thinkstep'); $app->loadLang('thinkrun'); list($quoteQuestions, $quotedQuestions, $step, $isRun, $wizard) = $this->prop(array('quoteQuestions', 'quotedQuestions', 'step', 'isRun', 'wizard')); $preViewModel = in_array($wizard->model, $config->thinkwizard->hiddenMenuModel); if(!empty($step->options->fields)) $step->options->fields = is_string($step->options->fields) ? explode(', ', $step->options->fields) : array_values((array)$step->options->fields); $questionType = !empty($step) && $step->type == 'question' ? $step->options->questionType : ''; $isCheckBox = !empty($step) && $step->type == 'question' && in_array($questionType, $config->thinkstep->quoteQuestionType); $isQuoteItem = $isCheckBox && !empty($step->options->setOption) && $step->options->setOption == 1; $quoteTitleList = !empty($step->options->quoteTitle) ? explode(", ", $step->options->quoteTitle) : array(); $detailTip = array(); $quotedItems = array(); $sourceQuestion = array(); $sourceItems = array(); $wizard->config = !empty($wizard->config) ? $wizard->config : array(); $wizard->config = is_string($wizard->config) ? json_decode($wizard->config, true) : $wizard->config; $configureObjects = !empty($wizard->config['configureObjects']) ? json_decode($wizard->config['configureObjects'], true) : array(); $isAssignedObject = !empty($configureObjects['isAssignedObject']) ? $configureObjects['isAssignedObject'] : 0; $showBuiltTip = isset($step->options->canConfigureRatio) && $step->options->canConfigureRatio == 0; if(!empty($quotedQuestions)) { foreach($quotedQuestions as $item) { $quotedItems[] = a ( setClass('block text-primary-500 leading-relaxed'), set::href(createLink('thinkstep', 'view', "marketID=0&&wizardID=$item->wizard&&stepID=$item->id&&from=detail")), setData('toggle', 'modal'), setData('dismiss', 'modal'), setData('size', 'sm'), $item->index . '. ' . $item->title ); } } if($isQuoteItem && !empty($quoteQuestions)) { foreach($quoteQuestions as $item) { if(!$isRun && in_array($item->id, $quoteTitleList)) $sourceQuestion[] = $item; if($isRun && in_array($item->origin, $quoteTitleList)) $sourceQuestion[] = $item; } } if(!empty($sourceQuestion)) { foreach ($sourceQuestion as $sourceQuestionItem) { $sourceItems[] = a ( setClass('block text-primary-500 leading-relaxed'), set::href(createLink('thinkstep', 'view', "marketID=0&&wizardID=$sourceQuestionItem->wizard&&stepID=$sourceQuestionItem->id&&from=detail")), setData('toggle', 'modal'), setData('dismiss', 'modal'), setData('size', 'sm'), $sourceQuestionItem->index . '. ' . $sourceQuestionItem->title ); } } $runSourceTip = !empty($sourceQuestion) && !$preViewModel; if($isRun && (!empty($quotedQuestions) || $runSourceTip)) { $tipType = $lang->thinkstep->label->option; $sourceQuestionTip = array(); if($runSourceTip) { foreach ($sourceQuestion as $sourceQuestionItem) { $sourceQuestionType = is_string($sourceQuestionItem->options) ? json_decode($sourceQuestionItem->options)->questionType : $sourceQuestionItem->options->questionType; if($sourceQuestionType == 'multicolumn') $tipType = sprintf($lang->thinkstep->entry, $step->options->selectColumn); $sourceQuestionTip[] = div ( setClass('ml-4 pl-0.5'), sprintf($lang->thinkstep->tips->checkbox, $lang->thinkstep->tips->options[$questionType], ($sourceQuestionItem->index . '. ' . $sourceQuestionItem->title)), $tipType ); } } $showRunTips = ((!empty($quotedQuestions) && empty($isAssignedObject)) || !empty($runSourceTip)); $detailTip[] = $showRunTips ? div ( setClass('bg-primary-50 text-gray p-2 mt-3 leading-normal'), (!empty($quotedQuestions) && empty($isAssignedObject)) ? div ( setClass('flex items-center'), icon(setClass('font text-warning mr-1'), 'about'), $lang->thinkrun->tips->quotedTip ) : null, !empty($runSourceTip) ? $sourceQuestionTip : null ) : null; } if(!$isRun) { /* 以下类型引用其他没有答案的问题,底部需提示信息。The following types of questions refer to other unanswered questions, and prompt information is required at the bottom. */ $quoteTipsType = array('multicolumn', 'score', 'tableInput'); if(!empty($sourceQuestion) && !empty($questionType) && in_array($questionType, $quoteTipsType)) { $quoteTips = empty($step->options->fields) ? div(setClass('text-sm text-gray-400 leading-loose mt-2'), $lang->thinkstep->tips->{$questionType}) : null; } $detailTip[] = array ( !empty($sourceQuestion) ? array( div ( setClass('bg-primary-50 leading-normal p-2 mt-3'), div(sprintf($lang->thinkstep->tips->sourceofOptions, $lang->thinkstep->tips->options[$questionType])), $sourceItems ), !empty($quoteTips) ? $quoteTips : null ) : null, (!empty($quotedQuestions) && !$preViewModel) ? div ( setClass('bg-primary-50 leading-normal p-2 mt-3'), div(sprintf($lang->thinkstep->tips->optionsAreReferenced, $questionType == 'multicolumn' ? $lang->thinkstep->inputItem : $lang->thinkstep->label->option)), $quotedItems ) : null ); } if($preViewModel) { if((!empty($quotedQuestions) && !empty($isAssignedObject)) || $showBuiltTip) $detailTip[] = $this->buildTipsNode($lang->thinkwizard->previewSteps->quotedTips); if(isset($step->options->isPreset) && $step->options->isPreset == 1) $detailTip[] = $this->buildTipsNode($lang->thinkwizard->previewSteps->presetDataTips); } return $detailTip; } /** * @param string $message */ protected function buildTipsNode($message) { return div ( setClass('flex text-gray-400 mt-2 items-center text-sm ml-2'), icon(setClass('text-important mr-2'), 'about'), span(setClass('leading-6'), $message) ); } protected function buildFormItem() { global $lang, $app; $app->loadLang('thinkstep'); list($step, $title, $desc, $type, $mode) = $this->prop(array('step', 'title', 'desc', 'type', 'mode')); if($mode == 'create') $title = $lang->thinkstep->untitled . $lang->thinkstep->$type; if($step) { $title = $step->title; $desc = htmlspecialchars_decode($step->desc); } return array( formGroup ( set::width('full'), set::label($lang->thinkstep->label->title), set::labelClass('required'), input ( setClass('is-required'), set::value($title ?? ''), set::name('title'), set::placeholder($lang->thinkstep->placeholder->inputContent) ) ), formGroup ( set::width('full'), set::label($lang->thinkstep->label->desc), editor ( setClass('desc'), set::name('desc'), set::placeholder($lang->thinkstep->placeholder->pleaseInput), html($desc ?? ''), set::rows(3) ) ) ); } protected function buildForm() { global $lang; $actions = array(array( 'text' => $lang->save, 'btnType' => 'submit', 'class' => 'primary h-7 ring-0 submit-btn px-4', 'style' => array('min-width' => '0') )); return formPanel ( setClass('think-step-panel py-4 px-0'), set::formClass('form-watched gap-3'), set::bodyClass('think-step-form'), set::actions($actions), formHidden('type', $this->prop('type')), $this->buildFormItem() ); } /** * @return \zin\wg|\zin\node|mixed[] */ protected function build() { list($isResult, $step, $isRun) = $this->prop(array('isResult', 'step', 'isRun')); $questionType = ''; if($isResult && isset($step->options->questionType)) $questionType = $step->options->questionType; $content = $isRun ? div ( setClass('w-full col bg-white items-center pt-4 pb-10 px-8 mb-4'), div ( setStyle(array('max-width' => '878px')), setClass('w-full'), $this->buildDetail(), $this->buildDetailTip() ) ) : div ( $questionType == 'tableInput' ? setStyle(array('min-width' => '220px')) : null, $this->buildDetail(), $this->buildDetailTip() ); return $this->prop('mode') == 'detail' ? $content : $this->buildForm(); } }