From 1970ec2c072c7c441e5d876c6c9a154dbfb36819 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Wed, 10 May 2023 11:21:17 +0800 Subject: [PATCH 1/7] * Modify create project page interaction style. --- module/project/js/common.ui.js | 111 ++++++++++++++++++++++++++++++ module/project/js/create.ui.js | 27 ++++++++ module/project/ui/create.html.php | 58 +++++++++------- 3 files changed, 170 insertions(+), 26 deletions(-) create mode 100644 module/project/js/common.ui.js create mode 100644 module/project/js/create.ui.js diff --git a/module/project/js/common.ui.js b/module/project/js/common.ui.js new file mode 100644 index 0000000000..b04dcb587e --- /dev/null +++ b/module/project/js/common.ui.js @@ -0,0 +1,111 @@ +/** + * 计算两个时间的天数。 + * Compute delta of two days. + * + * @param string date1 + * @param string date2 + * @access public + * @return int + */ +function computeDaysDelta(date1, date2) +{ + date1 = convertStringToDate(date1); + date2 = convertStringToDate(date2); + delta = (date2 - date1) / (1000 * 60 * 60 * 24) + 1; + + if(isNaN(delta)) return; + + weekEnds = 0; + for(i = 0; i < delta; i++) + { + if((weekend == 2 && date1.getDay() == 6) || date1.getDay() == 0) weekEnds ++; + date1 = date1.valueOf(); + date1 += 1000 * 60 * 60 * 24; + date1 = new Date(date1); + } + return delta - weekEnds; +} + +/** + * 计算可用工作日天数。 + * Compute work days. + * + * @param string currentID + * @access public + * @return void + */ +function computeWorkDays(currentID) +{ + isBactchEdit = false; + if(currentID) + { + index = currentID.replace('begins[', ''); + index = index.replace('ends[', ''); + index = index.replace(']', ''); + if(!isNaN(index)) isBactchEdit = true; + } + + if(isBactchEdit) + { + beginDate = $('#begins\\[' + index + '\\]').val(); + endDate = $('#ends\\[' + index + '\\]').val(); + } + else + { + beginDate = $('#begin').val(); + endDate = $('#end').val(); + + var begin = new Date(beginDate.replace(/-/g,"/")); + var end = new Date(endDate.replace(/-/g,"/")); + var time = end.getTime() - begin.getTime(); + var days = parseInt(time / (1000 * 60 * 60 * 24)) + 1; + if(days != $("input:radio[name='delta']:checked").val()) $("input:radio[name='delta']:checked").attr('checked', false); + if(endDate == longTime) $("#delta999").prop('checked', true); + } + + if(beginDate && endDate) + { + if(isBactchEdit) $('#dayses\\[' + index + '\\]').val(computeDaysDelta(beginDate, endDate)); + if(!isBactchEdit) $('#days').val(computeDaysDelta(beginDate, endDate)); + } + else if($('input[checked="true"]').val()) + { + computeEndDate(); + } + outOfDateTip(isBactchEdit ? index : 0); +} + +/** + * 计算并设置计划完成时间。 + * Compute the end date for project. + * + * @param int delta + * @access public + * @return void + */ +function computeEndDate(delta) +{ + beginDate = $('#begin').val(); + if(!beginDate) return; + + delta = parseInt(delta); + if(delta == 999) + { + $('#end').val(longTime).trigger('mousedown'); + $('#daysBox').addClass('hidden'); + $('#days').val(0).trigger('mousedown'); + outOfDateTip(); + return false; + } + $('#daysBox').removeClass('hidden'); + beginDate = convertStringToDate(beginDate); + if((delta == 7 || delta == 14) && (beginDate.getDay() == 1)) + { + delta = (weekend == 2) ? (delta - 2) : (delta - 1); + } + + endDate = $.formatDate(beginDate.addDays(delta - 1), 'yyyy-MM-dd'); + $('#end').val(endDate).datetimepicker('update').trigger('mousedown'); + computeWorkDays(); + $('#days').trigger('mousedown'); +} diff --git a/module/project/js/create.ui.js b/module/project/js/create.ui.js new file mode 100644 index 0000000000..5349beb533 --- /dev/null +++ b/module/project/js/create.ui.js @@ -0,0 +1,27 @@ +/** + * 处理项目类型改变的交互。 + * Handle project type change style. + * + * @param string $type + * @access public + * @return void + */ +function changeType(type) +{ + $('.project-type-1, .project-type-0').removeClass('primary-pale'); + $('.project-type-' + type).addClass('primary-pale'); + $('input[name=hasProduct]').val(type); +} + +/** + * 设置计划结束时间。 + * Set plan end date. + * + * @access public + * @return void + */ +function setDate() +{ + const delta = $('input[name=delta]:checked').val(); + computeEndDate(delta); +} diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index 828143061c..c752e0d615 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -90,8 +90,8 @@ formPanel set::label($lang->project->code), set::strong(true), set::placeholder($lang->project->inputProjectCode) - ) : NULL, - ($model == 'waterfall') ? NULL : formGroup + ) : null, + ($model == 'waterfall') ? null : formGroup ( set::width('1/2'), set::name('multiple'), @@ -99,7 +99,7 @@ formPanel set::control(array('type' => 'radioList', 'inline' => true)), set::items($lang->project->multipleList), set::value($multiple), - empty($copyProjectID) ? NULL : formHidden('multiple', $multiple) + empty($copyProjectID) ? null : formHidden('multiple', $multiple) ), formGroup ( @@ -144,7 +144,7 @@ formPanel 'suffix' => $lang->project->tenThousandYuan, 'suffixWidth' => 60, )), - $parentProgram ? NULL : formHidden('budgetUnit', $config->project->defaultCurrency) + $parentProgram ? null : formHidden('budgetUnit', $config->project->defaultCurrency) ), formGroup ( @@ -167,6 +167,7 @@ formPanel ( set::name('begin'), set::type('date'), + set('id', 'begin'), set::value(date('Y-m-d')), set::placeholder($lang->project->begin), set::required(true), @@ -177,6 +178,7 @@ formPanel input ( set::name('end'), + set('id', 'end'), set::type('date'), set::placeholder($lang->project->end), set::required(true), @@ -187,33 +189,37 @@ formPanel ), formGroup ( - set::width('1/4'), - inputGroup + set::width('1/2'), + radioList ( - $lang->execution->days, - setClass('has-suffix'), - input - ( - set::name('days'), - set::required(true), - ), - div - ( - setClass('input-control-suffix z-50'), - $lang->project->day - ) + on::change('setDate'), + set::name('delta'), + set::inline(true), + set::items($lang->project->endList) ) ), - formGroup + ), + formGroup + ( + set::label($lang->project->days), + set::width('1/2'), + inputGroup ( - set::width('1/4'), - set::name('delta'), - set::control(array('type' => 'checkList', 'inline' => true)), - set::items(array('999' => $lang->project->endList['999'])) - ), + setClass('has-suffix'), + input + ( + set::name('days'), + set::required(true), + ), + div + ( + setClass('input-control-suffix z-50'), + $lang->project->day + ) + ) ), /* TODO handle !empty($products) */ - $products ? NULL : + $products ? null : formRow ( formGroup @@ -253,7 +259,7 @@ formPanel select ( set::name('plans[][]'), - set::items(NULL), + set::items(null), set::multiple(false) ) ) From 763aacf17e0c39a3d92f47f7246ca91795cafd9d Mon Sep 17 00:00:00 2001 From: jukui Date: Wed, 10 May 2023 11:25:15 +0800 Subject: [PATCH 2/7] * Modify getlist function test case for todo model. --- module/todo/test/model/getlist.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/module/todo/test/model/getlist.php b/module/todo/test/model/getlist.php index 06a89b43c3..d21b6805a5 100755 --- a/module/todo/test/model/getlist.php +++ b/module/todo/test/model/getlist.php @@ -68,10 +68,11 @@ $thismonth = $todo->getListTest($typeList[4]) == $thisMonthNum ? '1' : '0'; $lastmonth = $todo->getListTest($typeList[5]) == $lastMonthNum ? '1' : '0'; $thisseason = $todo->getListTest($typeList[6]) == $thisSeasonNum ? '1' : '0'; -r($thisweek) && p() && e('1'); // 获取type为thisweek 当前用户的代办数量 -r($lastweek) && p() && e('1'); // 获取type为lastweek 当前用户的代办数量 -r($thismonth) && p() && e('1'); // 获取type为thismonth 当前用户的代办数量 -r($lastmonth) && p() && e('1'); // 获取type为lastmonth 当前用户的代办数量 +r($thisweek) && p() && e('1'); // 获取type为thisweek 当前用户的代办数量 +r($lastweek) && p() && e('1'); // 获取type为lastweek 当前用户的代办数量 +r($thismonth) && p() && e('1'); // 获取type为thismonth 当前用户的代办数量 +r($lastmonth) && p() && e('1'); // 获取type为lastmonth 当前用户的代办数量 +r($thisseason) && p() && e('1'); // 获取type为thisseason 当前用户的代办数量 r($todo->getListTest($typeList[0])) && p() && e('1'); // 获取type为today 当前用户的代办数量 r($todo->getListTest($typeList[1])) && p() && e('2'); // 获取type为yesterday 当前用户的代办数量 From 1b9b3e53c78869b78ff852cd25f77b659f882943 Mon Sep 17 00:00:00 2001 From: guofeilong Date: Wed, 10 May 2023 11:29:32 +0800 Subject: [PATCH 3/7] * Fix notes space problem in function project model update . --- module/project/model.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/module/project/model.php b/module/project/model.php index 649fa35c04..31cf98ecbe 100755 --- a/module/project/model.php +++ b/module/project/model.php @@ -1500,12 +1500,12 @@ class projectModel extends model /* 更新项目的关联信息。*/ /* Update relation info of this project. */ - $this->updateUserView($projectID, $project->acl); // 更新用户视图。 - $this->updateShadowProduct($project, $oldProject); // 更新影子产品关联信息。 - $this->updateWhitelist($project, $oldProject); // 更新关联的白名单列表 - $this->updateProductStage($projectID, $oldProject->stageBy); // 更新关联的所有产品的阶段。 + $this->updateUserView($projectID, $project->acl); // 更新用户视图。 + $this->updateShadowProduct($project, $oldProject); // 更新影子产品关联信息。 + $this->updateWhitelist($project, $oldProject); // 更新关联的白名单列表 + $this->updateProductStage($projectID, $oldProject->stageBy); // 更新关联的所有产品的阶段。 - $this->file->updateObjectID($this->post->uid, $projectID, 'project'); // 通过uid更新文件id。 + $this->file->updateObjectID($this->post->uid, $projectID, 'project'); // 通过uid更新文件id。 if($oldProject->parent != $project->parent) $this->loadModel('program')->fixPath($projectID, $project->parent, $oldProject->path, $oldProject->grade); // 更新项目从属路径。 if(empty($oldProject->multiple) and $oldProject->model != 'waterfall') $this->loadModel('execution')->syncNoMultipleSprint($projectID); // 无迭代的非瀑布项目需要更新。 From 0474b90e3b54ca9c2448d4685e6afa2f1a7b59b3 Mon Sep 17 00:00:00 2001 From: zhouxin Date: Wed, 10 May 2023 03:29:34 +0000 Subject: [PATCH 4/7] * Add unit test for checkHasChildren of taskTao. --- module/task/test/tao/checkhaschildren.php | 35 +++++++++++++++++++ .../task_checkhaschildren.yaml | 9 +++++ 2 files changed, 44 insertions(+) create mode 100755 module/task/test/tao/checkhaschildren.php create mode 100644 module/task/test/tao/yaml/checkhaschildren/task_checkhaschildren.yaml diff --git a/module/task/test/tao/checkhaschildren.php b/module/task/test/tao/checkhaschildren.php new file mode 100755 index 0000000000..17f96d9b37 --- /dev/null +++ b/module/task/test/tao/checkhaschildren.php @@ -0,0 +1,35 @@ +#!/usr/bin/env php +config('task_checkhaschildren')->gen(12); + +/** + +title=taskModel->checkHasChildren(); +timeout=0 +cid=1 + +*/ + +$task = $tester->loadModel('task'); + +$parentTaskList = array(1, 2, 3); +$aloneTaskList = array(4, 5, 6); +$childTaskList = array(7, 8, 9, 10, 11, 12); + +r($task->checkhaschildren($parentTaskList[0])) && p() && e('1'); // 测试任务1是否为父任务 +r($task->checkhaschildren($parentTaskList[1])) && p() && e('1'); // 测试任务2是否为父任务 +r($task->checkhaschildren($parentTaskList[2])) && p() && e('1'); // 测试任务3是否为父任务 + +r($task->checkhaschildren($aloneTaskList[0])) && p() && e('0'); // 测试任务4是否为父任务 +r($task->checkhaschildren($aloneTaskList[1])) && p() && e('0'); // 测试任务5是否为父任务 +r($task->checkhaschildren($aloneTaskList[2])) && p() && e('0'); // 测试任务6是否为父任务 + +r($task->checkhaschildren($childTaskList[0])) && p() && e('0'); // 测试任务7是否为父任务 +r($task->checkhaschildren($childTaskList[1])) && p() && e('0'); // 测试任务8是否为父任务 +r($task->checkhaschildren($childTaskList[2])) && p() && e('0'); // 测试任务9是否为父任务 +r($task->checkhaschildren($childTaskList[3])) && p() && e('0'); // 测试任务10是否为父任务 +r($task->checkhaschildren($childTaskList[4])) && p() && e('0'); // 测试任务11是否为父任务 +r($task->checkhaschildren($childTaskList[5])) && p() && e('0'); // 测试任务12是否为父任务 diff --git a/module/task/test/tao/yaml/checkhaschildren/task_checkhaschildren.yaml b/module/task/test/tao/yaml/checkhaschildren/task_checkhaschildren.yaml new file mode 100644 index 0000000000..5e6d1fcefd --- /dev/null +++ b/module/task/test/tao/yaml/checkhaschildren/task_checkhaschildren.yaml @@ -0,0 +1,9 @@ +--- +title: zt_task +author: auto_checkhaschildren +version: "1.0" +fields: +- field: parent + range: "`-1`{3},0{3},1,2{2},3{3}" +... + From 9db3f7027fbf71ceb5a9d33c4c804bae201d9088 Mon Sep 17 00:00:00 2001 From: sunhao Date: Wed, 10 May 2023 11:40:55 +0800 Subject: [PATCH 5/7] * zin: refactor. --- www/js/zui3/zin.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/www/js/zui3/zin.js b/www/js/zui3/zin.js index 7a19a68122..07cf6e3bdc 100644 --- a/www/js/zui3/zin.js +++ b/www/js/zui3/zin.js @@ -304,7 +304,7 @@ function loadTable(url, id) { url = url || currentAppUrl; - id = id || $('.dtable').attr('id') || 'dtable'; + id = id || $('.dtable').attr('id') || 'dtable'; if(!id) return; fetchContent(url, 'table/#' + id + ':type=json&data=props,#featureBar>*', {id: '#' + id, target: '#' + id}); @@ -316,7 +316,7 @@ if (!selector && url.includes(' ')) { const parts = url.split(' ', 2); - url = parts[0]; + url = parts[0]; selector = parts[1]; } if(DEBUG) console.log('[APP] ', 'load:', url); @@ -442,8 +442,8 @@ if(!result.name.length) { if(result.id.length) result.name = result.id; - else if(result.tag) result.name = result.tag; - else result.name = selector; + else if(result.tag) result.name = result.tag; + else result.name = selector; } result.select = [result.tag, result.id.length ? '#' + result.id : '', result.class.length ? '.' + result.class.join('.') : ''].join(''); From 5852b5ad7f14c5d323c53ebf50899d96ee9281ed Mon Sep 17 00:00:00 2001 From: sunhao Date: Wed, 10 May 2023 11:41:42 +0800 Subject: [PATCH 6/7] * zin: fix inner selector not work with x-zin-options. --- lib/zin/core/dom.class.php | 34 +++++++++++++++++++++++++--------- lib/zin/wg/pagebase/v1.php | 2 +- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/lib/zin/core/dom.class.php b/lib/zin/core/dom.class.php index 636db1315b..0cbe37ebe8 100644 --- a/lib/zin/core/dom.class.php +++ b/lib/zin/core/dom.class.php @@ -37,8 +37,11 @@ class dom public $buildList = null; + public $buildListInner = false; + /** * Construct the dom object. + * * @param wg $wg * @param array $children * @param array|string|object $selectors @@ -120,6 +123,7 @@ class dom { return $this->wg->isMatch($selector); } + /** * Build the children dom list. * @access public @@ -127,7 +131,7 @@ class dom */ public function build() { - if($this->buildList !== null) return $this->buildList; + if($this->buildList !== null && $this->buildListInner === $this->renderInner) return $this->buildList; if(empty($this->selectors) && !empty($this->dataCommands)) { @@ -144,7 +148,8 @@ class dom if(!empty($this->selectors)) $list = static::filter($list, $this->selectors); - $this->buildList = $list; + $this->buildList = $list; + $this->buildListInner = $this->renderInner; return $list; } @@ -226,7 +231,7 @@ class dom { foreach($this->dataCommands as $name => $command) { - $output[] = array('name' => $name, 'data' => data($command)); + $output[] = array('name' => $name, 'data' => data($command), 'type' => 'command'); } } @@ -324,6 +329,7 @@ class dom /** * Filter the dom list with selector. + * * @param array $list * @param object $selector * @param array $filteredList @@ -341,11 +347,13 @@ class dom if($item->wg->isMatch($selector)) { - $item->renderInner = $selector->inner ?? false; - $item->renderType = $selector->type ?? null; - $item->dataGetters = $selector->data ?? null; - $filteredList[] = $item->wg->gid; - $results[] = $item; + $item->selector = $selector; + $item->renderInner = isset($selector->inner) ? $selector->inner : false; + $item->renderType = isset($selector->type) ? $selector->type : null; + $item->dataGetters = isset($selector->data) ? $selector->data : null; + + $filteredList[] = $item->wg->gid; + $results[] = $item; } else { @@ -361,6 +369,14 @@ class dom return $results; } + /** + * Filter the dom list with selectors. + * + * @param array $domList + * @param array $selectors + * @access public + * @return array + */ public static function filter(&$domList, $selectors) { if(empty($selectors)) return $domList; @@ -370,7 +386,7 @@ class dom foreach($selectors as $selector) { $results = static::filterList($domList, $selector, $filteredList); - if(!empty($results)) $list[$selector->name] = $results; + $list[$selector->name] = $results; } return $list; diff --git a/lib/zin/wg/pagebase/v1.php b/lib/zin/wg/pagebase/v1.php index 1b467f6b6e..aa23facb11 100644 --- a/lib/zin/wg/pagebase/v1.php +++ b/lib/zin/wg/pagebase/v1.php @@ -73,7 +73,7 @@ class pageBase extends wg h::head ( html($metas), - html("$title"), + h::title($title), $this->block('headBefore'), $zui ? h::importCss($config->zin->zuiPath . 'zui.zentao.css', set::id('zuiCSS')) : null, $zui ? h::importJs($config->zin->zuiPath . 'zui.zentao.umd.cjs', set::id('zuiJS')) : null, From dbb8379033c8285047d048399ea6b4d63a480d96 Mon Sep 17 00:00:00 2001 From: jukui Date: Wed, 10 May 2023 13:06:29 +0800 Subject: [PATCH 7/7] * Modify getList function test case remark for todo model. --- module/todo/test/model/getlist.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/module/todo/test/model/getlist.php b/module/todo/test/model/getlist.php index d21b6805a5..c4f2f3c66a 100755 --- a/module/todo/test/model/getlist.php +++ b/module/todo/test/model/getlist.php @@ -68,15 +68,15 @@ $thismonth = $todo->getListTest($typeList[4]) == $thisMonthNum ? '1' : '0'; $lastmonth = $todo->getListTest($typeList[5]) == $lastMonthNum ? '1' : '0'; $thisseason = $todo->getListTest($typeList[6]) == $thisSeasonNum ? '1' : '0'; -r($thisweek) && p() && e('1'); // 获取type为thisweek 当前用户的代办数量 -r($lastweek) && p() && e('1'); // 获取type为lastweek 当前用户的代办数量 -r($thismonth) && p() && e('1'); // 获取type为thismonth 当前用户的代办数量 -r($lastmonth) && p() && e('1'); // 获取type为lastmonth 当前用户的代办数量 -r($thisseason) && p() && e('1'); // 获取type为thisseason 当前用户的代办数量 +r($thisweek) && p() && e('1'); // 获取type为thisweek 当前用户的待办数量 +r($lastweek) && p() && e('1'); // 获取type为lastweek 当前用户的待办数量 +r($thismonth) && p() && e('1'); // 获取type为thismonth 当前用户的待办数量 +r($lastmonth) && p() && e('1'); // 获取type为lastmonth 当前用户的待办数量 +r($thisseason) && p() && e('1'); // 获取type为thisseason 当前用户的待办数量 -r($todo->getListTest($typeList[0])) && p() && e('1'); // 获取type为today 当前用户的代办数量 -r($todo->getListTest($typeList[1])) && p() && e('2'); // 获取type为yesterday 当前用户的代办数量 -r($todo->getListTest($typeList[7])) && p() && e('9'); // 获取type为thisyear 当前用户的代办数量 -r($todo->getListTest($typeList[8])) && p() && e('0'); // 获取type为future 当前用户的代办数量 -r($todo->getListTest($typeList[9])) && p() && e('9'); // 获取type为before 当前用户的代办数量 -r($todo->getListTest($typeList[10])) && p() && e('0'); // 获取type为cycle 当前用户的代办数量 +r($todo->getListTest($typeList[0])) && p() && e('1'); // 获取type为today 当前用户的待办数量 +r($todo->getListTest($typeList[1])) && p() && e('2'); // 获取type为yesterday 当前用户的待办数量 +r($todo->getListTest($typeList[7])) && p() && e('9'); // 获取type为thisyear 当前用户的待办数量 +r($todo->getListTest($typeList[8])) && p() && e('0'); // 获取type为future 当前用户的待办数量 +r($todo->getListTest($typeList[9])) && p() && e('9'); // 获取type为before 当前用户的待办数量 +r($todo->getListTest($typeList[10])) && p() && e('0'); // 获取type为cycle 当前用户的待办数量