mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-08 15:42:48 +08:00
软删除功能作为trait扩展引入
This commit is contained in:
@@ -41,7 +41,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
{
|
{
|
||||||
|
|
||||||
// 数据库对象池
|
// 数据库对象池
|
||||||
private static $links = [];
|
protected static $links = [];
|
||||||
// 数据库配置
|
// 数据库配置
|
||||||
protected $connection = [];
|
protected $connection = [];
|
||||||
// 当前模型名称
|
// 当前模型名称
|
||||||
@@ -85,8 +85,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
protected $createTime = 'create_time';
|
protected $createTime = 'create_time';
|
||||||
// 更新时间字段
|
// 更新时间字段
|
||||||
protected $updateTime = 'update_time';
|
protected $updateTime = 'update_time';
|
||||||
// 删除时间字段
|
|
||||||
protected static $deleteTime;
|
|
||||||
// 时间字段取出后的默认时间格式
|
// 时间字段取出后的默认时间格式
|
||||||
protected $dateFormat = 'Y-m-d H:i:s';
|
protected $dateFormat = 'Y-m-d H:i:s';
|
||||||
// 字段类型或者格式转换
|
// 字段类型或者格式转换
|
||||||
@@ -133,10 +131,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$this->autoWriteTimestamp = $this->db()->getConfig('auto_timestamp');
|
$this->autoWriteTimestamp = $this->db()->getConfig('auto_timestamp');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_null(static::$deleteTime)) {
|
|
||||||
static::$deleteTime = $this->db()->getConfig('soft_delete_field');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行初始化操作
|
// 执行初始化操作
|
||||||
$this->initialize();
|
$this->initialize();
|
||||||
}
|
}
|
||||||
@@ -279,27 +273,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
*/
|
*/
|
||||||
public function setAttr($name, $value, $data = [])
|
public function setAttr($name, $value, $data = [])
|
||||||
{
|
{
|
||||||
if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime, static::$deleteTime])) {
|
if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {
|
||||||
// 自动写入的时间戳字段
|
// 自动写入的时间戳字段
|
||||||
if (isset($this->type[$name])) {
|
$value = $this->autoWriteTimestamp($name);
|
||||||
$type = $this->type[$name];
|
|
||||||
if (strpos($type, ':')) {
|
|
||||||
list($type, $param) = explode(':', $type, 2);
|
|
||||||
}
|
|
||||||
switch ($type) {
|
|
||||||
case 'datetime':
|
|
||||||
$format = !empty($param) ? $param : $this->dateFormat;
|
|
||||||
$value = date($format, $_SERVER['REQUEST_TIME']);
|
|
||||||
break;
|
|
||||||
case 'timestamp':
|
|
||||||
$value = $_SERVER['REQUEST_TIME'];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), ['datetime', 'date', 'timestamp'])) {
|
|
||||||
$value = date($this->dateFormat, $_SERVER['REQUEST_TIME']);
|
|
||||||
} else {
|
|
||||||
$value = $_SERVER['REQUEST_TIME'];
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 检测修改器
|
// 检测修改器
|
||||||
$method = 'set' . Loader::parseName($name, 1) . 'Attr';
|
$method = 'set' . Loader::parseName($name, 1) . 'Attr';
|
||||||
@@ -320,6 +296,36 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动写入时间戳
|
||||||
|
* @access public
|
||||||
|
* @param string $name 时间戳字段
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function autoWriteTimestamp($name)
|
||||||
|
{
|
||||||
|
if (isset($this->type[$name])) {
|
||||||
|
$type = $this->type[$name];
|
||||||
|
if (strpos($type, ':')) {
|
||||||
|
list($type, $param) = explode(':', $type, 2);
|
||||||
|
}
|
||||||
|
switch ($type) {
|
||||||
|
case 'datetime':
|
||||||
|
$format = !empty($param) ? $param : $this->dateFormat;
|
||||||
|
$value = date($format, $_SERVER['REQUEST_TIME']);
|
||||||
|
break;
|
||||||
|
case 'timestamp':
|
||||||
|
$value = $_SERVER['REQUEST_TIME'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), ['datetime', 'date', 'timestamp'])) {
|
||||||
|
$value = date($this->dateFormat, $_SERVER['REQUEST_TIME']);
|
||||||
|
} else {
|
||||||
|
$value = $_SERVER['REQUEST_TIME'];
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据写入 类型转换
|
* 数据写入 类型转换
|
||||||
* @access public
|
* @access public
|
||||||
@@ -790,33 +796,12 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (static::$deleteTime && !$force) {
|
$result = $this->db()->delete($this->data);
|
||||||
// 软删除
|
|
||||||
$this->setAttr(static::$deleteTime, null);
|
|
||||||
$result = $this->isUpdate()->save();
|
|
||||||
} else {
|
|
||||||
$result = $this->db()->delete($this->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->trigger('after_delete', $this);
|
$this->trigger('after_delete', $this);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 恢复被软删除的记录
|
|
||||||
* @access public
|
|
||||||
* @return integer
|
|
||||||
*/
|
|
||||||
public function restore()
|
|
||||||
{
|
|
||||||
if (static::$deleteTime) {
|
|
||||||
// 恢复删除
|
|
||||||
$this->setAttr(static::$deleteTime, 0);
|
|
||||||
return $this->isUpdate()->save();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置自动完成的字段( 规则通过修改器定义)
|
* 设置自动完成的字段( 规则通过修改器定义)
|
||||||
* @access public
|
* @access public
|
||||||
@@ -986,7 +971,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
*/
|
*/
|
||||||
public static function get($data = null, $with = [], $cache = false)
|
public static function get($data = null, $with = [], $cache = false)
|
||||||
{
|
{
|
||||||
$query = self::parseQuery($data, $with, $cache);
|
$query = static::parseQuery($data, $with, $cache);
|
||||||
return $query->find($data);
|
return $query->find($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1001,7 +986,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
*/
|
*/
|
||||||
public static function all($data = null, $with = [], $cache = false)
|
public static function all($data = null, $with = [], $cache = false)
|
||||||
{
|
{
|
||||||
$query = self::parseQuery($data, $with, $cache);
|
$query = static::parseQuery($data, $with, $cache);
|
||||||
return $query->select($data);
|
return $query->select($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1026,10 +1011,6 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$result = $data->with($with)->cache($cache);
|
$result = $data->with($with)->cache($cache);
|
||||||
$data = null;
|
$data = null;
|
||||||
}
|
}
|
||||||
if (static::$deleteTime) {
|
|
||||||
// 默认不查询软删除数据
|
|
||||||
$result->where(static::$deleteTime, 0);
|
|
||||||
}
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1037,10 +1018,9 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
* 删除记录
|
* 删除记录
|
||||||
* @access public
|
* @access public
|
||||||
* @param mixed $data 主键列表 支持闭包查询条件
|
* @param mixed $data 主键列表 支持闭包查询条件
|
||||||
* @param bool $force 是否强制删除
|
|
||||||
* @return integer 成功删除的记录数
|
* @return integer 成功删除的记录数
|
||||||
*/
|
*/
|
||||||
public static function destroy($data, $force = false)
|
public static function destroy($data)
|
||||||
{
|
{
|
||||||
$model = new static();
|
$model = new static();
|
||||||
$query = $model->db();
|
$query = $model->db();
|
||||||
@@ -1055,7 +1035,7 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
|
|||||||
$count = 0;
|
$count = 0;
|
||||||
if ($resultSet) {
|
if ($resultSet) {
|
||||||
foreach ($resultSet as $data) {
|
foreach ($resultSet as $data) {
|
||||||
$result = $data->delete($force);
|
$result = $data->delete();
|
||||||
$count += $result;
|
$count += $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
113
library/traits/model/SoftDelete.php
Normal file
113
library/traits/model/SoftDelete.php
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace traits\model;
|
||||||
|
|
||||||
|
trait SoftDelete
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 分析查询表达式
|
||||||
|
* @access public
|
||||||
|
* @param mixed $data 主键列表或者查询条件(闭包)
|
||||||
|
* @param string $with 关联预查询
|
||||||
|
* @param bool $cache 是否缓存
|
||||||
|
* @return Query
|
||||||
|
*/
|
||||||
|
protected static function parseQuery(&$data, $with, $cache)
|
||||||
|
{
|
||||||
|
$result = self::with($with)->cache($cache);
|
||||||
|
if (is_array($data) && key($data) !== 0) {
|
||||||
|
$result = $result->where($data);
|
||||||
|
$data = null;
|
||||||
|
} elseif ($data instanceof \Closure) {
|
||||||
|
call_user_func_array($data, [ & $result]);
|
||||||
|
$data = null;
|
||||||
|
} elseif ($data instanceof Query) {
|
||||||
|
$result = $data->with($with)->cache($cache);
|
||||||
|
$data = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static::$deleteTime) {
|
||||||
|
// 默认不查询软删除数据
|
||||||
|
$result->where(static::$deleteTime, 0);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询软删除数据
|
||||||
|
* @access public
|
||||||
|
* @return \think\db\Query
|
||||||
|
*/
|
||||||
|
public static function withTrashed()
|
||||||
|
{
|
||||||
|
$model = new static();
|
||||||
|
return $model->db();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除当前的记录
|
||||||
|
* @access public
|
||||||
|
* @param bool $force 是否强制删除
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function delete($force = false)
|
||||||
|
{
|
||||||
|
if (false === $this->trigger('before_delete', $this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static::$deleteTime && !$force) {
|
||||||
|
// 软删除
|
||||||
|
$name = static::$deleteTime;
|
||||||
|
$this->change[] = $name;
|
||||||
|
$this->data[$name] = $this->autoWriteTimestamp($name);
|
||||||
|
$result = $this->isUpdate()->save();
|
||||||
|
} else {
|
||||||
|
$result = $this->db()->delete($this->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->trigger('after_delete', $this);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复被软删除的记录
|
||||||
|
* @access public
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function restore()
|
||||||
|
{
|
||||||
|
if (static::$deleteTime) {
|
||||||
|
// 恢复删除
|
||||||
|
$this->setAttr(static::$deleteTime, 0);
|
||||||
|
return $this->isUpdate()->save();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __call($method, $args)
|
||||||
|
{
|
||||||
|
if (method_exists($this, 'scope' . $method)) {
|
||||||
|
// 动态调用命名范围
|
||||||
|
$method = 'scope' . $method;
|
||||||
|
array_unshift($args, $this->db());
|
||||||
|
call_user_func_array([$this, $method], $args);
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
$query = $this->db();
|
||||||
|
$query->where(static::$deleteTime, 0);
|
||||||
|
return call_user_func_array([$this->db(), $method], $args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function __callStatic($method, $params)
|
||||||
|
{
|
||||||
|
$model = get_called_class();
|
||||||
|
if (!isset(self::$links[$model])) {
|
||||||
|
self::$links[$model] = (new static())->db();
|
||||||
|
}
|
||||||
|
$query = self::$links[$model];
|
||||||
|
$query->where(static::$deleteTime, 0);
|
||||||
|
return call_user_func_array([$query, $method], $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user