study-api-v2/app/Services/BaseService.php

270 lines
6.7 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Services;
use App\Exceptions\BusinessException;
use App\Helpers\ResponseEnum;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
/**
* 基础服务类
*/
abstract class BaseService
{
/**
* 模型实例
*/
protected Model $model;
/**
* 模型类名
*/
protected string $modelClass;
public function __construct()
{
if (isset($this->modelClass)) {
$this->model = new $this->modelClass();
}
}
/**
* 创建记录
*/
public function create(array $data): Model
{
DB::beginTransaction();
try {
// 验证唯一性
$this->validateUnique($data);
// 过滤字段
$filteredData = $this->filterFields($data);
// 创建记录BaseModel会自动设置系统字段
$model = $this->modelClass::create($filteredData);
DB::commit();
return $model;
} catch (BusinessException $e) {
DB::rollBack();
throw $e;
} catch (\Exception $e) {
DB::rollBack();
throw new BusinessException(ResponseEnum::DATA_INSERT_ERROR, $e->getMessage());
}
}
/**
* 更新记录
*/
public function update(int $id, array $data): Model
{
DB::beginTransaction();
try {
$model = $this->findById($id);
// 验证租户权限
if (!$model->validateTenantAccess()) {
throw new BusinessException(ResponseEnum::CLIENT_HTTP_UNAUTHORIZED, '无权限访问该数据');
}
// 验证唯一性(排除当前记录)
$this->validateUnique($data, $id);
// 过滤字段
$filteredData = $this->filterFields($data);
// 更新记录BaseModel会自动设置更新字段
$model->update($filteredData);
DB::commit();
return $model;
} catch (BusinessException $e) {
DB::rollBack();
throw $e;
} catch (\Exception $e) {
DB::rollBack();
throw new BusinessException(ResponseEnum::DATA_UPDATE_ERROR, $e->getMessage());
}
}
/**
* 删除记录
*/
public function delete(int $id): bool
{
DB::beginTransaction();
try {
$model = $this->findById($id);
// 验证租户权限
if (!$model->validateTenantAccess()) {
throw new BusinessException(ResponseEnum::CLIENT_HTTP_UNAUTHORIZED, '无权限访问该数据');
}
$result = $model->delete();
DB::commit();
return $result;
} catch (BusinessException $e) {
DB::rollBack();
throw $e;
} catch (\Exception $e) {
DB::rollBack();
throw new BusinessException(ResponseEnum::DATA_DELETE_ERROR, $e->getMessage());
}
}
/**
* 批量删除记录
*/
public function batchDelete(array $ids): bool
{
DB::beginTransaction();
try {
if (empty($ids)) {
throw new BusinessException(ResponseEnum::CLIENT_PARAMETER_ERROR, 'ID列表不能为空');
}
// 验证所有记录的租户权限
$models = $this->modelClass::whereIn('id', $ids)->get();
foreach ($models as $model) {
if (!$model->validateTenantAccess()) {
throw new BusinessException(ResponseEnum::CLIENT_HTTP_UNAUTHORIZED, '无权限访问部分数据');
}
}
$deleteCount = $this->modelClass::whereIn('id', $ids)->delete();
if ($deleteCount === 0) {
throw new BusinessException(ResponseEnum::DATA_NOT_FOUND_ERROR);
}
DB::commit();
return true;
} catch (BusinessException $e) {
DB::rollBack();
throw $e;
} catch (\Exception $e) {
DB::rollBack();
throw new BusinessException(ResponseEnum::DATA_DELETE_ERROR, $e->getMessage());
}
}
/**
* 获取记录详情
*/
public function detail(int $id): Model
{
$model = $this->findById($id);
// 验证租户权限
if (!$model->validateTenantAccess()) {
throw new BusinessException(ResponseEnum::CLIENT_HTTP_UNAUTHORIZED, '无权限访问该数据');
}
return $model;
}
/**
* 获取记录列表(基础版)
*/
public function list(array $params): LengthAwarePaginator
{
$page = (int)($params['page'] ?? 1);
$pageSize = (int)($params['page_size'] ?? 15);
// 使用模型的全局作用域自动过滤租户数据
$query = $this->modelClass::query();
// 子类可以重写此方法来添加特定的搜索条件
$this->applySearchConditions($query, $params);
// 添加排序
$query->ordered();
return $query->paginate($pageSize, ['*'], 'page', $page);
}
/**
* 应用搜索条件(子类重写此方法)
*/
protected function applySearchConditions($query, array $params): void
{
// 默认不添加任何搜索条件,子类可以重写
}
/**
* 根据ID查找记录
*/
protected function findById(int $id): Model
{
// 使用模型的全局作用域自动过滤租户数据
$model = $this->modelClass::find($id);
if (!$model) {
throw new BusinessException(ResponseEnum::DATA_NOT_FOUND_ERROR);
}
return $model;
}
/**
* 验证唯一性(子类重写此方法)
*/
protected function validateUnique(array $data, ?int $excludeId = null): void
{
// 默认不验证唯一性,子类可以重写
}
/**
* 过滤字段
*/
protected function filterFields(array $data): array
{
$fillable = $this->model->getFillable();
return array_filter(
array_intersect_key($data, array_flip($fillable)),
function ($value) {
return $value !== null && $value !== '';
}
);
}
/**
* 获取当前租户ID
*/
protected function getCurrentTenantId(): ?int
{
$user = auth('admin')->user();
return $user ? $user->tenant_id : null;
}
/**
* 验证租户权限
*/
protected function validateTenantAccess(?int $tenantId): bool
{
$currentTenantId = $this->getCurrentTenantId();
if ($currentTenantId === null) {
return false;
}
return $tenantId == $currentTenantId;
}
}