shipfi

lumen-rule-modle

1 +<?php
2 +/**
3 + * Created by Qingger Corp.
4 + * User: jsspf
5 + * Date: 2017/5/5
6 + * Time: 15:37
7 + */
8 +namespace App\Models;
9 +
10 +use App\Exceptions\ECException;
11 +use App\Exceptions\ModelException;
12 +use App\Library\AppUtils\UtilToolMethods;
13 +use App\Library\VariDefines\Common\GlobalSysEnum;
14 +use App\Library\VariDefines\ErrorCodes\GlobalErrCode;
15 +use App\Services\Cache\AppCacheManager;
16 +use Illuminate\Database\Query\Builder;
17 +use Illuminate\Database\Eloquent\Model;
18 +use Illuminate\Database\Query\Expression;
19 +use Illuminate\Support\Collection;
20 +use Illuminate\Support\Facades\App;
21 +use Windwalker\String\SimpleTemplate;
22 +use Log;
23 +use DB;
24 +
25 +/**
26 + * Class BaseModel
27 + * @package App\Models
28 + *
29 + * @method Builder where(string|array|\Closure $column, string $operator = null, mixed $value = null, string $boolean = 'and')
30 + * @method Builder orWhere(string $column, string $operator = null, mixed $value = null)
31 + * @method Builder whereRaw(string $sql, array $bindings = array(), string $boolean = 'and')
32 + * @method Builder orWhereRaw(string $sql, array $bindings = array())
33 + * @method Builder whereBetween(string $column, array $values, string $boolean = 'and', bool $not = false)
34 + * @method Builder orWhereBetween(string $column, array $values)
35 + * @method Builder whereNotBetween(string $column, array $values, string $boolean = 'and')
36 + * @method Builder orWhereNotBetween(string $column, array $values)
37 + * @method Builder whereNested(\Closure $callback, string $boolean = 'and')
38 + * @method addNestedWhereQuery(Builder|Builder $query, string $boolean = 'and')
39 + * @method Builder whereExists(\Closure $callback, string $boolean = 'and', bool $not = false)
40 + * @method Builder orWhereExists(\Closure $callback, bool $not = false)
41 + * @method Builder whereNotExists(\Closure $callback, string $boolean = 'and')
42 + * @method Builder orWhereNotExists(\Closure $callback)
43 + * @method Builder whereIn(string $column, mixed $values, string $boolean = 'and', bool $not = false)
44 + * @method Builder orWhereIn(string $column, mixed $values)
45 + * @method Builder whereNotIn(string $column, mixed $values, string $boolean = 'and')
46 + * @method Builder orWhereNotIn(string $column, mixed $values)
47 + * @method Builder whereNull(string $column, string $boolean = 'and', bool $not = false)
48 + * @method Builder whereNotNull(string $column, string $boolean = 'and')
49 + * @method Builder orWhereNotNull(string $column)
50 + * @method Builder whereDate(string $column, string $operator, int $value, string $boolean = 'and')
51 + * @method Builder whereDay(string $column, string $operator, int $value, string $boolean = 'and')
52 + * @method Builder whereMonth(string $column, string $operator, int $value, string $boolean = 'and')
53 + * @method Builder whereYear(string $column, string $operator, int $value, string $boolean = 'and')
54 + * @method $this dynamicWhere(string $method, string $parameters)
55 + * @method Builder groupBy()
56 + * @method Builder having(string $column, string $operator = null, string $value = null, string $boolean = 'and')
57 + * @method Builder orHaving(string $column, string $operator = null, string $value = null)
58 + * @method $this havingRaw(string $sql, array $bindings = array(), string $boolean = 'and')
59 + * @method Builder orHavingRaw(string $sql, array $bindings = array())
60 + * @method Builder orderBy(string $column, string $direction = 'asc')
61 + * @method Builder latest(string $column = 'created_at')
62 + * @method Builder oldest(string $column = 'created_at')
63 + * @method Builder orderByRaw(string $sql, array $bindings = array())
64 + * @method $this offset(int $value)
65 + * @method Builder skip(int $value)
66 + * @method Builder limit(int $value)
67 + * @method Builder take(int $value)
68 + * @method Builder forPage(int $page, int $perPage = 15)
69 + * @method Builder union(Builder|\Closure $query, bool $all = false)
70 + * @method Builder unionAll(Builder|\Closure $query)
71 + * @method $this lock(bool $value = true)
72 + * @method Builder lockForUpdate()
73 + * @method Builder sharedLock()
74 + * @method string toSql()
75 + * @method mixed find(int $id, array $columns = array('*'))
76 + * @method mixed first(array $columns = array('*'))
77 + * @method mixed value(string $column)
78 + * @method $this select(array|mixed $columns = array('*'))
79 + * @method $this distinct()
80 + * @method $this join(string $table, string $one, string $operator = null, string $two = null, string $type = 'inner', bool $where = false)
81 + * @method Builder joinWhere(string $table, string $one, string $operator, string $two, string $type = 'inner')
82 + * @method Builder leftJoin(string $table, string $first, string $operator = null, string $second = null)
83 + * @method Builder leftJoinWhere(string $table, string $one, string $operator, string $two)
84 + * @method Builder rightJoin(string $table, string $first, string $operator = null, string $second = null)
85 + * @method Builder rightJoinWhere(string $table, string $one, string $operator, string $two)
86 + * @method Collection get(array $columns = array('*'))
87 + * @method array lists(string $column, string|null $key = null)
88 + * @method string implode(string $column, string $glue = '')
89 + * @method bool exists()
90 + * @method int count(string $columns = '*')
91 + * @method mixed min(string $column)
92 + * @method mixed max(string $column)
93 + * @method mixed sum(string $column)
94 + * @method mixed avg(string $column)
95 + * @method mixed average(string $column)
96 + * @method mixed aggregate(string $function, array $columns = array('*'))
97 + * @method float|int numericAggregate(string $function, array $columns = array('*'))
98 + * @method bool insert(array $values)
99 + * @method int insertGetId(array $values, string $sequence = null)
100 + * @method void truncate()
101 + * @method Builder newQuery()
102 + * @method void mergeWheres(array $wheres, array $bindings)
103 + * @method Expression raw(mixed $value)
104 + *
105 + */
106 +class BaseModel extends Model
107 +{
108 + use UtilToolMethods;
109 + protected $table='';
110 + protected $defautCacheTime = 60;
111 +
112 + /**
113 + * 缓存管理器
114 + * @var AppCacheManager
115 + */
116 + protected $appCacheManager = null;
117 +
118 + /**
119 + * 对Model的操作行为
120 + * @var string
121 + */
122 + private $modelAction = GlobalSysEnum::STS_CREATED;
123 +
124 +
125 + public function __construct(array $attributes = [])
126 + {
127 + parent::__construct($attributes);
128 + $this->appCacheManager = App::make(AppCacheManager::class);
129 + }
130 +
131 + public function getPrimaryKey() {
132 + return $this->primaryKey;
133 + }
134 +
135 + public function getMyId() {
136 + return $this->{$this->primaryKey};
137 + }
138 +
139 + public function getTable() {
140 + return $this->table;
141 + }
142 +
143 + public function getColItem($item) {
144 + return $this->table.".".$item;
145 + }
146 +
147 + public function formatArray($queryResult)
148 + {
149 + return json_decode(json_encode($queryResult), true);
150 + }
151 +
152 + /**
153 + * 基础的条件查询,支持以下几种方式
154 + * $this->getQueryByConditions(array(
155 + * 'id' => '1', // id==1
156 + * 'col1' => [1,2,3], // col1 in (1,2,3)
157 + * 'col2' => [ 'sign' => '!=' , value=>3 ] // col2 != 3
158 + * 'col3' => [ 'operator=>'whereNotIn', value=[1,2,3] ] // col3 not in (1,2,3)
159 + * ));
160 + * @param array $conditions
161 + *
162 + * @param array $selectItems
163 + * @param bool $isDistinct
164 + * @return Builder
165 + */
166 + public function getQueryByConditions(Array $conditions,Array $selectItems=[],$isDistinct=false) {
167 + $query = $this;
168 + foreach ($conditions as $key=>$val) {
169 + if(is_array($val) && isset($val['operator'])) {
170 + $query = $query->{$val['operator']}($val['value']);
171 + }elseif(is_array($val) && isset($val['sign'])) {
172 + $query = $query->where($key,$val['sign'],$val['value']);
173 + }elseif(is_array($val)){
174 + $query = $query->whereIn($key,$val);
175 + }else{
176 + $query = $query->where($key,$val);
177 + }
178 + }
179 + if(!empty($selectItems)) {
180 + $query = $query->select($selectItems);
181 + }
182 + if($isDistinct) {
183 + $query = $query->distinct();
184 + }
185 +
186 + return $query;
187 + }
188 +
189 +
190 +
191 + /* override */
192 + public function checkValidItem(Array $conditions) {
193 + return $this->where($conditions)->count();
194 + }
195 +
196 + /**
197 + * 根据primaryId更新数据字段
198 + * @param array $updateItems
199 + * @param $idVal
200 + * @return int
201 + */
202 + public function updateItemsByPrimaryId(Array $updateItems,$idVal) {
203 + return DB::table($this->table)->where($this->primaryKey,$idVal)->update($updateItems);
204 + }
205 +
206 + /**
207 + * 根据条件更新数据字段
208 + * @param array $updateItems
209 + * @param array $conditions
210 + * @return int
211 + */
212 + public function updateItemsByConditions(Array $updateItems,Array $conditions) {
213 + return DB::table($this->table)->where($conditions)->update($updateItems);
214 + }
215 +
216 + /**
217 + * 检查模型的ID数据是否存在,即是否真正的实体
218 + * @return bool
219 + * @throws ModelException
220 + */
221 + protected function checkObjectIdExist() {
222 + if(!isset($this->primaryKey) || !isset($this->{$this->primaryKey})) {
223 + throw new ModelException('Object Not Found Error',GlobalErrCode::ERR_MODEL_OBJECT_NOT_FOUND);
224 + }
225 + return true;
226 + }
227 +
228 +
229 + /**
230 + * 根据主键获得实例
231 + * @param $keyId
232 + * @return BaseModel
233 + */
234 + public function getInstanceByKeyId($keyId) {
235 + return $this->find($keyId);
236 + }
237 +
238 + /**
239 + * @return mixed|null
240 + */
241 + public function getMyUpdatedAt() {
242 + return isset($this->updated_at) ? $this->updated_at : null;
243 + }
244 +
245 + /**
246 + * @return mixed|null
247 + */
248 + public function getMyCreatedAt() {
249 + return isset($this->created_at) ? $this->created_at : null;
250 + }
251 +
252 +
253 + /**
254 + * 检查ID对应的数据实例是否存在
255 + * @param $id
256 + * @return true
257 + * @throws ECException
258 + */
259 + public function checkIdExists($id) {
260 + $instance = $this->find($id);
261 + if(!$instance) {
262 + throw new ECException('数据对应的ID不存在:'.$id,GlobalErrCode::ERR_DATA_NOT_FOUND);
263 + }
264 + return true;
265 + }
266 +
267 + /**
268 + * @override
269 + * @param array $options
270 + * @return bool
271 + */
272 + public function save(array $options = [])
273 + {
274 + if(isset($this->{$this->primaryKey})) {
275 + $this->modelAction = GlobalSysEnum::STS_UPDATED;
276 + } else {
277 + $this->modelAction = GlobalSysEnum::STS_CREATED;
278 + }
279 + Log::debug(SimpleTemplate::render('Model Save for {{table}} - {{action}}',[
280 + 'table' => $this->table,
281 + 'action' => $this->modelAction
282 + ]),['data'=>toArray($this)]);
283 +
284 +
285 + return parent::save($options);
286 + }
287 +
288 + /**
289 + * @override
290 + * @return bool|null
291 + */
292 + public function delete()
293 + {
294 + $this->modelAction = GlobalSysEnum::STS_DELETED;
295 + Log::debug(SimpleTemplate::render('Model Delete for {{table}}',[
296 + 'table' => $this->table
297 + ]),['id'=>$this->getMyId()]);
298 +
299 + return parent::delete();
300 + }
301 +
302 +
303 + /**
304 + * 基础方法,获得数据所归属的企业
305 + * @return mixed|null
306 + */
307 + public function getMyGroupId() {
308 + return isset($this->group_id) ? $this->group_id : null;
309 + }
310 +
311 +
312 + /**
313 + * 获得对象的Hash值
314 + * @param $objectId
315 + * @return string | null
316 + */
317 + protected function getObjectHashValue($objectId) {
318 + $fullClassName = $this->getFullClassName();
319 + $groupId = $this->getMyGroupId();
320 +
321 + if(!isset($fullClassName) || !isset($groupId)) {
322 + return null;
323 + }
324 +
325 + return (new ODAObjectKeyHash())->getObjectKeyHash($groupId,$fullClassName,$objectId);
326 + }
327 +
328 + /**
329 + * 设置对象的Hash值
330 + * @param $objectId
331 + * @param array $val
332 + * @return ODAObjectKeyHash|null
333 + */
334 + protected function setObjectHash($objectId,array $val) {
335 + $fullClassName = $this->getFullClassName();
336 + $groupId = $this->getMyGroupId();
337 +
338 + if(!isset($fullClassName) || !isset($groupId) || empty($val)) {
339 + return null;
340 + }
341 +
342 + $valEncoding = $this->arrayEncode($val,GlobalSysEnum::SIGN_SHA1);
343 +
344 + return (new ODAObjectKeyHash())->setObjectKeyHash($groupId,$fullClassName,$objectId,$valEncoding);
345 + }
346 +
347 +
348 + /**
349 + * 检查对象的Hash是否存在,如不存在则存储Hash
350 + * @param BaseModel $baseModel
351 + * @param $keyId
352 + * @param array $value
353 + * @return bool
354 + */
355 + protected function checkObjectExistAndStoreHash(BaseModel $baseModel, $keyId ,array $value) {
356 + if($baseModel) {
357 + $valEncodingHash = $this->arrayEncode($value,GlobalSysEnum::SIGN_SHA1);
358 +
359 + $storeValHash = $baseModel->getObjectHashValue($keyId);
360 +
361 + if(isset($storeValHash) && $storeValHash==$valEncodingHash) {
362 + return true;
363 + } else {
364 + $baseModel->setObjectHash($keyId,$value);
365 + }
366 + }
367 + return false;
368 + }
369 +
370 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -147,3 +147,74 @@ class Group extends BaseModel ...@@ -147,3 +147,74 @@ class Group extends BaseModel
147 147
148 148
149 149
150 +<br/>
151 +
152 +---
153 +
154 +<br/>
155 +
156 +## 2. Model必遵守规约
157 +
158 +#### 2.1 所有的Model不允许直接从Model中继承,而是继承自BaseModel。
159 +
160 +* BaseModel参考 [BaseModel](BaseModel.php)
161 +
162 +<br/>
163 +
164 +#### 2.2 Model层不允许出现警告错误
165 +
166 +* 在phpstorm中,Model层内不允许出现黄色警告错误。如果有,必须想办法解决。
167 +* first(), where(), get() 这些警告,已经在BaseModel中作出处理。
168 +
169 +<br/>
170 +
171 +#### 2.3 每个函数必须要有注释
172 +
173 +* 每个函数 **必须** 要有注释。且注释一定要完整准确,注释上 **不能** 出现波浪线.
174 +
175 +
176 +
177 +#### 2.4 必须确认函数参数 / 函数返回值 的类型(尤其是类型为对象/列表/数组时)
178 +
179 +* 当函数参数是
180 +
181 +
182 +
183 +#### 2.5 函数命名的规范性
184 +
185 +* 当函数用来定义ORM映射关系时
186 +* 当函
187 +
188 +
189 +
190 +#### 2.6 注释的写法
191 +
192 +
193 +
194 +#### 2.7 Model层的作用及注意事项
195 +
196 +
197 +
198 +#### 2.8 Service层的作用及注意事项
199 +
200 +* 不要作底层的SQL语句查询
201 +* 将业务和算法分离
202 +* 清晰定义具体的业务逻辑
203 +*
204 +
205 +
206 +
207 +#### 2.9 Controller层的作用及注意事项
208 +
209 +
210 +
211 +#### 2.10 Model ORM关系的定义
212 +
213 +
214 +
215 +
216 +
217 +
218 +
219 +
220 +
......