Rule.php 6.5 KB

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