QueryBuilderRepository.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. <?php
  2. namespace Dcat\Admin\Repositories;
  3. use Dcat\Admin\Contracts\TreeRepository;
  4. use Dcat\Admin\Form;
  5. use Dcat\Admin\Grid;
  6. use Dcat\Admin\Show;
  7. use Illuminate\Database\Eloquent\Builder;
  8. use Illuminate\Support\Collection;
  9. use Illuminate\Support\Facades\DB;
  10. use Illuminate\Support\Str;
  11. class QueryBuilderRepository extends Repository implements TreeRepository
  12. {
  13. /**
  14. * @var string
  15. */
  16. protected $table;
  17. /**
  18. * @var string
  19. */
  20. protected $connection;
  21. /**
  22. * @var string
  23. */
  24. protected $createdAtColumn = 'created_at';
  25. /**
  26. * @var string
  27. */
  28. protected $updatedAtColumn = 'updated_at';
  29. /**
  30. * @var Builder
  31. */
  32. protected $queryBuilder;
  33. /**
  34. * QueryBuilderRepository constructor.
  35. */
  36. public function __construct()
  37. {
  38. $this->initQueryBuilder();
  39. }
  40. /**
  41. * 初始化.
  42. */
  43. protected function initQueryBuilder()
  44. {
  45. $this->queryBuilder = $this->connection
  46. ? DB::connection($this->connection)->table($this->getTable())
  47. : DB::table($this->getTable());
  48. }
  49. /**
  50. * @return string
  51. */
  52. public function getTable()
  53. {
  54. return $this->table;
  55. }
  56. /**
  57. * @return string
  58. */
  59. public function getCreatedAtColumn()
  60. {
  61. return $this->createdAtColumn;
  62. }
  63. /**
  64. * @return string
  65. */
  66. public function getUpdatedAtColumn()
  67. {
  68. return $this->updatedAtColumn;
  69. }
  70. /**
  71. * 获取列表页面查询的字段.
  72. *
  73. * @return array
  74. */
  75. public function getGridColumns()
  76. {
  77. return ['*'];
  78. }
  79. /**
  80. * 获取表单页面查询的字段.
  81. *
  82. * @return array
  83. */
  84. public function getFormColumns()
  85. {
  86. return ['*'];
  87. }
  88. /**
  89. * 获取详情页面查询的字段.
  90. *
  91. * @return array
  92. */
  93. public function getDetailColumns()
  94. {
  95. return ['*'];
  96. }
  97. /**
  98. * 查询Grid表格数据.
  99. *
  100. * @param Grid\Model $model
  101. *
  102. * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator|Collection|array
  103. */
  104. public function get(Grid\Model $model)
  105. {
  106. $this->setSort($model);
  107. $this->setPaginate($model);
  108. $query = $this->newQuery();
  109. $model->getQueries()->unique()->each(function ($value) use (&$query) {
  110. if ($value['method'] == 'paginate') {
  111. $value['arguments'][1] = $this->getGridColumns();
  112. } elseif ($value['method'] == 'get') {
  113. $value['arguments'] = [$this->getGridColumns()];
  114. }
  115. $query = call_user_func_array([$query, $value['method']], $value['arguments'] ?? []);
  116. });
  117. return $query;
  118. }
  119. /**
  120. * 设置表格数据排序.
  121. *
  122. * @param Grid\Model $model
  123. *
  124. * @return void
  125. */
  126. protected function setSort(Grid\Model $model)
  127. {
  128. [$column, $type] = $model->getSort();
  129. if (empty($column) || empty($type)) {
  130. return;
  131. }
  132. if (Str::contains($column, '.')) {
  133. $this->setRelationSort($model, $column, $type);
  134. } else {
  135. $model->resetOrderBy();
  136. $model->addQuery('orderBy', [$column, $type]);
  137. }
  138. }
  139. /**
  140. * 设置关联数据排序.
  141. *
  142. * @param Grid\Model $model
  143. * @param string $column
  144. * @param string $type
  145. *
  146. * @return void
  147. */
  148. protected function setRelationSort(Grid\Model $model, $column, $type)
  149. {
  150. [$relationName, $relationColumn] = explode('.', $column);
  151. if ($model->getQueries()->contains(function ($query) use ($relationName) {
  152. return $query['method'] == 'with' && in_array($relationName, $query['arguments']);
  153. })) {
  154. $model->addQuery('select', [$this->getGridColumns()]);
  155. $model->resetOrderBy();
  156. $model->addQuery('orderBy', [
  157. $relationColumn,
  158. $type,
  159. ]);
  160. }
  161. }
  162. /**
  163. * 设置分页参数.
  164. *
  165. * @param Grid\Model $model
  166. *
  167. * @return void
  168. */
  169. protected function setPaginate(Grid\Model $model)
  170. {
  171. $paginate = $model->findQueryByMethod('paginate');
  172. $model->rejectQuery(['paginate']);
  173. if (! $model->allowPagination()) {
  174. $model->addQuery('get', [$this->getGridColumns()]);
  175. } else {
  176. $model->addQuery('paginate', $this->resolvePerPage($model, $paginate));
  177. }
  178. }
  179. /**
  180. * 获取分页参数.
  181. *
  182. * @param Grid\Model $model
  183. * @param array|null $paginate
  184. *
  185. * @return array
  186. */
  187. protected function resolvePerPage(Grid\Model $model, $paginate)
  188. {
  189. if ($paginate && is_array($paginate)) {
  190. if ($perPage = request()->input($model->getPerPageName())) {
  191. $paginate['arguments'][0] = (int) $perPage;
  192. }
  193. return $paginate['arguments'];
  194. }
  195. return [
  196. $model->getPerPage(),
  197. $this->getGridColumns(),
  198. $model->getPageName(),
  199. $model->getCurrentPage(),
  200. ];
  201. }
  202. /**
  203. * 查询编辑页面数据.
  204. *
  205. * @param Form $form
  206. *
  207. * @return array
  208. */
  209. public function edit(Form $form): array
  210. {
  211. $result = $this->newQuery()
  212. ->where($this->getKeyName(), $form->getKey())
  213. ->first($this->getFormColumns());
  214. if (! $result) {
  215. abort(404);
  216. }
  217. return (array) $result;
  218. }
  219. /**
  220. * 查询详情页面数据.
  221. *
  222. * @param Show $show
  223. *
  224. * @return array
  225. */
  226. public function detail(Show $show): array
  227. {
  228. $result = $this->newQuery()
  229. ->where($this->getKeyName(), $show->getKey())
  230. ->first($this->getDetailColumns());
  231. if (! $result) {
  232. abort(404);
  233. }
  234. return (array) $result;
  235. }
  236. /**
  237. * 新增记录.
  238. *
  239. * @param Form $form
  240. *
  241. * @return mixed
  242. */
  243. public function store(Form $form)
  244. {
  245. $result = null;
  246. DB::transaction(function () use ($form, &$result) {
  247. $result = $this->newQuery()
  248. ->insertGetId($form->updates());
  249. });
  250. return $result;
  251. }
  252. /**
  253. * 查询更新前的行数据.
  254. *
  255. * @param Form $form
  256. *
  257. * @return array
  258. */
  259. public function getDataWhenUpdating(Form $form): array
  260. {
  261. return $this->edit($form);
  262. }
  263. /**
  264. * 更新数据.
  265. *
  266. * @param Form $form
  267. *
  268. * @return bool
  269. */
  270. public function update(Form $form)
  271. {
  272. $result = null;
  273. DB::transaction(function () use ($form, &$result) {
  274. $result = $this->newQuery()
  275. ->where($this->getKeyName(), $form->getKey())
  276. ->limit(1)
  277. ->update($form->updates());
  278. });
  279. return $result;
  280. }
  281. /**
  282. * 数据行排序上移一个单位.
  283. *
  284. * @return bool
  285. */
  286. public function moveOrderUp()
  287. {
  288. throw new \RuntimeException('Not support.');
  289. }
  290. /**
  291. * 数据行排序下移一个单位.
  292. *
  293. * @return bool
  294. */
  295. public function moveOrderDown()
  296. {
  297. throw new \RuntimeException('Not support.');
  298. }
  299. /**
  300. * 删除数据.
  301. *
  302. * @param Form $form
  303. *
  304. * @return bool
  305. */
  306. public function destroy(Form $form, array $deletingData)
  307. {
  308. $id = $form->getKey();
  309. $deletingData = collect($deletingData)->keyBy($this->getKeyName());
  310. collect(explode(',', $id))->filter()->each(function ($id) use ($form, $deletingData) {
  311. $data = $deletingData->get($id, []);
  312. if (! $data) {
  313. return;
  314. }
  315. $form->deleteFiles($data);
  316. $this->newQuery()
  317. ->where($this->getKeyName(), $id)
  318. ->limit(1)
  319. ->delete();
  320. });
  321. return true;
  322. }
  323. /**
  324. * 查询删除前的行数据.
  325. *
  326. * @param Form $form
  327. *
  328. * @return array
  329. */
  330. public function getDataWhenDeleting(Form $form): array
  331. {
  332. $query = $this->newQuery();
  333. $id = $form->getKey();
  334. return $query
  335. ->whereIn(
  336. $this->getKeyName(),
  337. collect(explode(',', $id))->filter()->toArray()
  338. )
  339. ->get($this->getFormColumns())
  340. ->transform(function ($value) {
  341. return (array) $value;
  342. })
  343. ->toArray();
  344. }
  345. /**
  346. * 获取父级ID字段名称.
  347. *
  348. * @return string
  349. */
  350. public function getParentColumn()
  351. {
  352. throw new \RuntimeException('Not support.');
  353. }
  354. /**
  355. * 获取标题字段名称.
  356. *
  357. * @return string
  358. */
  359. public function getTitleColumn()
  360. {
  361. throw new \RuntimeException('Not support.');
  362. }
  363. /**
  364. * 获取排序字段名称.
  365. *
  366. * @return string
  367. */
  368. public function getOrderColumn()
  369. {
  370. throw new \RuntimeException('Not support.');
  371. }
  372. /**
  373. * 保存层级数据排序.
  374. *
  375. * @param array $tree
  376. * @param int $parentId
  377. */
  378. public function saveOrder($tree = [], $parentId = 0)
  379. {
  380. throw new \RuntimeException('Not support.');
  381. }
  382. /**
  383. * 设置数据查询回调.
  384. *
  385. * @param \Closure|null $query
  386. *
  387. * @return $this
  388. */
  389. public function withQuery($queryCallback)
  390. {
  391. throw new \RuntimeException('Not support.');
  392. }
  393. /**
  394. * 获取层级数据.
  395. *
  396. * @return array
  397. */
  398. public function toTree()
  399. {
  400. throw new \RuntimeException('Not support.');
  401. }
  402. /**
  403. * @return Builder
  404. */
  405. protected function newQuery()
  406. {
  407. return clone $this->queryBuilder;
  408. }
  409. }