| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | <?phpnamespace think\model\concern;use think\db\Query;/** * 数据软删除 */trait SoftDelete{    /**     * 是否包含软删除数据     * @var bool     */    protected $withTrashed = false;    /**     * 判断当前实例是否被软删除     * @access public     * @return boolean     */    public function trashed()    {        $field = $this->getDeleteTimeField();        if ($field && !empty($this->getOrigin($field))) {            return true;        }        return false;    }    /**     * 查询软删除数据     * @access public     * @return Query     */    public static function withTrashed()    {        $model = new static();        return $model->withTrashedData(true)->db(false);    }    /**     * 是否包含软删除数据     * @access protected     * @param  bool $withTrashed 是否包含软删除数据     * @return $this     */    protected function withTrashedData($withTrashed)    {        $this->withTrashed = $withTrashed;        return $this;    }    /**     * 只查询软删除数据     * @access public     * @return Query     */    public static function onlyTrashed()    {        $model = new static();        $field = $model->getDeleteTimeField(true);        if ($field) {            return $model                ->db(false)                ->useSoftDelete($field, $model->getWithTrashedExp());        }        return $model->db(false);    }    /**     * 获取软删除数据的查询条件     * @access protected     * @return array     */    protected function getWithTrashedExp()    {        return is_null($this->defaultSoftDelete) ?        ['notnull', ''] : ['<>', $this->defaultSoftDelete];    }    /**     * 删除当前的记录     * @access public     * @return bool     */    public function delete($force = false)    {        if (!$this->isExists() || false === $this->trigger('before_delete', $this)) {            return false;        }        $force = $force ?: $this->isForce();        $name  = $this->getDeleteTimeField();        if ($name && !$force) {            // 软删除            $this->data($name, $this->autoWriteTimestamp($name));            $result = $this->isUpdate()->withEvent(false)->save();            $this->withEvent(true);        } else {            // 读取更新条件            $where = $this->getWhere();            // 删除当前模型数据            $result = $this->db(false)                ->where($where)                ->removeOption('soft_delete')                ->delete();        }        // 关联删除        if (!empty($this->relationWrite)) {            $this->autoRelationDelete();        }        $this->trigger('after_delete', $this);        $this->exists(false);        return true;    }    /**     * 删除记录     * @access public     * @param  mixed $data 主键列表 支持闭包查询条件     * @param  bool  $force 是否强制删除     * @return bool     */    public static function destroy($data, $force = false)    {        // 传入空不执行删除,但是0可以删除        if (empty($data) && 0 !== $data) {            return false;        }        // 包含软删除数据        $query = (new static())->db(false);        if (is_array($data) && key($data) !== 0) {            $query->where($data);            $data = null;        } elseif ($data instanceof \Closure) {            call_user_func_array($data, [ & $query]);            $data = null;        } elseif (is_null($data)) {            return false;        }        $resultSet = $query->select($data);        if ($resultSet) {            foreach ($resultSet as $data) {                $data->force($force)->delete();            }        }        return true;    }    /**     * 恢复被软删除的记录     * @access public     * @param  array $where 更新条件     * @return bool     */    public function restore($where = [])    {        $name = $this->getDeleteTimeField();        if ($name) {            if (false === $this->trigger('before_restore')) {                return false;            }            if (empty($where)) {                $pk = $this->getPk();                $where[] = [$pk, '=', $this->getData($pk)];            }            // 恢复删除            $this->db(false)                ->where($where)                ->useSoftDelete($name, $this->getWithTrashedExp())                ->update([$name => $this->defaultSoftDelete]);            $this->trigger('after_restore');            return true;        }        return false;    }    /**     * 获取软删除字段     * @access protected     * @param  bool  $read 是否查询操作 写操作的时候会自动去掉表别名     * @return string|false     */    protected function getDeleteTimeField($read = false)    {        $field = property_exists($this, 'deleteTime') && isset($this->deleteTime) ? $this->deleteTime : 'delete_time';        if (false === $field) {            return false;        }        if (false === strpos($field, '.')) {            $field = '__TABLE__.' . $field;        }        if (!$read && strpos($field, '.')) {            $array = explode('.', $field);            $field = array_pop($array);        }        return $field;    }    /**     * 查询的时候默认排除软删除数据     * @access protected     * @param  Query  $query     * @return void     */    protected function withNoTrashed($query)    {        $field = $this->getDeleteTimeField(true);        if ($field) {            $condition = is_null($this->defaultSoftDelete) ? ['null', ''] : ['=', $this->defaultSoftDelete];            $query->useSoftDelete($field, $condition);        }    }}
 |