MenuRepository.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. // +----------------------------------------------------------------------
  12. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  13. // +----------------------------------------------------------------------
  14. // | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
  15. // +----------------------------------------------------------------------
  16. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  17. // +----------------------------------------------------------------------
  18. // | Author: CRMEB Team <admin@crmeb.com>
  19. // +----------------------------------------------------------------------
  20. namespace app\common\repositories\system\auth;
  21. //附件
  22. use app\common\dao\BaseDao;
  23. use app\common\dao\system\menu\MenuDao;
  24. use app\common\repositories\BaseRepository;
  25. use FormBuilder\Exception\FormBuilderException;
  26. use FormBuilder\Factory\Elm;
  27. use FormBuilder\Form;
  28. use think\db\exception\DataNotFoundException;
  29. use think\db\exception\DbException;
  30. use think\db\exception\ModelNotFoundException;
  31. use think\Exception;
  32. use think\facade\Db;
  33. use think\facade\Route;
  34. use think\Model;
  35. /**
  36. * Class BaseRepository
  37. * @package common\repositories
  38. * @mixin MenuDao
  39. */
  40. class MenuRepository extends BaseRepository
  41. {
  42. /**
  43. * MenuRepository constructor.
  44. * @param MenuDao $dao
  45. */
  46. protected $styles = array(
  47. 'success' => "\033[0;32m%s\033[0m",
  48. 'error' => "\033[31;31m%s\033[0m",
  49. 'info' => "\033[33;33m%s\033[0m"
  50. );
  51. public $prompt = 'all';
  52. public function __construct(MenuDao $dao)
  53. {
  54. /**
  55. * @var MenuDao
  56. */
  57. $this->dao = $dao;
  58. }
  59. /**
  60. * @param array $where
  61. * @param int $merId
  62. * @return array
  63. * @throws DataNotFoundException
  64. * @throws DbException
  65. * @throws ModelNotFoundException
  66. * @author xaboy
  67. * @day 2020-04-16
  68. */
  69. public function getList(array $where, $merId = 0)
  70. {
  71. $query = $this->dao->search($where, $merId);
  72. $count = $query->count();
  73. $list = $query->hidden(['update_time', 'path'])->select()->toArray();
  74. return compact('count', 'list');
  75. }
  76. /**
  77. * @param array $data
  78. * @return BaseDao|Model
  79. * @author xaboy
  80. * @day 2020-04-09
  81. */
  82. public function create(array $data)
  83. {
  84. $data['path'] = '/';
  85. if ($data['pid']) {
  86. $data['path'] = $this->getPath($data['pid']) . $data['pid'] . '/';
  87. }
  88. return $this->dao->create($data);
  89. }
  90. /**
  91. * @param int $id
  92. * @param array $data
  93. * @return int
  94. * @throws DbException
  95. * @author xaboy
  96. * @day 2020-04-09
  97. */
  98. public function update(int $id, array $data)
  99. {
  100. $menu = $this->dao->get($id);
  101. if ($menu->pid != $data['pid']) {
  102. Db::transaction(function () use ($menu, $data) {
  103. $data['path'] = '/';
  104. if ($data['pid']) {
  105. $data['path'] = $this->getPath($data['pid']) . $data['pid'] . '/';
  106. }
  107. $this->dao->updatePath($menu->path . $menu->menu_id . '/', $data['path'] . $menu->menu_id . '/');
  108. $menu->save($data);
  109. });
  110. } else {
  111. unset($data['path']);
  112. $this->dao->update($id, $data);
  113. }
  114. }
  115. /**
  116. * @param bool $is_mer
  117. * @return array
  118. * @author xaboy
  119. * @day 2020-04-18
  120. */
  121. public function getTree($merType = 0)
  122. {
  123. if (!$merType) {
  124. $options = $this->dao->getAllOptions();
  125. } else {
  126. $options = $this->dao->merchantTypeByOptions($merType);
  127. }
  128. return formatTree($options, 'menu_name');
  129. }
  130. /**
  131. * @param int $isMer
  132. * @param int|null $id
  133. * @param array $formData
  134. * @return Form
  135. * @throws FormBuilderException
  136. * @author xaboy
  137. * @day 2020-04-16
  138. */
  139. public function menuForm(int $isMer = 0, ?int $id = null, array $formData = []): Form
  140. {
  141. $action = $isMer == 0 ? (is_null($id) ? Route::buildUrl('systemMenuCreate')->build() : Route::buildUrl('systemMenuUpdate', ['id' => $id])->build())
  142. : (is_null($id) ? Route::buildUrl('systemMerchantMenuCreate')->build() : Route::buildUrl('systemMerchantMenuUpdate', ['id' => $id])->build());
  143. $form = Elm::createForm($action);
  144. $form->setRule([
  145. Elm::cascader('pid', '父级分类')->options(function () use ($id, $isMer) {
  146. $menus = $this->dao->getAllOptions($isMer, true);
  147. if ($id && isset($menus[$id])) unset($menus[$id]);
  148. $menus = formatCascaderData($menus, 'menu_name');
  149. array_unshift($menus, ['label' => '顶级分类', 'value' => 0]);
  150. return $menus;
  151. })->props(['props' => ['checkStrictly' => true, 'emitPath' => false]]),
  152. Elm::select('is_menu', '权限类型', 1)->options([
  153. ['value' => 1, 'label' => '菜单'],
  154. ['value' => 0, 'label' => '权限'],
  155. ])->control([
  156. [
  157. 'value' => 0,
  158. 'rule' => [
  159. Elm::input('menu_name', '路由名称')->required(),
  160. Elm::textarea('params', '参数')->placeholder("路由参数:\r\nkey1:value1\r\nkey2:value2"),
  161. ]
  162. ], [
  163. 'value' => 1,
  164. 'rule' => [
  165. Elm::switches('is_show', '是否显示', 1)->inactiveValue(0)->activeValue(1)->inactiveText('关')->activeText('开'),
  166. Elm::frameInput('icon', '菜单图标', '/' . config('admin.admin_prefix') . '/setting/icons?field=icon')->icon('el-icon-circle-plus-outline')->height('338px')->width('700px')->modal(['modal' => false]),
  167. Elm::input('menu_name', '菜单名称')->required(),
  168. ]
  169. ]
  170. ]),
  171. Elm::input('route', '路由'),
  172. Elm::number('sort', '排序', 0)->precision(0)->max(99999)
  173. ]);
  174. return $form->setTitle(is_null($id) ? '添加菜单' : '编辑菜单')->formData($formData);
  175. }
  176. /**
  177. * @param int $id
  178. * @param int $merId
  179. * @return Form
  180. * @throws DataNotFoundException
  181. * @throws DbException
  182. * @throws FormBuilderException
  183. * @throws ModelNotFoundException
  184. * @author xaboy
  185. * @day 2020-04-16
  186. */
  187. public function updateMenuForm(int $id, $merId = 0)
  188. {
  189. return $this->menuForm($merId, $id, $this->dao->get($id)->toArray());
  190. }
  191. /**
  192. * @param string $params
  193. * @return array
  194. * @author xaboy
  195. * @day 2020-04-22
  196. */
  197. public function tidyParams(?string $params)
  198. {
  199. return $params ? array_reduce(explode('|', $params), function ($initial, $val) {
  200. $data = explode(':', $val, 2);
  201. if (count($data) != 2) return $initial;
  202. $initial[$data[0]] = $data[1];
  203. return $initial;
  204. }, []) : [];
  205. }
  206. /**
  207. * @param array $params
  208. * @param array $routeParams
  209. * @return bool
  210. * @author xaboy
  211. * @day 2020-04-23
  212. */
  213. public function checkParams(array $params, array $routeParams)
  214. {
  215. foreach ($routeParams as $k => $param) {
  216. if (isset($params[$k]) && $params[$k] != $param)
  217. return false;
  218. }
  219. return true;
  220. }
  221. public function formatPath($is_mer = 0)
  222. {
  223. $options = $this->getAll($is_mer);
  224. $options = formatCategory($options, 'menu_id');
  225. Db::transaction(function () use ($options) {
  226. foreach ($options as $option) {
  227. $this->_formatPath($option);
  228. }
  229. });
  230. }
  231. protected function _formatPath($parent, $path = '/')
  232. {
  233. $this->dao->update($parent['menu_id'], ['path' => $path]);
  234. foreach ($parent['children'] ?? [] as $item) {
  235. $itemPath = $path . $item['pid'] . '/';
  236. $this->_formatPath($item, $itemPath);
  237. }
  238. }
  239. public function commandMenu($type, $data, $prompt)
  240. {
  241. $res = [];
  242. if ($prompt) $this->prompt = $prompt;
  243. $isMer = ($type == 'sys') ? 0 : 1;
  244. foreach ($data as $key => $value) {
  245. try{
  246. $result = $this->dao->getMenuPid($key, $isMer, 0);
  247. if (!$result) {
  248. $route = $key;
  249. $isAppend =0;
  250. if (substr($key,0,7) === 'append_') {
  251. $isAppend = 1;
  252. $route = substr($key,7);
  253. }
  254. $result = $this->dao->getMenuPid($route, $isMer, 1);
  255. if (!$result && $key !== 'self') {
  256. printf($this->styles['info'], '未找到菜单: '. $key);
  257. echo PHP_EOL;
  258. continue;
  259. } else {
  260. $result = $this->dao->create([
  261. 'pid' => $key == 'self' ? 0 : $result['menu_id'],
  262. 'path' => $key == 'self' ? '/' : $result['path'] . $result['menu_id'] . '/',
  263. 'menu_name' => $isAppend ? '附加权限' : '权限' ,
  264. 'route' => $key,
  265. 'is_mer' => $isMer,
  266. 'is_menu' => 0
  267. ]);
  268. }
  269. }
  270. $res = array_merge($res, $this->createSlit($isMer, $result['menu_id'], $result['path'], $value));
  271. }catch (\Exception $exception) {
  272. throw new Exception($key);
  273. }
  274. }
  275. $count = count($res);
  276. if (!empty($res)) $this->dao->insertAll($res);
  277. return $count;
  278. }
  279. /**
  280. * TODO 新增权限数据整理
  281. * @param int $isMer
  282. * @param int $menuId
  283. * @param string $path
  284. * @param array $data
  285. * @return array
  286. * @author Qinii
  287. * @day 3/18/22
  288. */
  289. public function createSlit(int $isMer,int $menuId, string $path,array $data)
  290. {
  291. $arr = [];
  292. try {
  293. foreach ($data as $k => $v) {
  294. $result = $this->dao->getWhere(['route' => $v['route'], 'pid' => $menuId]);
  295. if (!$result) {
  296. $arr[] = [
  297. 'pid' => $menuId,
  298. 'path' => $path . $menuId . '/',
  299. 'menu_name' => $v['menu_name'],
  300. 'route' => $v['route'],
  301. 'is_mer' => $isMer,
  302. 'is_menu' => 0,
  303. 'params' => $v['params'] ?? [],
  304. ];
  305. if ($this->prompt == 's') {
  306. printf($this->styles['success'], '新增权限: ' . $v['menu_name'] . ' [' . $v['route'] . ']');
  307. echo PHP_EOL;
  308. }
  309. }
  310. }
  311. return $arr;
  312. }catch (\Exception $exception) {
  313. halt($isMer, $menuId, $path, $data);
  314. }
  315. }
  316. }