Rule.php 7.5 KB

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