BaseModel.php 36 KB

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