feat: hồ sơ khách (ngày sinh, tỉnh/phường theo mã), gộp menu + nút tắt, thông báo theo uuid
- PUT v1/client/update: gender theo enum ClientGender (0 Nam/1 Nữ), thêm
birthday (cột mới), province_code/ward_code validate theo bảng provinces/wards
(phường phải thuộc tỉnh). Migration nạp dữ liệu hành chính 2025 từ
province_ward_import.sql (chỉ bảng trống), API GET v1/provinces[/{code}/wards].
- CustomerObserver/OrderObserver log giá trị cũ bằng getRawOriginal: getOriginal
trả enum object, nối chuỗi gây 500 khi khách đổi giới tính.
- ClientResource: các cờ trả boolean, CCCD chỉ trả cccd_updated (không lộ ảnh/số).
- GET v1/setting/menu trả cả items + quick_links, bỏ v1/setting/quick-links.
- Thông báo admin/khách tra theo uuid thay vì id tự tăng.
- Chặn gửi template marketing cho khách đã tắt nhận email marketing.
- Xoá ProvinceWardSeeder và Customer::$updatable không dùng.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
12d5b4951c
commit
bf78f3b810
+8
-8
@@ -13,6 +13,7 @@ use App\Http\Controllers\Api\Service\SnapshotController;
|
||||
use App\Http\Controllers\Api\Service\VmController;
|
||||
use App\Http\Controllers\Api\Service\VmRebuildController;
|
||||
use App\Http\Controllers\Api\Admin\Domain\InetDomainController;
|
||||
use App\Http\Controllers\Api\Client\AdministrativeDivisionController;
|
||||
use App\Http\Controllers\Api\Client\BankController as ClientBankController;
|
||||
use App\Http\Controllers\Api\Client\Docs\PostCategoryController as ClientPostCategoryController;
|
||||
use App\Http\Controllers\Api\Client\Docs\PostController as ClientPostController;
|
||||
@@ -39,12 +40,6 @@ Route::prefix('v1')
|
||||
Route::post('forgot-password', 'forgotPassword')->middleware(['throttle:client-auth', 'turnstile'])->name('forgot-password');
|
||||
Route::post('reset-password', 'resetPassword')->middleware(['throttle:client-auth', 'turnstile'])->name('reset-password');
|
||||
Route::get('reset-password/{token}', 'showResetToken')->middleware('throttle:client-auth')->name('reset-password.show');
|
||||
// Ảnh CCCD nằm trên disk private, chỉ truy cập qua URL ký (ClientResource cấp, hết hạn 60 phút)
|
||||
Route::get('cccd/{customer}/{side}', 'cccdImage')
|
||||
->whereNumber('customer')
|
||||
->whereIn('side', ['front', 'back'])
|
||||
->middleware('signed:relative')
|
||||
->name('cccd');
|
||||
Route::post('impersonate/exchange', 'impersonateExchange')->name('impersonate.exchange');
|
||||
Route::post('login/two-factor', 'verifyLoginTwoFactor')->middleware('throttle:client-auth')->name('login.two-factor');
|
||||
Route::post('login/two-factor/resend', 'resendLoginTwoFactor')->middleware('throttle:client-auth')->name('login.two-factor.resend');
|
||||
@@ -151,7 +146,8 @@ Route::prefix('v1')
|
||||
->controller(NotificationController::class)
|
||||
->group(function () {
|
||||
Route::get('/', fn () => app(NotificationController::class)->index(request(), 'client'));
|
||||
Route::patch('{id}/read', fn ($id) => app(NotificationController::class)->markRead(request(), 'client', (int) $id));
|
||||
Route::get('{uuid}', fn ($uuid) => app(NotificationController::class)->show(request(), 'client', $uuid))->whereUuid('uuid');
|
||||
Route::patch('{uuid}/read', fn ($uuid) => app(NotificationController::class)->markRead(request(), 'client', $uuid))->whereUuid('uuid');
|
||||
Route::patch('read-all', fn () => app(NotificationController::class)->markAllRead(request(), 'client'));
|
||||
});
|
||||
|
||||
@@ -207,7 +203,6 @@ Route::prefix('v1')
|
||||
Route::get('email', 'getEmailSetting')->name('email');
|
||||
Route::get('turnstile', 'getTurnstileSetting')->name('turnstile');
|
||||
Route::get('menu', 'getMenu')->name('menu');
|
||||
Route::get('quick-links', 'getQuickLinks')->name('quick-links');
|
||||
Route::get('popups', 'getPopups')->name('popups');
|
||||
});
|
||||
});
|
||||
@@ -215,6 +210,11 @@ Route::prefix('v1')
|
||||
// Public bank list for deposit form
|
||||
Route::get('banks', [ClientBankController::class, 'index'])->name('banks.list');
|
||||
|
||||
Route::controller(AdministrativeDivisionController::class)->group(function () {
|
||||
Route::get('provinces', 'provinces')->name('provinces');
|
||||
Route::get('provinces/{province}/wards', 'wards')->where('province', '[0-9]+')->name('provinces.wards');
|
||||
});
|
||||
|
||||
Route::prefix('post-categories')
|
||||
->controller(ClientPostCategoryController::class)
|
||||
->as('client.docs.categories.')
|
||||
|
||||
Reference in New Issue
Block a user