BaseModel.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. <?php
  2. namespace App\Base\Models;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Support\Facades\Cache;
  5. use Illuminate\Support\Facades\Date;
  6. use Illuminate\Support\Facades\DB;
  7. class BaseModel extends Model
  8. {
  9. use Criteria;
  10. /**
  11. * 插入时间字段
  12. */
  13. const CREATED_AT = 'create_time';
  14. /**
  15. * 更新时间字段
  16. */
  17. const UPDATED_AT = 'update_time';
  18. /**
  19. * 状态字段
  20. */
  21. const DELETED_AT = 'status';
  22. /**
  23. * 正常状态
  24. */
  25. const STATUS_ENABLED = 0;
  26. /**
  27. * 禁用状态
  28. */
  29. const STATUS_DISABLED = 1;
  30. /**
  31. * 删除状态
  32. */
  33. const STATUS_DELETED = 2;
  34. /**
  35. * 审核状态:未提交审核
  36. */
  37. const AUDIT_STATUS_NOT_SUBMITTED = 0;
  38. /**
  39. * 审核状态:已提交/审核中
  40. */
  41. const AUDIT_STATUS_SUBMITTED = 1;
  42. /**
  43. * 审核状态:审核通过
  44. */
  45. const AUDIT_STATUS_SUCCESSFUL = 2;
  46. /**
  47. * 审核状态:审核失败
  48. */
  49. const AUDIT_STATUS_FAIL = 3;
  50. /**
  51. * 该模型是否被自动维护时间戳
  52. *
  53. * @var bool
  54. */
  55. public $timestamps = true;
  56. /**
  57. * 别名名称
  58. * @var null
  59. */
  60. protected $aliasName = null;
  61. /**
  62. * 模型的日期字段保存格式。
  63. *
  64. * @var string
  65. */
  66. protected $dateFormat = 'Y-m-d H:i:s';
  67. /**
  68. * 新的连接方式,用于分库后可指定连接哪个库的,因原有的connection在分库中已失效,所以需要重新加此变量
  69. * @var null
  70. */
  71. protected $connectionNew = null;
  72. public function __construct(array $attributes = [])
  73. {
  74. parent::__construct($attributes);
  75. }
  76. /**
  77. * 自动获取数据库表字段
  78. */
  79. public function setFillable()
  80. {
  81. $key = get_class($this);
  82. $cache = Cache::store('file')->get($key);
  83. if (empty($cache)) {
  84. // $columns = Schema::getColumnListing($this->table);
  85. //如果是公共库的,会读取默认库,而默认库没有表的情况下会为空,所以改成以下语句
  86. $columns = $this->getConnection()->getSchemaBuilder()->getColumnListing($this->table);
  87. $cache = $columns;
  88. Cache::store('file')->put($key, $columns, config('cache.columns'));
  89. }
  90. $this->fillable = $cache;
  91. }
  92. /**
  93. * 获取所有列
  94. * @return array
  95. */
  96. public function getColumns()
  97. {
  98. $this->setFillable();
  99. return $this->getFillable();
  100. }
  101. /**
  102. * 过滤掉非数据库字段的数据
  103. * @param $data
  104. * @return array
  105. */
  106. public function filter($data)
  107. {
  108. if (empty($this->fillable)) {
  109. $this->setFillable();
  110. }
  111. $result = [];
  112. if (empty($data) || !is_array($data)) {
  113. return $result;
  114. }
  115. foreach ($this->fillable as $item) {
  116. if (isset($data[$item])) {
  117. $result[$item] = $data[$item];
  118. }
  119. }
  120. return $result;
  121. }
  122. /**
  123. * 覆盖setCreatedAt 不添加createAt字段
  124. *
  125. * @param mixed $value
  126. * @return $this
  127. */
  128. public function setCreatedAt($value)
  129. {
  130. if (!empty(static::CREATED_AT)) {
  131. $this->{static::CREATED_AT} = $value;
  132. }
  133. if (!empty(static::UPDATED_AT)) {
  134. $this->{static::UPDATED_AT} = $value;
  135. }
  136. return $this;
  137. }
  138. /**
  139. * Set the value of the "updated at" attribute.
  140. *
  141. * @param mixed $value
  142. * @return $this
  143. */
  144. public function setUpdatedAt($value)
  145. {
  146. if (!empty(static::UPDATED_AT)) {
  147. $this->{static::UPDATED_AT} = $value;
  148. }
  149. return $this;
  150. }
  151. /**
  152. * 覆盖父类方法 新建连接
  153. * @return \Illuminate\Database\Query\Builder|QueryBuilder
  154. */
  155. protected function newBaseQueryBuilder()
  156. {
  157. $connection = $this->getConnection();
  158. return new QueryBuilder(
  159. $connection, $connection->getQueryGrammar(), $connection->getPostProcessor()
  160. );
  161. }
  162. /**
  163. * 覆盖父类方法
  164. * @param \Illuminate\Database\Query\Builder $query
  165. * @return \App\Base\Models\EloquentBuilder|Model|Builder
  166. */
  167. public function newEloquentBuilder($query)
  168. {
  169. return new EloquentBuilder($query);
  170. }
  171. /**
  172. * 覆盖父类方法 获取连接名称
  173. * @return null|string
  174. */
  175. public function getConnectionName()
  176. {
  177. if (!config('app.database_split', false)) { // 未开启分库
  178. return null;
  179. }
  180. //判断是否在model中有指定连接哪个库,如果有,直接返回此指定库,没有则继续往下按公司连接判断
  181. if ($this->connectionNew) {
  182. return $this->connectionNew;
  183. }
  184. return $this->connection;
  185. }
  186. /**
  187. * 设置全局DB Config
  188. * @param $dbConnectionName
  189. * @param $db
  190. */
  191. public static function setConfigDBConnection($dbConnectionName, $db)
  192. {
  193. config([
  194. $dbConnectionName => [
  195. 'driver' => 'mysql',
  196. 'host' => $db['host'],
  197. 'port' => $db['port'],
  198. 'database' => $db['database'],
  199. 'username' => $db['username'],
  200. 'password' => $db['password'],
  201. 'charset' => config('database.connections.mysql.charset') ?? 'utf8mb4',
  202. 'collation' => config('database.connections.mysql.collation') ?? 'utf8mb4_general_ci',
  203. 'prefix' => '',
  204. 'timezone' => '+08:00',
  205. 'strict' => false
  206. ]]);
  207. }
  208. /**
  209. * 生成DBConnectionName
  210. * @param $connectionName
  211. * @return string
  212. */
  213. public static function getDBConnectionName($connectionName)
  214. {
  215. $dbConnectionName = 'database.connections.' . $connectionName;
  216. return $dbConnectionName;
  217. }
  218. /**
  219. * 别名
  220. * @param $name
  221. * @return
  222. */
  223. public function alias($name)
  224. {
  225. $this->aliasName = $name;
  226. return $this->from($this->getTable() . ' as ' . $name);
  227. }
  228. /**
  229. * 获取别名名称
  230. * @return null
  231. */
  232. public function getAliasName()
  233. {
  234. return $this->aliasName;
  235. }
  236. /**
  237. * Set the table associated with the model.
  238. *
  239. * @param string $table
  240. * @return $this
  241. */
  242. public function setTable($table)
  243. {
  244. $table = trim($table);
  245. $this->table = $table;
  246. if (strpos($table, ' as ')) {
  247. list($table, $alias) = explode(' as ', $table);
  248. if (!empty($alias)) {
  249. $this->aliasName = trim($alias);
  250. }
  251. }
  252. return $this;
  253. }
  254. /**
  255. * 返回正常状态的值
  256. * @return int
  257. */
  258. public function getStatusEnabled()
  259. {
  260. return self::STATUS_ENABLED;
  261. }
  262. /**
  263. * 返回禁用状态的值
  264. * @return int
  265. */
  266. public function getStatusDisabled()
  267. {
  268. return self::STATUS_DISABLED;
  269. }
  270. /**
  271. * 返回删除状态的值
  272. * @return int
  273. */
  274. public function getStatusDeleted()
  275. {
  276. return self::STATUS_DELETED;
  277. }
  278. public function isJsonCastingField($field)
  279. {
  280. if (isset($this->casts[$field]) && $this->casts[$field] == 'array') {
  281. return true;
  282. }
  283. return false;
  284. }
  285. //重载model里的事件通知
  286. public function fireModelEvent($event, $halt = true)
  287. {
  288. parent::fireModelEvent($event, $halt);
  289. }
  290. /**
  291. * 格式化时间
  292. * */
  293. protected function serializeDate($date)
  294. {
  295. if ($date instanceof \DateTimeInterface) {
  296. return $date->format('Y-m-d H:i:s');
  297. }
  298. return $date;
  299. }
  300. /**
  301. * 解析时间值
  302. * @param mixed $value
  303. * @return \Illuminate\Support\Carbon|mixed
  304. */
  305. protected function asDateTime($value)
  306. {
  307. if (null == $value || '0000-00-00 00:00:00' == $value) {
  308. return $value;
  309. }
  310. $format = $this->getDateFormat();
  311. try {
  312. $date = Date::createFromFormat($format, $value);
  313. } catch (\InvalidArgumentException $e) {
  314. $date = false;
  315. }
  316. return $date ?: Date::parse($value);
  317. }
  318. /**
  319. * @param bool $alias
  320. * @return \Illuminate\Database\Query\Builder
  321. */
  322. public function db($alias = false)
  323. {
  324. return DB::table($this->getTable() . ($alias ? " as $alias" : ''));
  325. }
  326. /**
  327. * 批量写入数据
  328. * @param $datas
  329. * @return bool
  330. */
  331. public function insertAll($datas)
  332. {
  333. if (empty($datas)) {
  334. return false;
  335. }
  336. foreach ($datas as &$data) {
  337. if ($this->timestamps) {
  338. $createAt = $this::CREATED_AT;
  339. $updateAt = $this::UPDATED_AT;
  340. $data[$updateAt] = $data[$createAt] = nowTime();
  341. }
  342. }
  343. return DB::table($this->table)->insert($datas);
  344. }
  345. /**
  346. * 保存一条记录或者多条记录
  347. * @param array $data
  348. * @param mixed $where
  349. * @return int
  350. */
  351. public function updateData($data, $where = false)
  352. {
  353. // $data = $this->filter($data);
  354. if ($this->timestamps) {
  355. $updateAt = $this::UPDATED_AT;
  356. $data[$updateAt] = nowTime();
  357. }
  358. if (!$where) {
  359. $id = $data[$this->getKeyName()];
  360. unset($data[$this->getKeyName()]);
  361. $where = [
  362. $this->getKeyName() => $id
  363. ];
  364. }
  365. return $this->bindCriteria($this->db(),$where)->update($data);
  366. }
  367. /**
  368. * 新增记录
  369. * @param $data
  370. * @return int
  371. */
  372. public function insertData($data)
  373. {
  374. // $data = $this->filter($data);
  375. if ($this->timestamps) {
  376. $createAt = $this::CREATED_AT;
  377. $updateAt = $this::UPDATED_AT;
  378. $data[$updateAt] = $data[$createAt] = nowTime();
  379. }
  380. return $this->db()->insertGetId($data);
  381. }
  382. /**
  383. * 获取一条记录
  384. * @param $id
  385. * @param $field
  386. * @return Model|\Illuminate\Database\Query\Builder|null|object
  387. */
  388. public function findOneById($id, $field = "*")
  389. {
  390. $db = $this->db()->selectRaw($field);
  391. if (method_exists($this, 'runSoftDelete') && !isset($criteria['status'])) {
  392. $db = $db->whereIn('status', [0, 1]);
  393. }
  394. return $db->where([$this->getKeyName() => $id])->first();
  395. }
  396. /**
  397. * 根据条件获取一条记录
  398. * @param $criteria
  399. * @param $field
  400. * @return \Illuminate\Database\Eloquent\Model|null|static
  401. */
  402. public function findOneBy($criteria, $field = "*")
  403. {
  404. $db = $this->db()->selectRaw($field);
  405. if (method_exists($this, 'runSoftDelete') && !isset($criteria['status'])) {
  406. $db = $db->whereIn('status', [0, 1]);
  407. }
  408. return $this->bindCriteria($db, $criteria)->first();
  409. }
  410. /**
  411. * 根据条件获取一条记录
  412. * @param $criteria
  413. * @param $field
  414. * @return \Illuminate\Database\Eloquent\Model|null|static
  415. */
  416. public function countBy($criteria)
  417. {
  418. $db = $this->db();
  419. if (method_exists($this, 'runSoftDelete') && !isset($criteria['status'])) {
  420. $db = $db->whereIn('status', [0, 1]);
  421. }
  422. return $this->bindCriteria($db, $criteria)->count();
  423. }
  424. /**
  425. * 绑定查询条件
  426. * @param \Illuminate\Database\Query\Builder $db
  427. * @param $criteria
  428. * @return \Illuminate\Database\Query\Builder
  429. */
  430. public function bindCriteria($db, &$criteria)
  431. {
  432. $where = [];
  433. foreach ($criteria as $k=>$v) {
  434. if (!is_numeric($k)) {
  435. if (is_array($v)) {
  436. if ($v[0] == 'in') {
  437. $db = $db->whereIn($k, $v[1]);
  438. } else {
  439. $where[] = [$k, $v[0], $v[1]];
  440. }
  441. } else {
  442. $where[$k] = $v;
  443. }
  444. } else if (is_array($v)) {
  445. if ($v[1] == 'in') {
  446. $db = $db->whereIn($v[0], $v[2]);
  447. } else {
  448. $where[] = $v;
  449. }
  450. }
  451. }
  452. return $db->where($where);
  453. }
  454. /**
  455. * 根据条件获取多条记录
  456. * @param $criteria
  457. * @param $field
  458. * @return array
  459. */
  460. public function findBy($criteria, $field = "*")
  461. {
  462. $db = $this->db()->selectRaw($field);
  463. if (method_exists($this, 'runSoftDelete') && !isset($criteria['status'])) {
  464. $db = $db->whereIn('status', [0, 1]);
  465. }
  466. return $this->bindCriteria($db,$criteria)
  467. ->get()->toArray();
  468. }
  469. /**
  470. * 根据条件删除
  471. * @param $criteria
  472. * @return int
  473. */
  474. public function deleteBy($criteria)
  475. {
  476. if (method_exists($this, 'runSoftDelete') && !isset($criteria['status'])) {
  477. return $this->db()->where($criteria)->update(['status'=>2]);
  478. } else {
  479. return $this->db()->where($criteria)->delete();
  480. }
  481. }
  482. }