* Add top to story.
This commit is contained in:
+4
-4
@@ -24,10 +24,10 @@ CREATE TABLE `zt_storygrade` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `zt_story` ADD `grade` smallint(6) NOT NULL AFTER `parent`;
|
||||
ALTER TABLE `zt_story` ADD `path` varchar(255) NULL AFTER `grade`;
|
||||
update zt_story set grade = 1, path = concat(',', id, ',') where type != 'story';
|
||||
update zt_story set grade = 1, path = concat(',', id, ',') where type = 'story' and parent <= 0;
|
||||
update zt_story set grade = 2, path = concat(',', parent, ',', id, ',') where type = 'story' and parent > 0;
|
||||
ALTER TABLE `zt_story` ADD `top` mediumint NOT NULL DEFAULT '0' AFTER `parent`;
|
||||
update zt_story set grade = 1, parent = 0, top = id where type != 'story';
|
||||
update zt_story set grade = 1, parent = 0, top = id where type = 'story' and parent <= 0;
|
||||
update zt_story set grade = 2, top = parent where type = 'story' and parent > 0;
|
||||
|
||||
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'story', '', 'gradeRule', 'stepwise');
|
||||
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'requirement', '', 'gradeRule', 'stepwise');
|
||||
|
||||
@@ -63,11 +63,11 @@ window.renderCell = function(result, info)
|
||||
const story = info.row.data;
|
||||
let html = '';
|
||||
if(typeof modulePairs[story.rawModule] != 'undefined') html += "<span class='label gray-pale rounded-xl clip'>" + modulePairs[story.rawModule] + "</span> ";
|
||||
if(story.parent > 0)
|
||||
{
|
||||
if($.cookie.get('tab') == 'project') html += story.parentName + ' / ';
|
||||
html += "<span class='label gray-pale rounded-xl clip'>" + (storyType == 'requirement' ? 'SR' : childrenAB) + "</span> ";
|
||||
}
|
||||
if(story.parent > 0) if($.cookie.get('tab') == 'project') html += story.parentName + ' / ';
|
||||
|
||||
let gradeLabel = gradeGroup[story.type][story.grade];
|
||||
if(!showGrade && story.grade < 2) gradeLabel = '';
|
||||
if(gradeLabel) html += "<span class='label gray-pale rounded-xl clip'>" + gradeLabel + "</span> ";
|
||||
if(story.color) result[0].props.style = 'color: ' + story.color;
|
||||
if(html) result.unshift({html});
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace zin;
|
||||
data('storyType', $storyType);
|
||||
data('activeMenuID', $storyType);
|
||||
jsVar('URChanged', $this->lang->story->URChanged);
|
||||
jsVar('gradeGroup', $gradeGroup);
|
||||
jsVar('showGrade', $showGrade);
|
||||
|
||||
$storyCommon = $storyType == 'requirement' ? $lang->URCommon : $lang->SRCommon;
|
||||
$isProjectStory = $this->app->rawModule == 'projectstory';
|
||||
|
||||
@@ -1451,6 +1451,10 @@ class productZen extends product
|
||||
$projectProducts = $this->getProjectProductList($projectID, $storyType, $isProjectStory);
|
||||
list($branchOpt, $branchTagOpt) = $this->getBranchAndTagOption($projectID, $product, $isProjectStory);
|
||||
|
||||
$gradeList = $this->loadModel('story')->getGradeList('');
|
||||
$gradeGroup = array();
|
||||
foreach($gradeList as $grade) $gradeGroup[$grade->type][$grade->grade] = $grade->name;
|
||||
|
||||
/* Set show module by config. */
|
||||
$showModule = empty($this->config->product->browse->showModule) ? 0 : $this->config->product->browse->showModule;
|
||||
if($isProjectStory) $showModule = empty($this->config->projectstory->story->showModule) ? 0 : $this->config->projectstory->story->showModule;
|
||||
@@ -1461,6 +1465,8 @@ class productZen extends product
|
||||
$this->view->projectID = $projectID;
|
||||
$this->view->project = $project;
|
||||
$this->view->stories = $stories;
|
||||
$this->view->gradeGroup = $gradeGroup;
|
||||
$this->view->showGrade = $storyType == 'story' ? count($gradeGroup[$storyType]) > 2 : count($gradeGroup[$storyType]) > 1;
|
||||
$this->view->storyType = $storyType;
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->isProjectStory = $isProjectStory;
|
||||
|
||||
+47
-29
@@ -447,8 +447,6 @@ class storyModel extends model
|
||||
$storyID = $this->storyTao->doCreateStory($story);
|
||||
if(!$storyID) return false;
|
||||
|
||||
$this->dao->update(TABLE_STORY)->set('path')->eq(",{$storyID},")->where('id')->eq($storyID)->exec();
|
||||
|
||||
/* Upload files. */
|
||||
$this->loadModel('action');
|
||||
$this->loadModel('file')->updateObjectID($this->post->uid, $storyID, $story->type);
|
||||
@@ -466,7 +464,14 @@ class storyModel extends model
|
||||
if($bugID) $this->storyTao->closeBugWhenToStory($bugID, $storyID);
|
||||
if(!empty($story->reviewer)) $this->storyTao->doCreateReviewer($storyID, $story->reviewer);
|
||||
if(!empty($story->URS)) $this->storyTao->doCreateURRelations($storyID, $story->URS);
|
||||
if(!empty($story->parent)) $this->subdivide($story->parent, array($storyID));
|
||||
if(!empty($story->parent))
|
||||
{
|
||||
$this->subdivide($story->parent, array($storyID));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->dao->update(TABLE_STORY)->set('top')->eq($storyID)->where('id')->eq($storyID)->exec();
|
||||
}
|
||||
if(!empty($story->plan))
|
||||
{
|
||||
$this->updateStoryOrderOfPlan($storyID, (string)$story->plan); // Set story order in this plan.
|
||||
@@ -586,7 +591,14 @@ class storyModel extends model
|
||||
if(!$storyID) return array();
|
||||
|
||||
$this->storyTao->doCreateSpec($storyID, $story);
|
||||
if($story->parent > 0) $this->subdivide($story->parent, array($storyID));
|
||||
if(!empty($story->parent))
|
||||
{
|
||||
$this->subdivide($story->parent, array($storyID));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->dao->update(TABLE_STORY)->set('top')->eq($storyID)->where('id')->eq($storyID)->exec();
|
||||
}
|
||||
|
||||
/* Update product plan stories order. */
|
||||
if(!empty($story->reviewer)) $this->storyTao->doCreateReviewer($storyID, $story->reviewer);
|
||||
@@ -748,10 +760,15 @@ class storyModel extends model
|
||||
if($story->grade != $oldStory->grade)
|
||||
{
|
||||
$gradeDiff = (int)$story->grade - (int)$oldStory->grade;
|
||||
$this->dao->update(TABLE_STORY)->set("grade = grade + $gradeDiff")->where('path')->like($oldStory->path . '%')->andWhere('id')->ne($storyID)->exec();
|
||||
$this->dao->update(TABLE_STORY)
|
||||
->set("grade = grade + $gradeDiff")
|
||||
->where('top')->eq($oldStory->top)
|
||||
->andWhere('grade')->gt($oldStory->grade)
|
||||
->andWhere('id')->ne($storyID)
|
||||
->exec();
|
||||
}
|
||||
$parentChanged = $story->parent != $oldStory->parent;
|
||||
if($parentChanged) $this->doChangeParent($storyID, $story, $oldStory->parent, $oldStory->path);
|
||||
if($parentChanged) $this->doChangeParent($storyID, $story, $oldStory->parent);
|
||||
if($oldStory->parent > 0) $this->updateParentStatus($storyID, $oldStory->parent, !$parentChanged);
|
||||
if($story->parent > 0) $this->updateParentStatus($storyID, $story->parent, !$parentChanged);
|
||||
|
||||
@@ -1004,12 +1021,11 @@ class storyModel extends model
|
||||
}
|
||||
|
||||
$this->loadModel('action');
|
||||
$changeGradeList = array();
|
||||
foreach($stories as $storyID => $story)
|
||||
{
|
||||
$oldStory = $oldStories[$storyID];
|
||||
if(!$story->grade) $story->grade = $oldStory->grade;
|
||||
$this->dao->update(TABLE_STORY)->data($story)
|
||||
$this->dao->update(TABLE_STORY)->data($story, 'grade')
|
||||
->autoCheck()
|
||||
->checkIF($story->closedBy, 'closedReason', 'notempty')
|
||||
->checkIF($story->closedReason == 'done', 'stage', 'notempty')
|
||||
@@ -1020,14 +1036,20 @@ class storyModel extends model
|
||||
if(dao::isError()) return false;
|
||||
|
||||
/* Update story sort of plan when story plan has changed. */
|
||||
if($oldStory->plan != $story->plan) $this->updateStoryOrderOfPlan($storyID, (string)$story->plan, $oldStory->plan);
|
||||
if($story->grade != $oldStory->grade)
|
||||
{
|
||||
$changeGradeList[$storyID]['oldGrade'] = $oldStory->grade;
|
||||
$changeGradeList[$storyID]['newGrade'] = $story->grade;
|
||||
$gradeDiff = (int)$story->grade - (int)$oldStory->grade;
|
||||
$this->dao->update(TABLE_STORY)
|
||||
->set("grade = grade + $gradeDiff")
|
||||
->where('top')->eq($oldStory->top)
|
||||
->andWhere('grade')->gt($oldStory->grade)
|
||||
->andWhere('id')->ne($storyID)
|
||||
->exec();
|
||||
$this->dao->update(TABLE_STORY)->set('grade')->eq($story->grade)->where('id')->eq($storyID)->exec();
|
||||
}
|
||||
if($oldStory->plan != $story->plan) $this->updateStoryOrderOfPlan($storyID, (string)$story->plan, $oldStory->plan);
|
||||
$parentChanged = $story->parent != $oldStory->parent;
|
||||
if($parentChanged) $this->doChangeParent($storyID, $story, $oldStory->parent, $oldStory->path);
|
||||
if($parentChanged) $this->doChangeParent($storyID, $story, $oldStory->parent);
|
||||
if($oldStory->parent > 0) $this->updateParentStatus($storyID, $oldStory->parent, !$parentChanged);
|
||||
if($story->parent > 0) $this->updateParentStatus($storyID, $story->parent, !$parentChanged);
|
||||
|
||||
@@ -1049,12 +1071,6 @@ class storyModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
foreach($changeGradeList as $storyID => $oldStory)
|
||||
{
|
||||
$gradeDiff = $oldStory['newGrade'] - $oldStory['oldGrade'];
|
||||
$this->dao->update(TABLE_STORY)->set("grade = grade + $gradeDiff")->where('path')->like("%,{$storyID},%")->andWhere('id')->ne($storyID)->exec();
|
||||
}
|
||||
|
||||
$this->loadModel('score')->create('ajax', 'batchEdit');
|
||||
foreach($unlinkPlans as $planID => $stories) $this->action->create('productplan', $planID, 'unlinkstory', '', $stories);
|
||||
foreach($link2Plans as $planID => $stories) $this->action->create('productplan', $planID, 'linkstory', '', $stories);
|
||||
@@ -1334,10 +1350,9 @@ class storyModel extends model
|
||||
/* Set parent to child story. */
|
||||
foreach($SRList as $childStoryID)
|
||||
{
|
||||
$path = rtrim($oldStory->path, ',') . ",$childStoryID,";
|
||||
$this->dao->update(TABLE_STORY)
|
||||
->set('parent')->eq($storyID)
|
||||
->set('path')->eq($path)
|
||||
->set('top')->eq($oldStory->top)
|
||||
->where('id')->eq($childStoryID)
|
||||
->exec();
|
||||
}
|
||||
@@ -2043,11 +2058,10 @@ class storyModel extends model
|
||||
* 获取需求的所有子需求ID。
|
||||
*
|
||||
* @param int $storyID
|
||||
* @param bool $includeSelf
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getAllChildId(int $storyID, bool $includeSelf = true): array
|
||||
public function getAllChildId(int $storyID): array
|
||||
{
|
||||
if($storyID == 0) return array();
|
||||
|
||||
@@ -2055,9 +2069,9 @@ class storyModel extends model
|
||||
if(empty($story)) return array();
|
||||
|
||||
$children = $this->dao->select('id')->from(TABLE_STORY)
|
||||
->where('path')->like($story->path . '%')
|
||||
->andWhere('deleted')->eq(0)
|
||||
->beginIF(!$includeSelf)->andWhere('id')->ne($storyID)->fi()
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('top')->eq($story->top)
|
||||
->andWhere('grade')->gt($story->grade)
|
||||
->fetchPairs();
|
||||
|
||||
return array_keys($children);
|
||||
@@ -2214,10 +2228,10 @@ class storyModel extends model
|
||||
* @param string|array $modules
|
||||
* @param string $fieldName
|
||||
* @param string $fieldValue
|
||||
* @param string $type requirement|story
|
||||
* @param string $type requirement|story
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param string $operator equal|include
|
||||
* @param string $operator equal|include
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
@@ -4636,7 +4650,11 @@ class storyModel extends model
|
||||
*/
|
||||
public function getGradeList($type = 'story'): array
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_STORYGRADE)->where('type')->eq($type)->orderBy('grade_asc')->fetchAll();
|
||||
return $this->dao->select('*')->from(TABLE_STORYGRADE)
|
||||
->where('1=1')
|
||||
->beginIF($type)->andWhere('type')->eq($type)->fi()
|
||||
->orderBy('grade_asc')
|
||||
->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4719,7 +4737,7 @@ class storyModel extends model
|
||||
public function checkGrade(object $story, object $oldStory, string $method = 'edit')
|
||||
{
|
||||
$maxGrade = $this->dao->select('max(grade) as maxGrade')->from(TABLE_STORY)
|
||||
->where('path')->like("{$oldStory->path}%")
|
||||
->where('top')->eq($oldStory->top)
|
||||
->andWhere('deleted')->eq('0')
|
||||
->fetch('maxGrade');
|
||||
|
||||
|
||||
+7
-14
@@ -817,14 +817,11 @@ class storyTao extends storyModel
|
||||
* @param int $storyID
|
||||
* @param object $story
|
||||
* @param int $oldStoryParent
|
||||
* @param string $oldStoryPath
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected function doChangeParent(int $storyID, object $story, int $oldStoryParent, string $oldStoryPath)
|
||||
protected function doChangeParent(int $storyID, object $story, int $oldStoryParent)
|
||||
{
|
||||
if($story->parent == $oldStoryParent) return;
|
||||
|
||||
$this->loadModel('action');
|
||||
if($oldStoryParent > 0)
|
||||
{
|
||||
@@ -841,9 +838,9 @@ class storyTao extends storyModel
|
||||
|
||||
if($story->parent > 0)
|
||||
{
|
||||
$parentStory = $this->dao->select('*')->from(TABLE_STORY)->where('id')->eq($story->parent)->fetch();
|
||||
$story->path = rtrim($parentStory->path, ',') . ',' . $storyID . ',';
|
||||
$children = $this->dao->select('id')->from(TABLE_STORY)->where('parent')->eq($story->parent)->andWhere('deleted')->eq(0)->fetchPairs('id', 'id');
|
||||
$parentStory = $this->dao->select('*')->from(TABLE_STORY)->where('id')->eq($story->parent)->fetch();
|
||||
$newTop = $parentStory->top;
|
||||
$children = $this->dao->select('id')->from(TABLE_STORY)->where('parent')->eq($story->parent)->andWhere('deleted')->eq(0)->fetchPairs('id', 'id');
|
||||
$this->dao->update(TABLE_STORY)
|
||||
->set('childStories')->eq(implode(',', $children))
|
||||
->set('lastEditedBy')->eq($this->app->user->account)
|
||||
@@ -859,16 +856,12 @@ class storyTao extends storyModel
|
||||
}
|
||||
else
|
||||
{
|
||||
$story->path = ",$storyID,";
|
||||
$newTop = $storyID;
|
||||
}
|
||||
|
||||
$childStories = $this->getAllChildId($storyID);
|
||||
foreach($childStories as $childStoryID)
|
||||
{
|
||||
$oldChildPath = $this->dao->select('path')->from(TABLE_STORY)->where('id')->eq($childStoryID)->fetch('path');
|
||||
$newChildPath = str_replace($oldStoryPath, $story->path, $oldChildPath);
|
||||
$this->dao->update(TABLE_STORY)->set('path')->eq($newChildPath)->where('id')->eq($childStoryID)->exec();
|
||||
}
|
||||
if($childStories) $this->dao->update(TABLE_STORY)->set('top')->eq($newTop)->where('id')->in($childStories)->exec();
|
||||
$this->dao->update(TABLE_STORY)->set('top')->eq($newTop)->where('id')->eq($storyID)->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user