diff --git a/module/tutorial/control.php b/module/tutorial/control.php index 7ebeafb5e9..941d921ad0 100644 --- a/module/tutorial/control.php +++ b/module/tutorial/control.php @@ -32,13 +32,12 @@ class tutorial extends control if($_POST) { $account = $this->app->user->account; - $setting = $_POST['tasks']; + $setting = $_POST['finish']; - if(empty($setting)) $this->send(array('result' => 'fail')); $this->loadModel('setting')->setItem("$account.tutorial.tasks.setting", $setting); $this->send(array('result' => 'success')); } - $setting = $this->config->tasks->setting; + $setting = $this->config->tutorial->tasks->setting; if($this->viewType === 'json') { diff --git a/module/tutorial/css/index.css b/module/tutorial/css/index.css index 0b9e37ed20..db76743656 100644 --- a/module/tutorial/css/index.css +++ b/module/tutorial/css/index.css @@ -55,7 +55,8 @@ #tasks > li.active > a, #tasks > li.active.finish > a {box-shadow: inset 2px 0 0 #114f8e; border-color: #ddd; border-left-color: #114f8e; color: #114f8e; background: #EBF2F9} #tasks > li.finish > a:hover, #tasks > li.active > a:hover {background-color: #f1f1f1} -#taskModalBack {position: absolute; top: 0; left: 0; bottom: 0; right: 0; background: #fff; opacity: .6; transition: opacity .4s; opacity: 0; display: none} +#taskModalBack {position: absolute; top: 0; left: 0; bottom: 0; right: 0; background: #fff; transition: opacity .4s; opacity: 0; display: none} +#taskModalBack.in {filter: alpha(opacity=60); opacity: 0.6;} #taskModal {width: 500px; position: absolute; background: #38B03F; color: #fff; text-align: center; overflow: hidden; transform: scale(.5) translate(0, 200px) rotateX(120deg); transition: transform .4s, opacity .4s; opacity: 0; transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); top: 0; padding: 30px; left: 50%; margin-left: -250px; top: 20%; box-shadow: 0 3px 9px rgba(0,0,0,.5); display: none} #taskModal.in {transform: scale(1) translate(0) rotateX(0); opacity: 1} #taskModal h3 {margin-bottom: 20px} @@ -64,3 +65,8 @@ #taskModal .start-icon > .icon-front {color: #38B03F; width: 60px; height: 60px; line-height: 60px; position: absolute; left: 0; top: 0; font-size: 28px;} #taskModal .start-icon > .icon-back {font-size: 56px; color: #fff; line-height: 60px;} #taskModal .btn-success {border-color: #DDF4DF} +#taskModal > .close {position: absolute; right: 15px; top: 10px;} +#taskModal > .finish-all {display: none} +#taskModal > .finish {display: block} +#taskModal.show-all > .finish-all {display: block} +#taskModal.show-all > .finish {display: none} diff --git a/module/tutorial/lang/zh-cn.php b/module/tutorial/lang/zh-cn.php index d36426fcdc..c1d7a27c6b 100644 --- a/module/tutorial/lang/zh-cn.php +++ b/module/tutorial/lang/zh-cn.php @@ -26,6 +26,9 @@ $lang->tutorial->atTargetPage = '已在 目 $lang->tutorial->reloadTargetPage = '重新载入'; $lang->tutorial->target = '目标'; $lang->tutorial->tagetPageTip = '按此指示打开【%s】页面'; +$lang->tutorial->requiredTip = '【%s】为必填项'; +$lang->tutorial->congratulateTask = '恭喜,你完成了任务 【】!'; +$lang->tutorial->serverErrorTip = '发生了一些错误。'; $lang->tutorial->tasks = array(); @@ -55,4 +58,4 @@ $lang->tutorial->tasks['createTask']['desc'] = "

将项目需求分解为任 $lang->tutorial->tasks['createBug'] = array('title' => '提Bug'); $lang->tutorial->tasks['createBug']['nav'] = array('module' => 'bug', 'method' => 'create', 'menuModule' => 'qa', 'menu' => 'bug', 'target' => '.btn-bug-create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '提Bug'); -$lang->tutorial->tasks['createBug']['desc'] = "

在系统中提交一个Bug:

"; +$lang->tutorial->tasks['createBug']['desc'] = "

在系统中提交一个Bug:

"; diff --git a/module/tutorial/view/index.html.php b/module/tutorial/view/index.html.php index 151133b5f7..125ce4df1b 100644 --- a/module/tutorial/view/index.html.php +++ b/module/tutorial/view/index.html.php @@ -18,10 +18,16 @@
+

tutorial->congratulation ?>

-   tutorial->exit ?> +   tutorial->exit ?> +
+
+
+

tutorial->congratulateTask ?>

+
@@ -101,23 +107,48 @@ $(function() var lang = { tagetPageTip: 'tutorial->tagetPageTip ?>', - target : 'tutorial->taget ?>' + target : 'tutorial->taget ?>', + requiredTip : 'tutorial->requiredTip ?>' } - console.log('TASKS', tasks); - console.log('SETTING', setting); - var $tasks = $('#tasks'), $task = $('#task'), $openTaskPage = $('#openTaskPage'), - $finish = $('#finish'); - var totalCount = $tasks.length; + $finish = $('#finish'), + $modal = $('#taskModal'), + $modalBack = $('#taskModalBack'); + var totalCount = $tasks.length, finishCount = 0; var iWindow = window.frames['iframePage']; var iframe = $('#iframePage').get(0); - var checkTaskId = null; + var checkTaskId = null, modalShowTaskId; var $lastTooltip; + var showModal = function(showAll) + { + clearTimeout(modalShowTaskId); + $modal.show(); + $modalBack.show(); + $modal.toggleClass('show-all', showAll); + modalShowTaskId = setTimeout(function() + { + $modal.addClass('in'); + $modalBack.addClass('in'); + }, 10); + }; + + var hideModal = function() + { + clearTimeout(modalShowTaskId); + $modal.removeClass('in'); + $modalBack.removeClass('in'); + modalShowTaskId = setTimeout(function() + { + $modal.hide(); + $modalBack.hide(); + }, 450); + }; + var highlight = function($e, callback) { $e = $e.first(); @@ -128,8 +159,44 @@ $(function() var finishTask = function() { - $task.addClass('finish').find('[data-target]').removeClass('active').addClass('finish'); - alert('you finish task: ' + JSON.stringify(task)); + var task = tasks[current]; + if(task) + { + setting[current] = true; + var postData = []; + $.each(setting, function(name, value) {if(value) postData.push(name);}); + + $.post('', {finish: postData.join(',')}, function(e) + { + if(e.result === 'success') + { + $task.addClass('finish').find('[data-target]').removeClass('active').addClass('finish'); + updateUI(); + showModal(finishCount >= totalCount); + } + else + { + setting[current] = false; + alert('tutorial->serverErrorTip ?>'); + } + }, 'json').error(function() {alert(lang.timeout)}); + } + }; + + var resetTasks = function() + { + $.post('', {finish: ''}, function(e) + { + if(e.result === 'success') + { + setting = {}; + updateUI(); + } + else + { + alert('tutorial->serverErrorTip ?>'); + } + }, 'json').error(function() {alert(lang.timeout)}); }; var showToolTip = function($e, text, options) @@ -149,16 +216,22 @@ $(function() $e.tooltip('show'); }; - var checkTask = function() + var tryCheckTask = function() { - if(!(iWindow && iWindow.config && iWindow.$)) - { - checkTaskId = setTimeout(checkTask, 1000); - return; - } - if(checkTaskId) clearTimeout(checkTaskId); + if(!(iWindow && iWindow.config && iWindow.$)) + { + checkTaskId = setTimeout(tryCheckTask, 1000); + } + else + { + checkTaskId = setTimeout(checkTask, 200); + } + }; + + var checkTask = function() + { var task = tasks[current]; var $$ = iWindow.$; var pageConfig = iWindow.config; @@ -195,14 +268,13 @@ $(function() { fieldSelector += ',' + '#' + requiredId; var $required = $$('#' + requiredId); - console.log('check', requiredId, $required.val(), $required); if($required.length) { var val = $required.val(); if(val === undefined || val === null || val === '') { targetStatus.form = false; - targetStatus.waitFeild = $required; + if(!targetStatus.waitFeild) targetStatus.waitFeild = $required; } } }); @@ -212,7 +284,7 @@ $(function() if(!$form.data('bindCheckTaskEvent')) { $form.off('submit .tutorial'); - $form.on('change.tutorial', fieldSelector, checkTask); + $form.on('change.tutorial', fieldSelector, tryCheckTask); var onSubmit = function(e) { var status = checkTask(); @@ -220,8 +292,11 @@ $(function() { if(status.waitFeild) { + var feildName = status.waitFeild.closest('td').prev('th').text(); + if(feildName) showToolTip(status.waitFeild, lang.requiredTip.replace('%s', feildName)); highlight(status.waitFeild, function() { setTimeout(function() { + showToolTip($formWrapper, $formTarget.text()); highlight($formWrapper); }, 2000); }); @@ -291,7 +366,7 @@ $(function() var onIframeLoad = function() { iWindow = window.frames['iframePage']; - checkTask(); + tryCheckTask(); var title = (iWindow.$ ? iWindow.$('head > title').text() : '') + $('head > title').text(); var url = createLink('tutorial', 'index', 'referer=' + Base64.encode(iWindow.location.href) + '&task=' + current); window.history.replaceState({}, title, url); @@ -300,7 +375,6 @@ $(function() var openIframePage = function(url) { url = url || tasks[current].url; - console.log('open', url); try { iWindow.location.replace(url); @@ -313,6 +387,8 @@ $(function() var showTask = function(taskName) { + hideModal(); + taskName = taskName || current; current = taskName; @@ -321,22 +397,23 @@ $(function() if(!task) return; var $li = $tasks.children('li').removeClass('active').filter('[data-name="' + taskName + '"]').addClass('active'); - $task.find('.task-name-current').text(task.title); - $task.find('.task-id-current').text(task.id); $task.toggleClass('finish', task.finish); - $task.find('.task-desc').html(task.desc).find('.task-nav').addClass('btn-open-target-page'); - $task.find('.task-page-name').text(task.nav.targetPageName || lang.target); + $('.task-name-current').text(task.title); + $('.task-id-current').text(task.id); + $('.task-desc').html(task.desc).find('.task-nav').addClass('btn-open-target-page'); + $('.task-page-name').text(task.nav.targetPageName || lang.target); var $prev = $li.prev('li'), $next = $li.next('li'); $('.btn-prev-task').toggleClass('hidden', !$prev.length).data('name', $prev.data('name')); $('.btn-next-task').toggleClass('hidden', !$next.length).data('name', $next.data('name')); - checkTask(); + tryCheckTask(); }; var updateUI = function() { - var currentTask, finishCount = 0; + var currentTask; + finishCount = 0 $tasks.children('li').each(function(idx) { var $li = $(this); @@ -354,10 +431,12 @@ $(function() $finish.toggleClass('show', finishCount >= totalCount); $('.task-num-finish').text(finishCount); + if(finishCount >= totalCount) current = $tasks.children('li').first().data('name'); showTask(current); }; updateUI(); + if(finishCount >= totalCount) showModal(true); $(document).on('click', '.btn-task', function() { @@ -365,6 +444,10 @@ $(function() }).on('click', '.btn-open-target-page', function() { openIframePage(); + }).on('click', '.btn-reset-tasks', function() + { + hideModal(); + resetTasks(); }); iframe.onload = iframe.onreadystatechange = function() @@ -374,6 +457,10 @@ $(function() }; iWindow.onload = onIframeLoad; + + $modal.on('click', '.close', hideModal); + + $('[data-toggle="tooltip"]').tooltip(); }); diff --git a/www/theme/default/style.css b/www/theme/default/style.css index 275638ab9c..9ff127b47d 100644 --- a/www/theme/default/style.css +++ b/www/theme/default/style.css @@ -725,6 +725,6 @@ body {font-size: 13px; color:#141414;padding-bottom: 40px;} #helpContent .load-error {padding: 20px; display: none} #helpContent.show-error .load-error {display: block} -.hl-tutorial {position: relative!important; z-index: 1010!important; box-shadow: 0 0 0 0px rgba(0,0,0,0)!important; transition: box-shadow 2s cubic-bezier(.175,.885,.32,1)!important;} +.hl-tutorial {position: relative!important; z-index: 1010!important; box-shadow: 0 0 0 0px #000!important; transition: box-shadow 1s!important;} .hl-tutorial.hl-in {box-shadow: 0 0 20px 0 #FFF0D5, 0 0 0 2px #F1A325, 0 0 0 2000px rgba(0,0,0,.2)!important} .hl-tutorial.hl-in:hover {box-shadow: 0 0 30px 0 #FFF0D5, 0 0 0 5px #F1A325, 0 0 0 2000px rgba(0,0,0,.3)!important}