1.繼承FormRequest? ?其中id是路由傳參 name是對象中必填校驗
<?phpnamespace App\Http\Requests\Admin\User;use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;class user_info_uptRequest extends FormRequest
{public function authorize(): bool{return true;}// 在驗證前把路由參數寫入到請求數據中protected function prepareForValidation(): void{$this->merge(['id' => $this->route('id'),]);}public function rules(): array{return ['id' => ['required','integer','min:1',// 需要的話可以加 exists 約束// Rule::exists('your_table', 'id'),],// 表單參數校驗'name' => ['required','string','min:1'],];}public function messages(): array{return ['required' => '必填','max' => '最大10'];}public function attributes(): array{return ['id' => trans('dict.id'),'name' => trans('dict.name'),];}// 如需獲取路由 idpublic function getNodataSeq(){return $this->route('id');}
}
2.router
// routes/web.php
Route::post('/user/{id}/update', [UserController::class, 'updateOneUser']);
3.controller
<?phpnamespace App\Http\Controllers;class UserControllerextends Controllerpublic function __construct(protected UserService $service) {}public function updateOneUser(user_info_uptRequest $request){return $this->service->executeQuery($request, 'updateOneUser');}
4.service(模擬)
<?phpnamespace App\Services;use App\Http\Requests\User\user_info_uptRequest; // 按你的實際命名空間調整
use App\Http\Resources\UserResource;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Throwable;class UserService
{/*** 統一入口:根據 action 路由到具體方法*/public function executeQuery($request, string $action){switch ($action) {case 'updateOneUser':return $this->updateOneUser($request);// 其他動作...default:abort(400, "Unknown action: {$action}");}}/*** 更新單個用戶* 期望 request 已通過 FormRequest 校驗,包含 id 與可更新字段*/public function updateOneUser(user_info_uptRequest $request){// 建議在 FormRequest 中已 merge 路由 id -> 'id'$validated = $request->validated();// 允許更新的字段(按你的業務調整)$updatable = collect($validated)->only(['name','email','phone','status',// ... 其它允許更新的列])->toArray();if (empty($validated['id'])) {abort(422, 'Missing user id.');}return DB::transaction(function () use ($validated, $updatable) {/** @var \App\Models\User $user */$user = User::query()->lockForUpdate()->findOrFail($validated['id']);// 可加業務規則:例如 email 不可重復、狀態流轉校驗等$user->fill($updatable);$user->save();// 返回標準資源return (new UserResource($user))->additional(['success' => true,'message' => 'User updated successfully.',]);});}
}
5.JsonResource
<?phpnamespace App\Http\Resources;use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;class UserResource extends JsonResource
{public static $wrap = 'data'; // 默認就是 data,可按需保留或去掉/*** @param Request $request*/public function toArray($request): array{return ['id' => $this->id,'name' => $this->name,'email' => $this->email,'phone' => $this->phone,'status' => $this->status,'roles' => $this->whenLoaded('roles', fn () => $this->roles->pluck('name')),'created_at' => optional($this->created_at)->toDateTimeString(),'updated_at' => optional($this->updated_at)->toDateTimeString(),];}
}
單條更新通常返回 UserResource?
分頁多條數據?用App\Http\Resources\UserCollection?
6.?Collection
<?phpnamespace App\Http\Resources;use Illuminate\Http\Resources\Json\ResourceCollection;class UserCollection extends ResourceCollection
{public static $wrap = 'data';public function toArray($request): array{// 將每個項包裝成 UserResourcereturn ['items' => UserResource::collection($this->collection),];}public function with($request): array{// 如果是 LengthAwarePaginator,會自帶 meta/links,這里可補充自定義 metareturn ['meta' => ['total' => method_exists($this->resource, 'total') ? $this->resource->total() : $this->collection->count(),'per_page' => method_exists($this->resource, 'perPage') ? $this->resource->perPage() : null,'current_page' => method_exists($this->resource, 'currentPage') ? $this->resource->currentPage() : null,'last_page' => method_exists($this->resource, 'lastPage') ? $this->resource->lastPage() : null,],'success' => true,];}
}
附件:AbstractApiBaseService
<?phpnamespace App\Services;use Exception;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;/*** 抽象 API 基礎服務類* 提供統一的增刪改查執行入口、事務處理、異常捕獲及日志功能* @author J總裁的小芒果*/
abstract class AbstractApiBaseService
{/*** 更新(增刪改)處理** @param mixed $request 請求對象(通常是 FormRequest)* @param string $method 調用的方法名* @return mixed 執行結果(通常是 Resource/Response)*/public function execute($request, $method){return $this->baseExecute($request, $method, true);}/*** 查詢處理** @param mixed $request 請求對象(通常是 FormRequest)* @param string $method 調用的方法名* @return mixed 執行結果(通常是 Resource/Response)*/public function executeQuery($request, $method){return $this->baseExecute($request, $method, false);}/*** 核心執行方法* 用于統一處理事務、調用對應的業務方法、異常捕獲及日志** @param mixed $request 請求對象* @param string $method 調用的方法名* @param bool $transFlg 是否啟用事務(true=啟用,用于增刪改;false=不啟用,用于查詢)* @return mixed 執行結果* @throws Exception*/private function baseExecute($request, $method, $transFlg){DB::beginTransaction();try {// 動態調用子類中對應的方法$result = $this->{$method}($request);if ($transFlg) {$statusCode = $result->getStatusCode();if ($statusCode == 200) {DB::commit();} else {DB::rollBack();}}return $result;} catch (Exception $e) {DB::rollBack();Log::debug($e);// 自定義的全局錯誤記錄方法log_error($e);throw $e;}}/*** 寫入操作日志** @param string $SBJ 日志主題* @param string $CONT 日志內容*/public function log($SBJ, $CONT){$admin = Auth::user();DB::table('LOG')->insert(['MEM_CODE' => $admin->MEM_CODE,'SBJ' => $SBJ,'CONT' => $CONT,'INS_DATE' => now()->format('YmdHis'),// 'ip' => Request::ip(), // 可選:記錄請求IP]);}
}