BaseModel.php 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250
  1. <?php
  2. /// +----------------------------------------------------------------------
  3. // | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2017~2021 LARAVEL研发中心
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://www.laravel.cn
  8. // +----------------------------------------------------------------------
  9. // | Author: laravel开发员 <laravel.qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace App\Models;
  12. /**
  13. * 缓存基类
  14. * @author zongjl
  15. * @date 2019/5/23
  16. * Class BaseModel
  17. * @package App\Models
  18. */
  19. class BaseModel extends CacheModel
  20. {
  21. // 创建时间
  22. const CREATED_AT = 'create_time';
  23. // 更新时间
  24. const UPDATED_AT = 'update_time';
  25. // // 删除时间
  26. // const DELETED_AT = 'delete_time';
  27. // 默认使用时间戳戳功能
  28. public $timestamps = true;
  29. // 人员ID
  30. public $userId;
  31. // 人员信息
  32. public $userInfo;
  33. // 时间
  34. public $time;
  35. /**
  36. * 构造函数
  37. * @author zongjl
  38. * @date 2019/5/30
  39. */
  40. public function __construct()
  41. {
  42. $this->time = time();
  43. }
  44. /**
  45. * 获取当前时间
  46. * @return int 时间戳
  47. * @author zongjl
  48. * @date 2019/5/30
  49. */
  50. public function freshTimestamp()
  51. {
  52. return time();
  53. }
  54. /**
  55. * 避免转换时间戳为时间字符串
  56. * @param mixed $value 时间
  57. * @return mixed|string|null
  58. * @author zongjl
  59. * @date 2019/5/30
  60. */
  61. public function fromDateTime($value)
  62. {
  63. return $value;
  64. }
  65. /**
  66. * 获取时间戳格式
  67. * @return string 时间戳字符串格式
  68. * @author zongjl
  69. * @date 2019/5/30
  70. */
  71. public function getDateFormat()
  72. {
  73. return 'U';
  74. }
  75. /**
  76. * 添加或编辑
  77. * @param array $data 数据源
  78. * @param string $error 异常错误信息
  79. * @param bool $is_sql 是否打印SQL
  80. * @return number 返回受影响行数据ID
  81. * @author zongjl
  82. * @date 2019/5/23
  83. */
  84. public function edit($data = [], &$error = '', $is_sql = false)
  85. {
  86. $id = isset($data['id']) ? (int)$data['id'] : 0;
  87. if ($id) {
  88. if (empty($data['update_user'])) {
  89. $data['update_user'] = $this->userId;
  90. }
  91. // 置空添加时间
  92. unset($data['create_time']);
  93. // 更新时间
  94. $data['update_time'] = time();
  95. } else {
  96. // 创建时间
  97. $data['create_time'] = time();
  98. // 置空更新时间
  99. unset($data['update_time']);
  100. if (empty($data['create_user'])) {
  101. $data['create_user'] = $this->userId;
  102. }
  103. }
  104. // 格式化表数据
  105. $this->formatData($data, $id);
  106. // 注册打印SQL监听事件
  107. $this->getLastSql($is_sql);
  108. // 入库处理
  109. if ($id) {
  110. // 修改数据
  111. $result = $this->where('id', $id)->update($data);
  112. // 更新ID
  113. $rowId = $id;
  114. } else {
  115. // 新增数据
  116. $result = $this->insertGetId($data);
  117. // 新增ID
  118. $rowId = $result;
  119. }
  120. if ($result !== false) {
  121. // 重置缓存
  122. if ($this->is_cache) {
  123. $data['id'] = $rowId;
  124. $this->cacheReset($rowId, $data, $id);
  125. }
  126. }
  127. return $rowId;
  128. }
  129. /**
  130. * 格式化数据
  131. * @param array $data 数组数据
  132. * @param int $id 数据记录ID
  133. * @param string $table 数据表
  134. * @return array 格式化数据
  135. * @author zongjl
  136. * @date 2019/5/24
  137. */
  138. private function formatData(&$data = [], $id = 0, $table = '')
  139. {
  140. $data_arr = [];
  141. $tables = $table ? explode(",", $table) : array($this->getTable());
  142. $item_data = [];
  143. foreach ($tables as $table) {
  144. $temp_data = [];
  145. $table_fields_list = $this->getTableFields($table);
  146. foreach ($table_fields_list as $field => $fieldInfo) {
  147. if ($field == "id") {
  148. continue;
  149. }
  150. //对强制
  151. if (isset($data[$field])) {
  152. if ($fieldInfo['Type'] == "int") {
  153. $item_data[$field] = (int)$data[$field];
  154. } else {
  155. $item_data[$field] = (string)$data[$field];
  156. }
  157. }
  158. if (!isset($data[$field]) && in_array($field, array('update_time', 'create_time'))) {
  159. continue;
  160. }
  161. //插入数据-设置默认值
  162. if (!$id && !isset($data[$field])) {
  163. $item_data[$field] = $fieldInfo['Default'];
  164. }
  165. if (isset($item_data[$field])) {
  166. $temp_data[$field] = $item_data[$field];
  167. }
  168. }
  169. $data_arr[] = $temp_data;
  170. }
  171. $data = $item_data;
  172. return $data_arr;
  173. }
  174. /**
  175. * 获取数据表字段
  176. * @param string $table 数据表名
  177. * @return array 字段数组
  178. * @author zongjl
  179. * @date 2019/5/24
  180. */
  181. private function getTableFields($table = '')
  182. {
  183. $table = $table ? $table : $this->getTable();
  184. if (strpos($table, DB_PREFIX) === false) {
  185. $table = DB_PREFIX . $table;
  186. }
  187. $field_list = \DB::select("SHOW FIELDS FROM {$table}");
  188. $info_list = [];
  189. foreach ($field_list as $row) {
  190. // 对象转数组格式
  191. $item = object_array($row);
  192. if ((strpos($item['Type'], "int") === false) || (strpos($item['Type'], "bigint") !== false)) {
  193. $type = "string";
  194. $default = $item['Default'] ? $item['Default'] : "";
  195. } else {
  196. $type = "int";
  197. $default = $item['Default'] ? $item['Default'] : 0;
  198. }
  199. $info_list[$item['Field']] = array(
  200. 'Type' => $type,
  201. 'Default' => $default
  202. );
  203. }
  204. return $info_list;
  205. }
  206. /**
  207. * 删除数据
  208. * @param int $id 删除数据ID
  209. * @param bool $is_sql 是否打印SQL
  210. * @return bool 返回true或false
  211. * @author zongjl
  212. * @date 2019/5/23
  213. */
  214. public function drop($id, $is_sql = false)
  215. {
  216. // 注册打印SQL监听事件
  217. $this->getLastSql($is_sql);
  218. $result = $this->where('id', $id)->update(['mark' => 0]);
  219. if ($result !== false && $this->is_cache) {
  220. // 删除成功
  221. $this->cacheDelete($id);
  222. }
  223. return $result;
  224. }
  225. /**
  226. * 查询缓存信息
  227. * @param int $id 查询数据ID
  228. * @return string 返回查询结果
  229. * @author zongjl
  230. * @date 2019/5/23
  231. */
  232. public function getInfo($id)
  233. {
  234. // 获取参数(用户提取操作人信息)
  235. $arg_list = func_get_args();
  236. $flag = isset($arg_list[0]) ? $arg_list[0] : 0;
  237. // 获取缓存信息
  238. $info = $this->getCacheFunc("info", $id);
  239. if ($info) {
  240. // 获取系统人员缓存
  241. $adminModel = new UserModel();
  242. $adminAll = $adminModel->getAll([], false, true);
  243. // 添加人
  244. if (isset($info['create_user']) && !empty($info['create_user'])) {
  245. $info['create_user_name'] = $adminAll[$info['create_user']]['realname'];
  246. }
  247. // 添加时间
  248. if (!empty($info['create_time'])) {
  249. $info['create_time'] = datetime($info['create_time'], 'Y-m-d H:i:s');
  250. }
  251. // 更新人
  252. if (isset($info['update_user']) && !empty($info['update_user'])) {
  253. $info['update_user_name'] = $adminAll[$info['update_user']]['realname'];
  254. }
  255. // 更新时间
  256. if (!empty($info['update_time'])) {
  257. $info['update_time'] = datetime($info['update_time'], 'Y-m-d H:i:s');
  258. }
  259. // 格式化信息(预留扩展方法,可不用)
  260. if (method_exists($this, 'formatInfo')) {
  261. $info = $this->formatInfo($info);
  262. }
  263. }
  264. return $info;
  265. }
  266. /**
  267. * 格式化数据
  268. * @param array $info 实体数据对象
  269. * @return array 返回实体对象
  270. * @author zongjl
  271. * @date 2019/5/23
  272. */
  273. public function formatInfo($info)
  274. {
  275. // 基类方法可不做任何操作,在子类重写即可
  276. // TODO...
  277. return $info;
  278. }
  279. /**
  280. * 查询记录总数
  281. * @param array $map 查询条件(默认:数组格式)
  282. * @param string $fields 查询字段
  283. * @param bool $is_sql 是否打印SQL
  284. * @return int 返回记录总数
  285. * @author zongjl
  286. * @date 2019/5/23
  287. */
  288. public function getCount($map = [], $fields = null, $is_sql = false)
  289. {
  290. // 注册打印SQL监听事件
  291. $this->getLastSql($is_sql);
  292. // 必备查询条件
  293. $map[] = ['mark', '=', 1];
  294. // 闭包查询条件格式化
  295. $query = $this->formatQuery($this, $map);
  296. // 链式操作
  297. if ($fields) {
  298. $count = $query->count($fields);
  299. } else {
  300. $count = $query->count();
  301. }
  302. return (int)$count;
  303. }
  304. /**
  305. * 查询某个字段的求和值
  306. * @param array $map 查询条件(默认:数组)
  307. * @param string $field 求和字段
  308. * @param bool $is_sql 是否打印SQL
  309. * @return string 返回结果
  310. * @author zongjl
  311. * @date 2019/5/23
  312. */
  313. public function getSum($map = [], $field = '', $is_sql = false)
  314. {
  315. // 注册打印SQL监听事件
  316. $this->getLastSql($is_sql);
  317. // 必备查询条件
  318. $map[] = ['mark', '=', 1];
  319. // 闭包查询条件格式化
  320. $query = $this->formatQuery($this, $map);
  321. // 链式操作
  322. $result = $query->sum($field);
  323. return $result;
  324. }
  325. /**
  326. * 查询某个字段的最大值
  327. * @param array $map 查询条件(默认:数组)
  328. * @param string $field 查询字段
  329. * @param bool $is_sql 是否打印SQL
  330. * @return string 返回结果
  331. * @author zongjl
  332. * @date 2019/5/23
  333. */
  334. public function getMax($map = [], $field = '', $is_sql = false)
  335. {
  336. // 注册打印SQL监听事件
  337. $this->getLastSql($is_sql);
  338. // 必备查询条件
  339. $map[] = ['mark', '=', 1];
  340. // 闭包查询条件格式化
  341. $query = $this->formatQuery($this, $map);
  342. // 链式操作
  343. $result = $$query->max($field);
  344. return $result;
  345. }
  346. /**
  347. * 查询某个字段的最小值
  348. * @param array $map 查询条件(默认:数组)
  349. * @param string $field 查询字典
  350. * @param bool $is_sql 是否打印SQL
  351. * @return string 返回结果
  352. * @author zongjl
  353. * @date 2019/5/23
  354. */
  355. public function getMin($map = [], $field = '', $is_sql = false)
  356. {
  357. // 注册打印SQL监听事件
  358. $this->getLastSql($is_sql);
  359. // 必备查询条件
  360. $map[] = ['mark', '=', 1];
  361. // 闭包查询条件格式化
  362. $query = $this->formatQuery($this, $map);
  363. // 链式操作
  364. $result = $query->min($field);
  365. return $result;
  366. }
  367. /**
  368. * 查询某个字段的平均值
  369. * @param array $map 查询条件(默认:数组)
  370. * @param string $field 查询字段
  371. * @param bool $is_sql 是否打印SQL
  372. * @return string 返回结果
  373. * @author zongjl
  374. * @date 2019/5/23
  375. */
  376. public function getAvg($map = [], $field = '', $is_sql = false)
  377. {
  378. // 注册打印SQL监听事件
  379. $this->getLastSql($is_sql);
  380. // 必备查询条件
  381. $map[] = ['mark', '=', 1];
  382. // 闭包查询条件格式化
  383. $query = $this->formatQuery($this, $map);
  384. // 链式操作
  385. $result = $query->avg($field);
  386. return $result;
  387. }
  388. /**
  389. * 查询某个字段的单个值
  390. * @param array $map 查询条件(默认:数组)
  391. * @param string $field 查询字段
  392. * @param bool $is_sql 是否打印SQL
  393. * @return string 返回结果
  394. * @author zongjl
  395. * @date 2019/5/23
  396. */
  397. public function getValue($map = [], $field = 'id', $is_sql = false)
  398. {
  399. // 注册打印SQL监听事件
  400. $this->getLastSql($is_sql);
  401. // 必备查询条件
  402. $map[] = ['mark', '=', 1];
  403. // 闭包查询条件格式化
  404. $query = $this->formatQuery($this, $map);
  405. // 链式操作
  406. $result = $query->value($field);
  407. return $result;
  408. }
  409. /**
  410. * 查询单条数据
  411. * @param array $map 查询条件(默认:数组)
  412. * @param string $field 查询字段(默认:全部)
  413. * @param bool $is_sql 是否打印SQL
  414. * @return array 返回结果
  415. * @author zongjl
  416. * @date 2019/5/23
  417. */
  418. public function getOne($map = [], $field = '*', $is_sql = false)
  419. {
  420. // 注册打印SQL监听事件
  421. $this->getLastSql($is_sql);
  422. // 必备查询条件
  423. $map[] = ['mark', '=', 1];
  424. // 闭包查询条件格式化
  425. $query = $this->formatQuery($this, $map);
  426. // 分析字段
  427. if (!is_array($field) && strpos($field, ',')) {
  428. $field = explode(',', $field);
  429. }
  430. // 链式操作
  431. $result = $query->select($field)->first();
  432. // 对象转数组
  433. return $result ? $result->toArray() : [];
  434. }
  435. /**
  436. * 根据记录ID获取某一行的值
  437. * @param int $id 记录ID
  438. * @param string $field 指定字段(默认:所有字段)
  439. * @param bool $is_sql 是否打印SQL
  440. * @return array 返回结果
  441. * @author zongjl
  442. * @date 2019/5/23
  443. */
  444. public function getRow($id, $field = '*', $is_sql = false)
  445. {
  446. // 注册打印SQL监听事件
  447. $this->getLastSql($is_sql);
  448. // 分析字段
  449. if (!is_array($field) && strpos($field, ',')) {
  450. $field = explode(',', $field);
  451. }
  452. // 链式操作
  453. $result = $this->where('id', $id)->select($field)->first();
  454. // 对象转数组
  455. return $result ? $result->toArray() : [];
  456. }
  457. /**
  458. * 获取某一列的值
  459. * @param array $map 查询条件
  460. * @param string $field 字段
  461. * @param bool $is_sql 是否打印SQL
  462. * @return array 返回结果
  463. * @author zongjl
  464. * @date 2019/5/29
  465. */
  466. public function getColumn($map = [], $field = 'id', $is_sql = false)
  467. {
  468. // 注册打印SQL监听事件
  469. $this->getLastSql($is_sql);
  470. // 必备查询条件
  471. $map[] = ['mark', '=', 1];
  472. // 闭包查询条件格式化
  473. $query = $this->formatQuery($this, $map);
  474. // 链式操作
  475. $result = $query->pluck($field);
  476. // 对象转数组
  477. return $result ? $result->toArray() : [];
  478. }
  479. /**
  480. * 根据条件查询单条缓存记录
  481. * @param array $map 查询条件
  482. * @param array $fields 查询字段
  483. * @param array $sort 排序
  484. * @param int $id 记录ID
  485. * @return array 结果返回值
  486. * @author zongjl
  487. * @date 2019/5/29
  488. */
  489. public function getInfoByAttr($map = [], $fields = [], $sort = [['id', 'desc']], $id = 0)
  490. {
  491. // 必备查询条件
  492. $map[] = ['mark', '=', 1];
  493. // 排除主键
  494. if ($id) {
  495. $map[] = ['id', '!=', $id];
  496. }
  497. // 闭包查询条件格式化
  498. $query = $this->formatQuery($this, $map);
  499. // 排序(支持多重排序)
  500. $query = $query->when($sort, function ($query, $sort) {
  501. foreach ($sort as $v) {
  502. $query->orderBy($v[0], $v[1]);
  503. }
  504. });
  505. // 链式操作
  506. $result = $query->select('id')->first();
  507. $result = $result ? $result->toArray() : [];
  508. // 查询缓存
  509. $data = [];
  510. if ($result) {
  511. $info = $this->getInfo($result['id']);
  512. if ($info && !empty($fields)) {
  513. // 分析字段
  514. if (!is_array($fields) && strpos($fields, ',')) {
  515. $fields = explode(',', $fields);
  516. }
  517. foreach ($fields as $val) {
  518. $data[trim($val)] = $info[trim($val)];
  519. }
  520. unset($info);
  521. } else {
  522. $data = $info;
  523. }
  524. }
  525. return $data;
  526. }
  527. /**
  528. * 获取数据表
  529. * @return array 返回结果
  530. * @author zongjl
  531. * @date 2019/5/29
  532. */
  533. public function getTablesList()
  534. {
  535. $tables = [];
  536. $database = strtolower(env('DB_DATABASE'));
  537. $sql = 'SHOW TABLES';
  538. $list = \DB::select($sql);
  539. // 对象转数组
  540. $data = object_array($list);
  541. foreach ($data as $v) {
  542. $tables[] = $v["Tables_in_{$database}"];
  543. }
  544. return $tables;
  545. }
  546. /**
  547. * 检查表是否存在
  548. * @param string $table 数据表名
  549. * @return bool 返回结果:true存在,false不存在
  550. * @author zongjl
  551. * @date 2019/5/29
  552. */
  553. public function tableExists($table)
  554. {
  555. if (strpos($table, DB_PREFIX) === false) {
  556. $table = DB_PREFIX . $table;
  557. }
  558. $tables = $this->getTablesList();
  559. return in_array($table, $tables) ? true : false;
  560. }
  561. /**
  562. * 删除数据表
  563. * @param string $table 数据表名
  564. * @return mixed 结果返回值
  565. * @author zongjl
  566. * @date 2019/5/29
  567. */
  568. public function dropTable($table)
  569. {
  570. if (strpos($table, DB_PREFIX) === false) {
  571. $table = DB_PREFIX . $table;
  572. }
  573. return \DB::statement("DROP TABLE {$table}");
  574. }
  575. /**
  576. * 获取表字段
  577. * @param string $table 数据表名
  578. * @return array 字段数组
  579. * @author zongjl
  580. * @date 2019/5/29
  581. */
  582. public function getFieldsList($table)
  583. {
  584. if (strpos($table, DB_PREFIX) === false) {
  585. $table = DB_PREFIX . $table;
  586. }
  587. $fields = [];
  588. $list = \DB::select("SHOW COLUMNS FROM {$table}");
  589. // 对象转数组
  590. $data = object_array($list);
  591. foreach ($data as $v) {
  592. $fields[$v['Field']] = $v['Type'];
  593. }
  594. return $fields;
  595. }
  596. /**
  597. * 检查字段是否存在
  598. * @param string $table 数据表名
  599. * @param string $field 字段名
  600. * @return bool 返回结果true或false
  601. * @author zongjl
  602. * @date 2019/5/29
  603. */
  604. public function fieldExists($table, $field)
  605. {
  606. $fields = $this->getFieldsList($table);
  607. return array_key_exists($field, $fields);
  608. }
  609. /**
  610. * 插入数据(不存在缓存操作,请慎用)
  611. * @param array $data 数据源
  612. * @param bool $get_id 是否返回插入主键ID:true返回、false不返回
  613. * @return mixed 返回结果
  614. * @author zongjl
  615. * @date 2019/5/29
  616. */
  617. public function doInsert($data, $get_id = true)
  618. {
  619. if ($get_id) {
  620. // 插入数据并返回主键
  621. return $this->insertGetId($data);
  622. } else {
  623. // 返回影响数据的条数,没修改任何数据返回 0
  624. return $this->insert($data);
  625. }
  626. }
  627. /**
  628. * 更新数据(不存在缓存操作,请慎用)
  629. * @param array $data 数据源
  630. * @param array $where 更新条件
  631. * @param bool $is_sql
  632. * @return mixed 返回结果
  633. * @author zongjl
  634. * @date 2019/5/29
  635. */
  636. public function doUpdate($data, $where, $is_sql = false)
  637. {
  638. // 注册打印SQL监听事件
  639. $this->getLastSql($is_sql);
  640. // 闭包查询条件格式化
  641. $query = $this->formatQuery($this, $where);
  642. return $query->update($data);
  643. }
  644. /**
  645. * 删除数据(不存在缓存操作,请慎用)
  646. * @param array $where 查询条件
  647. * @param bool $is_sql 是否打印SQL
  648. * @return mixed 返回结果
  649. * @author zongjl
  650. * @date 2019/5/29
  651. */
  652. public function doDelete($where, $is_sql = false)
  653. {
  654. // 注册打印SQL监听事件
  655. $this->getLastSql($is_sql);
  656. // 闭包查询条件格式化
  657. $query = $this->formatQuery($this, $where);
  658. return $query->delete();
  659. }
  660. /**
  661. * 批量插入数据
  662. * @param array $data 数据源
  663. * @param bool $is_cache 是否设置缓存:true设置,false不设置
  664. * @return bool 返回结果true或false
  665. * @author zongjl
  666. * @date 2019/5/30
  667. */
  668. public function insertAll($data, $is_cache = true)
  669. {
  670. if (!is_array($data)) {
  671. return false;
  672. }
  673. if ($is_cache) {
  674. // 插入数据并设置缓存
  675. $num = 0;
  676. foreach ($data as $val) {
  677. $result = $this->edit($val);
  678. if ($result) {
  679. $num++;
  680. }
  681. }
  682. return $num ? true : false;
  683. } else {
  684. // 插入数据不设置缓存
  685. return $this->insert($data);
  686. }
  687. return false;
  688. }
  689. /**
  690. * 批量更新数据
  691. * @param array $data 数据源(备注,需要更新的数据对象中必须包含有效主键)
  692. * @param bool $is_cache 是否设置缓存:true设置,false不设置
  693. * @return bool 返回结果true或false
  694. * @author zongjl
  695. * @date 2019/5/30
  696. */
  697. public function saveAll($data, $is_cache = true)
  698. {
  699. if (!is_array($data)) {
  700. return false;
  701. }
  702. $num = 0;
  703. foreach ($data as $val) {
  704. if (!isset($val['id']) || empty($val['id'])) {
  705. continue;
  706. }
  707. if ($is_cache) {
  708. // 更新数据并设置缓存
  709. $result = $this->edit($val);
  710. } else {
  711. // 更新数据不设置缓存
  712. $id = $val['id'];
  713. unset($val['id']);
  714. $result = $this->where('id', $id)->update($val);
  715. }
  716. if ($result) {
  717. $num++;
  718. }
  719. }
  720. return $num ? true : false;
  721. }
  722. /**
  723. * 批量删除
  724. * @param array $data 删除记录ID(支持传入数组和逗号分隔ID字符串)
  725. * @param bool $is_force 是否物理删除,true物理删除false软删除
  726. * @return bool 返回结果true或false
  727. * @author zongjl
  728. * @date 2019/5/30
  729. */
  730. public function deleteAll($data, $is_force = false)
  731. {
  732. if (empty($data)) {
  733. return false;
  734. }
  735. if (!is_array($data)) {
  736. $data = explode(',', $data);
  737. }
  738. $num = 0;
  739. foreach ($data as $val) {
  740. if ($is_force) {
  741. // 物理删除
  742. $result = $this->where('id', $val)->delete();
  743. if ($result) {
  744. $this->cacheDelete($val);
  745. }
  746. } else {
  747. // 软删除
  748. $result = $this->drop($val);
  749. }
  750. if ($result) {
  751. $num++;
  752. }
  753. }
  754. return $num ? true : false;
  755. }
  756. /**
  757. * 获取数据列表【根据业务场景需要,封装的获取列表数据的常用方法】
  758. * @param array $map 查询条件
  759. * @param array $sort 排序(默认:id asc)
  760. * @param string $limit 限制条数
  761. * @param bool $is_sql 是否打印SQL
  762. * @return array 返回结果
  763. * @author zongjl
  764. * @date 2019/5/23
  765. */
  766. public function getList($map = [], $sort = [['id', 'asc']], $limit = '', $is_sql = false)
  767. {
  768. // 注册打印SQL监听事件
  769. $this->getLastSql($is_sql);
  770. // 必备查询条件
  771. $map[] = ['mark', '=', 1];
  772. // 闭包查询条件格式化
  773. $query = $this->formatQuery($this, $map);
  774. // 数据分页设置
  775. if ($limit) {
  776. list($offset, $page_size) = explode(',', $limit);
  777. $query = $query->offset($offset)->limit($page_size);
  778. }
  779. // 排序(支持多重排序)
  780. $query = $query->when($sort, function ($query, $sort) {
  781. foreach ($sort as $v) {
  782. $query->orderBy($v[0], $v[1]);
  783. }
  784. });
  785. // 查询数据并将对象转数组
  786. $result = $query->select('id')->get();
  787. $result = $result ? $result->toArray() : [];
  788. $list = [];
  789. if ($result) {
  790. foreach ($result as $val) {
  791. $info = $this->getInfo($val['id']);
  792. if (!$info) {
  793. continue;
  794. }
  795. $list[] = $info;
  796. }
  797. }
  798. return $list;
  799. }
  800. /**
  801. * 获取数据列表
  802. * @return array 返回结果
  803. * @author zongjl
  804. * @date 2019/5/27
  805. */
  806. public function getData()
  807. {
  808. // 获取参数
  809. $arg_list = func_get_args();
  810. // 查询参数
  811. $map = isset($arg_list[0]['query']) ? $arg_list[0]['query'] : [];
  812. // 排序
  813. $sort = isset($arg_list[0]['sort']) ? $arg_list[0]['sort'] : [['id', 'desc']];
  814. // 获取条数
  815. $limit = isset($arg_list[0]['limit']) ? $arg_list[0]['limit'] : '';
  816. // 回调方法名
  817. $func = isset($arg_list[1]) ? $arg_list[1] : "Short";
  818. // 自定义MODEL
  819. $model = isset($arg_list[2]) ? $arg_list[2] : $this;
  820. // 必备查询条件
  821. $map[] = ['mark', '=', 1];
  822. // 闭包查询条件格式化
  823. $query = $this->formatQuery($model, $map);
  824. // 排序(支持多重排序)
  825. $query = $query->when($sort, function ($query, $sort) {
  826. foreach ($sort as $v) {
  827. $query->orderBy($v[0], $v[1]);
  828. }
  829. });
  830. // 查询数据源
  831. if ($limit) {
  832. list($offset, $page_size) = explode(',', $limit);
  833. $query->offset($offset)->limit($page_size);
  834. } else {
  835. // TODO...
  836. }
  837. // 查询数据并转为数组
  838. $result = $query->select('id')->get();
  839. $result = $result ? $result->toArray() : [];
  840. $list = [];
  841. if (is_array($result)) {
  842. foreach ($result as $val) {
  843. $info = $model->getInfo($val['id']);
  844. if (!$info) {
  845. continue;
  846. }
  847. if (is_object($func)) {
  848. // 方法函数
  849. $data = $func($info);
  850. } else {
  851. // 直接返回
  852. $data = $info;
  853. }
  854. $list[] = $data;
  855. }
  856. }
  857. return $list;
  858. }
  859. /**
  860. * 获取数据列表
  861. * @return array 返回结果
  862. * @author zongjl
  863. * @date 2019/5/27
  864. */
  865. public function pageData()
  866. {
  867. // 获取参数
  868. $arg_list = func_get_args();
  869. // 查询参数
  870. $map = isset($arg_list[0]['query']) ? $arg_list[0]['query'] : [];
  871. // 排序
  872. $sort = isset($arg_list[0]['sort']) ? $arg_list[0]['sort'] : [['id', 'desc']];
  873. // 页码
  874. $page = isset($arg_list[0]['page']) ? $arg_list[0]['page'] : 1;
  875. // 每页数
  876. $perpage = isset($arg_list[0]['perpage']) ? $arg_list[0]['perpage'] : 20;
  877. // 回调方法名
  878. $func = isset($arg_list[1]) ? $arg_list[1] : "Short";
  879. // 自定义MODEL
  880. $model = isset($arg_list[2]) ? $arg_list[2] : $this;
  881. // 必备查询条件
  882. $map[] = ['mark', '=', 1];
  883. // 分页设置
  884. $start = ($page - 1) * $perpage;
  885. $limit = "{$start},{$perpage}";
  886. // 闭包查询条件格式化
  887. $query = $this->formatQuery($model, $map);
  888. // 查询总数
  889. $count = $query->count();
  890. // 排序(支持多重排序)
  891. $query = $query->when($sort, function ($query, $sort) {
  892. foreach ($sort as $v) {
  893. $query->orderBy($v[0], $v[1]);
  894. }
  895. });
  896. // 分页设置
  897. list($offset, $page_size) = explode(',', $limit);
  898. $result = $query->offset($offset)->limit($page_size)->select('id')->get();
  899. $result = $result ? $result->toArray() : [];
  900. $list = [];
  901. if (is_array($result)) {
  902. foreach ($result as $val) {
  903. $info = $model->getInfo($val['id']);
  904. if (!$info) {
  905. continue;
  906. }
  907. if (is_object($func)) {
  908. //方法函数
  909. $data = $func($info);
  910. } else {
  911. // 直接返回
  912. $data = $info;
  913. }
  914. $list[] = $data;
  915. }
  916. }
  917. // 返回结果
  918. $result = array(
  919. 'count' => $count,
  920. 'perpage' => $perpage,
  921. 'page' => $page,
  922. 'list' => $list,
  923. );
  924. return $result;
  925. }
  926. /**
  927. * 格式化查询条件
  928. * @param $model 模型
  929. * @param array $map 查询条件
  930. * @return mixed 返回结果
  931. * @author zongjl
  932. * @date 2019/5/30
  933. */
  934. public function formatQuery($model, $map)
  935. {
  936. $query = $model->where(function ($query) use ($map) {
  937. foreach ($map as $v) {
  938. if ($v instanceof \Closure) {
  939. $query = $query->where($v);
  940. continue;
  941. }
  942. // 判断是否是键值对类型
  943. if (key($v) !== 0) {
  944. $key = key($v);
  945. $val = $v[$key];
  946. $v = [$key, is_array($val) ? 'in' : '=', $val];
  947. }
  948. switch ($v[1]) {
  949. case 'like':
  950. // like查询
  951. if (strpos($v[0], '|') !== false) {
  952. $query->where(function ($query) use ($v) {
  953. $item = explode('|', $v[0]);
  954. foreach ($item as $vo) {
  955. $query->orWhere($vo, $v[1], $v[2]);
  956. }
  957. });
  958. } else {
  959. $query->where($v[0], $v[1], $v[2]);
  960. }
  961. break;
  962. case 'in':
  963. // in查询
  964. if (!is_array($v[2])) {
  965. $v[2] = explode(',', $v[2]);
  966. }
  967. $query->whereIn($v[0], $v[2]);
  968. break;
  969. case 'not in':
  970. // not in查询
  971. if (!is_array($v[2])) {
  972. $v[2] = explode(',', $v[2]);
  973. }
  974. $query->whereNotIn($v[0], $v[2]);
  975. break;
  976. case 'between':
  977. // between查询
  978. if (!is_array($v[2])) {
  979. $v[2] = explode(',', $v[2]);
  980. }
  981. $query->whereBetween($v[0], $v[2]);
  982. break;
  983. case 'not between':
  984. // not between查询
  985. if (!is_array($v[2])) {
  986. $v[2] = explode(',', $v[2]);
  987. }
  988. $query->whereNotBetween($v[0], $v[2]);
  989. break;
  990. case 'null':
  991. // null查询
  992. $query->whereNull($v[0]);
  993. break;
  994. case "not null":
  995. // not null查询
  996. $query->whereNotNull($v[0]);
  997. break;
  998. case "or":
  999. // or查询
  1000. //格式:or (status=1 and status=2)
  1001. $where = $v[0];
  1002. $query->orWhere(function ($query) use ($where) {
  1003. // 递归解析查询条件
  1004. $this->formatQuery($query, $where);
  1005. });
  1006. break;
  1007. case 'xor':
  1008. // xor查询
  1009. // 格式:and (status=1 or status=2)
  1010. $where = $v[0];
  1011. $query->where(function ($query) use ($where) {
  1012. foreach ($where as $w) {
  1013. $query->orWhere(function ($query) use ($w) {
  1014. // 递归解析查询条件
  1015. $this->formatQuery($query, [$w]);
  1016. });
  1017. }
  1018. });
  1019. break;
  1020. default:
  1021. // 常规查询
  1022. if (count($v) == 2) {
  1023. $query->where($v[0], '=', $v[1]);
  1024. } else {
  1025. $query->where($v[0], $v[1], $v[2]);
  1026. }
  1027. break;
  1028. }
  1029. }
  1030. });
  1031. return $query;
  1032. }
  1033. /**
  1034. * 添加打印SQL语句监听事件
  1035. * @param bool $is_sql 是否打印SQL
  1036. * @author zongjl
  1037. * @date 2019/5/29
  1038. */
  1039. public function getLastSql($is_sql = false)
  1040. {
  1041. if ($is_sql) {
  1042. \DB::listen(function ($query) {
  1043. $bindings = $query->bindings;
  1044. $sql = $query->sql;
  1045. foreach ($bindings as $replace) {
  1046. $value = is_numeric($replace) ? $replace : "'" . $replace . "'";
  1047. $sql = preg_replace('/\?/', $value, $sql, 1);
  1048. }
  1049. echo $sql;
  1050. });
  1051. }
  1052. }
  1053. /**
  1054. * 开启事务
  1055. * @author zongjl
  1056. * @date 2019/5/30
  1057. */
  1058. public function startTrans()
  1059. {
  1060. // 事务-缓存相关处理
  1061. $GLOBALS['trans'] = true;
  1062. $transId = uniqid("trans_");
  1063. $GLOBALS['trans_id'] = $transId;
  1064. $GLOBALS['trans_keys'] = [];
  1065. $info = debug_backtrace();
  1066. $this->setCache($transId, $info[0]);
  1067. // 开启事务
  1068. \DB::beginTransaction();
  1069. }
  1070. /**
  1071. * 事务回滚
  1072. * @author zongjl
  1073. * @date 2019/5/30
  1074. */
  1075. public function rollBack()
  1076. {
  1077. // 事务回滚
  1078. \DB::rollBack();
  1079. // 回滚缓存处理
  1080. foreach ($GLOBALS['trans_keys'] as $key) {
  1081. $this->deleteCache($key);
  1082. }
  1083. $this->deleteCache($GLOBALS['trans_id']);
  1084. $GLOBALS['trans'] = false;
  1085. $GLOBALS['trans_keys'] = [];
  1086. }
  1087. /**
  1088. * 提交事务
  1089. * @author zongjl
  1090. * @date 2019/5/30
  1091. */
  1092. public function commit()
  1093. {
  1094. // 提交事务
  1095. \DB::commit();
  1096. // 事务缓存同步删除
  1097. $GLOBALS['trans'] = false;
  1098. $GLOBALS['trans_keys'] = [];
  1099. $this->deleteCache($GLOBALS['trans_id']);
  1100. }
  1101. /**
  1102. * 开启执行日志
  1103. * @author zongjl
  1104. * @date 2019/5/31
  1105. */
  1106. public function beginSQLLog()
  1107. {
  1108. \DB::connection()->enableQueryLog();
  1109. }
  1110. /**
  1111. * 结束日志并打印
  1112. * @author zongjl
  1113. * @date 2019/5/30
  1114. */
  1115. public function endSQLLog()
  1116. {
  1117. // 获取查询语句、参数和执行时间
  1118. $result = \DB::getLastSql();
  1119. if ($result) {
  1120. foreach ($result as &$val) {
  1121. $bindings = $val['bindings'];
  1122. $sql = $val['query'];
  1123. foreach ($bindings as $replace) {
  1124. $value = is_numeric($replace) ? $replace : "'" . $replace . "'";
  1125. $val['query'] = preg_replace('/\?/', $value, $sql, 1);
  1126. }
  1127. }
  1128. }
  1129. print_r($result);
  1130. exit;
  1131. }
  1132. }