NavMenuModel.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2013-present http://www.thinkcmf.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: 老猫 <thinkcmf@126.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\admin\model;
  12. use think\Exception;
  13. use think\Model;
  14. use tree\Tree;
  15. class NavMenuModel extends Model
  16. {
  17. /**
  18. * 模型名称
  19. * @var string
  20. */
  21. protected $name = 'nav_menu';
  22. /**
  23. * 获取某导航下所有菜单树形结构数组
  24. * @param int $navId 导航id
  25. * @param int $maxLevel 最大获取层级,默认不限制
  26. * @return array
  27. * @throws \think\db\exception\DataNotFoundException
  28. * @throws \think\db\exception\ModelNotFoundException
  29. * @throws \think\exception\DbException
  30. */
  31. public function navMenusTreeArray($navId = 0, $maxLevel = 0)
  32. {
  33. if (empty($navId)) {
  34. $navId = NavModel::where('is_main', 1)->value('id');
  35. }
  36. $navMenus = $this->where('nav_id', $navId)->where('status', 1)->order('list_order ASC')->select()->toArray();
  37. $navMenusTree = [];
  38. if (!empty($navMenus)) {
  39. $tree = new Tree();
  40. $this->parseNavMenu4Home($navMenus);
  41. $tree->init($navMenus);
  42. $navMenusTree = $tree->getTreeArray(0, $maxLevel);
  43. }
  44. return $navMenusTree;
  45. }
  46. /**
  47. * 获取某导航菜单下的所有子菜单树形结构数组
  48. * @param $menuId 导航菜单 id
  49. * @return array
  50. * @throws \think\db\exception\DataNotFoundException
  51. * @throws \think\db\exception\ModelNotFoundException
  52. * @throws \think\exception\DbException
  53. */
  54. public function subNavMenusTreeArray($menuId)
  55. {
  56. $navId = $this->where('id', $menuId)->where('status', 1)->value('nav_id');
  57. if (empty($navId)) {
  58. return [];
  59. }
  60. $navMenus = $this->where('nav_id', $navId)->where('status', 1)->order('list_order ASC')->select()->toArray();
  61. $navMenusTree = [];
  62. if (!empty($navMenus)) {
  63. $tree = new Tree();
  64. $this->parseNavMenu4Home($navMenus);
  65. $tree->init($navMenus);
  66. $navMenusTree = $tree->getTreeArray($menuId);
  67. }
  68. return $navMenusTree;
  69. }
  70. private function parseNavMenu4Home(&$navMenus)
  71. {
  72. foreach ($navMenus as $key => $navMenu) {
  73. $href = htmlspecialchars_decode($navMenu['href']);
  74. $hrefOld = $href;
  75. if (strpos($hrefOld, "{") !== false) {
  76. $href = json_decode($navMenu['href'], true);
  77. $href = cmf_url($href['action'], $href['param']);
  78. } else {
  79. if ($hrefOld == "home") {
  80. $href = request()->root() . "/";
  81. } else {
  82. $href = $hrefOld;
  83. }
  84. }
  85. $navMenu['href'] = $href;
  86. $navMenus[$key] = $navMenu;
  87. }
  88. }
  89. /**
  90. * 获取共享nav模板结构
  91. * @return array
  92. */
  93. public function selectNavs()
  94. {
  95. $tree = new Tree();
  96. $tree->icon = ['&nbsp;│ ', '&nbsp;├─ ', '&nbsp;└─ '];
  97. $tree->nbsp = '&nbsp;';
  98. $navs = $this->getNavData();
  99. foreach ($navs as $key => $navData) {
  100. $tree->init($navData['items']);
  101. $tpl = "<option value='\$rule' data-name='\$name'>\$spacer\$name</option>";
  102. $html = $tree->getTree(0, $tpl);
  103. $navs[$key]['html'] = $html;
  104. }
  105. return $navs;
  106. }
  107. /**
  108. * 获取共享nav数据
  109. * @return array
  110. */
  111. private function getNavData()
  112. {
  113. $apps = cmf_scan_dir(app_path() . "*");
  114. array_push($apps, 'admin', 'user');
  115. $navs = [];
  116. foreach ($apps as $app) {
  117. if (is_dir(app_path() . $app)) {
  118. if (!(strpos($app, ".") === 0)) {
  119. $navConfigFile = cmf_get_app_config_file($app, 'nav');
  120. if (file_exists($navConfigFile)) {
  121. $navApis = include $navConfigFile;
  122. if (is_array($navApis) && !empty($navApis)) {
  123. foreach ($navApis as $navApi) {
  124. if (!empty($navApi['api'])) {
  125. try {
  126. $navData = action($app . '/' . $navApi['api'], [], 'api');
  127. } catch (Exception $e) {
  128. $navData = null;
  129. }
  130. if (!empty($navData) && !empty($navData['rule']) && count($navData['items']) > 0) {
  131. $this->parseNavData($navData, $navApi);
  132. if (!empty($navData['items'])) {
  133. array_push($navs, $navData);
  134. }
  135. }
  136. }
  137. }
  138. }
  139. }
  140. }
  141. }
  142. }
  143. return $navs;
  144. }
  145. /**
  146. * 解析导航数据
  147. * @param $navData
  148. * @param $navApi
  149. */
  150. private function parseNavData(&$navData, $navApi)
  151. {
  152. //TODO 检查导航数据合法性
  153. if (!empty($navData) && !empty($navData['rule']) && count($navData['items']) > 0) {
  154. $navData['name'] = $navApi['name'];
  155. $urlRule = $navData['rule'];
  156. $items = $navData['items'];
  157. $navData['items'] = [];
  158. if ($items instanceof \think\Collection) {
  159. $items = $items->toArray();
  160. }
  161. foreach ($items as $item) {
  162. $rule = [];
  163. $rule['action'] = $urlRule['action'];
  164. $rule['param'] = [];
  165. if (isset($urlRule['param'])) {
  166. foreach ($urlRule['param'] as $key => $val) {
  167. $rule['param'][$key] = $item[$val];
  168. }
  169. }
  170. array_push($navData['items'], [
  171. "name" => $item['name'],
  172. "url" => url($rule['action'], $rule['param']),
  173. "rule" => base64_encode(json_encode($rule)),
  174. "parent_id" => empty($item['parent_id']) ? 0 : $item['parent_id'],
  175. "id" => $item['id'],
  176. ]);
  177. }
  178. }
  179. }
  180. }