diff --git a/app/Http/Controllers/Admin/MemberNoteController.php b/app/Http/Controllers/Admin/MemberNoteController.php new file mode 100644 index 0000000..d664883 --- /dev/null +++ b/app/Http/Controllers/Admin/MemberNoteController.php @@ -0,0 +1,48 @@ +notes()->with('author')->get(); + + return response()->json(['notes' => $notes]); + } + + /** + * Store a new note for a member + */ + public function store(StoreNoteRequest $request, Member $member) + { + $note = DB::transaction(function () use ($request, $member) { + $note = $member->notes()->create([ + 'content' => $request->content, + 'author_user_id' => $request->user()->id, + ]); + + AuditLogger::log('note.created', $note, [ + 'member_id' => $member->id, + 'member_name' => $member->full_name, + 'author' => $request->user()->name, + ]); + + return $note; + }); + + return response()->json([ + 'note' => $note->load('author'), + 'message' => '備忘錄已新增', + ], 201); + } +} diff --git a/app/Http/Requests/StoreNoteRequest.php b/app/Http/Requests/StoreNoteRequest.php new file mode 100644 index 0000000..1515363 --- /dev/null +++ b/app/Http/Requests/StoreNoteRequest.php @@ -0,0 +1,41 @@ +|string> + */ + public function rules(): array + { + return [ + 'content' => ['required', 'string', 'min:1', 'max:65535'], + ]; + } + + /** + * Get custom messages for validator errors. + */ + public function messages(): array + { + return [ + 'content.required' => '備忘錄內容為必填欄位', + 'content.min' => '備忘錄內容不可為空白', + 'content.max' => '備忘錄內容不可超過 65535 字元', + ]; + } +} diff --git a/routes/web.php b/routes/web.php index 2717abb..a6e6e67 100644 --- a/routes/web.php +++ b/routes/web.php @@ -27,6 +27,7 @@ use App\Http\Controllers\Admin\ArticleController; use App\Http\Controllers\Admin\ArticleCategoryController; use App\Http\Controllers\Admin\ArticleTagController; use App\Http\Controllers\Admin\PageController; +use App\Http\Controllers\Admin\MemberNoteController; use App\Http\Controllers\PublicBugReportController; use App\Http\Controllers\IncomeController; use Illuminate\Support\Facades\Route; @@ -138,6 +139,10 @@ Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(fun Route::delete('/members/{member}/payments/{payment}', [AdminPaymentController::class, 'destroy'])->name('members.payments.destroy'); Route::get('/members/{member}/payments/{payment}/receipt', [AdminPaymentController::class, 'receipt'])->name('members.payments.receipt'); + // Member Notes (會員備忘錄) + Route::get('/members/{member}/notes', [MemberNoteController::class, 'index'])->name('members.notes.index'); + Route::post('/members/{member}/notes', [MemberNoteController::class, 'store'])->name('members.notes.store'); + Route::get('/finance-documents', [FinanceDocumentController::class, 'index'])->name('finance.index'); Route::get('/finance-documents/create', [FinanceDocumentController::class, 'create'])->name('finance.create'); Route::post('/finance-documents', [FinanceDocumentController::class, 'store'])->name('finance.store');