问题描述
在后台用户列表管理功能中,用户模型(User)已启用软删除(SoftDelete)并实现邀请人关联查询。但在实际查询时,发现主表(fa_user)的软删除条件未生效,导致已软删除的用户仍会被统计和查询出来。
相关代码片段
1. 用户列表查询方法
php
/**
* 查看
*/
public function index()
{
$this->relationSearch = true;
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage,则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->with(['withparent'])
->where($where)
->order($sort, $order)
->paginate($limit);
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
2. 用户模型定义
php
class User extends Model
{
use SoftDelete;
// 表名
protected $name = 'user';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = 'deletetime';
/**
* 关联邀请人
**/
public function withparent()
{
return $this->belongsTo('User', 'parent_user_id', 'id', [], 'LEFT')->field('id,username,mobile,nickname')->setEagerlyType(0);
}
}
问题分析
- 实际生成的 SQL 只对关联表(withparent)添加了软删除过滤(withparent.deletetime IS NULL),主表(fa_user)未添加软删除条件(user.deletetime IS NULL)。
- 结果:主表已软删除的用户仍会被统计和查询出来。
示例 SQL:
php
SELECT
COUNT(*) AS tp_count
FROM
`fa_user` `user`
LEFT JOIN `fa_user` `withparent` ON `user`.`parent_user_id` = `withparent`.`id`
WHERE
`withparent`.`deletetime` IS NULL
LIMIT 1
- 如果去掉关联邀请人查询,则主表软删除过滤正常。
- 该情况未在官方文档中明确说明。
解决方案
手动增加主表软删除过滤条件,即在查询中添加 whereNull('user.deletetime'):
php
$list = $this->model
->with(['withparent'])
->where($where)
->whereNull('user.deletetime')
->order($sort, $order)
->paginate($limit);
最终生成 SQL:
sql
SELECT
COUNT(*) AS tp_count
FROM
`fa_user` `user`
LEFT JOIN `fa_user` `withparent` ON `user`.`parent_user_id` = `withparent`.`id`
WHERE (`user`.`deletetime` IS NULL)
AND `withparent`.`deletetime` IS NULL
LIMIT 1
总结与建议
- 主表软删除过滤需手动添加:在涉及关联查询时,需注意主表软删除条件不会自动生效,需手动补充。
- 建议:在类似场景下,务必检查 SQL 生成结果,确保软删除逻辑完整覆盖主表与关联表,避免数据异常。