308 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			308 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
<?php
 | 
						||
/**
 | 
						||
 * 事务块
 | 
						||
 * @author: JiaoYuKun
 | 
						||
 * @day: 2019/12/9
 | 
						||
 */
 | 
						||
namespace traits;
 | 
						||
use think\Db;
 | 
						||
use think\Loader;
 | 
						||
use think\Lang;
 | 
						||
trait ModelTrait
 | 
						||
{
 | 
						||
 | 
						||
    protected $withTable = [];
 | 
						||
 | 
						||
    public static $url_enpity = null;
 | 
						||
    public static $url_lock = false;
 | 
						||
    public static $url_lock_key = "";
 | 
						||
    public static $url_lock_suffix = "";
 | 
						||
 | 
						||
    public static $url_lock_timeout = 120;
 | 
						||
 | 
						||
    public static $url_error_msg = "您的请求过于频繁,请您稍后再试!";
 | 
						||
 | 
						||
    /**
 | 
						||
     * 开启事务
 | 
						||
     */
 | 
						||
    public static function beginTrans()
 | 
						||
    {
 | 
						||
        if (static::$url_lock) {
 | 
						||
//            var_dump(static::$url_lock);
 | 
						||
            if(!static::$url_lock_suffix){
 | 
						||
                //用继承的类名当锁的key
 | 
						||
                static::$url_lock_suffix = get_called_class()."-lock-suffix";
 | 
						||
            }
 | 
						||
 | 
						||
            static::$url_enpity = new \bw\UrlLock(static::$url_lock_key, static::$url_lock_suffix, static::$url_lock_timeout, static::$url_error_msg);
 | 
						||
            static::$url_enpity->lock();
 | 
						||
        }
 | 
						||
        Db::startTrans();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 提交事务
 | 
						||
     */
 | 
						||
    public static function commitTrans()
 | 
						||
    {
 | 
						||
        if(static::$url_enpity)static::$url_enpity->free();
 | 
						||
        Db::commit();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 关闭事务
 | 
						||
     */
 | 
						||
    public static function rollbackTrans()
 | 
						||
    {
 | 
						||
        if(static::$url_enpity){
 | 
						||
//           var_dump(22222222);
 | 
						||
            static::$url_enpity->free();
 | 
						||
        };
 | 
						||
        Db::rollback();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 根据结果提交滚回事务
 | 
						||
     * @param $res
 | 
						||
     */
 | 
						||
    public static function checkTrans($res)
 | 
						||
    {
 | 
						||
        if ($res) {
 | 
						||
            static::commitTrans();
 | 
						||
        } else {
 | 
						||
            static::rollbackTrans();
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    public static function check($param,$rule=[],$rule_msg=[])
 | 
						||
    {
 | 
						||
        $self= new static;
 | 
						||
        if(property_exists($self,'rule')){
 | 
						||
            $rule = array_merge(static::$rule,$rule);
 | 
						||
        }
 | 
						||
        if(property_exists($self,'rule_msg')){
 | 
						||
            $rule_msg = array_merge(static::$rule_msg,$rule_msg);
 | 
						||
        }
 | 
						||
        $validate = new \think\Validate($rule, $rule_msg);
 | 
						||
        $result = $validate->check($param);
 | 
						||
        if (!$result) {
 | 
						||
            if (method_exists($self, 'setError')) {
 | 
						||
                return self::setError($validate->getError());
 | 
						||
            } else {
 | 
						||
                throw new \Exception($validate->getError());
 | 
						||
            }
 | 
						||
        }
 | 
						||
        return true;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 设置异常
 | 
						||
     * @param string $errorMsg
 | 
						||
     * @return bool
 | 
						||
     */
 | 
						||
    protected static function setException($errorMsg = "操作失败,请稍候再试!")
 | 
						||
    {
 | 
						||
        throw new \Exception($errorMsg);
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 带有乐观锁的修改
 | 
						||
     * Power: Mikkle
 | 
						||
     * Email:776329498@qq.com
 | 
						||
     * @param $save_data   修改的数据
 | 
						||
     * @param string $edit_pk  修改的ID字段名称
 | 
						||
     * @param string $version_field  乐观锁版本号字段名称
 | 
						||
     * @return array
 | 
						||
     */
 | 
						||
    public function editDateWithLock($save_data,$edit_pk="",$version_field=""){
 | 
						||
        if (empty($version_field)){
 | 
						||
            $version_field = isset($this->versionField) ? $this->versionField : "edit_version";
 | 
						||
        }
 | 
						||
        if (empty($edit_pk)){
 | 
						||
            $edit_pk = isset($this->editPk) ? $this->editPk : $this->getPk();
 | 
						||
        }
 | 
						||
        //判断PK字段是否存在
 | 
						||
        if (!isset($save_data[$edit_pk])||!isset($save_data[$version_field])){
 | 
						||
            throw new \Exception("参数缺失");
 | 
						||
        }else{
 | 
						||
            //设置升级检索条件 PK和版本号
 | 
						||
            $map[$edit_pk] = $save_data[$edit_pk];
 | 
						||
            $map[$version_field] = $save_data[$version_field];
 | 
						||
            //剔除PK
 | 
						||
            unset($save_data[$edit_pk]);
 | 
						||
        }
 | 
						||
            //检测版本字段
 | 
						||
            if($this->hasColumn($version_field)){
 | 
						||
                throw new \Exception("乐观锁版本字段[$version_field]不存在");
 | 
						||
            }
 | 
						||
            $original_data = $this->where($map)->find();
 | 
						||
            if (empty($original_data)){
 | 
						||
                throw new \Exception("此条信息已经变动了,请重新操作!");
 | 
						||
            }
 | 
						||
            foreach ($save_data as $item=>$value){
 | 
						||
                if (isset($original_data[$item])){
 | 
						||
                    //修改的数值不变时候 剔除
 | 
						||
                    if ($original_data[$item]==$value){
 | 
						||
                        unset( $save_data[$item]);
 | 
						||
                    }elseif($item!=$version_field){
 | 
						||
                        unset( $original_data[$item]);
 | 
						||
                    }
 | 
						||
                }else{
 | 
						||
                    //修改的字段不存在 剔除
 | 
						||
                    unset( $save_data[$item]);
 | 
						||
                }
 | 
						||
            }
 | 
						||
            if(empty($save_data)){
 | 
						||
                throw new \Exception("修改的数值无变化");
 | 
						||
            }
 | 
						||
            //版本号升级
 | 
						||
            $save_data[$version_field]=(int)$original_data[$version_field]+1;
 | 
						||
            if (1!=$this->allowField(true)->save($save_data,$map)){
 | 
						||
                throw new \Exception("修改信息出错:".$this->getError());
 | 
						||
            }
 | 
						||
 | 
						||
            return true;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 判断字段是否存在
 | 
						||
     * Power: Mikkle
 | 
						||
     * Email:776329498@qq.com
 | 
						||
     * @param $column
 | 
						||
     * @param string $table
 | 
						||
     * @return bool
 | 
						||
     */
 | 
						||
    protected function hasColumn($column,$table=""){
 | 
						||
        $table = isset($table)?$table:$this->table;
 | 
						||
        if (empty($table)||$column){
 | 
						||
            $this->error="hasColumn方法参数缺失";
 | 
						||
            return false;
 | 
						||
        }
 | 
						||
        $sql = "SELECT * FROM information_schema.columns WHERE table_schema=CurrentDatabase AND table_name = '{$table}' AND column_name = '{$column}'";
 | 
						||
        return $this->query($sql) ? true : false;
 | 
						||
    }
 | 
						||
 | 
						||
    public function getWithAlisaName(){
 | 
						||
        return strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '_$1', (new \ReflectionClass(static::class))->getShortName()));
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
//    /**得到基础条件
 | 
						||
//     * @param $status
 | 
						||
//     * @param null $model
 | 
						||
//     * @param string $alisa
 | 
						||
//     */
 | 
						||
//    public  function getBaseWhere($whereData = [], $model = null, $alisa = '')
 | 
						||
//    {
 | 
						||
//        if (!$model) {
 | 
						||
//            $model = new self;
 | 
						||
//            if ($alisa) $model = $model->alias($alisa);
 | 
						||
//        }
 | 
						||
//        if ($alisa) $alisa = $alisa . '.';
 | 
						||
//        $model = $model->where($whereData);
 | 
						||
//        return $model;
 | 
						||
//    }
 | 
						||
//
 | 
						||
//
 | 
						||
//    /**
 | 
						||
//     * 基础列表
 | 
						||
//     */
 | 
						||
//    public function getBaseList($whereData = [], $page = 0, $limit = 0, $sort = '',$field ="*",$where=[],$alisa = '')
 | 
						||
//    {
 | 
						||
//        if ($alisa) $alisa = $alisa . '.';
 | 
						||
//        if(!$sort)$sort = "{$alisa}id desc";
 | 
						||
//        $self = $this->getBaseWhere($whereData, null, $alisa)->where($where)->field($field);
 | 
						||
//        if($page&&$limit)$self = $self->page($page, $limit);
 | 
						||
//        $list = $self->orderRaw($sort)->select();
 | 
						||
//        $count = $this->getBaseWhere($whereData, null, $alisa)
 | 
						||
//            ->where($where)
 | 
						||
//            ->count();
 | 
						||
//        return compact('list', 'count','page','limit');
 | 
						||
//    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 获取时间段之间的model
 | 
						||
     * @param int|string $time
 | 
						||
     * @param string $ceil
 | 
						||
     * @return array
 | 
						||
     */
 | 
						||
    public static function getModelTime($where, $model = null, $prefix = 'add_time', $data = 'data', $field = ' - ')
 | 
						||
    {
 | 
						||
        if ($model == null) $model = new self;
 | 
						||
        if (!isset($where[$data])) return $model;
 | 
						||
        switch ($where[$data]) {
 | 
						||
            case 'today':
 | 
						||
            case 'week':
 | 
						||
            case 'month':
 | 
						||
            case 'year':
 | 
						||
            case 'yesterday':
 | 
						||
                $model = $model->whereTime($prefix, $where[$data]);
 | 
						||
                break;
 | 
						||
            case 'quarter':
 | 
						||
                list($startTime, $endTime) = self::getMonth();
 | 
						||
                $model = $model->where($prefix, '>', strtotime($startTime));
 | 
						||
                $model = $model->where($prefix, '<', strtotime($endTime));
 | 
						||
                break;
 | 
						||
            case 'lately7':
 | 
						||
                $model = $model->where($prefix, 'between time', [strtotime("-7 day"), time()]);
 | 
						||
                break;
 | 
						||
            case 'lately30':
 | 
						||
                $model = $model->where($prefix, 'between time', [strtotime("-30 day"), time()]);
 | 
						||
                break;
 | 
						||
            default:
 | 
						||
                if (strstr($where[$data], $field) !== false) {
 | 
						||
                    list($startTime, $endTime) = explode($field, $where[$data]);
 | 
						||
                    $model = $model->where($prefix, '>', strtotime($startTime));
 | 
						||
                    $model = $model->where($prefix, '<', bcadd(strtotime($endTime), 86400, 0));
 | 
						||
                }
 | 
						||
                break;
 | 
						||
        }
 | 
						||
        return $model;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 获取本季度 time
 | 
						||
     * @param int|string $time
 | 
						||
     * @param string $ceil
 | 
						||
     * @return array
 | 
						||
     */
 | 
						||
    public static function getMonth($time = '', $ceil = 0)
 | 
						||
    {
 | 
						||
        if ($ceil != 0)
 | 
						||
            $season = ceil(date('n') / 3) - $ceil;
 | 
						||
        else
 | 
						||
            $season = ceil(date('n') / 3);
 | 
						||
        $firstday = date('Y-m-01', mktime(0, 0, 0, ($season - 1) * 3 + 1, 1, date('Y')));
 | 
						||
        $lastday = date('Y-m-t', mktime(0, 0, 0, $season * 3, 1, date('Y')));
 | 
						||
        return array($firstday, $lastday);
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 加载语言文件
 | 
						||
     * @param string $name
 | 
						||
     */
 | 
						||
    protected function loadlang($name=null)
 | 
						||
    {
 | 
						||
        if(!$name)$name = str_replace('model/', '', strstr(str_replace('\\', '/', $this->class), 'model/'));
 | 
						||
        $name = Loader::parseName($name);
 | 
						||
        $name_arr = explode('/',$name);
 | 
						||
        $i = count($name_arr)-1;
 | 
						||
        if($name_arr[$i][0]=='_')$name_arr[$i] = substr($name_arr[$i],1);
 | 
						||
        $name = implode("/",$name_arr);
 | 
						||
        Lang::load(APP_PATH . request()->module() . '/lang/' . request()->langset() . '/' . str_replace('.', '/', $name) . '.php');
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
} |