* Finish task #8085.

This commit is contained in:
holan20180123
2020-10-10 16:56:36 +08:00
parent 4262f4c782
commit 02eb03583d
9 changed files with 112 additions and 147 deletions
+1
View File
@@ -169,6 +169,7 @@ define('TABLE_STORY', '`' . $config->db->prefix . 'story`');
define('TABLE_STORYSPEC', '`' . $config->db->prefix . 'storyspec`');
define('TABLE_STORYSTAGE', '`' . $config->db->prefix . 'storystage`');
define('TABLE_PRODUCTPLAN', '`' . $config->db->prefix . 'productplan`');
define('TABLE_PLANSTORY', '`' . $config->db->prefix . 'planstory`');
define('TABLE_RELEASE', '`' . $config->db->prefix . 'release`');
define('TABLE_PROJECT', '`' . $config->db->prefix . 'project`');
+6
View File
@@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS `zt_planstory` (
`plan` mediumint(8) unsigned NOT NULL,
`story` mediumint(8) unsigned NOT NULL,
`order` mediumint(9) NOT NULL,
UNIQUE KEY `unique` (`plan`,`story`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-18
View File
@@ -1238,24 +1238,6 @@ EOD;
$preAndNextObject->pre = '';
$preAndNextObject->next = '';
if($type == 'story' and !empty($_SESSION['sortedIdList']))
{
$objects = explode(',', $_SESSION['sortedIdList']);
$key = array_search($objectID, $objects);
if($key > 0)
{
$preObjectID = $objects[$key - 1];
$preAndNextObject->pre = $this->loadModel('story')->getByID($preObjectID);
}
if($key < (count($objects) - 1))
{
$nextObjectID = $objects[$key + 1];
$preAndNextObject->next = $this->loadModel('story')->getByID($nextObjectID);
}
return $preAndNextObject;
}
/* Get objectIDList. */
$table = $this->config->objectTables[$type];
$queryCondition = $type . 'QueryCondition';
-1
View File
@@ -112,7 +112,6 @@ class product extends control
/* Save session. */
$this->session->set('storyList', $this->app->getURI(true));
$this->session->set('productList', $this->app->getURI(true));
$this->session->set('sortedIdList', '');
/* Set product, module and query. */
$productID = $this->product->saveState($productID, $this->products);
+6 -34
View File
@@ -253,17 +253,6 @@ class productplan extends control
$this->app->loadClass('pager', $static = true);
if($this->app->getViewType() == 'mhtml') $recPerPage = 10;
$reSort = false;
if($type == 'story' && strpos($orderBy, 'order') !== false)
{
$orderBy = str_replace('order', 'id', $orderBy);
$reSort = true;
}
else
{
$this->session->set('sortedIdList', '');
}
/* Append id for secend sort. */
$sort = $this->loadModel('common')->appendOrder($orderBy);
@@ -273,26 +262,9 @@ class productplan extends control
$bugPager = new pager(0, $recPerPage, $type == 'bug' ? $pageID : 1);
$storyPager = new pager(0, $recPerPage, $type == 'story' ? $pageID : 1);
/* Get stories of plan. */
$this->loadModel('story');
if(!$reSort or empty($plan->order)) $planStories = $this->story->getPlanStories($planID, 'all', $type == 'story' ? $sort : 'id_desc', $storyPager);
if($reSort)
{
if(!empty($plan->order))
{
$planStories = $this->story->getPlanStories($planID, 'all', $sort);
$planStories = $this->story->sortPlanStory($planStories, $plan->order, $orderBy);
$storyIDList = implode(',', array_keys($planStories));
$this->session->set('sortedIdList', $storyIDList);
$storyPager->recTotal = count($planStories);
$frontCount = $storyPager->recPerPage * ($storyPager->pageID - 1);
$planStories = array_slice($planStories, $frontCount, $storyPager->recPerPage);
}
$orderBy = str_replace('id', 'order', $orderBy);
}
$planStories = $this->story->getPlanStories($planID, 'all', $type == 'story' ? $sort : 'id_desc', $storyPager);
$this->executeHooks($planID);
if($plan->parent > 0) $this->view->parentPlan = $this->productplan->getById($plan->parent);
@@ -351,11 +323,11 @@ class productplan extends control
{
if(empty($planID)) return true;
$plan = $this->productplan->getByID($planID, true);
$order = $this->loadModel('story')->sortStoriesOfPlan($planID, $plan->order);
/* Get story id list. */
$storyIDList = explode(',', trim($this->post->stories, ','));
$this->dao->update(TABLE_PRODUCTPLAN)->set('`order`')->eq($order)->where('id')->eq((int)$planID)->exec();
$this->session->set('sortedIdList', $order);
/* Update the story order according to the plan. */
$this->loadModel('story')->sortStoriesOfPlan($planID, $storyIDList, $this->post->orderBy, $this->post->pageID, $this->post->recPerPage);
}
/**
+10 -18
View File
@@ -466,7 +466,6 @@ class productplanModel extends model
$stories = $this->story->getByList($this->post->stories);
$plan = $this->getByID($planID);
$currentOrder = $plan->order;
foreach($this->post->stories as $storyID)
{
if(!isset($stories[$storyID])) continue;
@@ -474,31 +473,27 @@ class productplanModel extends model
$story = $stories[$storyID];
if(strpos(",$story->plan,", ",{$planID},") !== false) continue;
/* Fix Bug #1538*/
$currentOrder = $currentOrder . $storyID . ',';
$oldOrder = $this->dao->select('*')->from(TABLE_PRODUCTPLAN)->where("id")->eq($story->plan)->fetch('order');
$oldOrder = explode(',', $oldOrder);
unset($oldOrder[array_search($storyID, $oldOrder)]);
$oldOrder = implode(',', $oldOrder);
$this->dao->update(TABLE_PRODUCTPLAN)->set("order")->eq($oldOrder)->where('id')->eq($story->plan)->exec();
/* Modify the plan linked with the story. */
if($this->session->currentProductType == 'normal' or $story->branch != 0 or empty($story->plan))
{
$this->dao->update(TABLE_STORY)->set("plan")->eq($planID)->where('id')->eq((int)$storyID)->exec();
/* Update the order of the story in the plan. */
$this->story->updateStoryOrderOfPlan($storyID, $planID, $story->plan);
}
else
{
$plansOfStory = $story->plan . ',' . $planID;
$this->dao->update(TABLE_STORY)->set("plan")->eq($plansOfStory)->where('id')->eq((int)$storyID)->andWhere('branch')->eq('0')->exec();
/* Update the order of the story in the plan. */
$this->story->updateStoryOrderOfPlan($storyID, $planID);
}
$this->action->create('story', $storyID, 'linked2plan', '', $planID);
$this->story->setStage($storyID);
}
$this->dao->update(TABLE_PRODUCTPLAN)->set("order")->eq($currentOrder)->where('id')->eq((int)$planID)->exec();
}
/**
@@ -514,14 +509,11 @@ class productplanModel extends model
$plans = array_unique(explode(',', trim(str_replace(",$planID,", ',', ',' . trim($story->plan) . ','). ',')));
$this->dao->update(TABLE_STORY)->set('plan')->eq(join(',', $plans))->where('id')->eq((int)$storyID)->exec();
/* Fix Bug #1538. */
$oldOrder = $this->dao->select('*')->from(TABLE_PRODUCTPLAN)->where("id")->eq($story->plan)->fetch('order');
$oldOrder = explode(',', $oldOrder);
unset($oldOrder[array_search($storyID, $oldOrder)]);
$oldOrder = implode(',', $oldOrder);
$this->dao->update(TABLE_PRODUCTPLAN)->set('order')->eq($oldOrder)->where('id')->eq($story->plan)->exec();
/* Delete the story in the sort of the plan. */
$this->loadModel('story');
$this->story->updateStoryOrderOfPlan($storyID, '', $planID);
$this->loadModel('story')->setStage($storyID);
$this->story->setStage($storyID);
$this->loadModel('action')->create('story', $storyID, 'unlinkedfromplan', '', $planID);
}
-1
View File
@@ -689,7 +689,6 @@ class project extends control
/* Save session. */
$this->app->session->set('storyList', $this->app->getURI(true));
$this->session->set('sortedIdList', '');
/* Process the order by field. */
if(!$orderBy) $orderBy = $this->cookie->projectStoryOrder ? $this->cookie->projectStoryOrder : 'pri';
+85 -75
View File
@@ -211,11 +211,7 @@ class storyModel extends model
$this->file->updateObjectID($this->post->uid, $storyID, 'story');
$this->file->saveUpload('story', $storyID, $extra = 1);
if(!empty($story->plan))
{
$plan[$story->plan][] = $storyID;
$this->updatePlanStoryOrder($plan);
}
if(!empty($story->plan)) $this->updateStoryOrderOfPlan($storyID, $story->plan); // Set story order in this plan.
$data = new stdclass();
$data->story = $storyID;
@@ -381,7 +377,8 @@ class storyModel extends model
$storyID = $this->dao->lastInsertID();
$this->setStage($storyID);
if($story->plan) $planStories[$story->plan][] = $storyID;
/* Update product plan stories order. */
if($story->plan) $this->updateStoryOrderOfPlan($storyID, $story->plan);
$specData = new stdclass();
$specData->story = $storyID;
@@ -433,8 +430,6 @@ class storyModel extends model
$mails[$i]->actionID = $actionID;
}
/* Update product plan stories order. */
if(!empty($planStories)) $this->updatePlanStoryOrder($planStories);
/* Remove upload image file and session. */
if(!empty($stories->uploadImage) and $this->session->storyImagesFile)
@@ -670,8 +665,14 @@ class storyModel extends model
if(isset($story->closedReason) and $story->closedReason == 'done') $this->loadModel('score')->create('story', 'close');
/* Fix bug #3153. */
if($oldStory->plan != $story->plan and (empty($oldStory->plan) or empty($story->plan))) $this->setStage($storyID);
/* Set new stage and update story sort of plan when story plan has changed. */
if($oldStory->plan != $story->plan)
{
/* Insert a new story sort in this plan. */
$this->updateStoryOrderOfPlan($storyID, $story->plan, $oldStory->plan);
if(empty($oldStory->plan) or empty($story->plan)) $this->setStage($storyID); // Set new stage for this story.
}
unset($oldStory->parent);
unset($story->parent);
@@ -800,25 +801,47 @@ class storyModel extends model
}
/**
* update plan story order.
* update the story order of plan.
*
* @param int $planStories
* @param int $storyID
* @param string $oldPlanIDList
* @param string $planIDList
* @access public
* @return void
*/
public function updatePlanStoryOrder($planStories)
public function updateStoryOrderOfPlan($storyID, $planIDList = '', $oldPlanIDList = '')
{
$planIDList = array_keys($planStories);
$plans = $this->dao->select('id, `order`')->from(TABLE_PRODUCTPLAN)->where('id')->in($planIDList)->fetchAll('id');
$planIDList = $planIDList ? explode(',', $planIDList) : array();
$oldPlanIDList = $oldPlanIDList ? explode(',', $oldPlanIDList) : array();
foreach($planStories as $planID => $stories)
/* Get the ids to be inserted and deleted by comparing plan ids. */
$insertedPlanIDList = array_diff($planIDList, $oldPlanIDList);
$deletedPlanIDList = array_diff($oldPlanIDList, $planIDList);
/* Delete old story sort of plan. */
if(!empty($deletedPlanIDList))
{
$data = new stdClass();
$data->order = implode(',', $stories);
$productPlan = $plans[$planID];
if(!empty($productPlan->order)) $data->order = $data->order . ',' . $productPlan->order;
foreach($deletedPlanIDList as $planID)
{
$this->dao->delete()->from(TABLE_PLANSTORY)->where('plan')->eq($planID)->andWhere('story')->eq($storyID)->exec();
}
}
$this->dao->update(TABLE_PRODUCTPLAN)->data($data)->where('id')->eq($planID)->exec();
if(!empty($insertedPlanIDList))
{
/* Get last story order of plan list. */
$lastOrderOfPlans = $this->dao->select('plan, `order`')->from(TABLE_PLANSTORY)->where('plan')->in($insertedPlanIDList)->orderBy('order_asc')->fetchPairs();
foreach($insertedPlanIDList as $planID)
{
/* Set story order in new plan. */
$data = new stdClass();
$data->plan = $planID;
$data->story = $storyID;
$data->order = zget($lastOrderOfPlans, $planID, 0) + 1;
$this->dao->replace(TABLE_PLANSTORY)->data($data)->exec();
}
}
}
@@ -952,8 +975,10 @@ class storyModel extends model
if(!dao::isError())
{
$this->executeHooks($storyID);
/* Update story sort of plan when story plan has changed. */
if($oldStory->plan != $story->plan) $this->updateStoryOrderOfPlan($storyID, $story->plan, $oldStory->plan);
$this->executeHooks($storyID);
$this->setStage($storyID);
if($story->closedReason == 'done') $this->loadModel('score')->create('story', 'close');
$allChanges[$storyID] = common::createChanges($oldStory, $story);
@@ -1292,6 +1317,9 @@ class storyModel extends model
/* Remove old plan from the plan field. */
if($oldPlanID) $story->plan = trim(str_replace(",$oldPlanID,", ',', ",$oldStory->plan,"), ',');
/* Update the order of the story in the plan. */
$this->updateStoryOrderOfPlan($storyID, $planID, $oldStory->plan);
/* Replace plan field if product is normal or not linked to plan or story linked to a branch. */
if($this->session->currentProductType == 'normal') $story->plan = $planID;
if(empty($oldPlanID)) $story->plan = $planID;
@@ -2184,13 +2212,15 @@ class storyModel extends model
*/
public function getPlanStories($planID, $status = 'all', $orderBy = 'id_desc', $pager = null)
{
$stories = $this->dao->select('*')->from(TABLE_STORY)
->where("CONCAT(',', plan, ',')")->like("%,$planID,%")
->beginIF($status and $status != 'all')->andWhere('status')->in($status)->fi()
->andWhere('deleted')->eq(0)
$stories = $this->dao->select('distinct t1.story, t1.plan, t1.order, t2.*')
->from(TABLE_PLANSTORY)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
->where('t1.plan')->eq($planID)
->beginIF($status and $status != 'all')->andWhere('t2.status')->in($status)->fi()
->andWhere('t2.deleted')->eq(0)
->orderBy($orderBy)->page($pager)->fetchAll('id');
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story');
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story', false);
return $stories;
}
@@ -2353,34 +2383,6 @@ class storyModel extends model
return $allStories;
}
/**
* Get all story sort.
*
* @param int $planID
* @param int $planOrder
* @access public
* @return string
*/
public function sortStoriesOfPlan($planID, $planOrder)
{
$orderBy = $this->post->orderBy;
if(strpos($orderBy, 'order') !== false) $orderBy = str_replace('order', 'id', $orderBy);
$stories = $this->loadModel('story')->getPlanStories($planID, 'all');
$storyIDList = array_keys($stories);
if(strpos($this->post->orderBy, 'order') !== false and !empty($planOrder)) $stories = $this->sortPlanStory($stories, $planOrder, $orderBy);
$frontCount = (int)$this->post->recPerPage * ((int)$this->post->pageID - 1);
$behindCount = (int)$this->post->recPerPage * (int)$this->post->pageID;
$frontIDList = array_slice($storyIDList, 0, $frontCount);
$behindIDList = array_slice($storyIDList, $behindCount, count($storyIDList) - $behindCount);
$frontIDList = !empty($frontIDList) ? implode(',', $frontIDList) . ',' : '';
$behindIDList = !empty($behindIDList) ? implode(',', $behindIDList) : '';
return $frontIDList . $this->post->stories . $behindIDList;
}
/**
* Batch get story stage.
*
@@ -3298,32 +3300,40 @@ class storyModel extends model
}
/**
* Sort product plan story.
* Update the story order according to the plan.
*
* @param int $planStories
* @param string $order
* @param int $planID
* @param array $sortIDList
* @param string $orderBy
* @param int $pageID
* @param int $recPerPage
* @access public
* @return array
* @return void
*/
public function sortPlanStory($planStories, $order = '', $orderBy = 'order_asc')
public function sortStoriesOfPlan($planID, $sortIDList, $orderBy = 'id_desc', $pageID = 1, $recPerPage = 100)
{
$stories = array();
if(!empty($order))
/* Append id for secend sort. */
$orderBy = $this->loadModel('common')->appendOrder($orderBy);
/* Get all stories by plan. */
$stories = $this->getPlanStories($planID, 'all', $orderBy);
$storyIDList = array_keys($stories);
/* Calculate how many numbers there are before the sort list and after the sort list. */
$frontStoryCount = $recPerPage * ($pageID - 1);
$behindStoryCount = $recPerPage * $pageID;
$frontStoryIDList = array_slice($storyIDList, 0, $frontStoryCount);
$behindStoryIDList = array_slice($storyIDList, $behindStoryCount, count($storyIDList) - $behindStoryCount);
/* Merge to get a new sort list. */
$newSortIDList = array_merge($frontStoryIDList, $sortIDList, $behindStoryIDList);
/* Loop update the story order of plan. */
$order = 1;
foreach($newSortIDList as $storyID)
{
if(is_string($order)) $order = explode(',', $order);
if(strpos($orderBy, 'desc') !== false) $order = array_reverse($order, true);
foreach($order as $id)
{
if(empty($id)) continue;
if(!isset($planStories[$id])) continue;
$stories[$id] = $planStories[$id];
unset($planStories[$id]);
}
if($planStories) $stories += $planStories;
$this->dao->update(TABLE_PLANSTORY)->set('`order`')->eq($order)->where('story')->eq($storyID)->andWhere('plan')->eq($planID)->exec();
$order++;
}
return $stories;
}
}
+4
View File
@@ -610,6 +610,10 @@ class upgradeModel extends model
$this->saveLogs('Execute 12_4_1');
$this->execSQL($this->getUpgradeFile('12.4.1'));
$this->appendExec('12_4_1');
case '12_4_2':
$this->saveLogs('Execute 12_4_2');
$this->execSQL($this->getUpgradeFile('12.4.2'));
$this->appendExec('12_4_2');
}
$this->deletePatch();