You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Eloquent加密字段查询异常:无法获取全部符合条件的发票数据

看起来你的查询逻辑出了问题,主要是运算符优先级导致条件判断混乱,另外还要注意加密字段的查询方式是否正确。咱们一步步来解决:

1. 修复查询逻辑错误

你的原查询中,whereHas、where和orWhere的组合方式不对,因为AND的优先级比OR高,导致最终的查询逻辑变成了:

(匹配指定nif的客户 AND 状态为0) OR 匹配指定nif的客户 OR 状态为2

这会导致所有状态为2的发票都被拉出来,不管是否属于目标客户,同时重复的whereHas也完全没必要。

正确的逻辑应该是:匹配指定nif的客户,并且发票状态是0或者2,你可以用以下两种方式实现:

方法一:用闭包分组状态条件

$nif = \Crypt::decryptString(\Auth::user()->userprofile->nif_dni_cif); 
$invoices = Invoices::whereHas('userclient', function($query) use($nif) { 
    $query->where('nif', $nif); 
})
->where(function($query) {
    $query->where('status', 0)
          ->orWhere('status', 2);
})
->orderBy('updated_at', 'desc')
->get();

方法二:用whereIn简化状态判断(更简洁)

$nif = \Crypt::decryptString(\Auth::user()->userprofile->nif_dni_cif); 
$invoices = Invoices::whereHas('userclient', function($query) use($nif) { 
    $query->where('nif', $nif); 
})
->whereIn('status', [0, 2])
->orderBy('updated_at', 'desc')
->get();
2. 检查加密字段的查询方式

你提到“身份文档字段为加密存储”,如果这里指的是数据库中userclient表的nif字段是加密存储的,那原查询的匹配方式就错了:

  • 你现在是把当前用户的加密nif解密成明文,然后用明文去匹配数据库里的加密字段,这肯定匹配不到(除非数据库里的nif是明文)。

正确的做法应该是:把明文的$nif加密后,再去匹配数据库里的加密字段,也就是修改whereHas里的条件:

$nif = \Crypt::decryptString(\Auth::user()->userprofile->nif_dni_cif); 
// 把明文nif加密,匹配数据库里的加密字段
$encryptedNif = \Crypt::encryptString($nif);

$invoices = Invoices::whereHas('userclient', function($query) use($encryptedNif) { 
    $query->where('nif', $encryptedNif); 
})
->whereIn('status', [0, 2])
->orderBy('updated_at', 'desc')
->get();

如果userclient的nif是明文存储的,那这一步可以忽略,只需要修复查询逻辑即可。

额外提示

如果同一客户有多条userclient记录,whereHas会自动匹配所有关联的记录,只要有一条符合条件就会返回对应的发票,所以不需要额外处理多记录的情况。

内容的提问来源于stack exchange,提问作者jagcweb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 14:17:31