BaseModel.php 9.2 KB
<?php
/**
+-----------------------------------------------------------------------------------------------------------------------
 * 模型层基类:业务模型的基类,提供对数据库基本的增删改查类操作,不包含业务逻辑
+-----------------------------------------------------------------------------------------------------------------------
 *
 * PHP version 7
 *
 * @category  App\Admin\Controllers
 * @package   App\Admin\Controllers
 * @author    Richer <yangzi1028@163.com>
 * @date      2020年11月13日 01:26:09
 * @copyright 2020-2022 Richer (http://www.Richer.com/)
 * @license   http://www.Richer.com/ License
 * @link      http://www.Richer.com/
 */
namespace App\Models;

use App\Models\Traits\ModelAppendFieldTrait;
use Encore\Admin\Traits\DefaultDatetimeFormat;
use Exception;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Spatie\Activitylog\Models\Activity as ActivityLog;
use App\Models\Traits\CreatorTrait;
use Illuminate\Database\Eloquent\Relations;
use Spatie\Activitylog\Traits\LogsActivity;

/**
 * Class BaseModel
 *
 * @category  App\Admin\Controllers
 * @package   App\Admin\Controllers
 * @author    Richer <yangzi1028@163.com>
 * @date      2020年11月13日 01:26:09
 * @copyright 2020-2022 Richer (http://www.Richer.com/)
 * @license   http://www.Richer.com/ License
 * @link      http://www.Richer.com/
 */

/**
 * @property mixed id
 * @property mixed sort
 * @property mixed status
 * @property mixed status_show
 * @property mixed created_at
 * @property mixed updated_at
 */
class BaseModel extends Model //implements HasMedia
{
    use Notifiable, SoftDeletes, CreatorTrait, ModelAppendFieldTrait;
//    use LogsActivity;
    // add by Richer 于 2022年4月13日16:45:14 解决laravel-admin时间展示问题
    use DefaultDatetimeFormat;

    /**
     * Remove flag in `has many` form.
     * 在一对多模型使用的时候增加该变量,如果有该变量并且变量值为1,则代表该row将被删除
     */
    const REMOVE_FLAG_NAME  = '_remove_';
    /**
     * ADD flag in `has many` form.
     * 在一对多模型使用的时候增加该变量,如果有该变量,则代表该row将被新增
     */
    const ADD_FLAG_NAME     = '_new_';

    // 缓存时间
    const CACHE_EXPIRY_SECOND   = 10 * 60;

    protected $guarded = ['id'];

    protected $perPage = 10;

    // 设置显示的最多数
    protected $maxCount     = 10000;

    /**
     * 需要被转换成日期的属性。
     *
     * @var array
     */
    protected $dates = ['deleted_at'];

    /**
     * 列表查询字段
     *
     * @var array
     */
    const LIST_QUERY_COLUMNS = ['*'];


    /**
     * 执行自定义的赋值
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        self::bootHasCreator();
    }

    /**
     * 方法:whereHas 的 where in 实现
     *
     * @param Builder $builder  $builder
     * @param string            $relationName $relationName
     * @param callable          $callable     $callable
     *
     * @return Builder
     *
     * @throws Exception
     */
    public function scopeWhereHasIn($builder, $relationName, callable $callable)
    {
        $relationNames = explode('.', $relationName);
        $nextRelation = implode('.', array_slice($relationNames, 1));

        $method = $relationNames[0];
        // @var Relations\BelongsTo|Relations\HasOne $relation
        $relation = Relations\Relation::noConstraints(
            function () use ($method) {
                return $this->$method();
            }
        );

        // @var Builder $in
        $in = $relation->getQuery()->whereHasIn($nextRelation, $callable);

        if ($relation instanceof Relations\BelongsTo) {
            return $builder->whereIn($relation->getForeignKey(), $in->select($relation->getOwnerKey()));
        } elseif ($relation instanceof Relations\HasOne) {
            return $builder->whereIn($this->getKeyName(), $in->select($relation->getForeignKeyName()));
        }

        throw new Exception(__METHOD__ . " 不支持 " . get_class($relation));
    }

    /**
     * 动态自定义字段赋值
     *
     * @param ActivityLog $activity  $activity
     * @param string      $eventName $eventName
     *
     * @return void
     */
    public function tapActivity(ActivityLog $activity, string $eventName)
    {
        //$activity->ip = Request::getClientIp();
    }

    /**
     * 获取操作类型
     *
     * @param string $eventName 操作
     *
     * @return string
     */
    public function getDescriptionForEvent(string $eventName): string
    {
        if ($eventName == 'created') {
            return '添加';
        }

        if ($eventName == 'updated') {
            return '更新';
        }

        if ($eventName == 'deleted') {
            return '删除';
        }
    }

    /**
     * 自定义加密
     *
     * @param string $value 值
     *
     * @return mixed
     */
    public function encrypt($value)
    {
        if ($value) {
            return encrypt($value);
        }
        //base64_encode
        return $value;
    }

    /**
     * 自定义解密
     *
     * @param string $value 值
     *
     * @return mixed
     */
    public function decrypt($value)
    {
        if ($value) {
            try {
                return decrypt($value);
            } catch (DecryptException $e) {
                return $value;
            }
        }
        //base64_encode
        return $value;
    }

    /**
     * 批量新增数据
     *
     * @param array $data 数据
     *
     * @return bool
     */
    public function addAll(Array $data)
    {
        $rs = DB::table($this->getTable())->insert($data);
        return $rs;
    }


    /**
     * 根据Id批量更新数据,可以放在model里面,使得每个model都是调用这个方法
     *
     * @param array $multipleData 数据
     *
     * @return bool
     * @throws ValidationException
     * @author Richer
     */
    public function updateBatch($multipleData = array())
    {
        $tableName = $this->getTable();
        if (!is_array($multipleData)) {
            throw new ValidationException('must be an array', null, '6001');
        }

        foreach ($multipleData as &$row) {
            if (!array_key_exists('id', $row)) {
                throw new ValidationException('参数错误,缺少主键', null, '6001');
            }
            //$row[Model::FIELD_UPDATED_AT] = Carbon::now();
        }

        if ($tableName && !empty($multipleData)) {
            $updateColumn  = array_keys(\Arr::first($multipleData));
            $referenceColumn = \Arr::first($updateColumn);
            unset($updateColumn[0]);
            $whereIn = "";
            $q = "UPDATE " . $tableName . " SET ";
            foreach ($updateColumn as $uColumn) {
                $q .= $uColumn . " = CASE ";
                foreach ($multipleData as $data) {
                    $q .= "WHEN " . $referenceColumn . " = " . $data[$referenceColumn] . " THEN '" . $data[$uColumn] . "' ";
                }
                $q .= "ELSE " . $uColumn . " END, ";
            }
            foreach ($multipleData as $data) {
                $whereIn .= "'" . $data[$referenceColumn] . "', ";
            }

            $q = rtrim($q, ", ") . " WHERE " . $referenceColumn . " IN (" . rtrim($whereIn, ', ') . ")";


            return \DB::update(\DB::raw($q));
        } else {
            return false;
        }
    }

    /**
     * 是否收藏
     *
     * @param null $favorites
     * @return int
     */
    public function isFavorited($favorites = null)
    {
        if (!$user = auth('user')->user()) {
            return 0;
        }
        if ($favorites) {
            if ($favorites->isEmpty()) {
                return 0;
            }
            if ($is = $favorites->where('user_id', $user->id)->first()) {
                return 1;
            }
            return 0;
        } else {
            if (!$user = auth('user')->user()) {
                return 0;
            }
            return $hasFavorited = $user->hasFavorited($this) === true ? 1 : 0;
        }
    }

    /**
     * 是否点赞
     *
     * @param null $voters
     * @return int
     */
    public function isVoted($voters = null)
    {
        if ($voters) {
            if ($voters->isNotEmpty()) {
                return 1;
            }
            return 0;
        } else {
            if (!$user = auth('user')->user()) {
                return 0;
            }
            return $hasUpvoted = $user->hasUpvoted($this) === true ? 1 : 0;
        }
    }

    /**
     * 是否被分销
     *
     * @param $distributions
     * @return int
     */
    public function isDistributed($distributions = null)
    {
        if ($distributions) {
            if ($distributions->isNotEmpty()) {
                return 1;
            }
            return 0;
        } else {
            if (!$user = auth('user')->user()) {
                return 0;
            }
            return $this->isDistributedBy($user) ? 1 : 0;
        }
    }
}