Files
yuezi-saas/backend/app/Traits/BelongsToStore.php
T
li c778639f05 fix: 修复列表筛选空参与树数据展示
将后端 status/audit_status 筛选从 has() 改为 filled(),避免空字符串导致列表被误筛空;修复预定 status=0 筛选失效;前端兼容财务分类树形返回与菜单/字典数组返回,解决新增成功但列表空。
2026-03-15 00:06:11 +08:00

75 lines
2.0 KiB
PHP

<?php
namespace App\Traits;
use App\Models\Store;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* 门店隔离 Trait
* 使用方法:在 Model 中 use BelongsToStore;
* 自动 Scope 过滤当前门店数据
*/
trait BelongsToStore
{
public static function bootBelongsToStore(): void
{
// 查询自动过滤门店
static::addGlobalScope('store', function (Builder $builder) {
// 超管:不带 X-Store-Id 时默认“总览”(不加 store 过滤)
// 普通用户:按自身 store_id 过滤
if ($storeId = self::getQueryStoreId()) {
$builder->where($builder->getModel()->getTable() . '.store_id', $storeId);
}
});
// 创建时自动填入 store_id
static::creating(function ($model) {
if (empty($model->store_id)) {
// 创建时:超管若指定 X-Store-Id 则写入该门店;否则落到自身 store_id
if ($storeId = self::getCreateStoreId()) {
$model->store_id = $storeId;
}
}
});
}
public function store(): BelongsTo
{
return $this->belongsTo(Store::class);
}
private static function getQueryStoreId(): ?int
{
$user = auth()->user();
if (!$user) {
return null;
}
// 超管默认总览:不传 X-Store-Id 则不做门店过滤
if ($user->is_super) {
if (request()->header('X-Store-Id')) {
return (int) request()->header('X-Store-Id');
}
return null;
}
return $user?->store_id;
}
private static function getCreateStoreId(): ?int
{
$user = auth()->user();
if (!$user) {
return null;
}
if ($user->is_super && request()->header('X-Store-Id')) {
return (int) request()->header('X-Store-Id');
}
return $user?->store_id;
}
}