BaseModel.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace cores;
  13. use think\Model;
  14. use think\db\Query;
  15. use think\Paginator;
  16. use think\model\Collection;
  17. use cores\extension\ModelExt;
  18. use app\common\exception\BaseException;
  19. /**
  20. * 模型基类
  21. * Class BaseModel
  22. * @package app\common\model
  23. */
  24. abstract class BaseModel extends Model
  25. {
  26. // 当前访问的商城ID
  27. public static $storeId;
  28. // 定义表名
  29. protected $name;
  30. // 模型别名
  31. protected $alias = '';
  32. // 定义全局的查询范围
  33. protected $globalScope = ['store_id'];
  34. // 是否允许全局查询store_id
  35. protected $isGlobalScopeStoreId = true;
  36. // 错误信息
  37. protected $error = '';
  38. // 模型基类扩展
  39. /* @var ModelExt $ModelExt */
  40. private static $ModelExt;
  41. /**
  42. * 模型基类初始化
  43. * @throws BaseException
  44. */
  45. public static function init()
  46. {
  47. parent::init();
  48. // 绑定ModelExt
  49. if (!self::$ModelExt) {
  50. self::$ModelExt = ModelExt::getInstance();
  51. }
  52. // 绑定store_id
  53. self::getStoreId();
  54. }
  55. /**
  56. * 获取当前操作的商城ID
  57. * @return int|null
  58. */
  59. private static function getStoreId()
  60. {
  61. if (empty(self::$storeId) && in_array(app_name(), ['store', 'api'])) {
  62. self::$storeId = getStoreId();
  63. }
  64. return self::$storeId;
  65. }
  66. /**
  67. * 获取当前调用来源的应用名称
  68. * 例如:admin, api, store
  69. * @return string|bool
  70. */
  71. protected final static function getCalledModule()
  72. {
  73. if (preg_match('/app\\\(\w+)/', get_called_class(), $class)) {
  74. return $class[1];
  75. }
  76. return 'common';
  77. }
  78. /**
  79. * 查找单条记录
  80. * @param mixed $data 查询条件
  81. * @param array $with 关联查询
  82. * @return array|static|null
  83. */
  84. public static function get($data, $with = [])
  85. {
  86. try {
  87. $query = (new static)->with($with);
  88. return is_array($data) ? $query->where($data)->find() : $query->find((int)$data);
  89. } catch (\Exception $e) {
  90. return null;
  91. }
  92. }
  93. /**
  94. * 定义全局的查询范围
  95. * @param Query $query
  96. * @return bool
  97. */
  98. public function scopeStore_id(Query $query)
  99. {
  100. if (!$this->isGlobalScopeStoreId) return false;
  101. $storeId = self::getStoreId();
  102. $storeId > 0 && $query->where($query->getTable() . '.store_id', $storeId);
  103. return true;
  104. }
  105. /**
  106. * 设置默认的检索数据
  107. * @param array $query
  108. * @param array $default
  109. * @return array
  110. */
  111. public function setQueryDefaultValue(array $query, array $default = [])
  112. {
  113. $data = array_merge($default, $query);
  114. foreach ($query as $field => $value) {
  115. // 不存在默认值跳出循环
  116. if (!isset($default[$field])) continue;
  117. // 如果传参为空, 设置默认值
  118. if (empty($value) && $value !== '0') {
  119. $data[$field] = $default[$field];
  120. }
  121. }
  122. return $data;
  123. }
  124. /**
  125. * 设置基础查询条件(用于简化基础alias和field)
  126. * @param string $alias
  127. * @param array $join
  128. * @return static
  129. */
  130. public function setBaseQuery($alias = '', $join = [])
  131. {
  132. // 设置别名
  133. $aliasValue = $alias ?: $this->alias;
  134. $query = $this->alias($aliasValue)->field("{$aliasValue}.*");
  135. // join条件
  136. if (!empty($join)) : foreach ($join as $item):
  137. $query->join($item[0], "{$item[0]}.{$item[1]}={$aliasValue}."
  138. . (isset($item[2]) ? $item[2] : $item[1]));
  139. endforeach; endif;
  140. return $query;
  141. }
  142. /**
  143. * 批量更新多条数据(支持带where条件)
  144. * @param iterable $dataSet [0 => ['data'=>[], 'where'=>[]]]
  145. * @return array|false
  146. */
  147. public function updateAll(iterable $dataSet)
  148. {
  149. if (empty($dataSet)) {
  150. return false;
  151. }
  152. return $this->transaction(function () use ($dataSet) {
  153. $result = [];
  154. foreach ($dataSet as $key => $item) {
  155. $result[$key] = self::updateBase($item['data'], $item['where']);
  156. }
  157. return $result;
  158. });
  159. }
  160. /**
  161. * 批量新增数据
  162. * @param iterable $dataSet [0 => ['id'=>10001, 'name'=>'wang']]
  163. * @return array|false
  164. */
  165. public function addAll(iterable $dataSet)
  166. {
  167. if (empty($dataSet)) {
  168. return false;
  169. }
  170. return $this->transaction(function () use ($dataSet) {
  171. $result = [];
  172. foreach ($dataSet as $key => $item) {
  173. $result[$key] = self::create($item, $this->field);
  174. }
  175. return $result;
  176. });
  177. }
  178. /**
  179. * 删除记录
  180. * @param array $where
  181. * 方式1: ['goods_id' => $goodsId]
  182. * 方式2: [
  183. * ['store_user_id', '=', $storeUserId],
  184. * ['role_id', 'in', $deleteRoleIds]
  185. * ]
  186. * @return int
  187. */
  188. public static function deleteAll(array $where)
  189. {
  190. return (new static)->where($where)->delete();
  191. }
  192. /**
  193. * 返回错误信息
  194. * @return string
  195. */
  196. public function getError()
  197. {
  198. return empty($this->error) ? false : $this->error;
  199. }
  200. /**
  201. * 字段值增长
  202. * @param array|int|bool $where
  203. * @param string $field
  204. * @param float $step
  205. * @return mixed
  206. */
  207. protected function setInc($where, string $field, float $step = 1)
  208. {
  209. if (is_numeric($where)) {
  210. $where = [$this->getPk() => (int)$where];
  211. }
  212. return $this->where($where)->inc($field, $step)->update();
  213. }
  214. /**
  215. * 字段值消减
  216. * @param array|int|bool $where
  217. * @param string $field
  218. * @param float $step
  219. * @return mixed
  220. */
  221. protected function setDec($where, string $field, float $step = 1)
  222. {
  223. return $this->where($where)->dec($field, $step)->update();
  224. }
  225. /**
  226. * 实例化新查询对象
  227. * @return \think\db\BaseQuery
  228. */
  229. protected function getNewQuery()
  230. {
  231. return $this->db();
  232. }
  233. /**
  234. * 新增hidden属性
  235. * @param array $hidden
  236. * @return $this
  237. */
  238. protected function addHidden(array $hidden)
  239. {
  240. $this->hidden = array_merge($this->hidden, $hidden);
  241. return $this;
  242. }
  243. /**
  244. * 生成字段列表(字段加上$alias别名)
  245. * @param string $alias 别名
  246. * @param array $withoutFields 排除的字段
  247. * @return array
  248. */
  249. protected function getAliasFields(string $alias, $withoutFields = [])
  250. {
  251. $fields = array_diff($this->getTableFields(), $withoutFields);
  252. foreach ($fields as &$field) {
  253. $field = "$alias.$field";
  254. }
  255. return $fields;
  256. }
  257. /**
  258. * 更新数据[单条]
  259. * @param array|int $where 更新条件默认arra, 也支持传参int, 但必须是主键id
  260. * @param array $data 更新的数据内容
  261. * @return bool
  262. */
  263. public static function updateOne($where, array $data): bool
  264. {
  265. $model = new static;
  266. return self::$ModelExt->updateOne($model, $where, $data);
  267. }
  268. /**
  269. * 更新数据[批量] 如果只更新单条记录请使用 updateOne方法
  270. * @param array $data 更新的数据内容
  271. * @param array $where 更新条件
  272. * @param array $allowField 允许的字段
  273. * @return bool
  274. */
  275. public static function updateBase(array $data, array $where, array $allowField = []): bool
  276. {
  277. $model = new static;
  278. return self::$ModelExt->updateBase($model, $data, $where, $allowField);
  279. }
  280. /**
  281. * 设置模型的更新条件
  282. * @access protected
  283. * @param mixed $where 更新条件
  284. * @return static
  285. */
  286. public function mySetUpdateWhere($where)
  287. {
  288. parent::setUpdateWhere($where);
  289. return $this;
  290. }
  291. /**
  292. * 合并设置项
  293. * @param array $confusion 系统默认配置
  294. * @param array $variable 用户自定义
  295. * @param string $_ 数据来源[后期加载附加数据]
  296. * @param false $__ 是否只显示value
  297. * @return array
  298. */
  299. protected static function reorganize(array $confusion, array $variable, string $_ = 'cache', $__ = false)
  300. {
  301. return self::$ModelExt->reorganize($confusion, $variable, $_, $__);
  302. }
  303. /**
  304. * 仅返回values数据
  305. * @param array $setting 全部设置
  306. * @param bool $setKey 是否设置键值
  307. * @return array
  308. */
  309. public final static function getValues(array $setting, bool $setKey = true)
  310. {
  311. return self::$ModelExt->getValues($setting, $setKey);
  312. }
  313. /**
  314. * 加载关联数据 [列表数据类型]
  315. * @param iterable $dataSet 数据集
  316. * @param array $with 关联方法名 例如: ['user']; 支持嵌套['user.avatar'] ['user' => 'avatar']
  317. * @param bool $isToArray 是否用数组格式输出
  318. * @return Collection|Paginator|iterable
  319. */
  320. public static final function preload(iterable $dataSet, array $with, bool $isToArray = false)
  321. {
  322. return self::$ModelExt->preload($dataSet, $with, $isToArray);
  323. }
  324. /**
  325. * 加载关联数据 [单条数据类型]
  326. * @param mixed $model
  327. * @param array $with 关联方法名 例如: ['user']; 不支持嵌套
  328. * @return Model|static|false
  329. */
  330. public static final function related($model, array $with)
  331. {
  332. return self::$ModelExt->related($model, $with);
  333. }
  334. }