v1.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <?php
  2. namespace zin;
  3. require_once dirname(__DIR__) . DS . 'datalist' . DS . 'v1.php';
  4. class storyBasicInfo extends wg
  5. {
  6. /**
  7. * @var mixed[]
  8. */
  9. protected static $defineProps = array
  10. (
  11. 'story' => '?object', // 当前需求。
  12. 'product' => '?object', // 当前产品。
  13. 'branches' => '?array', // 当前分支信息。
  14. 'storyModule' => '?object', // 需求分支信息。
  15. 'hiddenPlan' => '?bool', // 是否隐藏计划。
  16. 'users' => '?array', // 用户列表。
  17. 'statusText' => '?string', // 状态信息。
  18. 'modulePath' => '?string' // 模块路径。
  19. );
  20. /**
  21. * @param object $story
  22. * @param object $product
  23. */
  24. protected function getModuleItems($story, $product)
  25. {
  26. global $app, $config;
  27. $modulePath = $this->prop('modulePath', data('modulePath'));
  28. $storyModule = $this->prop('storyModule', data('storyModule'));
  29. $items = array();
  30. $isInLite = $config->vision == 'lite';
  31. if($modulePath)
  32. {
  33. if($storyModule->branch and isset($branches[$storyModule->branch]))
  34. {
  35. $items[] = $branches[$storyModule->branch];
  36. }
  37. foreach($modulePath as $module)
  38. {
  39. $url = commonModel::hasPriv('product', 'browse') ? createLink('product', 'browse', "productID=$story->product&branch=$story->branch&browseType=byModule&param=$module->id") : '';
  40. if($isInLite) $url = commonModel::hasPriv('projectstory', 'story') ? createLink('projectstory', 'story', "projectID={$app->session->project}&productID=$story->product&branch=$story->branch&browseType=byModule&param=$module->id") : '';
  41. $items[] = $product->shadow || empty($url) ? $module->name : array('text' => $module->name, 'url' => $url);
  42. }
  43. }
  44. if(!$items) $items = array('/');
  45. return $items;
  46. }
  47. /**
  48. * @param object $story
  49. * @param mixed[]|null $branches
  50. */
  51. protected function getMinStage($story, $branches)
  52. {
  53. global $lang;
  54. $minStage = $story->stage;
  55. $stageList = implode(',', array_keys($lang->story->stageList));
  56. $minStagePos = strpos($stageList, $minStage);
  57. if($story->stages and $branches)
  58. {
  59. foreach($story->stages as $stage)
  60. {
  61. if(strpos($stageList, $stage) !== false and strpos($stageList, $stage) > $minStagePos)
  62. {
  63. $minStage = $stage;
  64. $minStagePos = strpos($stageList, $stage);
  65. }
  66. }
  67. }
  68. return $minStage;
  69. }
  70. protected function getItems()
  71. {
  72. global $lang, $config;
  73. $story = $this->prop('story', data('story'));
  74. if(!$story) return array();
  75. $product = $this->prop('product', data('product'));
  76. $branches = $this->prop('branches', data('branches'));
  77. $hiddenPlan = $this->prop('hiddenPlan', data('hiddenPlan'));
  78. $statusText = $this->prop('statusText', $story->status);
  79. $users = $this->prop('users', data('users'));
  80. $gradePairs = $this->prop('gradePairs', data('gradePairs'));
  81. $roadmaps = $this->prop('roadmaps', data('roadmaps'));
  82. $demand = $this->prop('demand', data('demand'));
  83. $showGrade = $this->prop('showGrade', data('showGrade'));
  84. $items = array();
  85. if(!$product->shadow)
  86. {
  87. $items[$lang->story->product] = hasPriv('product', 'view') ? array('control' => 'link', 'url' => createLink('product', 'view', "productID=$story->product"), 'text' => $product->name) : $product->name;
  88. }
  89. if($product->type !== 'normal')
  90. {
  91. $items[$lang->story->branch] = hasPriv('product', 'browse') ? array('control' => 'link', 'url' => createLink('product', 'browse', "productID=$story->product&branch=$story->branch"), 'text' => $branches[$story->branch]) : $branches[$story->branch];
  92. }
  93. $items[$lang->story->module] = array
  94. (
  95. 'control' => 'breadcrumb',
  96. 'items' => $this->getModuleItems($story, $product)
  97. );
  98. if(!empty($story->demand) && !empty($demand) && $story->parent <= 0)
  99. {
  100. $demandHtml = div(setClass('flex'), hasPriv('demand', 'view') ? a
  101. (
  102. $demand->title,
  103. set::href(helper::createLink('demand', 'view', "demandID=$story->demand")),
  104. set::title($demand->title),
  105. setClass('basis-52 text-clip mr-2.5'),
  106. setData('toggle', 'modal'),
  107. setData('size', 'lg')
  108. ) : $demand->title, $demand->status == 'active' && $story->demandVersion < $demand->version && common::hasPriv($story->type, 'processStoryChange') ? span
  109. (
  110. ' (',
  111. $lang->story->storyChange . ' ',
  112. a(setClass('btn primary-pale border-primary size-xs ajax-submit'), set::href(createLink($story->type, 'processStoryChange', "storyID={$story->id}")), $lang->confirm),
  113. ')'
  114. ) : null);
  115. $items[$lang->story->upstreamDemand] = array
  116. (
  117. 'control' => 'div',
  118. 'content' => $demandHtml
  119. );
  120. }
  121. if(isset($story->parentName))
  122. {
  123. $storyHtml = hasPriv($story->parentType, 'view') ? div(setClass('flex'), a
  124. (
  125. $story->parentName,
  126. set::href(helper::createLink($story->parentType, 'view', "storyID=$story->parent")),
  127. set::title($story->parentName),
  128. setClass('basis-52 text-clip mr-2.5'),
  129. setData('toggle', 'modal'),
  130. setData('size', 'lg')
  131. ), $story->parentChanged && common::hasPriv($story->parentType, 'processStoryChange') ? span
  132. (
  133. ' (',
  134. $lang->story->storyChange . ' ',
  135. a(setClass('btn primary-pale border-primary size-xs ajax-submit'), set::href(createLink($story->type, 'processStoryChange', "storyID={$story->id}")), $lang->confirm),
  136. ')'
  137. ) : null) : $story->parentName;
  138. $items[$lang->story->parent] = array
  139. (
  140. 'children' => $storyHtml
  141. );
  142. }
  143. if($showGrade)
  144. {
  145. $items[$lang->story->grade] = array
  146. (
  147. 'control' => 'text',
  148. 'content' => zget($gradePairs, $story->grade)
  149. );
  150. }
  151. if($config->edition == 'ipd' && $story->type != 'story')
  152. {
  153. $items[$lang->story->roadmap] = hasPriv('roadmap', 'view') ? array
  154. (
  155. 'control' => 'link',
  156. 'url' => createLink('roadmap', 'view', "roadmapID=$story->roadmap"),
  157. 'text' => zget($roadmaps, $story->roadmap)
  158. ) : zget($roadmaps, $story->roadmap, '');
  159. }
  160. if(!$hiddenPlan)
  161. {
  162. $planTitleItems = array();
  163. if(isset($story->planTitle) && $story->planTitle)
  164. {
  165. foreach($story->planTitle as $planID => $planTitle)
  166. {
  167. $planTitleItems[] = hasPriv('productplan', 'view') ? array
  168. (
  169. 'control' => 'link',
  170. 'url' => !in_array($config->vision, array('lite', 'or')) ? createLink('productplan', 'view', "planID=$planID") : null,
  171. 'text' => $planTitle . ' '
  172. ) : $planTitle;
  173. }
  174. }
  175. $items[$lang->story->plan] = array
  176. (
  177. 'control' => 'list',
  178. 'items' => $planTitleItems
  179. );
  180. }
  181. $items[$lang->story->source] = array
  182. (
  183. 'control' => 'text',
  184. 'content' => zget($lang->{$story->type}->sourceList, $story->source, ''),
  185. 'id' => 'sourceBox'
  186. );
  187. $items[$lang->story->sourceNote] = array
  188. (
  189. 'control' => 'text',
  190. 'content' => $story->sourceNote,
  191. 'id' => 'sourceNoteBox'
  192. );
  193. $items[$lang->story->status] = array
  194. (
  195. 'control' => 'status',
  196. 'class' => 'status-story',
  197. 'status' => $story->URChanged ? 'changed' : $story->status,
  198. 'text' => $statusText
  199. );
  200. $items[$lang->story->stage] = array
  201. (
  202. 'control' => 'text',
  203. 'class' => 'stage-line',
  204. 'text' => zget($lang->{$story->type}->stageList, $this->getMinStage($story, $branches), '')
  205. );
  206. $items[$lang->story->category] = zget($lang->{$story->type}->categoryList, $story->category);
  207. $items[$lang->story->pri] = array
  208. (
  209. 'control' => 'pri',
  210. 'pri' => $story->pri,
  211. 'text' => $lang->{$story->type}->priList
  212. );
  213. $items[$lang->story->estimate] = $story->estimate . $config->hourUnit;
  214. if(in_array($story->source, $config->story->feedbackSource))
  215. {
  216. $items[$lang->story->feedbackBy] = $story->feedbackBy;
  217. $items[$lang->story->notifyEmail] = $story->notifyEmail;
  218. }
  219. $items[$lang->story->keywords] = $story->keywords;
  220. $items[$lang->story->legendMailto] = joinMailtoList($story->mailto, $users);
  221. if($config->vision == 'lite')
  222. {
  223. unset($items[$lang->story->product]);
  224. unset($items[$lang->story->branch]);
  225. unset($items[$lang->story->plan]);
  226. unset($items[$lang->story->source]);
  227. unset($items[$lang->story->sourceNote]);
  228. unset($items[$lang->story->stage]);
  229. unset($items[$lang->story->category]);
  230. }
  231. return $items;
  232. }
  233. protected function build()
  234. {
  235. return new datalist
  236. (
  237. set::className('story-basic-info'),
  238. set::items($this->getItems())
  239. );
  240. }
  241. }