feat: Add deposit success email notification system with new mailer, job, view, and client update request.

This commit is contained in:
pbao9
2026-02-19 20:33:24 +07:00
parent c720e62bda
commit 7769326ac9
9 changed files with 612 additions and 0 deletions
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api\Client;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\Client\ClientAuthRequest;
use App\Http\Requests\Api\Client\ClientRegisterRequest;
use App\Http\Requests\Api\Client\ClientUpdateRequest;
use App\Http\Resources\Api\Client\ClientResource;
use App\Services\Api\Client\ClientAuthService;
use Illuminate\Support\Facades\Auth;
@@ -213,4 +214,20 @@ class ClientController extends Controller
'message' => 'Đã đăng xuất thành công.',
]);
}
public function update(ClientUpdateRequest $request)
{
$user = auth('client')->user();
$user->fill($request->validated());
$user->save();
return response()->json([
'error' => false,
'message' => 'Cập nhật thông tin thành công',
'data' => [
'client' => new ClientResource($user),
],
]);
}
}
@@ -6,6 +6,7 @@ use App\Enums\TransactionStatus;
use App\Http\Controllers\Controller;
use App\Http\Requests\DepositRequest;
use App\Http\Services\VNPayService;
use App\Jobs\Mail\Customer\DepositSuccessJob;
use App\Models\Customer;
use App\Models\Log;
use App\Models\Transaction;
@@ -148,6 +149,17 @@ class TransactionController extends Controller
'customer_id' => $transaction->customer_id,
]);
DepositSuccessJob::dispatch([
'customer_email' => $customer->email,
'customer_name' => $customer->fullname,
'transaction_code' => $transaction->public_code,
'amount' => $transaction->amount,
'credit' => $transaction->amount / 100,
'current_total' => $customer->total,
'current_credit' => $customer->credit,
'deposit_date' => now()->format('d/m/Y H:i:s'),
]);
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
@@ -0,0 +1,34 @@
<?php
namespace App\Http\Requests\Api\Client;
use Illuminate\Foundation\Http\FormRequest;
class ClientUpdateRequest extends FormRequest
{
public function authorize(): bool
{
return auth('client')->check();
}
public function rules(): array
{
return [
'fullname' => 'required|string|max:255',
'phone' => 'required|string|max:20',
'company' => 'nullable|string|max:255',
'address' => 'nullable|string|max:500',
'province_code' => 'nullable|string|max:10',
'ward_code' => 'nullable|string|max:10',
'gender' => 'nullable|in:1,2,3',
];
}
public function messages(): array
{
return [
'fullname.required' => 'Họ tên là bắt buộc',
'phone.required' => 'Số điện thoại là bắt buộc',
];
}
}
@@ -0,0 +1,36 @@
<?php
namespace App\Jobs\Mail\Customer;
use App\Mail\Customer\DepositSuccess;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
class DepositSuccessJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public array $data;
public function __construct(array $data)
{
$this->data = $data;
}
public function handle(): void
{
try {
Mail::to($this->data['customer_email'])
->send(new DepositSuccess($this->data));
} catch (\Throwable $e) {
\Log::error('Không thể gửi email thông báo nạp tiền thành công: ' . $e->getMessage(), [
'customer_email' => $this->data['customer_email'] ?? null,
'transaction_code' => $this->data['transaction_code'] ?? null,
]);
}
}
}
+50
View File
@@ -0,0 +1,50 @@
<?php
namespace App\Mail\Customer;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class DepositSuccess extends Mailable
{
use Queueable, SerializesModels;
public array $data;
public function __construct(array $data)
{
$this->data = $data;
}
public function envelope(): Envelope
{
return new Envelope(
subject: '✅ Nạp tiền thành công - ' . number_format($this->data['amount']) . ' VNĐ',
);
}
public function content(): Content
{
return new Content(
view: 'emails.customer.deposit-success',
with: [
'customerName' => $this->data['customer_name'] ?? 'Khách hàng',
'transactionCode' => $this->data['transaction_code'] ?? 'N/A',
'amount' => $this->data['amount'] ?? 0,
'amountFormatted' => number_format($this->data['amount']) ?? '0',
'credit' => $this->data['credit'] ?? 0,
'creditFormatted' => number_format($this->data['credit']) ?? '0',
'currentTotal' => $this->data['current_total'] ?? 0,
'currentTotalFormatted' => number_format($this->data['current_total']) ?? '0',
'currentCredit' => $this->data['current_credit'] ?? 0,
'currentCreditFormatted' => number_format($this->data['current_credit']) ?? '0',
'depositDate' => $this->data['deposit_date'] ?? now()->format('d/m/Y H:i:s'),
'supportEmail' => config('mail.support_email', 'support@thegioiso.com'),
'supportPhone' => config('mail.support_phone', '1900.xxxx'),
],
);
}
}
+19
View File
@@ -52,6 +52,25 @@ class Customer extends Authenticatable implements JWTSubject
'ward_code',
];
protected $updatable = [
'fullname',
'phone',
'company',
'address',
'province_code',
'ward_code',
'gender',
];
public function updatableFill(array $data): self
{
$data = array_intersect_key($data, array_flip($this->updatable));
foreach ($data as $key => $value) {
$this->{$key} = $value;
}
return $this;
}
/**
* Appends for API
*/