Menu.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. namespace app\admin\controller\auth;
  3. use ba\Tree;
  4. use Exception;
  5. use think\facade\Db;
  6. use app\admin\model\MenuRule;
  7. use app\common\controller\Backend;
  8. use think\db\exception\PDOException;
  9. use think\exception\ValidateException;
  10. class Menu extends Backend
  11. {
  12. /**
  13. * @var MenuRule
  14. */
  15. protected $model = null;
  16. /**
  17. * @var Tree
  18. */
  19. protected $tree = null;
  20. protected $preExcludeFields = ['createtime', 'updatetime'];
  21. protected $quickSearchField = 'title';
  22. /**
  23. * 远程select初始化传值
  24. * @var array
  25. */
  26. protected $initValue;
  27. /**
  28. * 搜索关键词
  29. * @var array
  30. */
  31. protected $keyword = false;
  32. /**
  33. * 是否组装Tree
  34. * @var bool
  35. */
  36. protected $assembleTree;
  37. protected $modelValidate = false;
  38. public function initialize()
  39. {
  40. parent::initialize();
  41. $this->model = new MenuRule();
  42. $this->tree = Tree::instance();
  43. $isTree = $this->request->param('isTree', true);
  44. $this->initValue = $this->request->get("initValue/a", '');
  45. $this->keyword = $this->request->request("quick_search");
  46. // 有初始化值时不组装树状(初始化出来的值更好看)
  47. $this->assembleTree = $isTree && !$this->initValue;
  48. }
  49. public function index()
  50. {
  51. if ($this->request->param('select')) {
  52. $this->select();
  53. }
  54. $this->success('', [
  55. 'list' => $this->getMenus(),
  56. 'remark' => get_route_remark(),
  57. ]);
  58. }
  59. /**
  60. * 编辑
  61. */
  62. public function edit()
  63. {
  64. $id = $this->request->param($this->model->getPk());
  65. $row = $this->model->find($id);
  66. if (!$row) {
  67. $this->error(__('Record not found'));
  68. }
  69. $dataLimitAdminIds = $this->getDataLimitAdminIds();
  70. if ($dataLimitAdminIds && !in_array($row[$this->dataLimitField], $dataLimitAdminIds)) {
  71. $this->error(__('You have no permission'));
  72. }
  73. if ($this->request->isPost()) {
  74. $data = $this->request->post();
  75. if (!$data) {
  76. $this->error(__('Parameter %s can not be empty', ['']));
  77. }
  78. $data = $this->excludeFields($data);
  79. $result = false;
  80. Db::startTrans();
  81. try {
  82. // 模型验证
  83. if ($this->modelValidate) {
  84. $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
  85. if (class_exists($validate)) {
  86. $validate = new $validate;
  87. if ($this->modelSceneValidate) $validate->scene('edit');
  88. $validate->check($data);
  89. }
  90. }
  91. if (isset($data['pid']) && $data['pid'] > 0) {
  92. // 满足意图并消除副作用
  93. $parent = $this->model->where('id', $data['pid'])->find();
  94. if ($parent['pid'] == $row['id']) {
  95. $parent->pid = 0;
  96. $parent->save();
  97. }
  98. }
  99. $result = $row->save($data);
  100. Db::commit();
  101. } catch (ValidateException|Exception|PDOException $e) {
  102. Db::rollback();
  103. $this->error($e->getMessage());
  104. }
  105. if ($result !== false) {
  106. $this->success(__('Update successful'));
  107. } else {
  108. $this->error(__('No rows updated'));
  109. }
  110. }
  111. $this->success('', [
  112. 'row' => $row
  113. ]);
  114. }
  115. /**
  116. * 删除
  117. * @param array $ids
  118. */
  119. public function del(array $ids = [])
  120. {
  121. if (!$this->request->isDelete() || !$ids) {
  122. $this->error(__('Parameter error'));
  123. }
  124. $dataLimitAdminIds = $this->getDataLimitAdminIds();
  125. if ($dataLimitAdminIds) {
  126. $this->model->where($this->dataLimitField, 'in', $dataLimitAdminIds);
  127. }
  128. $pk = $this->model->getPk();
  129. $data = $this->model->where($pk, 'in', $ids)->select();
  130. $subData = $this->model->where('pid', 'in', $ids)->column('pid', 'id');
  131. foreach ($subData as $key => $subDatum) {
  132. if (!in_array($key, $ids)) {
  133. $this->error(__('Please delete the child element first, or use batch deletion'));
  134. }
  135. }
  136. $count = 0;
  137. Db::startTrans();
  138. try {
  139. foreach ($data as $v) {
  140. $count += $v->delete();
  141. }
  142. Db::commit();
  143. } catch (PDOException|Exception $e) {
  144. Db::rollback();
  145. $this->error($e->getMessage());
  146. }
  147. if ($count) {
  148. $this->success(__('Deleted successfully'));
  149. } else {
  150. $this->error(__('No rows were deleted'));
  151. }
  152. }
  153. /**
  154. * 重写select方法
  155. */
  156. public function select()
  157. {
  158. $data = $this->getMenus([['type', 'in', ['menu_dir', 'menu']], ['status', '=', '1']]);
  159. if ($this->assembleTree) {
  160. $data = $this->tree->assembleTree($this->tree->getTreeArray($data, 'title'));
  161. }
  162. $this->success('', [
  163. 'options' => $data
  164. ]);
  165. }
  166. protected function getMenus($where = []): array
  167. {
  168. $pk = $this->model->getPk();
  169. $initKey = $this->request->get("initKey/s", $pk);
  170. $ids = $this->auth->getRuleIds();
  171. // 如果没有 * 则只获取用户拥有的规则
  172. if (!in_array('*', $ids)) {
  173. $where[] = ['id', 'in', $ids];
  174. }
  175. if ($this->keyword) {
  176. $keyword = explode(' ', $this->keyword);
  177. foreach ($keyword as $item) {
  178. $where[] = [$this->quickSearchField, 'like', '%' . $item . '%'];
  179. }
  180. }
  181. if ($this->initValue) {
  182. $where[] = [$initKey, 'in', $this->initValue];
  183. }
  184. // 读取用户组所有权限规则
  185. $rules = $this->model
  186. ->where($where)
  187. ->order('weigh desc,id asc')
  188. ->select()->toArray();
  189. // 如果要求树状,此处先组装好 children
  190. return $this->assembleTree ? $this->tree->assembleChild($rules) : $rules;
  191. }
  192. }