diff --git a/db/update9.5.1.sql b/db/update9.5.1.sql index 50c22de4a3..7223eb3bf6 100644 --- a/db/update9.5.1.sql +++ b/db/update9.5.1.sql @@ -94,4 +94,4 @@ CREATE TABLE `zt_score` ( KEY `method` (`method`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('*/5', '*', '*', '*', '*', 'moduleName=webhook&methodName=asyncSend', '异步发送Webhook', 'zentao', 0, 'normal', '0000-00-00 00:00:00'); +INSERT INTO `zt_cron` (`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('*/5', '*', '*', '*', '*', 'moduleName=webhook&methodName=asyncSend', '异步发送Webhook', 'zentao', 1, 'normal', '0000-00-00 00:00:00'); diff --git a/lib/base/dao/dao.class.php b/lib/base/dao/dao.class.php index 24592083f8..c772e56f42 100644 --- a/lib/base/dao/dao.class.php +++ b/lib/base/dao/dao.class.php @@ -172,6 +172,15 @@ class baseDAO */ static public $cache = array(); + /** + * 缓存过期时间 + * The cache timeout. + * + * @var float + * @access public + */ + public $cacheTimeout = 60; + /** * 构造方法。 * The construct method. @@ -757,6 +766,7 @@ class baseDAO try { + if($this->table) unset(dao::$cache[$this->table]); $this->reset(); return $this->dbh->exec($sql); } @@ -779,26 +789,29 @@ class baseDAO */ public function fetch($field = '') { - $sql = $this->processSQL(); - $key = md5($sql); - if(isset(dao::$cache['fetch'][$key])) + $sql = $this->processSQL(); + $table = $this->table; + $key = md5($sql); + if(isset(dao::$cache[$table]['fetch'][$key]) and dao::$cache[$table]['fetch'][$key]['time'] <= time() - $this->cacheTimeout) { - if(empty($field)) return $this->getRow(dao::$cache['fetch'][$key]); + if(empty($field)) return $this->getRow(dao::$cache[$table]['fetch'][$key]['data']); - $result = dao::$cache['fetch'][$key]; + $result = dao::$cache[$table]['fetch'][$key]['data']; return $result ? $result->$field : ''; } if(empty($field)) { $data = $this->query()->fetch(); - dao::$cache['fetch'][$key] = $data; + dao::$cache[$table]['fetch'][$key]['data'] = $data; + dao::$cache[$table]['fetch'][$key]['time'] = time(); return $this->getRow($data); } $this->setFields($field); $result = $this->query()->fetch(PDO::FETCH_OBJ); - dao::$cache['fetch'][$key] = $result; + dao::$cache[$table]['fetch'][$key]['data'] = $result; + dao::$cache[$table]['fetch'][$key]['time'] = time(); return $result ? $result->$field : ''; } @@ -813,11 +826,12 @@ class baseDAO */ public function fetchAll($keyField = '') { - $sql = $this->processSQL(); - $key = md5($sql . $keyField); - if(isset(dao::$cache['fetchAll'][$key])) + $sql = $this->processSQL(); + $table = $this->table; + $key = md5($sql . $keyField); + if(isset(dao::$cache[$table]['fetchAll'][$key]) and dao::$cache[$table]['fetchAll'][$key]['time'] <= time() - $this->cacheTimeout) { - $rows = dao::$cache['fetchAll'][$key]; + $rows = dao::$cache[$table]['fetchAll'][$key]['data']; $result = array(); foreach($rows as $i => $row) $result[$i] = $this->getRow($row); return $result; @@ -828,14 +842,19 @@ class baseDAO { $rows = $stmt->fetchAll(); $result = array(); - dao::$cache['fetchAll'][$key] = $rows; + dao::$cache[$table]['fetchAll'][$key]['data'] = $rows; + dao::$cache[$table]['fetchAll'][$key]['time'] = time(); foreach($rows as $i => $row) $result[$i] = $this->getRow($row); return $result; } $rows = array(); - while($row = $stmt->fetch()) $rows[$row->$keyField] = $this->getRow($row); - dao::$cache['fetchAll'][$key] = $rows; + dao::$cache[$table]['fetchAll'][$key]['time'] = time(); + while($row = $stmt->fetch()) + { + dao::$cache[$table]['fetchAll'][$key]['data'][$row->$keyField] = $row; + $rows[$row->$keyField] = $this->getRow($row); + } return $rows; } @@ -850,12 +869,13 @@ class baseDAO */ public function fetchGroup($groupField, $keyField = '') { - $sql = $this->processSQL(); - $key = md5($sql . $groupField . $keyField); - if(isset(dao::$cache['fetchGroup'][$key])) + $sql = $this->processSQL(); + $table = $this->table; + $key = md5($sql . $groupField . $keyField); + if(isset(dao::$cache[$table]['fetchGroup'][$key]) and dao::$cache[$table]['fetchGroup'][$key]['time'] <= time() - $this->cacheTimeout) { $result = array(); - $groupRows = dao::$cache['fetchGroup'][$key]; + $groupRows = dao::$cache[$table]['fetchGroup'][$key]['data']; foreach($groupRows as $groupField => $rows) { foreach($rows as $keyField => $row) $result[$groupField][$keyField] = $this->getRow($row); @@ -869,7 +889,8 @@ class baseDAO { empty($keyField) ? $rows[$row->$groupField][] = $row : $rows[$row->$groupField][$row->$keyField] = $this->getRow($row); } - dao::$cache['fetchGroup'][$key] = $rows; + dao::$cache[$table]['fetchGroup'][$key]['data'] = $rows; + dao::$cache[$table]['fetchGroup'][$key]['time'] = time(); return $rows; } @@ -890,9 +911,10 @@ class baseDAO $keyField = trim($keyField, '`'); $valueField = trim($valueField, '`'); - $sql = $this->processSQL(); - $key = md5($sql . $keyField . $valueField); - if(isset(dao::$cache["fetchPairs"][$key])) return dao::$cache['fetchPairs'][$key]; + $sql = $this->processSQL(); + $table = $this->table; + $key = md5($sql . $keyField . $valueField); + if(isset(dao::$cache[$table]["fetchPairs"][$key]) and dao::$cache[$table]["fetchPairs"][$key]['time'] <= time() - $this->cacheTimeout) return dao::$cache[$table]['fetchPairs'][$key]['data']; $pairs = array(); $ready = false; @@ -913,7 +935,8 @@ class baseDAO $pairs[$row[$keyField]] = $row[$valueField]; } - dao::$cache['fetchPairs'][$key] = $pairs; + dao::$cache[$table]['fetchPairs'][$key]['data'] = $pairs; + dao::$cache[$table]['fetchPairs'][$key]['time'] = time(); return $pairs; } diff --git a/module/project/control.php b/module/project/control.php index 47eff3bad5..eee780130c 100644 --- a/module/project/control.php +++ b/module/project/control.php @@ -1247,7 +1247,7 @@ class project extends control * @access public * @return void */ - public function kanban($projectID, $orderBy = 'pri_asc') + public function kanban($projectID, $type = 'story', $orderBy = 'pri_asc') { /* Save to session. */ $uri = $this->app->getURI(true); @@ -1260,19 +1260,22 @@ class project extends control $this->project->setMenu($this->projects, $projectID); $project = $this->loadModel('project')->getById($projectID); - $stories = $this->loadModel('story')->getProjectStories($projectID, $orderBy); $tasks = $this->project->getKanbanTasks($projectID, "id"); $bugs = $this->loadModel('bug')->getProjectBugs($projectID); - $stories = $this->project->getKanbanGroupData($stories, $tasks, $bugs); + $stories = $this->loadModel('story')->getProjectStories($projectID, $orderBy); - $this->view->title = $this->lang->project->kanban; - $this->view->position[] = html::a($this->createLink('project', 'browse', "projectID=$projectID"), $project->name); - $this->view->position[] = $this->lang->project->kanban; - $this->view->stories = $stories; - $this->view->realnames = $this->loadModel('user')->getPairs('noletter'); - $this->view->orderBy = $orderBy; - $this->view->projectID = $projectID; - $this->view->project = $project; + $kanbanGroup = $this->project->getKanbanGroupData($stories, $tasks, $bugs, $type); + + $this->view->title = $this->lang->project->kanban; + $this->view->position[] = html::a($this->createLink('project', 'browse', "projectID=$projectID"), $project->name); + $this->view->position[] = $this->lang->project->kanban; + $this->view->stories = $stories; + $this->view->realnames = $this->loadModel('user')->getPairs('noletter'); + $this->view->orderBy = $orderBy; + $this->view->projectID = $projectID; + $this->view->project = $project; + $this->view->type = $type; + $this->view->kanbanGroup = $kanbanGroup; $kanbanSetting = $this->project->getKanbanSetting($projectID); diff --git a/module/project/css/kanban.css b/module/project/css/kanban.css index cae429cd04..1d9ebc48cf 100644 --- a/module/project/css/kanban.css +++ b/module/project/css/kanban.css @@ -63,12 +63,12 @@ table th.col-closed {width:14%} .board {background: #333; color: #f1f1f1; outline: 1px solid rgba(0,0,0,.1); outline-offset: -1px;} .board:hover {outline: 1px solid rgba(0,0,0,.3); color:#fff} -.board-bug-cancel, .board-task-cancel {background: #333; opacity: 0.7;} -.board-bug-wait, .board-task-wait {background: #2b529c;opacity: 0.7;} -.board-task-pause {background: #E48600;opacity: 0.7;} -.board-bug-doing, .board-task-doing {background: #D2322D;opacity: 0.7;} -.board-bug-done, .board-task-done {background: #229F24;opacity: 0.7;} -.board-bug-closed, .board-task-closed {background: #777; opacity: 0.7;} +.board-bug-cancel, .board-task-cancel {background: #333; opacity: 1;} +.board-bug-wait, .board-task-wait {background: #2b529c;opacity: 1;} +.board-task-pause {background: #E48600;opacity: 1;} +.board-bug-doing, .board-task-doing {background: #D2322D;opacity: 1;} +.board-bug-done, .board-task-done {background: #229F24;opacity: 1;} +.board-bug-closed, .board-task-closed {background: #777; opacity: 1;} .board-bug-cancel.inverse, .board-task-cancel.inverse {opacity: 1;} .board-bug-wait.inverse, .board-task-wait.inverse {opacity: 1} diff --git a/module/project/model.php b/module/project/model.php index cb89ef9044..5ceb134028 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -2103,41 +2103,49 @@ class projectModel extends model * @access public * @return array */ - public function getKanbanGroupData($stories, $tasks, $bugs) + public function getKanbanGroupData($stories, $tasks, $bugs, $type = 'story') { - $stories['nostory'] = new stdclass(); + $kanbanGroup = array(); + if($type == 'story') $kanbanGroup = $stories; + foreach($tasks as $task) { - $storyID = $task->storyID; - $status = $task->status; - if(!empty($storyID) and isset($stories[$storyID])) + $groupKey = $type == 'story' ? $task->storyID : $task->$type; + + $status = $task->status; + if(!empty($groupKey) and (($type == 'story' and isset($stories[$groupKey])) or $type != 'story')) { - $stories[$storyID]->tasks[$status][] = $task; + if(!isset($kanbanGroup[$groupKey])) $kanbanGroup[$groupKey] = new stdclass(); + $kanbanGroup[$groupKey]->tasks[$status][] = $task; } else { - $noStoryTasks[$status][] = $task; + $noKeyTasks[$status][] = $task; } } - if(isset($noStoryTasks)) $stories['nostory']->tasks = $noStoryTasks; foreach($bugs as $bug) { - $storyID = $bug->story; + $groupKey = $type == 'finishedBy' ? $bug->resolvedBy : $bug->$type; + $status = $bug->status; $status = $status == 'active' ? 'wait' : ($status == 'resolved' ? ($bug->resolution == 'postponed' ? 'cancel' : 'done') : $status); - if(!empty($storyID) and isset($stories[$storyID])) + if(!empty($groupKey) and (($type == 'story' and isset($stories[$groupKey])) or $type != 'story')) { - $stories[$storyID]->bugs[$status][] = $bug; + if(!isset($kanbanGroup[$groupKey])) $kanbanGroup[$groupKey] = new stdclass(); + $kanbanGroup[$groupKey]->bugs[$status][] = $bug; } else { - $noStoryBugs[$status][] = $bug; + $noKeyBugs[$status][] = $bug; } } - if(isset($noStoryBugs)) $stories['nostory']->bugs = $noStoryBugs; - return $stories; + $kanbanGroup['nokey'] = new stdclass(); + if(isset($noKeyTasks)) $kanbanGroup['nokey']->tasks = $noKeyTasks; + if(isset($noKeyBugs)) $kanbanGroup['nokey']->bugs = $noKeyBugs; + + return $kanbanGroup; } /** diff --git a/module/project/view/kanban.html.php b/module/project/view/kanban.html.php index a8e56ac739..457de5ea64 100644 --- a/module/project/view/kanban.html.php +++ b/module/project/view/kanban.html.php @@ -24,17 +24,21 @@ $account = $this->app->user->account
| + + + task->$type;?> + | @@ -48,6 +52,15 @@ $account = $this->app->user->account @@ -61,7 +74,7 @@ $account = $this->app->user->account
|---|
| @@ -69,12 +82,14 @@ $account = $this->app->user->account | |
|---|---|
|
- id)):?>
+
+
+
assignedTo == $account) echo ' inverse';?>' data-id='id?>'>
+
+
createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', 'class="kanbanFrame" title="' . $story->title . '"');?>
@@ -103,13 +118,20 @@ $account = $this->app->user->account
estimate . 'h ';?>
+
+
+
+
+ |
- tasks[$col])):?>
- tasks[$col] as $task):?>
+ tasks[$col])):?>
+ tasks[$col] as $task):?>
assignedTo == $account) echo ' inverse';?>' data-id='id?>' id='task-id?>'>
app->user->account
$labelClass = $task->status == 'doing' ? 'label-delay-doing' : 'label-delay-wait';
echo "{$lang->task->delayed}";
}
- echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', true), $task->name, '', 'class="kanbanFrame" title="' . $task->name . '"');
+ $childrenAB = empty($task->parent) ? '' : "" . $lang->task->childrenAB . ' ';
+ echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', true), $childrenAB . $task->name, '', 'class="kanbanFrame" title="' . $task->name . '"');
?>
@@ -126,7 +149,7 @@ $account = $this->app->user->account
- |