shipfi

lumen-rule-modle

<?php
/**
* Created by Qingger Corp.
* User: jsspf
* Date: 2017/5/5
* Time: 15:37
*/
namespace App\Models;
use App\Exceptions\ECException;
use App\Exceptions\ModelException;
use App\Library\AppUtils\UtilToolMethods;
use App\Library\VariDefines\Common\GlobalSysEnum;
use App\Library\VariDefines\ErrorCodes\GlobalErrCode;
use App\Services\Cache\AppCacheManager;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Query\Expression;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Windwalker\String\SimpleTemplate;
use Log;
use DB;
/**
* Class BaseModel
* @package App\Models
*
* @method Builder where(string|array|\Closure $column, string $operator = null, mixed $value = null, string $boolean = 'and')
* @method Builder orWhere(string $column, string $operator = null, mixed $value = null)
* @method Builder whereRaw(string $sql, array $bindings = array(), string $boolean = 'and')
* @method Builder orWhereRaw(string $sql, array $bindings = array())
* @method Builder whereBetween(string $column, array $values, string $boolean = 'and', bool $not = false)
* @method Builder orWhereBetween(string $column, array $values)
* @method Builder whereNotBetween(string $column, array $values, string $boolean = 'and')
* @method Builder orWhereNotBetween(string $column, array $values)
* @method Builder whereNested(\Closure $callback, string $boolean = 'and')
* @method addNestedWhereQuery(Builder|Builder $query, string $boolean = 'and')
* @method Builder whereExists(\Closure $callback, string $boolean = 'and', bool $not = false)
* @method Builder orWhereExists(\Closure $callback, bool $not = false)
* @method Builder whereNotExists(\Closure $callback, string $boolean = 'and')
* @method Builder orWhereNotExists(\Closure $callback)
* @method Builder whereIn(string $column, mixed $values, string $boolean = 'and', bool $not = false)
* @method Builder orWhereIn(string $column, mixed $values)
* @method Builder whereNotIn(string $column, mixed $values, string $boolean = 'and')
* @method Builder orWhereNotIn(string $column, mixed $values)
* @method Builder whereNull(string $column, string $boolean = 'and', bool $not = false)
* @method Builder whereNotNull(string $column, string $boolean = 'and')
* @method Builder orWhereNotNull(string $column)
* @method Builder whereDate(string $column, string $operator, int $value, string $boolean = 'and')
* @method Builder whereDay(string $column, string $operator, int $value, string $boolean = 'and')
* @method Builder whereMonth(string $column, string $operator, int $value, string $boolean = 'and')
* @method Builder whereYear(string $column, string $operator, int $value, string $boolean = 'and')
* @method $this dynamicWhere(string $method, string $parameters)
* @method Builder groupBy()
* @method Builder having(string $column, string $operator = null, string $value = null, string $boolean = 'and')
* @method Builder orHaving(string $column, string $operator = null, string $value = null)
* @method $this havingRaw(string $sql, array $bindings = array(), string $boolean = 'and')
* @method Builder orHavingRaw(string $sql, array $bindings = array())
* @method Builder orderBy(string $column, string $direction = 'asc')
* @method Builder latest(string $column = 'created_at')
* @method Builder oldest(string $column = 'created_at')
* @method Builder orderByRaw(string $sql, array $bindings = array())
* @method $this offset(int $value)
* @method Builder skip(int $value)
* @method Builder limit(int $value)
* @method Builder take(int $value)
* @method Builder forPage(int $page, int $perPage = 15)
* @method Builder union(Builder|\Closure $query, bool $all = false)
* @method Builder unionAll(Builder|\Closure $query)
* @method $this lock(bool $value = true)
* @method Builder lockForUpdate()
* @method Builder sharedLock()
* @method string toSql()
* @method mixed find(int $id, array $columns = array('*'))
* @method mixed first(array $columns = array('*'))
* @method mixed value(string $column)
* @method $this select(array|mixed $columns = array('*'))
* @method $this distinct()
* @method $this join(string $table, string $one, string $operator = null, string $two = null, string $type = 'inner', bool $where = false)
* @method Builder joinWhere(string $table, string $one, string $operator, string $two, string $type = 'inner')
* @method Builder leftJoin(string $table, string $first, string $operator = null, string $second = null)
* @method Builder leftJoinWhere(string $table, string $one, string $operator, string $two)
* @method Builder rightJoin(string $table, string $first, string $operator = null, string $second = null)
* @method Builder rightJoinWhere(string $table, string $one, string $operator, string $two)
* @method Collection get(array $columns = array('*'))
* @method array lists(string $column, string|null $key = null)
* @method string implode(string $column, string $glue = '')
* @method bool exists()
* @method int count(string $columns = '*')
* @method mixed min(string $column)
* @method mixed max(string $column)
* @method mixed sum(string $column)
* @method mixed avg(string $column)
* @method mixed average(string $column)
* @method mixed aggregate(string $function, array $columns = array('*'))
* @method float|int numericAggregate(string $function, array $columns = array('*'))
* @method bool insert(array $values)
* @method int insertGetId(array $values, string $sequence = null)
* @method void truncate()
* @method Builder newQuery()
* @method void mergeWheres(array $wheres, array $bindings)
* @method Expression raw(mixed $value)
*
*/
class BaseModel extends Model
{
use UtilToolMethods;
protected $table='';
protected $defautCacheTime = 60;
/**
* 缓存管理器
* @var AppCacheManager
*/
protected $appCacheManager = null;
/**
* 对Model的操作行为
* @var string
*/
private $modelAction = GlobalSysEnum::STS_CREATED;
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->appCacheManager = App::make(AppCacheManager::class);
}
public function getPrimaryKey() {
return $this->primaryKey;
}
public function getMyId() {
return $this->{$this->primaryKey};
}
public function getTable() {
return $this->table;
}
public function getColItem($item) {
return $this->table.".".$item;
}
public function formatArray($queryResult)
{
return json_decode(json_encode($queryResult), true);
}
/**
* 基础的条件查询,支持以下几种方式
* $this->getQueryByConditions(array(
* 'id' => '1', // id==1
* 'col1' => [1,2,3], // col1 in (1,2,3)
* 'col2' => [ 'sign' => '!=' , value=>3 ] // col2 != 3
* 'col3' => [ 'operator=>'whereNotIn', value=[1,2,3] ] // col3 not in (1,2,3)
* ));
* @param array $conditions
*
* @param array $selectItems
* @param bool $isDistinct
* @return Builder
*/
public function getQueryByConditions(Array $conditions,Array $selectItems=[],$isDistinct=false) {
$query = $this;
foreach ($conditions as $key=>$val) {
if(is_array($val) && isset($val['operator'])) {
$query = $query->{$val['operator']}($val['value']);
}elseif(is_array($val) && isset($val['sign'])) {
$query = $query->where($key,$val['sign'],$val['value']);
}elseif(is_array($val)){
$query = $query->whereIn($key,$val);
}else{
$query = $query->where($key,$val);
}
}
if(!empty($selectItems)) {
$query = $query->select($selectItems);
}
if($isDistinct) {
$query = $query->distinct();
}
return $query;
}
/* override */
public function checkValidItem(Array $conditions) {
return $this->where($conditions)->count();
}
/**
* 根据primaryId更新数据字段
* @param array $updateItems
* @param $idVal
* @return int
*/
public function updateItemsByPrimaryId(Array $updateItems,$idVal) {
return DB::table($this->table)->where($this->primaryKey,$idVal)->update($updateItems);
}
/**
* 根据条件更新数据字段
* @param array $updateItems
* @param array $conditions
* @return int
*/
public function updateItemsByConditions(Array $updateItems,Array $conditions) {
return DB::table($this->table)->where($conditions)->update($updateItems);
}
/**
* 检查模型的ID数据是否存在,即是否真正的实体
* @return bool
* @throws ModelException
*/
protected function checkObjectIdExist() {
if(!isset($this->primaryKey) || !isset($this->{$this->primaryKey})) {
throw new ModelException('Object Not Found Error',GlobalErrCode::ERR_MODEL_OBJECT_NOT_FOUND);
}
return true;
}
/**
* 根据主键获得实例
* @param $keyId
* @return BaseModel
*/
public function getInstanceByKeyId($keyId) {
return $this->find($keyId);
}
/**
* @return mixed|null
*/
public function getMyUpdatedAt() {
return isset($this->updated_at) ? $this->updated_at : null;
}
/**
* @return mixed|null
*/
public function getMyCreatedAt() {
return isset($this->created_at) ? $this->created_at : null;
}
/**
* 检查ID对应的数据实例是否存在
* @param $id
* @return true
* @throws ECException
*/
public function checkIdExists($id) {
$instance = $this->find($id);
if(!$instance) {
throw new ECException('数据对应的ID不存在:'.$id,GlobalErrCode::ERR_DATA_NOT_FOUND);
}
return true;
}
/**
* @override
* @param array $options
* @return bool
*/
public function save(array $options = [])
{
if(isset($this->{$this->primaryKey})) {
$this->modelAction = GlobalSysEnum::STS_UPDATED;
} else {
$this->modelAction = GlobalSysEnum::STS_CREATED;
}
Log::debug(SimpleTemplate::render('Model Save for {{table}} - {{action}}',[
'table' => $this->table,
'action' => $this->modelAction
]),['data'=>toArray($this)]);
return parent::save($options);
}
/**
* @override
* @return bool|null
*/
public function delete()
{
$this->modelAction = GlobalSysEnum::STS_DELETED;
Log::debug(SimpleTemplate::render('Model Delete for {{table}}',[
'table' => $this->table
]),['id'=>$this->getMyId()]);
return parent::delete();
}
/**
* 基础方法,获得数据所归属的企业
* @return mixed|null
*/
public function getMyGroupId() {
return isset($this->group_id) ? $this->group_id : null;
}
/**
* 获得对象的Hash值
* @param $objectId
* @return string | null
*/
protected function getObjectHashValue($objectId) {
$fullClassName = $this->getFullClassName();
$groupId = $this->getMyGroupId();
if(!isset($fullClassName) || !isset($groupId)) {
return null;
}
return (new ODAObjectKeyHash())->getObjectKeyHash($groupId,$fullClassName,$objectId);
}
/**
* 设置对象的Hash值
* @param $objectId
* @param array $val
* @return ODAObjectKeyHash|null
*/
protected function setObjectHash($objectId,array $val) {
$fullClassName = $this->getFullClassName();
$groupId = $this->getMyGroupId();
if(!isset($fullClassName) || !isset($groupId) || empty($val)) {
return null;
}
$valEncoding = $this->arrayEncode($val,GlobalSysEnum::SIGN_SHA1);
return (new ODAObjectKeyHash())->setObjectKeyHash($groupId,$fullClassName,$objectId,$valEncoding);
}
/**
* 检查对象的Hash是否存在,如不存在则存储Hash
* @param BaseModel $baseModel
* @param $keyId
* @param array $value
* @return bool
*/
protected function checkObjectExistAndStoreHash(BaseModel $baseModel, $keyId ,array $value) {
if($baseModel) {
$valEncodingHash = $this->arrayEncode($value,GlobalSysEnum::SIGN_SHA1);
$storeValHash = $baseModel->getObjectHashValue($keyId);
if(isset($storeValHash) && $storeValHash==$valEncodingHash) {
return true;
} else {
$baseModel->setObjectHash($keyId,$value);
}
}
return false;
}
}
\ No newline at end of file
......@@ -147,3 +147,74 @@ class Group extends BaseModel
<br/>
---
<br/>
## 2. Model必遵守规约
#### 2.1 所有的Model不允许直接从Model中继承,而是继承自BaseModel。
* BaseModel参考 [BaseModel](BaseModel.php)
<br/>
#### 2.2 Model层不允许出现警告错误
* 在phpstorm中,Model层内不允许出现黄色警告错误。如果有,必须想办法解决。
* first(), where(), get() 这些警告,已经在BaseModel中作出处理。
<br/>
#### 2.3 每个函数必须要有注释
* 每个函数 **必须** 要有注释。且注释一定要完整准确,注释上 **不能** 出现波浪线.
#### 2.4 必须确认函数参数 / 函数返回值 的类型(尤其是类型为对象/列表/数组时)
* 当函数参数是
#### 2.5 函数命名的规范性
* 当函数用来定义ORM映射关系时
* 当函
#### 2.6 注释的写法
#### 2.7 Model层的作用及注意事项
#### 2.8 Service层的作用及注意事项
* 不要作底层的SQL语句查询
* 将业务和算法分离
* 清晰定义具体的业务逻辑
*
#### 2.9 Controller层的作用及注意事项
#### 2.10 Model ORM关系的定义
......