AbstractBaseService.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. <?php
  2. namespace App\Base\Services;
  3. use App\Base\Models\BaseModel;
  4. use Illuminate\Http\Request;
  5. use Illuminate\Pagination\LengthAwarePaginator;
  6. use Illuminate\Support\Collection;
  7. use Illuminate\Support\Facades\Cache;
  8. use Illuminate\Support\Facades\DB;
  9. class AbstractBaseService
  10. {
  11. use CacheTrait;
  12. /**
  13. * BaseModel
  14. * @var BaseModel
  15. */
  16. protected $model;
  17. /**
  18. * 是否缓存数据
  19. * @var bool
  20. */
  21. protected $cache = false;
  22. /**
  23. * 缓存空间
  24. * @var string
  25. */
  26. protected $cacheBucket = '';
  27. /**
  28. * Service constructor.
  29. * @param BaseModel $model
  30. */
  31. public function __construct(BaseModel $model)
  32. {
  33. $this->model = $model;
  34. }
  35. /**
  36. * DB:select对象转数组
  37. * @param $list
  38. */
  39. public function toArray(&$list) {
  40. $res = [];
  41. foreach ($list as &$v) {
  42. $res[] = (array)$v;
  43. }
  44. return $res;
  45. }
  46. /**
  47. * 获取url地址
  48. *
  49. * @return string
  50. */
  51. public function getBaseUrl()
  52. {
  53. return app()->make(Request::class)->root();
  54. }
  55. /**
  56. * 缓存key
  57. * @param $id
  58. * @return string
  59. */
  60. protected function getCacheId($id)
  61. {
  62. return $this->cacheBucket . '-' . md5($id);
  63. }
  64. /**
  65. * 获取绑定的model
  66. * @return BaseModel
  67. */
  68. public function getModel(){
  69. return $this->model;
  70. }
  71. /**
  72. * 开启事务
  73. */
  74. public function beginTransaction()
  75. {
  76. $this->model->getConnection()->beginTransaction();
  77. }
  78. /**
  79. * 提交事务
  80. */
  81. public function commit()
  82. {
  83. $this->model->getConnection()->commit();
  84. }
  85. /**
  86. * 回滚事务
  87. */
  88. public function rollback()
  89. {
  90. $this->model->getConnection()->rollBack();
  91. }
  92. /**
  93. * 保存数据
  94. * @param $data
  95. * @return BaseModel
  96. */
  97. public function save($data)
  98. {
  99. $this->model = $this->model->newInstance();
  100. $data = $this->model->filter($data);
  101. foreach ($data as $key => $item) {
  102. $this->model->$key = $item;
  103. }
  104. $this->model->save();
  105. return $this->model;
  106. }
  107. /**
  108. * 批量保存数据
  109. * @param $data
  110. */
  111. public function saveAll($data)
  112. {
  113. if (empty($data)) {
  114. return;
  115. }
  116. //过滤字段数据
  117. foreach ($data as &$item) {
  118. $item = $this->model->filter($item);
  119. // self::save($item);
  120. }
  121. //更改为批量插入
  122. if($this->model->timestamps && $this->model::CREATED_AT && $this->model::UPDATED_AT) {
  123. $time = nowTime();
  124. foreach ($data as &$item) {
  125. $item[$this->model::CREATED_AT] = $item[$this->model::UPDATED_AT] = $time;
  126. foreach ($item as $key => $itemValue) {
  127. if ($this->model->isJsonCastingField($key) && is_array($itemValue)) {
  128. $item[$key] = json_encode($itemValue);
  129. }
  130. }
  131. }
  132. }
  133. return $this->model->insert($data);
  134. //批量插入
  135. // $this->model->newInstance()->getConnection()->table($this->model->getTable())->insert($data);
  136. }
  137. /**
  138. * 根据主键判断保存或者更新
  139. * @param $data
  140. * @return BaseModel
  141. */
  142. public function saveOrUpdate($data)
  143. {
  144. $key = $this->model->getKeyName();
  145. if (isset($data[$key]) && !empty($data[$key])) {
  146. return $this->update($data[$key], $data);
  147. } else {
  148. return $this->save($data);
  149. }
  150. }
  151. /**
  152. * 详情
  153. * @param $id
  154. * @return BaseModel
  155. */
  156. public function show($id)
  157. {
  158. return $this->findOneById($id);
  159. }
  160. /**
  161. * 更新数据
  162. * @param int $id
  163. * @param array $data 更新数据
  164. * @return BaseModel
  165. */
  166. public function update($id, array $data)
  167. {
  168. if ($this->cache) {
  169. Cache::forget($this->getCacheId($id));
  170. }
  171. $res = $this->model->newInstance()->whereKey($id)->update($data);
  172. if ($res) {
  173. $data['id'] = $id;
  174. $this->model->options = [
  175. 'where' => ['id' => $id]
  176. ];
  177. $this->model->data = $data;
  178. $this->model->fireModelEvent('updated', false);
  179. }
  180. return $res;
  181. }
  182. /**
  183. * 根据多个条件更新数据
  184. * @param array $criteria
  185. * @param array $data
  186. * @return bool
  187. */
  188. public function updateBy($criteria, array $data)
  189. {
  190. if ($this->cache) {
  191. if (method_exists($this->model, 'runSoftDelete')) {
  192. $list = $this->model->newInstance()->buildQuery($criteria)->withAll()->get();
  193. } else {
  194. $list = $this->model->newInstance()->buildQuery($criteria)->get();
  195. }
  196. foreach ($list as $item) {
  197. Cache::forget($this->getCacheId($item[$this->model->getKeyName()]));
  198. }
  199. }
  200. $data = $this->model->filter($data);
  201. if (method_exists($this->model, 'runSoftDelete')) {
  202. $res = $this->model->newInstance()->buildQuery($criteria)->withAll()->update($data);
  203. } else {
  204. $res = $this->model->newInstance()->buildQuery($criteria)->update($data);
  205. }
  206. if ($res) {
  207. if(isset($criteria['id'])){
  208. $data['id'] = $criteria['id'];
  209. }
  210. $this->model->options = ['where'=>$criteria];
  211. $this->model->data = $data;
  212. $this->model->fireModelEvent('updated', false);
  213. }
  214. return $res;
  215. }
  216. /**
  217. * 列表查询
  218. * @param $data
  219. * @return Collection
  220. */
  221. public function index($data)
  222. {
  223. return $this->model->whereRaw($this->getCondition($data))->paginate($this->getPageSize($data));
  224. }
  225. /**
  226. * 获取查询条件
  227. * @param $data
  228. * @return string
  229. */
  230. protected function getCondition($data)
  231. {
  232. if (!is_array($data)) {
  233. return '';
  234. }
  235. $data = $this->model->filter($data);
  236. $condition = '1=1';
  237. foreach ($data as $key => $item) {
  238. $condition .= " and " . $key . "='" . $item . "'";
  239. }
  240. return $condition;
  241. }
  242. /**
  243. * 获取分页行数
  244. * @param $data
  245. * @return int
  246. */
  247. protected function getPageSize($data)
  248. {
  249. return $data['page_size']??config('app.app_rows');
  250. }
  251. /**
  252. * 删除数据
  253. * @param $id int|array
  254. * @return bool|null
  255. */
  256. public function delete($id)
  257. {
  258. if (is_array($id)) {
  259. return $this->deleteBy([
  260. $this->model->getKeyName() => [
  261. ['in', $id]
  262. ]
  263. ]);
  264. } else {
  265. return $this->deleteBy([
  266. $this->model->getKeyName() => $id
  267. ]);
  268. }
  269. }
  270. /**
  271. * 根据条件删除数据
  272. * @param $criteria
  273. * @return bool|null
  274. */
  275. public function deleteBy($criteria)
  276. {
  277. if ($this->cache) {
  278. if (method_exists($this->model, 'runSoftDelete')) {
  279. $res = $this->model->newInstance()->buildQuery($criteria)->withAll()->get();
  280. } else {
  281. $res = $this->model->newInstance()->buildQuery($criteria)->get();
  282. }
  283. foreach ($res as $item) {
  284. Cache::forget($this->getCacheId($item[$this->model->getKeyName()]));
  285. }
  286. }
  287. if (method_exists($this->model, 'runSoftDelete')) {
  288. return $this->model->newInstance()->buildQuery($criteria)->withAll()->delete();
  289. } else {
  290. return $this->model->newInstance()->buildQuery($criteria)->delete();
  291. }
  292. }
  293. /**
  294. * 根据条件恢复数据
  295. * @param $criteria
  296. * @return bool|null
  297. */
  298. public function restoreBy($criteria)
  299. {
  300. if ($this->cache) {
  301. $res = $this->model->newInstance()->buildQuery($criteria)->get();
  302. foreach ($res as $item) {
  303. Cache::forget($this->getCacheId($item[$this->model->getKeyName()]));
  304. }
  305. }
  306. return $this->model->newInstance()->buildQuery($criteria)->restore();
  307. }
  308. /**
  309. * 启用
  310. * @param $id
  311. * @return bool|null
  312. */
  313. public function enabled($id)
  314. {
  315. if ($this->cache) {
  316. Cache::forget($this->getCacheId($id));
  317. }
  318. $model = $this->model->newInstance();
  319. return $model->whereKey($id)->restore();
  320. }
  321. /**
  322. * 禁用
  323. * @param $id
  324. * @return mixed
  325. */
  326. public function disabled($id)
  327. {
  328. if ($this->cache) {
  329. Cache::forget($this->getCacheId($id));
  330. }
  331. $model = $this->model->newInstance();
  332. return $model->whereKey($id)->update(['status' => $model::STATUS_DISABLED]);
  333. }
  334. /**
  335. * id获取详情
  336. * @param $id
  337. * @return BaseModel
  338. */
  339. public function findOneById($id, $fields = '*')
  340. {
  341. $model = $this->model->newInstance();
  342. if ($this->cache && $fields == '*') {
  343. $info = Cache::remember($this->getCacheId($id), config('cache.time'), function () use ($model, $id, $fields) {
  344. if (method_exists($model, 'runSoftDelete')) {
  345. return $model->whereKey($id)->withAll()->select(DB::raw($fields))->first();
  346. }else {
  347. return $model->whereKey($id)->select(DB::raw($fields))->first();
  348. }
  349. });
  350. } else {
  351. if (method_exists($model, 'runSoftDelete')) {
  352. $info = $model->whereKey($id)->withAll()->selectRaw($fields)->first();
  353. }else {
  354. $info = $model->whereKey($id)->select(DB::raw($fields))->first();
  355. }
  356. }
  357. return $info;
  358. }
  359. /**
  360. * 查找数据
  361. * @param array|string $criteria
  362. * @return BaseModel
  363. */
  364. public function findOneBy($criteria, $fields = '*')
  365. {
  366. $model = $this->model->newInstance();
  367. if (method_exists($model, 'runSoftDelete') && !isset($criteria['status'])) {
  368. $model = $model->whereRaw('status <> 2');
  369. }
  370. return $model->buildQuery($criteria)->select(DB::raw($fields))->first();
  371. }
  372. /**
  373. * 查找数据
  374. * @param array|string $criteria
  375. * @return Collection
  376. */
  377. public function findBy($criteria, $fields = '*')
  378. {
  379. $model = $this->model->newInstance();
  380. if (method_exists($model, 'runSoftDelete') && !isset($criteria['status'])) {
  381. $model = $model->whereRaw('status <> 2');
  382. }
  383. return $model->buildQuery($criteria)->select(DB::raw($fields))->get();
  384. }
  385. /**
  386. * 查询符合条件的行数
  387. * @param $criteria
  388. * @return int
  389. */
  390. public function count($criteria)
  391. {
  392. $model = $this->model->newInstance();
  393. if (method_exists($model, 'runSoftDelete') && !isset($criteria['status'])) {
  394. $model = $model->whereRaw('status <> 2');
  395. }
  396. return $model->buildQuery($criteria)->count();
  397. }
  398. /**
  399. * sql原生查询
  400. * @param $sql
  401. * @return array
  402. */
  403. public function query($sql)
  404. {
  405. $data = $this->model->getConnection()->select($sql);
  406. return json_decode(json_encode($data), true);
  407. }
  408. /**
  409. * 字段唯一性性验证
  410. * 修改数据验证时请组装主键notIn条件语句,返回false时为存在重复
  411. * @param $field
  412. * @param $value
  413. * @param $criteria
  414. * @return bool
  415. */
  416. public function checkFieldUnique($field, $value, $criteria)
  417. {
  418. $collection = $this->model->newInstance()->buildQuery($criteria)->selectRaw($field)->get();
  419. if (empty($collection->toArray())) {
  420. return true;
  421. }
  422. $checkArray = array_column($collection->toArray(), $field);
  423. if (in_array($value, $checkArray, true)) {
  424. return false;
  425. }
  426. return true;
  427. }
  428. /**
  429. * Increment a column's value by a given amount.
  430. * @param $criteria
  431. * @param $column
  432. * @param int $amount
  433. * @param array $extra
  434. * @return int
  435. */
  436. public function incrementBy($criteria, $column, $amount = 1, array $extra = [])
  437. {
  438. return $this->model->newInstance()->buildQuery($criteria)->increment($column, $amount, $extra);
  439. }
  440. /**
  441. * Decrement a column's value by a given amount.
  442. * @param $criteria
  443. * @param $column
  444. * @param int $amount
  445. * @param array $extra
  446. * @return int
  447. */
  448. public function decrementBy($criteria, $column, $amount = 1, array $extra = [])
  449. {
  450. return $this->model->newInstance()->buildQuery($criteria)->decrement($column, $amount, $extra);
  451. }
  452. /**
  453. * 获取某一字段值
  454. * @param $field
  455. * @param $criteria
  456. * @return string|int|array
  457. */
  458. public function getFieldBy($field, $criteria)
  459. {
  460. $findOne = $this->findOneBy($criteria, $field);
  461. $findOne = $findOne ? $findOne->toArray() : [];
  462. return $findOne[$field]??'';
  463. }
  464. /**
  465. * 根据id获取某一个字段值
  466. * @param $field
  467. * @param $id
  468. * @return array|int|string
  469. */
  470. public function getFieldById($field, $id)
  471. {
  472. return $this->getFieldBy($field, [
  473. $this->model->getKeyName() => $id
  474. ]);
  475. }
  476. /**
  477. * 获取模型的table
  478. * @return string
  479. */
  480. public function getTable()
  481. {
  482. return $this->model->getTable();
  483. }
  484. /**
  485. * 分页
  486. * @param $items 数据结果集
  487. * @param $total 总数量
  488. * @param $perPage 每页数量
  489. * @return LengthAwarePaginator
  490. */
  491. public function paginator($items, $total, $perPage = null)
  492. {
  493. $request = app()->make(Request::class);
  494. $params = $request->all();
  495. if (isset($params['page'])) unset($params['page']);
  496. $path = $request->url();
  497. if ($perPage === null) {
  498. $perPage = $this->getPageSize($params);
  499. }
  500. $options = [
  501. 'path' => $path,
  502. 'query' => $params,
  503. ];
  504. $page = new LengthAwarePaginator($items, $total, $perPage, $currentPage = null, $options);
  505. return $page;
  506. }
  507. /**
  508. * 过滤数据库字段
  509. * @param $data
  510. * @return array
  511. */
  512. public function create($data)
  513. {
  514. return $this->model->filter($data);
  515. }
  516. }